mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-13 09:33:50 +00:00
mcize a bunch more stuff, using EmitRawText for things we
don't have mcstreamer support for yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100319 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7ad07c4636
commit
9d7efd3081
@ -221,6 +221,14 @@ namespace {
|
||||
/// EmitMachineConstantPoolValue - Print a machine constantpool value to
|
||||
/// the .s file.
|
||||
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
|
||||
SmallString<128> Str;
|
||||
raw_svector_ostream OS(Str);
|
||||
EmitMachineConstantPoolValue(MCPV, OS);
|
||||
OutStreamer.EmitRawText(OS.str());
|
||||
}
|
||||
|
||||
void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV,
|
||||
raw_ostream &O) {
|
||||
switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) {
|
||||
case 1: O << MAI->getData8bitsDirective(0); break;
|
||||
case 2: O << MAI->getData16bitsDirective(0); break;
|
||||
@ -229,12 +237,9 @@ namespace {
|
||||
}
|
||||
|
||||
ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
|
||||
SmallString<128> TmpNameStr;
|
||||
|
||||
if (ACPV->isLSDA()) {
|
||||
raw_svector_ostream(TmpNameStr) << MAI->getPrivateGlobalPrefix() <<
|
||||
"_LSDA_" << getFunctionNumber();
|
||||
O << TmpNameStr.str();
|
||||
O << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
|
||||
} else if (ACPV->isBlockAddress()) {
|
||||
O << GetBlockAddressSymbol(ACPV->getBlockAddress())->getName();
|
||||
} else if (ACPV->isGlobalValue()) {
|
||||
@ -271,7 +276,6 @@ namespace {
|
||||
O << "-.";
|
||||
O << ')';
|
||||
}
|
||||
OutStreamer.AddBlankLine();
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
@ -287,11 +291,11 @@ namespace {
|
||||
|
||||
void ARMAsmPrinter::EmitFunctionEntryLabel() {
|
||||
if (AFI->isThumbFunction()) {
|
||||
O << "\t.code\t16\n";
|
||||
O << "\t.thumb_func";
|
||||
OutStreamer.EmitRawText(StringRef("\t.code\t16"));
|
||||
if (Subtarget->isTargetDarwin())
|
||||
O << '\t' << *CurrentFnSym;
|
||||
O << '\n';
|
||||
OutStreamer.EmitRawText("\t.thumb_func\t"+Twine(CurrentFnSym->getName()));
|
||||
else
|
||||
OutStreamer.EmitRawText(StringRef("\t.thumb_func"));
|
||||
}
|
||||
|
||||
OutStreamer.EmitLabel(CurrentFnSym);
|
||||
@ -1146,38 +1150,48 @@ void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
|
||||
}
|
||||
|
||||
// Use unified assembler syntax.
|
||||
O << "\t.syntax unified\n";
|
||||
OutStreamer.EmitRawText(StringRef("\t.syntax unified"));
|
||||
|
||||
// Emit ARM Build Attributes
|
||||
if (Subtarget->isTargetELF()) {
|
||||
// CPU Type
|
||||
std::string CPUString = Subtarget->getCPUString();
|
||||
if (CPUString != "generic")
|
||||
O << "\t.cpu " << CPUString << '\n';
|
||||
OutStreamer.EmitRawText("\t.cpu " + Twine(CPUString));
|
||||
|
||||
// FIXME: Emit FPU type
|
||||
if (Subtarget->hasVFP2())
|
||||
O << "\t.eabi_attribute " << ARMBuildAttrs::VFP_arch << ", 2\n";
|
||||
OutStreamer.EmitRawText("\t.eabi_attribute " +
|
||||
Twine(ARMBuildAttrs::VFP_arch) + ", 2");
|
||||
|
||||
// Signal various FP modes.
|
||||
if (!UnsafeFPMath)
|
||||
O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_denormal << ", 1\n"
|
||||
<< "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_exceptions << ", 1\n";
|
||||
|
||||
if (!UnsafeFPMath) {
|
||||
OutStreamer.EmitRawText("\t.eabi_attribute " +
|
||||
Twine(ARMBuildAttrs::ABI_FP_denormal) + ", 1");
|
||||
OutStreamer.EmitRawText("\t.eabi_attribute " +
|
||||
Twine(ARMBuildAttrs::ABI_FP_exceptions) + ", 1");
|
||||
}
|
||||
|
||||
if (FiniteOnlyFPMath())
|
||||
O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_number_model << ", 1\n";
|
||||
OutStreamer.EmitRawText("\t.eabi_attribute " +
|
||||
Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 1");
|
||||
else
|
||||
O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_FP_number_model << ", 3\n";
|
||||
OutStreamer.EmitRawText("\t.eabi_attribute " +
|
||||
Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 3");
|
||||
|
||||
// 8-bytes alignment stuff.
|
||||
O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_needed << ", 1\n"
|
||||
<< "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_preserved << ", 1\n";
|
||||
OutStreamer.EmitRawText("\t.eabi_attribute " +
|
||||
Twine(ARMBuildAttrs::ABI_align8_needed) + ", 1");
|
||||
OutStreamer.EmitRawText("\t.eabi_attribute " +
|
||||
Twine(ARMBuildAttrs::ABI_align8_preserved) + ", 1");
|
||||
|
||||
// Hard float. Use both S and D registers and conform to AAPCS-VFP.
|
||||
if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard)
|
||||
O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_HardFP_use << ", 3\n"
|
||||
<< "\t.eabi_attribute " << ARMBuildAttrs::ABI_VFP_args << ", 1\n";
|
||||
|
||||
if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
|
||||
OutStreamer.EmitRawText("\t.eabi_attribute " +
|
||||
Twine(ARMBuildAttrs::ABI_HardFP_use) + ", 3");
|
||||
OutStreamer.EmitRawText("\t.eabi_attribute " +
|
||||
Twine(ARMBuildAttrs::ABI_VFP_args) + ", 1");
|
||||
}
|
||||
// FIXME: Should we signal R9 usage?
|
||||
}
|
||||
}
|
||||
@ -1191,8 +1205,6 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
|
||||
MachineModuleInfoMachO &MMIMacho =
|
||||
MMI->getObjFileInfo<MachineModuleInfoMachO>();
|
||||
|
||||
O << '\n';
|
||||
|
||||
// Output non-lazy-pointers for external and common global variables.
|
||||
MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
|
||||
|
||||
|
@ -130,21 +130,18 @@ void AlphaAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) {
|
||||
/// EmitFunctionBodyStart - Targets can override this to emit stuff before
|
||||
/// the first basic block in the function.
|
||||
void AlphaAsmPrinter::EmitFunctionBodyStart() {
|
||||
O << "\t.ent " << *CurrentFnSym << "\n";
|
||||
OutStreamer.EmitRawText("\t.ent " + Twine(CurrentFnSym->getName()));
|
||||
}
|
||||
|
||||
/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
|
||||
/// the last basic block in the function.
|
||||
void AlphaAsmPrinter::EmitFunctionBodyEnd() {
|
||||
O << "\t.end " << *CurrentFnSym << "\n";
|
||||
OutStreamer.EmitRawText("\t.end " + Twine(CurrentFnSym->getName()));
|
||||
}
|
||||
|
||||
void AlphaAsmPrinter::EmitStartOfAsmFile(Module &M) {
|
||||
if (TM.getSubtarget<AlphaSubtarget>().hasCT())
|
||||
O << "\t.arch ev6\n"; //This might need to be ev67, so leave this test here
|
||||
else
|
||||
O << "\t.arch ev6\n";
|
||||
O << "\t.set noat\n";
|
||||
OutStreamer.EmitRawText(StringRef("\t.arch ev6"));
|
||||
OutStreamer.EmitRawText(StringRef("\t.set noat"));
|
||||
}
|
||||
|
||||
/// PrintAsmOperand - Print out an operand for an inline asm expression.
|
||||
|
@ -73,8 +73,7 @@ namespace {
|
||||
const char *Modifier = 0);
|
||||
void printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
|
||||
const char *Modifier = 0);
|
||||
void printSavedRegsBitmask();
|
||||
void printHex32(unsigned int Value);
|
||||
void printSavedRegsBitmask(raw_ostream &OS);
|
||||
|
||||
const char *emitCurrentABIString();
|
||||
void emitFrameDirective();
|
||||
@ -131,9 +130,17 @@ namespace {
|
||||
// Mask directives
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Print a 32 bit hex number with all numbers.
|
||||
static void printHex32(unsigned int Value, raw_ostream &O) {
|
||||
O << "0x";
|
||||
for (int i = 7; i >= 0; i--)
|
||||
O << utohexstr((Value & (0xF << (i*4))) >> (i*4));
|
||||
}
|
||||
|
||||
|
||||
// Create a bitmask with all callee saved registers for CPU or Floating Point
|
||||
// registers. For CPU registers consider RA, GP and FP for saving if necessary.
|
||||
void MBlazeAsmPrinter::printSavedRegsBitmask() {
|
||||
void MBlazeAsmPrinter::printSavedRegsBitmask(raw_ostream &O) {
|
||||
const TargetRegisterInfo &RI = *TM.getRegisterInfo();
|
||||
const MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>();
|
||||
|
||||
@ -159,15 +166,8 @@ void MBlazeAsmPrinter::printSavedRegsBitmask() {
|
||||
getRegisterNumbering(RI.getRARegister()));
|
||||
|
||||
// Print CPUBitmask
|
||||
O << "\t.mask \t"; printHex32(CPUBitmask); O << ','
|
||||
<< MBlazeFI->getCPUTopSavedRegOff() << '\n';
|
||||
}
|
||||
|
||||
// Print a 32 bit hex number with all numbers.
|
||||
void MBlazeAsmPrinter::printHex32(unsigned int Value) {
|
||||
O << "0x";
|
||||
for (int i = 7; i >= 0; i--)
|
||||
O << utohexstr( (Value & (0xF << (i*4))) >> (i*4) );
|
||||
O << "\t.mask \t"; printHex32(CPUBitmask, O);
|
||||
O << ',' << MBlazeFI->getCPUTopSavedRegOff() << '\n';
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -183,28 +183,31 @@ void MBlazeAsmPrinter::emitFrameDirective() {
|
||||
unsigned stackSize = MF->getFrameInfo()->getStackSize();
|
||||
|
||||
|
||||
O << "\t.frame\t" << getRegisterName(stackReg)
|
||||
<< ',' << stackSize << ','
|
||||
<< getRegisterName(returnReg)
|
||||
<< '\n';
|
||||
OutStreamer.EmitRawText("\t.frame\t" + Twine(getRegisterName(stackReg)) +
|
||||
"," + Twine(stackSize) + "," +
|
||||
Twine(getRegisterName(returnReg)));
|
||||
}
|
||||
|
||||
void MBlazeAsmPrinter::EmitFunctionEntryLabel() {
|
||||
O << "\t.ent\t" << *CurrentFnSym << '\n';
|
||||
OutStreamer.EmitLabel(CurrentFnSym);
|
||||
OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName()));
|
||||
OutStreamer.EmitLabel(CurrentFnSym);
|
||||
}
|
||||
|
||||
/// EmitFunctionBodyStart - Targets can override this to emit stuff before
|
||||
/// the first basic block in the function.
|
||||
void MBlazeAsmPrinter::EmitFunctionBodyStart() {
|
||||
emitFrameDirective();
|
||||
printSavedRegsBitmask();
|
||||
|
||||
SmallString<128> Str;
|
||||
raw_svector_ostream OS(Str);
|
||||
printSavedRegsBitmask(OS);
|
||||
OutStreamer.EmitRawText(OS.str());
|
||||
}
|
||||
|
||||
/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
|
||||
/// the last basic block in the function.
|
||||
void MBlazeAsmPrinter::EmitFunctionBodyEnd() {
|
||||
O << "\t.end\t" << *CurrentFnSym << '\n';
|
||||
OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));
|
||||
}
|
||||
|
||||
// Print out an operand for an inline asm expression.
|
||||
@ -233,11 +236,11 @@ void MBlazeAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
|
||||
break;
|
||||
|
||||
case MachineOperand::MO_FPImmediate: {
|
||||
const ConstantFP* fp = MO.getFPImm();
|
||||
printHex32(fp->getValueAPF().bitcastToAPInt().getZExtValue());
|
||||
const ConstantFP *fp = MO.getFPImm();
|
||||
printHex32(fp->getValueAPF().bitcastToAPInt().getZExtValue(), O);
|
||||
O << ";\t# immediate = " << *fp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case MachineOperand::MO_MachineBasicBlock:
|
||||
O << *MO.getMBB()->getSymbol();
|
||||
|
@ -50,18 +50,10 @@ namespace {
|
||||
return "MSP430 Assembly Printer";
|
||||
}
|
||||
|
||||
void printMCInst(const MCInst *MI) {
|
||||
MSP430InstPrinter(*MAI).printInstruction(MI, O);
|
||||
}
|
||||
void printOperand(const MachineInstr *MI, int OpNum,
|
||||
const char* Modifier = 0);
|
||||
void printPCRelImmOperand(const MachineInstr *MI, int OpNum) {
|
||||
printOperand(MI, OpNum);
|
||||
}
|
||||
raw_ostream &O, const char* Modifier = 0);
|
||||
void printSrcMemOperand(const MachineInstr *MI, int OpNum,
|
||||
const char* Modifier = 0);
|
||||
void printCCOperand(const MachineInstr *MI, int OpNum);
|
||||
void printMachineInstruction(const MachineInstr * MI);
|
||||
raw_ostream &O);
|
||||
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
unsigned AsmVariant, const char *ExtraCode,
|
||||
raw_ostream &O);
|
||||
@ -79,7 +71,7 @@ namespace {
|
||||
|
||||
|
||||
void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
|
||||
const char* Modifier) {
|
||||
raw_ostream &O, const char *Modifier) {
|
||||
const MachineOperand &MO = MI->getOperand(OpNum);
|
||||
switch (MO.getType()) {
|
||||
default: assert(0 && "Not implemented yet!");
|
||||
@ -126,7 +118,7 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
|
||||
}
|
||||
|
||||
void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
|
||||
const char* Modifier) {
|
||||
raw_ostream &O) {
|
||||
const MachineOperand &Base = MI->getOperand(OpNum);
|
||||
const MachineOperand &Disp = MI->getOperand(OpNum+1);
|
||||
|
||||
@ -135,28 +127,16 @@ void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
|
||||
// Imm here is in fact global address - print extra modifier.
|
||||
if (Disp.isImm() && !Base.getReg())
|
||||
O << '&';
|
||||
printOperand(MI, OpNum+1, "nohash");
|
||||
printOperand(MI, OpNum+1, O, "nohash");
|
||||
|
||||
// Print register base field
|
||||
if (Base.getReg()) {
|
||||
O << '(';
|
||||
printOperand(MI, OpNum);
|
||||
printOperand(MI, OpNum, O);
|
||||
O << ')';
|
||||
}
|
||||
}
|
||||
|
||||
void MSP430AsmPrinter::printCCOperand(const MachineInstr *MI, int OpNum) {
|
||||
switch (MI->getOperand(OpNum).getImm()) {
|
||||
default: assert(0 && "Unknown cond");
|
||||
case MSP430CC::COND_E: O << "eq"; break;
|
||||
case MSP430CC::COND_NE: O << "ne"; break;
|
||||
case MSP430CC::COND_HS: O << "hs"; break;
|
||||
case MSP430CC::COND_LO: O << "lo"; break;
|
||||
case MSP430CC::COND_GE: O << "ge"; break;
|
||||
case MSP430CC::COND_L: O << 'l'; break;
|
||||
}
|
||||
}
|
||||
|
||||
/// PrintAsmOperand - Print out an operand for an inline asm expression.
|
||||
///
|
||||
bool MSP430AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
@ -166,7 +146,7 @@ bool MSP430AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
if (ExtraCode && ExtraCode[0])
|
||||
return true; // Unknown modifier.
|
||||
|
||||
printOperand(MI, OpNo);
|
||||
printOperand(MI, OpNo, O);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -177,7 +157,7 @@ bool MSP430AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
|
||||
if (ExtraCode && ExtraCode[0]) {
|
||||
return true; // Unknown modifier.
|
||||
}
|
||||
printSrcMemOperand(MI, OpNo);
|
||||
printSrcMemOperand(MI, OpNo, O);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -72,8 +72,8 @@ namespace {
|
||||
void printSavedRegsBitmask(raw_ostream &O);
|
||||
void printHex32(unsigned int Value, raw_ostream &O);
|
||||
|
||||
const char *emitCurrentABIString();
|
||||
void emitFrameDirective(raw_ostream &O);
|
||||
const char *getCurrentABIString() const;
|
||||
void emitFrameDirective();
|
||||
|
||||
void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen'd.
|
||||
void EmitInstruction(const MachineInstr *MI) {
|
||||
@ -179,29 +179,28 @@ void MipsAsmPrinter::printHex32(unsigned Value, raw_ostream &O) {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// Frame Directive
|
||||
void MipsAsmPrinter::emitFrameDirective(raw_ostream &O) {
|
||||
void MipsAsmPrinter::emitFrameDirective() {
|
||||
const TargetRegisterInfo &RI = *TM.getRegisterInfo();
|
||||
|
||||
unsigned stackReg = RI.getFrameRegister(*MF);
|
||||
unsigned returnReg = RI.getRARegister();
|
||||
unsigned stackSize = MF->getFrameInfo()->getStackSize();
|
||||
|
||||
|
||||
O << "\t.frame\t" << '$' << LowercaseString(getRegisterName(stackReg))
|
||||
<< ',' << stackSize << ','
|
||||
<< '$' << LowercaseString(getRegisterName(returnReg))
|
||||
<< '\n';
|
||||
OutStreamer.EmitRawText("\t.frame\t$" +
|
||||
Twine(LowercaseString(getRegisterName(stackReg))) +
|
||||
"," + Twine(stackSize) + ",$" +
|
||||
Twine(LowercaseString(getRegisterName(returnReg))));
|
||||
}
|
||||
|
||||
/// Emit Set directives.
|
||||
const char *MipsAsmPrinter::emitCurrentABIString() {
|
||||
switch(Subtarget->getTargetABI()) {
|
||||
case MipsSubtarget::O32: return "abi32";
|
||||
case MipsSubtarget::O64: return "abiO64";
|
||||
case MipsSubtarget::N32: return "abiN32";
|
||||
case MipsSubtarget::N64: return "abi64";
|
||||
case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64
|
||||
default: break;
|
||||
const char *MipsAsmPrinter::getCurrentABIString() const {
|
||||
switch (Subtarget->getTargetABI()) {
|
||||
case MipsSubtarget::O32: return "abi32";
|
||||
case MipsSubtarget::O64: return "abiO64";
|
||||
case MipsSubtarget::N32: return "abiN32";
|
||||
case MipsSubtarget::N64: return "abi64";
|
||||
case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64
|
||||
default: break;
|
||||
}
|
||||
|
||||
llvm_unreachable("Unknown Mips ABI");
|
||||
@ -209,15 +208,19 @@ const char *MipsAsmPrinter::emitCurrentABIString() {
|
||||
}
|
||||
|
||||
void MipsAsmPrinter::EmitFunctionEntryLabel() {
|
||||
O << "\t.ent\t" << *CurrentFnSym << '\n';
|
||||
OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName()));
|
||||
OutStreamer.EmitLabel(CurrentFnSym);
|
||||
}
|
||||
|
||||
/// EmitFunctionBodyStart - Targets can override this to emit stuff before
|
||||
/// the first basic block in the function.
|
||||
void MipsAsmPrinter::EmitFunctionBodyStart() {
|
||||
emitFrameDirective(O);
|
||||
printSavedRegsBitmask(O);
|
||||
emitFrameDirective();
|
||||
|
||||
SmallString<128> Str;
|
||||
raw_svector_ostream OS(Str);
|
||||
printSavedRegsBitmask(OS);
|
||||
OutStreamer.EmitRawText(OS.str());
|
||||
}
|
||||
|
||||
/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
|
||||
@ -226,10 +229,9 @@ void MipsAsmPrinter::EmitFunctionBodyEnd() {
|
||||
// There are instruction for this macros, but they must
|
||||
// always be at the function end, and we can't emit and
|
||||
// break with BB logic.
|
||||
O << "\t.set\tmacro\n";
|
||||
O << "\t.set\treorder\n";
|
||||
|
||||
O << "\t.end\t" << *CurrentFnSym << '\n';
|
||||
OutStreamer.EmitRawText(StringRef("\t.set\tmacro"));
|
||||
OutStreamer.EmitRawText(StringRef("\t.set\treorder"));
|
||||
OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));
|
||||
}
|
||||
|
||||
|
||||
@ -351,15 +353,17 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
|
||||
// FIXME: Use SwitchSection.
|
||||
|
||||
// Tell the assembler which ABI we are using
|
||||
O << "\t.section .mdebug." << emitCurrentABIString() << '\n';
|
||||
OutStreamer.EmitRawText("\t.section .mdebug." + Twine(getCurrentABIString()));
|
||||
|
||||
// TODO: handle O64 ABI
|
||||
if (Subtarget->isABI_EABI())
|
||||
O << "\t.section .gcc_compiled_long" <<
|
||||
(Subtarget->isGP32bit() ? "32" : "64") << '\n';
|
||||
if (Subtarget->isGP32bit())
|
||||
OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long32"));
|
||||
else
|
||||
OutStreamer.EmitRawText(StringRef("\t.section .gcc_compiled_long64"));
|
||||
|
||||
// return to previous section
|
||||
O << "\t.previous" << '\n';
|
||||
OutStreamer.EmitRawText(StringRef("\t.previous"));
|
||||
}
|
||||
|
||||
// Force static initialization.
|
||||
|
@ -56,7 +56,7 @@ using namespace llvm;
|
||||
namespace {
|
||||
class PPCAsmPrinter : public AsmPrinter {
|
||||
protected:
|
||||
DenseMap<const MCSymbol*, const MCSymbol*> TOC;
|
||||
DenseMap<MCSymbol*, MCSymbol*> TOC;
|
||||
const PPCSubtarget &Subtarget;
|
||||
uint64_t LabelID;
|
||||
public:
|
||||
@ -316,10 +316,10 @@ namespace {
|
||||
raw_ostream &O) {
|
||||
const MachineOperand &MO = MI->getOperand(OpNo);
|
||||
assert(MO.getType() == MachineOperand::MO_GlobalAddress);
|
||||
const MCSymbol *Sym = Mang->getSymbol(MO.getGlobal());
|
||||
MCSymbol *Sym = Mang->getSymbol(MO.getGlobal());
|
||||
|
||||
// Map symbol -> label of TOC entry.
|
||||
const MCSymbol *&TOCEntry = TOC[Sym];
|
||||
MCSymbol *&TOCEntry = TOC[Sym];
|
||||
if (TOCEntry == 0)
|
||||
TOCEntry = OutContext.
|
||||
GetOrCreateSymbol(StringRef(MAI->getPrivateGlobalPrefix()) +
|
||||
@ -553,6 +553,9 @@ void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
/// the current output stream.
|
||||
///
|
||||
void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
SmallString<128> Str;
|
||||
raw_svector_ostream O(Str);
|
||||
|
||||
// Check for slwi/srwi mnemonics.
|
||||
if (MI->getOpcode() == PPC::RLWINM) {
|
||||
unsigned char SH = MI->getOperand(2).getImm();
|
||||
@ -571,7 +574,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
O << ", ";
|
||||
printOperand(MI, 1, O);
|
||||
O << ", " << (unsigned int)SH;
|
||||
OutStreamer.AddBlankLine();
|
||||
OutStreamer.EmitRawText(O.str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -582,7 +585,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
printOperand(MI, 0, O);
|
||||
O << ", ";
|
||||
printOperand(MI, 1, O);
|
||||
OutStreamer.AddBlankLine();
|
||||
OutStreamer.EmitRawText(O.str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -596,15 +599,13 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
O << ", ";
|
||||
printOperand(MI, 1, O);
|
||||
O << ", " << (unsigned int)SH;
|
||||
OutStreamer.AddBlankLine();
|
||||
OutStreamer.EmitRawText(O.str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SmallString<128> Str;
|
||||
raw_svector_ostream OS(Str);
|
||||
printInstruction(MI, OS);
|
||||
OutStreamer.EmitRawText(OS.str());
|
||||
printInstruction(MI, O);
|
||||
OutStreamer.EmitRawText(O.str());
|
||||
}
|
||||
|
||||
void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
|
||||
@ -613,12 +614,13 @@ void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
|
||||
|
||||
// Emit an official procedure descriptor.
|
||||
// FIXME 64-bit SVR4: Use MCSection here!
|
||||
O << "\t.section\t\".opd\",\"aw\"\n";
|
||||
O << "\t.align 3\n";
|
||||
OutStreamer.EmitRawText(StringRef("\t.section\t\".opd\",\"aw\""));
|
||||
OutStreamer.EmitRawText(StringRef("\t.align 3"));
|
||||
OutStreamer.EmitLabel(CurrentFnSym);
|
||||
O << "\t.quad .L." << *CurrentFnSym << ",.TOC.@tocbase\n";
|
||||
O << "\t.previous\n";
|
||||
O << ".L." << *CurrentFnSym << ":\n";
|
||||
OutStreamer.EmitRawText("\t.quad .L." + Twine(CurrentFnSym->getName()) +
|
||||
",.TOC.@tocbase");
|
||||
OutStreamer.EmitRawText(StringRef("\t.previous"));
|
||||
OutStreamer.EmitRawText(".L." + Twine(CurrentFnSym->getName()) + ":");
|
||||
}
|
||||
|
||||
|
||||
@ -629,13 +631,14 @@ bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
|
||||
|
||||
if (isPPC64 && !TOC.empty()) {
|
||||
// FIXME 64-bit SVR4: Use MCSection here?
|
||||
O << "\t.section\t\".toc\",\"aw\"\n";
|
||||
OutStreamer.EmitRawText(StringRef("\t.section\t\".toc\",\"aw\""));
|
||||
|
||||
// FIXME: This is nondeterminstic!
|
||||
for (DenseMap<const MCSymbol*, const MCSymbol*>::iterator I = TOC.begin(),
|
||||
for (DenseMap<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
|
||||
E = TOC.end(); I != E; ++I) {
|
||||
O << *I->second << ":\n";
|
||||
O << "\t.tc " << *I->first << "[TC]," << *I->first << '\n';
|
||||
OutStreamer.EmitLabel(I->second);
|
||||
OutStreamer.EmitRawText("\t.tc " + Twine(I->first->getName()) +
|
||||
"[TC]," + I->first->getName());
|
||||
}
|
||||
}
|
||||
|
||||
@ -663,7 +666,7 @@ void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
|
||||
if (Subtarget.isPPC64() && Directive < PPC::DIR_970)
|
||||
Directive = PPC::DIR_64;
|
||||
assert(Directive <= PPC::DIR_64 && "Directive out of range.");
|
||||
O << "\t.machine " << CPUDirectives[Directive] << '\n';
|
||||
OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
|
||||
|
||||
// Prime text sections so they are adjacent. This reduces the likelihood a
|
||||
// large data or debug section causes a branch to exceed 16M limit.
|
||||
@ -721,12 +724,12 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
|
||||
OutStreamer.SwitchSection(StubSection);
|
||||
EmitAlignment(4);
|
||||
|
||||
const MCSymbol *Stub = Stubs[i].first;
|
||||
MCSymbol *Stub = Stubs[i].first;
|
||||
const MCSymbol *RawSym = Stubs[i].second.getPointer();
|
||||
const MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
|
||||
const MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
|
||||
|
||||
O << *Stub << ":\n";
|
||||
OutStreamer.EmitLabel(Stub);
|
||||
O << "\t.indirect_symbol " << *RawSym << '\n';
|
||||
O << "\tmflr r0\n";
|
||||
O << "\tbcl 20,31," << *AnonSymbol << '\n';
|
||||
@ -745,7 +748,7 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
|
||||
O << "\t.indirect_symbol " << *RawSym << '\n';
|
||||
O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n";
|
||||
}
|
||||
O << '\n';
|
||||
OutStreamer.AddBlankLine();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -755,13 +758,13 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
|
||||
MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
|
||||
16, SectionKind::getText());
|
||||
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
|
||||
const MCSymbol *Stub = Stubs[i].first;
|
||||
MCSymbol *Stub = Stubs[i].first;
|
||||
const MCSymbol *RawSym = Stubs[i].second.getPointer();
|
||||
const MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
|
||||
|
||||
OutStreamer.SwitchSection(StubSection);
|
||||
EmitAlignment(4);
|
||||
O << *Stub << ":\n";
|
||||
OutStreamer.EmitLabel(Stub);
|
||||
O << "\t.indirect_symbol " << *RawSym << '\n';
|
||||
O << "\tlis r11,ha16(" << *LazyPtr << ")\n";
|
||||
O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(" << *LazyPtr
|
||||
|
@ -74,9 +74,7 @@ namespace {
|
||||
unsigned AsmVariant, const char *ExtraCode,
|
||||
raw_ostream &O);
|
||||
|
||||
void emitGlobalDirective(const MCSymbol *Sym);
|
||||
|
||||
void emitArrayBound(const MCSymbol *Sym, const GlobalVariable *GV);
|
||||
void emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV);
|
||||
virtual void EmitGlobalVariable(const GlobalVariable *GV);
|
||||
|
||||
void emitFunctionStart(MachineFunction &MF);
|
||||
@ -99,18 +97,13 @@ namespace {
|
||||
|
||||
#include "XCoreGenAsmWriter.inc"
|
||||
|
||||
void XCoreAsmPrinter::emitGlobalDirective(const MCSymbol *Sym) {
|
||||
O << MAI->getGlobalDirective() << *Sym << "\n";
|
||||
}
|
||||
|
||||
void XCoreAsmPrinter::emitArrayBound(const MCSymbol *Sym,
|
||||
const GlobalVariable *GV) {
|
||||
void XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) {
|
||||
assert(((GV->hasExternalLinkage() ||
|
||||
GV->hasWeakLinkage()) ||
|
||||
GV->hasLinkOnceLinkage()) && "Unexpected linkage");
|
||||
if (const ArrayType *ATy = dyn_cast<ArrayType>(
|
||||
cast<PointerType>(GV->getType())->getElementType())) {
|
||||
O << MAI->getGlobalDirective() << *Sym;
|
||||
OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global);
|
||||
O << ".globound" << "\n";
|
||||
O << "\t.set\t" << *Sym;
|
||||
O << ".globound" << "," << ATy->getNumElements() << "\n";
|
||||
@ -147,7 +140,8 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
|
||||
case GlobalValue::WeakODRLinkage:
|
||||
case GlobalValue::ExternalLinkage:
|
||||
emitArrayBound(GVSym, GV);
|
||||
emitGlobalDirective(GVSym);
|
||||
OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
|
||||
|
||||
// TODO Use COMDAT groups for LinkOnceLinkage
|
||||
if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())
|
||||
O << MAI->getWeakDefDirective() << *GVSym << "\n";
|
||||
@ -207,14 +201,14 @@ void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
|
||||
case Function::LinkerPrivateLinkage:
|
||||
break;
|
||||
case Function::ExternalLinkage:
|
||||
emitGlobalDirective(CurrentFnSym);
|
||||
OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
|
||||
break;
|
||||
case Function::LinkOnceAnyLinkage:
|
||||
case Function::LinkOnceODRLinkage:
|
||||
case Function::WeakAnyLinkage:
|
||||
case Function::WeakODRLinkage:
|
||||
// TODO Use COMDAT groups for LinkOnceLinkage
|
||||
O << MAI->getGlobalDirective() << *CurrentFnSym << "\n";
|
||||
OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_Global);
|
||||
O << MAI->getWeakDefDirective() << *CurrentFnSym << "\n";
|
||||
break;
|
||||
}
|
||||
@ -223,7 +217,7 @@ void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
|
||||
if (MAI->hasDotTypeDotSizeDirective())
|
||||
O << "\t.type " << *CurrentFnSym << ",@function\n";
|
||||
|
||||
O << *CurrentFnSym << ":\n";
|
||||
OutStreamer.EmitLabel(CurrentFnSym);
|
||||
}
|
||||
|
||||
|
||||
@ -231,7 +225,8 @@ void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
|
||||
/// the last basic block in the function.
|
||||
void XCoreAsmPrinter::EmitFunctionBodyEnd() {
|
||||
// Emit function end directives
|
||||
O << "\t.cc_bottom " << *CurrentFnSym << ".function\n";
|
||||
OutStreamer.EmitRawText("\t.cc_bottom " + Twine(CurrentFnSym->getName()) +
|
||||
".function");
|
||||
}
|
||||
|
||||
/// runOnMachineFunction - This uses the printMachineInstruction()
|
||||
@ -327,18 +322,18 @@ bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
}
|
||||
|
||||
void XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
SmallString<128> Str;
|
||||
raw_svector_ostream O(Str);
|
||||
|
||||
// Check for mov mnemonic
|
||||
unsigned src, dst, srcSR, dstSR;
|
||||
if (TM.getInstrInfo()->isMoveInstr(*MI, src, dst, srcSR, dstSR)) {
|
||||
O << "\tmov " << getRegisterName(dst) << ", ";
|
||||
O << getRegisterName(src);
|
||||
OutStreamer.AddBlankLine();
|
||||
return;
|
||||
} else {
|
||||
printInstruction(MI, O);
|
||||
}
|
||||
SmallString<128> Str;
|
||||
raw_svector_ostream OS(Str);
|
||||
printInstruction(MI, OS);
|
||||
OutStreamer.EmitRawText(OS.str());
|
||||
OutStreamer.EmitRawText(O.str());
|
||||
}
|
||||
|
||||
// Force static initialization.
|
||||
|
Loading…
x
Reference in New Issue
Block a user