Added Subtarget support into RegisterInfo

Added HasABICall and HasAbsoluteCall (equivalent to gcc -mabicall and 
-mno-shared). HasAbsoluteCall is not implemented but HasABICall is the 
default for o32 ABI. Now, both should help into a more accurate 
relocation types implementation. 
Added IsLinux is needed to choose between asm directives.
Instruction name strings cleanup.
AsmPrinter improved.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53551 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bruno Cardoso Lopes
2008-07-14 14:42:54 +00:00
parent 91e1c32dd0
commit 43d526d162
9 changed files with 200 additions and 116 deletions

View File

@ -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);
}