summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2008-07-14 14:42:54 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2008-07-14 14:42:54 +0000
commit43d526d162c69f29a1cc6734014576eade49529b (patch)
tree1e06364189d502030d9727a5cee6da5a0139e76b /lib
parent91e1c32dd025c1595a46e2ae59b0ce6ad0f0edea (diff)
downloadllvm-43d526d162c69f29a1cc6734014576eade49529b.tar.gz
llvm-43d526d162c69f29a1cc6734014576eade49529b.tar.bz2
llvm-43d526d162c69f29a1cc6734014576eade49529b.tar.xz
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
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp132
-rw-r--r--lib/Target/Mips/MipsInstrInfo.cpp5
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td71
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.cpp22
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.h9
-rw-r--r--lib/Target/Mips/MipsSubtarget.cpp24
-rw-r--r--lib/Target/Mips/MipsSubtarget.h23
-rw-r--r--lib/Target/Mips/MipsTargetAsmInfo.cpp24
-rw-r--r--lib/Target/Mips/MipsTargetMachine.cpp6
9 files changed, 200 insertions, 116 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);
}
diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp
index 687237f972..3a0e114fdc 100644
--- a/lib/Target/Mips/MipsInstrInfo.cpp
+++ b/lib/Target/Mips/MipsInstrInfo.cpp
@@ -11,8 +11,9 @@
//
//===----------------------------------------------------------------------===//
-#include "Mips.h"
+//#include "Mips.h"
#include "MipsInstrInfo.h"
+#include "MipsTargetMachine.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "MipsGenInstrInfo.inc"
@@ -21,7 +22,7 @@ using namespace llvm;
MipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm)
: TargetInstrInfoImpl(MipsInsts, array_lengthof(MipsInsts)),
- TM(tm), RI(*this) {}
+ TM(tm), RI(*TM.getSubtargetImpl(), *this) {}
static bool isZeroImm(const MachineOperand &op) {
return op.isImmediate() && op.getImm() == 0;
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index 0e0af5d45a..de5a53617d 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -31,7 +31,8 @@ def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, [SDNPHasChain,
// Hi and Lo nodes are used to handle global addresses. Used on
// MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol
// static model. (nothing to do with Mips Registers Hi and Lo)
-def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp, [SDNPOutFlag]>;
+//def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp, [SDNPOutFlag]>;
+def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
// Return
@@ -125,7 +126,7 @@ class ArithR<bits<6> op, bits<6> func, string instr_asm, SDNode OpNode,
func,
(outs CPURegs:$dst),
(ins CPURegs:$b, CPURegs:$c),
- !strconcat(instr_asm, " $dst, $b, $c"),
+ !strconcat(instr_asm, "\t$dst, $b, $c"),
[(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], itin>;
let isCommutable = 1 in
@@ -134,7 +135,7 @@ class ArithOverflowR<bits<6> op, bits<6> func, string instr_asm>:
func,
(outs CPURegs:$dst),
(ins CPURegs:$b, CPURegs:$c),
- !strconcat(instr_asm, " $dst, $b, $c"),
+ !strconcat(instr_asm, "\t$dst, $b, $c"),
[], IIAlu>;
// Arithmetic 2 register operands
@@ -143,7 +144,7 @@ class ArithI<bits<6> op, string instr_asm, SDNode OpNode,
FI< op,
(outs CPURegs:$dst),
(ins CPURegs:$b, Od:$c),
- !strconcat(instr_asm, " $dst, $b, $c"),
+ !strconcat(instr_asm, "\t$dst, $b, $c"),
[(set CPURegs:$dst, (OpNode CPURegs:$b, imm_type:$c))], IIAlu>;
// Arithmetic Multiply ADD/SUB
@@ -153,7 +154,7 @@ class MArithR<bits<6> func, string instr_asm> :
func,
(outs CPURegs:$rs),
(ins CPURegs:$rt),
- !strconcat(instr_asm, " $rs, $rt"),
+ !strconcat(instr_asm, "\t$rs, $rt"),
[], IIImul>;
// Logical
@@ -162,14 +163,14 @@ class LogicR<bits<6> func, string instr_asm, SDNode OpNode>:
func,
(outs CPURegs:$dst),
(ins CPURegs:$b, CPURegs:$c),
- !strconcat(instr_asm, " $dst, $b, $c"),
+ !strconcat(instr_asm, "\t$dst, $b, $c"),
[(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>;
class LogicI<bits<6> op, string instr_asm, SDNode OpNode>:
FI< op,
(outs CPURegs:$dst),
(ins CPURegs:$b, uimm16:$c),
- !strconcat(instr_asm, " $dst, $b, $c"),
+ !strconcat(instr_asm, "\t$dst, $b, $c"),
[(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt16:$c))], IIAlu>;
class LogicNOR<bits<6> op, bits<6> func, string instr_asm>:
@@ -177,7 +178,7 @@ class LogicNOR<bits<6> op, bits<6> func, string instr_asm>:
func,
(outs CPURegs:$dst),
(ins CPURegs:$b, CPURegs:$c),
- !strconcat(instr_asm, " $dst, $b, $c"),
+ !strconcat(instr_asm, "\t$dst, $b, $c"),
[(set CPURegs:$dst, (not (or CPURegs:$b, CPURegs:$c)))], IIAlu>;
// Shifts
@@ -187,7 +188,7 @@ class LogicR_shift_imm<bits<6> func, string instr_asm, SDNode OpNode>:
func,
(outs CPURegs:$dst),
(ins CPURegs:$b, shamt:$c),
- !strconcat(instr_asm, " $dst, $b, $c"),
+ !strconcat(instr_asm, "\t$dst, $b, $c"),
[(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt5:$c))], IIAlu>;
class LogicR_shift_reg<bits<6> func, string instr_asm, SDNode OpNode>:
@@ -195,7 +196,7 @@ class LogicR_shift_reg<bits<6> func, string instr_asm, SDNode OpNode>:
func,
(outs CPURegs:$dst),
(ins CPURegs:$b, CPURegs:$c),
- !strconcat(instr_asm, " $dst, $b, $c"),
+ !strconcat(instr_asm, "\t$dst, $b, $c"),
[(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>;
// Load Upper Imediate
@@ -203,7 +204,7 @@ class LoadUpper<bits<6> op, string instr_asm>:
FI< op,
(outs CPURegs:$dst),
(ins uimm16:$imm),
- !strconcat(instr_asm, " $dst, $imm"),
+ !strconcat(instr_asm, "\t$dst, $imm"),
[], IIAlu>;
// Memory Load/Store
@@ -212,14 +213,14 @@ class LoadM<bits<6> op, string instr_asm, PatFrag OpNode>:
FI< op,
(outs CPURegs:$dst),
(ins mem:$addr),
- !strconcat(instr_asm, " $dst, $addr"),
+ !strconcat(instr_asm, "\t$dst, $addr"),
[(set CPURegs:$dst, (OpNode addr:$addr))], IILoad>;
class StoreM<bits<6> op, string instr_asm, PatFrag OpNode>:
FI< op,
(outs),
(ins CPURegs:$dst, mem:$addr),
- !strconcat(instr_asm, " $dst, $addr"),
+ !strconcat(instr_asm, "\t$dst, $addr"),
[(OpNode CPURegs:$dst, addr:$addr)], IIStore>;
// Conditional Branch
@@ -228,7 +229,7 @@ class CBranch<bits<6> op, string instr_asm, PatFrag cond_op>:
FI< op,
(outs),
(ins CPURegs:$a, CPURegs:$b, brtarget:$offset),
- !strconcat(instr_asm, " $a, $b, $offset"),
+ !strconcat(instr_asm, "\t$a, $b, $offset"),
[(brcond (cond_op CPURegs:$a, CPURegs:$b), bb:$offset)],
IIBranch>;
@@ -237,7 +238,7 @@ class CBranchZero<bits<6> op, string instr_asm, PatFrag cond_op>:
FI< op,
(outs),
(ins CPURegs:$src, brtarget:$offset),
- !strconcat(instr_asm, " $src, $offset"),
+ !strconcat(instr_asm, "\t$src, $offset"),
[(brcond (cond_op CPURegs:$src, 0), bb:$offset)],
IIBranch>;
}
@@ -249,7 +250,7 @@ class SetCC_R<bits<6> op, bits<6> func, string instr_asm,
func,
(outs CPURegs:$dst),
(ins CPURegs:$b, CPURegs:$c),
- !strconcat(instr_asm, " $dst, $b, $c"),
+ !strconcat(instr_asm, "\t$dst, $b, $c"),
[(set CPURegs:$dst, (cond_op CPURegs:$b, CPURegs:$c))],
IIAlu>;
@@ -258,7 +259,7 @@ class SetCC_I<bits<6> op, string instr_asm, PatFrag cond_op,
FI< op,
(outs CPURegs:$dst),
(ins CPURegs:$b, Od:$c),
- !strconcat(instr_asm, " $dst, $b, $c"),
+ !strconcat(instr_asm, "\t$dst, $b, $c"),
[(set CPURegs:$dst, (cond_op CPURegs:$b, imm_type:$c))],
IIAlu>;
@@ -268,7 +269,7 @@ class JumpFJ<bits<6> op, string instr_asm>:
FJ< op,
(outs),
(ins brtarget:$target),
- !strconcat(instr_asm, " $target"),
+ !strconcat(instr_asm, "\t$target"),
[(br bb:$target)], IIBranch>;
let isBranch=1, isTerminator=1, isBarrier=1, rd=0, hasDelaySlot = 1 in
@@ -277,7 +278,7 @@ class JumpFR<bits<6> op, bits<6> func, string instr_asm>:
func,
(outs),
(ins CPURegs:$target),
- !strconcat(instr_asm, " $target"),
+ !strconcat(instr_asm, "\t$target"),
[(brind CPURegs:$target)], IIBranch>;
// Jump and Link (Call)
@@ -289,7 +290,7 @@ let isCall=1, hasDelaySlot=1,
FJ< op,
(outs),
(ins calltarget:$target),
- !strconcat(instr_asm, " $target"),
+ !strconcat(instr_asm, "\t$target"),
[(MipsJmpLink imm:$target)], IIBranch>;
let rd=31 in
@@ -298,14 +299,14 @@ let isCall=1, hasDelaySlot=1,
func,
(outs),
(ins CPURegs:$rs),
- !strconcat(instr_asm, " $rs"),
+ !strconcat(instr_asm, "\t$rs"),
[(MipsJmpLink CPURegs:$rs)], IIBranch>;
class BranchLink<string instr_asm>:
FI< 0x1,
(outs),
(ins CPURegs:$rs, brtarget:$target),
- !strconcat(instr_asm, " $rs, $target"),
+ !strconcat(instr_asm, "\t$rs, $target"),
[], IIBranch>;
}
@@ -315,7 +316,7 @@ class MulDiv<bits<6> func, string instr_asm, InstrItinClass itin>:
func,
(outs),
(ins CPURegs:$a, CPURegs:$b),
- !strconcat(instr_asm, " $a, $b"),
+ !strconcat(instr_asm, "\t$a, $b"),
[], itin>;
// Move from Hi/Lo
@@ -324,7 +325,7 @@ class MoveFromTo<bits<6> func, string instr_asm>:
func,
(outs CPURegs:$dst),
(ins),
- !strconcat(instr_asm, " $dst"),
+ !strconcat(instr_asm, "\t$dst"),
[], IIHiLo>;
// Count Leading Ones/Zeros in Word
@@ -333,7 +334,7 @@ class CountLeading<bits<6> func, string instr_asm>:
func,
(outs CPURegs:$dst),
(ins CPURegs:$src),
- !strconcat(instr_asm, " $dst, $src"),
+ !strconcat(instr_asm, "\t$dst, $src"),
[], IIAlu>;
class EffectiveAddress<string instr_asm> :
@@ -345,7 +346,7 @@ class EffectiveAddress<string instr_asm> :
class SignExtInReg<bits<6> func, string instr_asm, ValueType vt>:
FR< 0x3f, func, (outs CPURegs:$dst), (ins CPURegs:$src),
- !strconcat(instr_asm, " $dst, $src"),
+ !strconcat(instr_asm, "\t$dst, $src"),
[(set CPURegs:$dst, (sext_inreg CPURegs:$src, vt))], NoItinerary>;
@@ -363,15 +364,19 @@ def ADJCALLSTACKUP : MipsPseudo<(outs), (ins uimm16:$amt1, uimm16:$amt2),
[(callseq_end imm:$amt1, imm:$amt2)]>;
}
+// Some assembly macros need to avoid pseudoinstructions and assembler
+// automatic reodering, we should reorder ourselves.
+def MACRO : MipsPseudo<(outs), (ins), ".set\tmacro", []>;
+def REORDER : MipsPseudo<(outs), (ins), ".set\treorder", []>;
+def NOMACRO : MipsPseudo<(outs), (ins), ".set\tnomacro", []>;
+def NOREORDER : MipsPseudo<(outs), (ins), ".set\tnoreorder", []>;
+
// When handling PIC code the assembler needs .cpload and .cprestore
// directives. If the real instructions corresponding these directives
// are used, we have the same behavior, but get also a bunch of warnings
// from the assembler.
-def CPLOAD : MipsPseudo<(outs), (ins CPURegs:$reg),
- ".set noreorder\n\t.cpload $reg\n\t.set reorder\n",
- []>;
-def CPRESTORE : MipsPseudo<(outs), (ins uimm16:$loc),
- ".cprestore $loc\n", []>;
+def CPLOAD : MipsPseudo<(outs), (ins CPURegs:$picreg), ".cpload\t$picreg", []>;
+def CPRESTORE : MipsPseudo<(outs), (ins uimm16:$loc), ".cprestore\t$loc\n", []>;
// The supported Mips ISAs dont have any instruction close to the SELECT_CC
// operation. The solution is to create a Mips pseudo SELECT_CC instruction
@@ -488,14 +493,14 @@ let isReturn=1, isTerminator=1, hasDelaySlot=1,
isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in
{
def RET : FR <0x00, 0x02, (outs), (ins CPURegs:$target),
- "jr $target", [(MipsRet CPURegs:$target)], IIBranch>;
+ "jr\t$target", [(MipsRet CPURegs:$target)], IIBranch>;
}
// FrameIndexes are legalized when they are operands from load/store
// instructions. The same not happens for stack address copies, so an
// add op with mem ComplexPattern is used and the stack address copy
// can be matched. It's similar to Sparc LEA_ADDRi
-def LEA_ADDiu : EffectiveAddress<"addiu $dst, ${addr:stackloc}">;
+def LEA_ADDiu : EffectiveAddress<"addiu\t$dst, ${addr:stackloc}">;
// Count Leading
// CLO/CLZ are part of the newer MIPS32(tm) instruction
diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp
index 75d9b24d7d..cd42abd300 100644
--- a/lib/Target/Mips/MipsRegisterInfo.cpp
+++ b/lib/Target/Mips/MipsRegisterInfo.cpp
@@ -14,6 +14,7 @@
#define DEBUG_TYPE "mips-reg-info"
#include "Mips.h"
+#include "MipsSubtarget.h"
#include "MipsRegisterInfo.h"
#include "MipsMachineFunction.h"
#include "llvm/Constants.h"
@@ -35,9 +36,10 @@
using namespace llvm;
-MipsRegisterInfo::MipsRegisterInfo(const TargetInstrInfo &tii)
+MipsRegisterInfo::MipsRegisterInfo(const MipsSubtarget &ST,
+ const TargetInstrInfo &tii)
: MipsGenRegisterInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP),
- TII(tii) {}
+ Subtarget(ST), TII(tii) {}
/// getRegisterNumbering - Given the enum value for some register, e.g.
/// Mips::RA, return the number that it corresponds to (e.g. 31).
@@ -82,10 +84,10 @@ getRegisterNumbering(unsigned RegEnum)
return 0; // Not reached
}
+unsigned MipsRegisterInfo::getPICCallReg(void) { return Mips::T9; }
+
//===----------------------------------------------------------------------===//
-//
// Callee Saved Registers methods
-//
//===----------------------------------------------------------------------===//
/// Mips Callee Saved Registers
@@ -306,9 +308,12 @@ emitPrologue(MachineFunction &MF) const
// Update frame info
MFI->setStackSize(NumBytes);
- // PIC speficic function prologue
- if (isPIC)
- BuildMI(MBB, MBBI, TII.get(Mips::CPLOAD)).addReg(Mips::T9);
+ BuildMI(MBB, MBBI, TII.get(Mips::NOREORDER));
+
+ // TODO: check need from GP here.
+ if (isPIC && Subtarget.isABI_O32())
+ BuildMI(MBB, MBBI, TII.get(Mips::CPLOAD)).addReg(getPICCallReg());
+ BuildMI(MBB, MBBI, TII.get(Mips::NOMACRO));
// Adjust stack : addi sp, sp, (-imm)
BuildMI(MBB, MBBI, TII.get(Mips::ADDiu), Mips::SP)
@@ -334,9 +339,10 @@ emitPrologue(MachineFunction &MF) const
}
// PIC speficic function prologue
- if ((isPIC) && (MFI->hasCalls()))
+ if ((isPIC) && (MFI->hasCalls())) {
BuildMI(MBB, MBBI, TII.get(Mips::CPRESTORE))
.addImm(MipsFI->getGPStackOffset());
+ }
}
void MipsRegisterInfo::
diff --git a/lib/Target/Mips/MipsRegisterInfo.h b/lib/Target/Mips/MipsRegisterInfo.h
index 823461610d..2d0436b7a6 100644
--- a/lib/Target/Mips/MipsRegisterInfo.h
+++ b/lib/Target/Mips/MipsRegisterInfo.h
@@ -14,23 +14,28 @@
#ifndef MIPSREGISTERINFO_H
#define MIPSREGISTERINFO_H
+#include "Mips.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "MipsGenRegisterInfo.h.inc"
namespace llvm {
-
+class MipsSubtarget;
class TargetInstrInfo;
class Type;
struct MipsRegisterInfo : public MipsGenRegisterInfo {
+ const MipsSubtarget &Subtarget;
const TargetInstrInfo &TII;
- MipsRegisterInfo(const TargetInstrInfo &tii);
+ MipsRegisterInfo(const MipsSubtarget &Subtarget, const TargetInstrInfo &tii);
/// getRegisterNumbering - Given the enum value for some register, e.g.
/// Mips::RA, return the number that it corresponds to (e.g. 31).
static unsigned getRegisterNumbering(unsigned RegEnum);
+ /// Get PIC indirect call register
+ static unsigned getPICCallReg(void);
+
/// Code Generation virtual methods...
const unsigned *getCalleeSavedRegs(const MachineFunction* MF = 0) const;
diff --git a/lib/Target/Mips/MipsSubtarget.cpp b/lib/Target/Mips/MipsSubtarget.cpp
index 96ff30ba4a..3424388011 100644
--- a/lib/Target/Mips/MipsSubtarget.cpp
+++ b/lib/Target/Mips/MipsSubtarget.cpp
@@ -15,23 +15,34 @@
#include "Mips.h"
#include "MipsGenSubtarget.inc"
#include "llvm/Module.h"
+#include "llvm/Support/CommandLine.h"
using namespace llvm;
+cl::opt<bool> NotABICall("disable-mips-abicall", cl::Hidden,
+ cl::desc("Disable code for SVR4-style dynamic objects"));
+cl::opt<bool> AbsoluteCall("enable-mips-absolute-call", cl::Hidden,
+ cl::desc("Enable absolute call within abicall"));
+
MipsSubtarget::MipsSubtarget(const TargetMachine &TM, const Module &M,
const std::string &FS, bool little) :
MipsArchVersion(Mips1), MipsABI(O32), IsLittle(little), IsSingleFloat(false),
- IsFP64bit(false), IsGP64bit(false), HasVFPU(false), HasSEInReg(false)
+ IsFP64bit(false), IsGP64bit(false), HasVFPU(false), HasSEInReg(false),
+ HasABICall(true), HasAbsoluteCall(false), IsLinux(true)
{
std::string CPU = "mips1";
// Parse features string.
ParseSubtargetFeatures(FS, CPU);
+ const std::string& TT = M.getTargetTriple();
+
+ // Is the target system Linux ?
+ if (TT.find("linux") == std::string::npos)
+ IsLinux = false;
// When only the target triple is specified and is
// a allegrex target, set the features. We also match
// big and little endian allegrex cores (dont really
// know if a big one exists)
- const std::string& TT = M.getTargetTriple();
if (TT.find("mipsallegrex") != std::string::npos) {
MipsABI = EABI;
IsSingleFloat = true;
@@ -39,4 +50,13 @@ MipsSubtarget::MipsSubtarget(const TargetMachine &TM, const Module &M,
HasVFPU = true; // Enables Allegrex Vector FPU (not supported yet)
HasSEInReg = true;
}
+
+ // Abicall is the default for O32 ABI and is ignored
+ // for EABI.
+ if (NotABICall || isABI_EABI())
+ HasABICall = false;
+
+ // TODO: disable when handling 64 bit symbols in the future.
+ if (HasABICall && AbsoluteCall)
+ HasAbsoluteCall = true;
}
diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h
index 281f3bb167..5140e1eb22 100644
--- a/lib/Target/Mips/MipsSubtarget.h
+++ b/lib/Target/Mips/MipsSubtarget.h
@@ -24,16 +24,17 @@ class Module;
class MipsSubtarget : public TargetSubtarget {
+public:
+ enum MipsABIEnum {
+ O32, O64, N32, N64, EABI
+ };
+
protected:
enum MipsArchEnum {
Mips1, Mips2, Mips3, Mips4, Mips32, Mips32r2, Mips64, Mips64r2
};
- enum MipsABIEnum {
- O32, EABI
- };
-
// Mips architecture version
MipsArchEnum MipsArchVersion;
@@ -60,6 +61,16 @@ protected:
// HasSEInReg - Target has SEB and SEH (signext in register) instructions.
bool HasSEInReg;
+ // IsABICall - Enable SRV4 code for SVR4-style dynamic objects
+ bool HasABICall;
+
+ // HasAbsoluteCall - Enable code that is not fully position-independent.
+ // Only works with HasABICall enabled.
+ bool HasAbsoluteCall;
+
+ // isLinux - Target system is Linux. Is false we consider ELFOS for now.
+ bool IsLinux;
+
InstrItineraryData InstrItins;
public:
@@ -67,6 +78,7 @@ public:
/// Only O32 and EABI supported right now.
bool isABI_EABI() const { return MipsABI == EABI; }
bool isABI_O32() const { return MipsABI == O32; }
+ unsigned getTargetABI() const { return MipsABI; }
/// This constructor initializes the data members to match that
/// of the specified module.
@@ -87,6 +99,9 @@ public:
bool isNotSingleFloat() const { return !IsSingleFloat; };
bool hasVFPU() const { return HasVFPU; };
bool hasSEInReg() const { return HasSEInReg; };
+ bool hasABICall() const { return HasABICall; };
+ bool hasAbsoluteCall() const { return HasAbsoluteCall; };
+ bool isLinux() const { return IsLinux; };
};
} // End llvm namespace
diff --git a/lib/Target/Mips/MipsTargetAsmInfo.cpp b/lib/Target/Mips/MipsTargetAsmInfo.cpp
index d69e78fe35..a4e13f5f34 100644
--- a/lib/Target/Mips/MipsTargetAsmInfo.cpp
+++ b/lib/Target/Mips/MipsTargetAsmInfo.cpp
@@ -17,21 +17,23 @@
using namespace llvm;
MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM) {
- AlignmentIsInBytes = false;
- Data16bitsDirective = "\t.half\t";
- Data32bitsDirective = "\t.word\t";
- PrivateGlobalPrefix = "$";
- JumpTableDataSection = "\t.rdata";
- CommentString = "#";
- ReadOnlySection = "\t.rdata";
- ZeroDirective = "\t.space\t";
- BSSSection = "\t.section\t.bss";
- LCOMMDirective = "\t.lcomm\t";
+
+ AlignmentIsInBytes = false;
+ COMMDirectiveTakesAlignment = true;
+ Data16bitsDirective = "\t.half\t";
+ Data32bitsDirective = "\t.word\t";
+ Data64bitsDirective = NULL;
+ PrivateGlobalPrefix = "$";
+ JumpTableDataSection = "\t.rdata";
+ CommentString = "#";
+ ReadOnlySection = "\t.rdata";
+ ZeroDirective = "\t.space\t";
+ BSSSection = "\t.section\t.bss";
+ LCOMMDirective = "\t.lcomm\t";
if (TM.getRelocationModel() == Reloc::Static)
JumpTableDirective = "\t.word\t";
else
JumpTableDirective = "\t.gpword\t";
- COMMDirectiveTakesAlignment = true;
}
diff --git a/lib/Target/Mips/MipsTargetMachine.cpp b/lib/Target/Mips/MipsTargetMachine.cpp
index a170d6fb36..bc4a2a1dfc 100644
--- a/lib/Target/Mips/MipsTargetMachine.cpp
+++ b/lib/Target/Mips/MipsTargetMachine.cpp
@@ -44,8 +44,12 @@ MipsTargetMachine(const Module &M, const std::string &FS, bool isLittle=false):
FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0),
TLInfo(*this)
{
- if (getRelocationModel() != Reloc::Static)
+ // Abicall enables PIC by default
+ if (Subtarget.hasABICall() && (getRelocationModel() != Reloc::Static))
setRelocationModel(Reloc::PIC_);
+
+ // TODO: create an option to enable long calls, like -mlong-calls,
+ // that would be our CodeModel::Large. It must not work with Abicall.
if (getCodeModel() == CodeModel::Default)
setCodeModel(CodeModel::Small);
}