aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Mips/MipsAsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Mips/MipsAsmPrinter.cpp')
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp132
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);
}