mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 16:24:23 +00:00
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:
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user