diff options
Diffstat (limited to 'lib/Target/Mips/MipsAsmPrinter.cpp')
-rw-r--r-- | lib/Target/Mips/MipsAsmPrinter.cpp | 132 |
1 files changed, 79 insertions, 53 deletions
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index 178ca141b0..d2288e61a0 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -15,6 +15,7 @@ #define DEBUG_TYPE "mips-asm-printer" #include "Mips.h" +#include "MipsSubtarget.h" #include "MipsInstrInfo.h" #include "MipsTargetMachine.h" #include "MipsMachineFunction.h" @@ -44,21 +45,19 @@ STATISTIC(EmittedInsts, "Number of machine instrs printed"); namespace { struct VISIBILITY_HIDDEN MipsAsmPrinter : public AsmPrinter { + + const MipsSubtarget *Subtarget; + MipsAsmPrinter(std::ostream &O, MipsTargetMachine &TM, const TargetAsmInfo *T): - AsmPrinter(O, TM, T) {} + AsmPrinter(O, TM, T) { + Subtarget = &TM.getSubtarget<MipsSubtarget>(); + } virtual const char *getPassName() const { return "Mips Assembly Printer"; } - enum SetDirectiveFlags { - REORDER, // enables instruction reordering. - NOREORDER, // disables instruction reordering. - MACRO, // enables GAS macros. - NOMACRO // disables GAS macros. - }; - void printOperand(const MachineInstr *MI, int opNum); void printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier = 0); @@ -68,13 +67,13 @@ namespace { unsigned int getSavedRegsBitmask(bool isFloat, MachineFunction &MF); void printHex32(unsigned int Value); + const char *emitCurrentABIString(void); void emitFunctionStart(MachineFunction &MF); void emitFunctionEnd(MachineFunction &MF); void emitFrameDirective(MachineFunction &MF); void emitMaskDirective(MachineFunction &MF); void emitFMaskDirective(MachineFunction &MF); - void emitSetDirective(SetDirectiveFlags Flag); - + bool printInstruction(const MachineInstr *MI); // autogenerated. bool runOnMachineFunction(MachineFunction &F); bool doInitialization(Module &M); @@ -125,6 +124,10 @@ FunctionPass *llvm::createMipsCodePrinterPass(std::ostream &o, // //===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// +// Mask directives +//===----------------------------------------------------------------------===// + /// Mask directive for GPR void MipsAsmPrinter:: emitMaskDirective(MachineFunction &MF) @@ -159,37 +162,6 @@ emitFMaskDirective(MachineFunction &MF) O << ",0" << "\n"; } -/// Frame Directive -void MipsAsmPrinter:: -emitFrameDirective(MachineFunction &MF) -{ - const TargetRegisterInfo &RI = *TM.getRegisterInfo(); - - unsigned stackReg = RI.getFrameRegister(MF); - unsigned returnReg = RI.getRARegister(); - unsigned stackSize = MF.getFrameInfo()->getStackSize(); - - - O << "\t.frame\t" << "$" << LowercaseString(RI.get(stackReg).AsmName) - << "," << stackSize << "," - << "$" << LowercaseString(RI.get(returnReg).AsmName) - << "\n"; -} - -/// Emit Set directives. -void MipsAsmPrinter:: -emitSetDirective(SetDirectiveFlags Flag) -{ - O << "\t.set\t"; - switch(Flag) { - case REORDER: O << "reorder" << "\n"; break; - case NOREORDER: O << "noreorder" << "\n"; break; - case MACRO: O << "macro" << "\n"; break; - case NOMACRO: O << "nomacro" << "\n"; break; - default: break; - } -} - // 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. @@ -231,6 +203,44 @@ printHex32(unsigned int Value) O << std::dec; } +//===----------------------------------------------------------------------===// +// Frame and Set directives +//===----------------------------------------------------------------------===// + +/// Frame Directive +void MipsAsmPrinter:: +emitFrameDirective(MachineFunction &MF) +{ + const TargetRegisterInfo &RI = *TM.getRegisterInfo(); + + unsigned stackReg = RI.getFrameRegister(MF); + unsigned returnReg = RI.getRARegister(); + unsigned stackSize = MF.getFrameInfo()->getStackSize(); + + + O << "\t.frame\t" << "$" << LowercaseString(RI.get(stackReg).AsmName) + << "," << stackSize << "," + << "$" << LowercaseString(RI.get(returnReg).AsmName) + << "\n"; +} + +/// Emit Set directives. +const char * MipsAsmPrinter:: +emitCurrentABIString(void) +{ + 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; + } + + assert(0 && "Unknown Mips ABI"); + return NULL; +} + /// Emit the directives used by GAS on the start of functions void MipsAsmPrinter:: emitFunctionStart(MachineFunction &MF) @@ -244,18 +254,16 @@ emitFunctionStart(MachineFunction &MF) O << "\t.globl\t" << CurrentFnName << "\n"; O << "\t.ent\t" << CurrentFnName << "\n"; - O << "\t.type\t" << CurrentFnName << ", @function\n"; + + if ((TAI->hasDotTypeDotSizeDirective()) && Subtarget->isLinux()) + O << "\t.type\t" << CurrentFnName << ", @function\n"; + O << CurrentFnName << ":\n"; emitFrameDirective(MF); emitMaskDirective(MF); emitFMaskDirective(MF); - if (TM.getRelocationModel() == Reloc::Static) { - emitSetDirective(NOREORDER); - emitSetDirective(NOMACRO); - } - O << "\n"; } @@ -263,12 +271,15 @@ emitFunctionStart(MachineFunction &MF) void MipsAsmPrinter:: emitFunctionEnd(MachineFunction &MF) { - if (TM.getRelocationModel() == Reloc::Static) { - emitSetDirective(MACRO); - emitSetDirective(REORDER); - } + // 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" << CurrentFnName << "\n"; + if (TAI->hasDotTypeDotSizeDirective() && !Subtarget->isLinux()) + O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << "\n"; } /// runOnMachineFunction - This uses the printMachineInstruction() @@ -441,6 +452,18 @@ bool MipsAsmPrinter:: doInitialization(Module &M) { Mang = new Mangler(M); + + // Tell the assembler which ABI we are using + O << "\t.section .mdebug." << emitCurrentABIString() << "\n"; + + // TODO: handle O64 ABI + if (Subtarget->isABI_EABI()) + O << "\t.section .gcc_compiled_long" << + (Subtarget->isGP32bit() ? "32" : "64") << "\n"; + + // return to previous section + O << "\t.previous" << "\n"; + return false; // success } @@ -548,8 +571,11 @@ doFinalization(Module &M) } O << "\t.align " << Align << "\n"; - O << "\t.type " << name << ",@object\n"; - O << "\t.size " << name << "," << Size << "\n"; + + if (TAI->hasDotTypeDotSizeDirective()) { + O << "\t.type " << name << ",@object\n"; + O << "\t.size " << name << "," << Size << "\n"; + } O << name << ":\n"; EmitGlobalConstant(C); } |