1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 11:42:57 +01:00

Added support for PIC code with "explicit relocations" *only*.

Removed all macro code for PIC (goodbye "la").
Support tested with shootout bench.

llvm-svn: 43697
This commit is contained in:
Bruno Cardoso Lopes 2007-11-05 03:02:32 +00:00
parent 314e68f58f
commit 569b5512b0
9 changed files with 214 additions and 103 deletions

View File

@ -250,7 +250,7 @@ emitFunctionStart(MachineFunction &MF)
emitMaskDirective(MF);
emitFMaskDirective(MF);
if (MF.getTarget().getRelocationModel() == Reloc::Static) {
if (TM.getRelocationModel() == Reloc::Static) {
emitSetDirective(NOREORDER);
emitSetDirective(NOMACRO);
}
@ -262,7 +262,7 @@ emitFunctionStart(MachineFunction &MF)
void MipsAsmPrinter::
emitFunctionEnd(MachineFunction &MF)
{
if (MF.getTarget().getRelocationModel() == Reloc::Static) {
if (TM.getRelocationModel() == Reloc::Static) {
emitSetDirective(MACRO);
emitSetDirective(REORDER);
}
@ -305,6 +305,9 @@ runOnMachineFunction(MachineFunction &MF)
printInstruction(II);
++EmittedInsts;
}
// Each Basic Block is separated by a newline
O << '\n';
}
// Emit function end directives
@ -320,16 +323,40 @@ printOperand(const MachineInstr *MI, int opNum)
const MachineOperand &MO = MI->getOperand(opNum);
const MRegisterInfo &RI = *TM.getRegisterInfo();
bool closeP = false;
bool isPIC = (TM.getRelocationModel() == Reloc::PIC_);
bool isCodeLarge = (TM.getCodeModel() == CodeModel::Large);
// %hi and %lo used on mips gas to break large constants
// %hi and %lo used on mips gas to load global addresses on
// static code. %got is used to load global addresses when
// using PIC_. %call16 is used to load direct call targets
// on PIC_ and small code size. %call_lo and %call_hi load
// direct call targets on PIC_ and large code size.
if (MI->getOpcode() == Mips::LUi && !MO.isRegister()
&& !MO.isImmediate()) {
if ((isPIC) && (isCodeLarge))
O << "%call_hi(";
else
O << "%hi(";
closeP = true;
} else if ((MI->getOpcode() == Mips::ADDiu) && !MO.isRegister()
&& !MO.isImmediate()) {
O << "%lo(";
closeP = true;
} else if ((isPIC) && (MI->getOpcode() == Mips::LW)
&& (!MO.isRegister()) && (!MO.isImmediate())) {
const MachineOperand &firstMO = MI->getOperand(opNum-1);
const MachineOperand &lastMO = MI->getOperand(opNum+1);
if ((firstMO.isRegister()) && (lastMO.isRegister())) {
if ((firstMO.getReg() == Mips::T9) && (lastMO.getReg() == Mips::GP)
&& (!isCodeLarge))
O << "%call16(";
else if ((firstMO.getReg() != Mips::T9) && (lastMO.getReg() == Mips::GP))
O << "%got(";
else if ((firstMO.getReg() == Mips::T9) && (lastMO.getReg() != Mips::GP)
&& (isCodeLarge))
O << "%call_lo(";
closeP = true;
}
}
switch (MO.getType())
@ -361,6 +388,7 @@ printOperand(const MachineInstr *MI, int opNum)
O << MO.getSymbolName();
break;
// FIXME: Verify correct
case MachineOperand::MO_ConstantPoolIndex:
O << TAI->getPrivateGlobalPrefix() << "CPI"
<< getFunctionNumber() << "_" << MO.getConstantPoolIndex();
@ -386,6 +414,8 @@ printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier)
}
// Load/Store memory operands -- imm($reg)
// If PIC target the target is loaded as the
// pattern lw $25,%call16($28)
printOperand(MI, opNum);
O << "(";
printOperand(MI, opNum+1);

View File

@ -15,6 +15,7 @@
#include "Mips.h"
#include "MipsISelLowering.h"
#include "MipsMachineFunction.h"
#include "MipsRegisterInfo.h"
#include "MipsSubtarget.h"
#include "MipsTargetMachine.h"
@ -135,20 +136,24 @@ SelectAddr(SDOperand Op, SDOperand Addr, SDOperand &Offset, SDOperand &Base)
return true;
}
// TargetExternalSymbol and TargetGlobalAddress are
// lowered and their addresses go into registers, so
// they should not be touched here.
// on PIC code Load GA
if (TM.getRelocationModel() == Reloc::PIC_) {
if (Addr.getOpcode() == ISD::TargetGlobalAddress) {
Base = CurDAG->getRegister(Mips::GP, MVT::i32);
Offset = Addr;
return true;
}
} else {
if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
Addr.getOpcode() == ISD::TargetGlobalAddress))
return false;
}
// Operand is a result from an ADD.
if (Addr.getOpcode() == ISD::ADD)
{
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
{
if (Predicate_immSExt16(CN))
{
if (Addr.getOpcode() == ISD::ADD) {
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
if (Predicate_immSExt16(CN)) {
// If the first operand is a FI, get the TargetFI Node
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
(Addr.getOperand(0))) {
@ -247,6 +252,51 @@ Select(SDOperand N)
SDOperand MFInFlag = SDOperand(RemNode, 0);
return CurDAG->getTargetNode(Mips::MFHI, MVT::i32, MFInFlag);
}
/// Handle direct and indirect calls when using PIC. On PIC, when
/// GOT is smaller than about 64k (small code) the GA target is
/// loaded with only one instruction. Otherwise GA's target must
/// be loaded with 3 instructions.
case MipsISD::JmpLink: {
if (TM.getRelocationModel() == Reloc::PIC_) {
//bool isCodeLarge = (TM.getCodeModel() == CodeModel::Large);
SDOperand Chain = Node->getOperand(0);
SDOperand Callee = Node->getOperand(1);
AddToISelQueue(Chain);
SDOperand T9Reg = CurDAG->getRegister(Mips::T9, MVT::i32);
SDOperand InFlag(0, 0);
if ( (isa<GlobalAddressSDNode>(Callee)) ||
(isa<ExternalSymbolSDNode>(Callee)) )
{
/// Direct call for global addresses and external symbols
SDOperand GPReg = CurDAG->getRegister(Mips::GP, MVT::i32);
// Use load to get GOT target
SDOperand Ops[] = { Callee, GPReg, Chain };
SDOperand Load = SDOperand(CurDAG->getTargetNode(Mips::LW, MVT::i32,
MVT::Other, Ops, 3), 0);
Chain = Load.getValue(1);
AddToISelQueue(Chain);
// Call target must be on T9
Chain = CurDAG->getCopyToReg(Chain, T9Reg, Load, InFlag);
} else
/// Indirect call
Chain = CurDAG->getCopyToReg(Chain, T9Reg, Callee, InFlag);
AddToISelQueue(Chain);
// Emit Jump and Link Register
SDNode *ResNode = CurDAG->getTargetNode(Mips::JALR, MVT::Other,
MVT::Flag, T9Reg, Chain);
Chain = SDOperand(ResNode, 0);
InFlag = SDOperand(ResNode, 1);
ReplaceUses(SDOperand(Node, 0), Chain);
ReplaceUses(SDOperand(Node, 1), InFlag);
return ResNode;
}
}
}
// Select the default instruction

View File

@ -43,8 +43,6 @@ getTargetNodeName(unsigned Opcode) const
case MipsISD::Hi : return "MipsISD::Hi";
case MipsISD::Lo : return "MipsISD::Lo";
case MipsISD::Ret : return "MipsISD::Ret";
case MipsISD::Add : return "MipsISD::Add";
case MipsISD::LoadAddr : return "MipsISD::LoadAddr";
default : return NULL;
}
}
@ -149,21 +147,24 @@ LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG)
{
SDOperand ResNode;
GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
bool isPIC = (getTargetMachine().getRelocationModel() == Reloc::PIC_);
// On PIC code global addresses are loaded with "la" instruction
if (!(getTargetMachine().getRelocationModel() == Reloc::PIC_)) {
const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::i32, MVT::Flag);
SDOperand HiPart;
if (!isPIC) {
const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::i32);
SDOperand Ops[] = { GA };
HiPart = DAG.getNode(MipsISD::Hi, VTs, 1, Ops, 1);
} else // Emit Load from Global Pointer
HiPart = DAG.getLoad(MVT::i32, DAG.getEntryNode(), GA, NULL, 0);
// On functions and global targets not internal linked only
// a load from got/GP is necessary for PIC to work.
if ((isPIC) && ((!GV->hasInternalLinkage()) || (isa<Function>(GV))))
return HiPart;
SDOperand Hi = DAG.getNode(MipsISD::Hi, VTs, 2, Ops, 1);
SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, GA);
SDOperand InFlag = Hi.getValue(1);
ResNode = DAG.getNode(MipsISD::Add, MVT::i32, Lo, Hi, InFlag);
} else
ResNode = DAG.getNode(MipsISD::LoadAddr, MVT::i32, GA);
ResNode = DAG.getNode(ISD::ADD, MVT::i32, HiPart, Lo);
return ResNode;
}
@ -211,7 +212,7 @@ LowerCALL(SDOperand Op, SelectionDAG &DAG)
/// LowerCCCCallTo - functions arguments are copied from virtual
/// regs to (physical regs)/(stack frame), CALLSEQ_START and
/// CALLSEQ_END are emitted.
/// TODO: isVarArg, isTailCall, sret, GOT, linkage types.
/// TODO: isVarArg, isTailCall, sret.
SDOperand MipsTargetLowering::
LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC)
{
@ -244,7 +245,7 @@ LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC)
SmallVector<SDOperand, 8> MemOpChains;
SDOperand StackPtr;
unsigned LastStackLoc=0;
int LastStackLoc=0;
// Walk the register/memloc assignments, inserting copies/loads.
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
@ -268,8 +269,8 @@ LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC)
break;
}
// Arguments that can be passed on register,
// must be kept at RegsToPass vector
// Arguments that can be passed on register must be kept at
// RegsToPass vector
if (VA.isRegLoc()) {
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
} else {
@ -294,14 +295,6 @@ LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC)
}
}
// Create a stack location to hold GP when PIC is used
if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
LastStackLoc = (!LastStackLoc) ? (16) : (LastStackLoc+4);
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
MFI->CreateFixedObject(4, LastStackLoc);
MipsFI->setGPStackOffset(LastStackLoc);
}
// Transform all store nodes into one single node because
// all store nodes are independent of each other.
if (!MemOpChains.empty())
@ -321,13 +314,13 @@ LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC)
// If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
// direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
// node so that legalize doesn't hack it. Otherwise we have an indirect call,
// if PIC is used, the call must use register GP
// node so that legalize doesn't hack it.
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
// MipsJmpLink = #chain, #target_address, #opt_in_flags...
// = Chain, Callee, Reg#1, Reg#2, ...
//
@ -349,6 +342,37 @@ LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC)
Chain = DAG.getNode(MipsISD::JmpLink, NodeTys, &Ops[0], Ops.size());
InFlag = Chain.getValue(1);
// Create a stack location to hold GP when PIC is used. This stack
// location is used on function prologue to save GP and also after all
// emited CALL's to restore GP.
if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
// Function can have an arbitrary number of calls, so
// hold the LastStackLoc with the biggest offset.
int FI;
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
if (LastStackLoc >= MipsFI->getGPStackOffset()) {
LastStackLoc = (!LastStackLoc) ? (16) : (LastStackLoc+4);
// Create the frame index only once. SPOffset here can be anything
// (this will be fixed on processFunctionBeforeFrameFinalized)
if (MipsFI->getGPStackOffset() == -1) {
FI = MFI->CreateFixedObject(4, 0);
MipsFI->setGPFI(FI);
}
MipsFI->setGPStackOffset(LastStackLoc);
}
// Reload GP value.
FI = MipsFI->getGPFI();
SDOperand FIN = DAG.getFrameIndex(FI,getPointerTy());
SDOperand GPLoad = DAG.getLoad(MVT::i32, Chain, FIN, NULL, 0);
Chain = GPLoad.getValue(1);
Chain = DAG.getCopyToReg(Chain, DAG.getRegister(Mips::GP, MVT::i32),
GPLoad, SDOperand(0,0));
}
// Create the CALLSEQ_END node.
NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
Ops.clear();
@ -389,8 +413,9 @@ LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode *TheCall,
ResultVals.push_back(Chain.getValue(0));
}
// Merge everything together with a MERGE_VALUES node.
ResultVals.push_back(Chain);
// Merge everything together with a MERGE_VALUES node.
return DAG.getNode(ISD::MERGE_VALUES, TheCall->getVTList(),
&ResultVals[0], ResultVals.size()).Val;
}

View File

@ -38,13 +38,7 @@ namespace llvm {
Lo,
// Return
Ret,
// Need to support addition with a input flag
Add,
// Used on PIC Code to load global addresses
LoadAddr
Ret
};
}

View File

@ -22,21 +22,12 @@ def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, [SDNPHasChain,
SDNPOutFlag]>;
// Hi and Lo nodes are created to let easy manipulation of 16-bit when
// handling 32-bit immediates. They are used on MipsISelLowering to
// lower stuff like GlobalAddress, ExternalSymbol, ... on static model
// This two nodes have nothing to do with Mips Registers Hi and Lo.
// 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 MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
// Necessary to generate glued instructions when loading GlobalAddress
// into registers.
def MipsAdd : SDNode<"MipsISD::Add", SDTIntBinOp, [SDNPCommutative,
SDNPAssociative, SDNPOptInFlag]>;
// Used to Load Addresses on PIC code.
def MipsLoadAddr: SDNode<"MipsISD::LoadAddr", SDTIntUnaryOp>;
// Return
def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
def MipsRet : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain,
@ -371,15 +362,9 @@ def IMPLICIT_DEF_CPURegs : PseudoInstMips<(outs CPURegs:$dst), (ins),
// are used, we have the same behavior, but get also a bunch of warnings
// from the assembler.
def CPLOAD: PseudoInstMips<(outs), (ins CPURegs:$reg),
".set noreorder\n\t.cpload $reg\n\t.set reorder", []>;
".set noreorder\n\t.cpload $reg\n\t.set reorder\n", []>;
def CPRESTORE: PseudoInstMips<(outs), (ins uimm16:$loc),
".cprestore $loc", []>;
// Used on PIC code only, it loads the address of label into register reg. The
// address is calculated from the global pointer ($gp) and is expanded by the
// assembler into two instructions "lw" and "addiu".
def LA: PseudoInstMips<(outs CPURegs:$dst), (ins addrlabel:$label),
"la $dst, $label", []>;
".cprestore $loc\n", []>;
//===----------------------------------------------------------------------===//
// Instruction definition
@ -393,17 +378,13 @@ def LA: PseudoInstMips<(outs CPURegs:$dst), (ins addrlabel:$label),
// ADDiu just accept 16-bit immediates but we handle this on Pat's.
// immZExt32 is used here so it can match GlobalAddress immediates.
def ADDiu : ArithI<0x09, "addiu", MipsAdd, uimm16, immZExt16>;
def ADDiu : ArithI<0x09, "addiu", add, uimm16, immZExt16>;
def ADDi : ArithI<0x08, "addi", add, simm16, immSExt16>;
def MUL : ArithR<0x1c, 0x02, "mul", mul, IIImul>;
def ADDu : ArithR<0x00, 0x21, "addu", add, IIAlu>;
def SUBu : ArithR<0x00, 0x23, "subu", sub, IIAlu>;
def ADD : ArithOverflowR<0x00, 0x20, "add">;
def SUB : ArithOverflowR<0x00, 0x22, "sub">;
def MADD : MArithR<0x00, "madd">;
def MADDU : MArithR<0x01, "maddu">;
def MSUB : MArithR<0x04, "msub">;
def MSUBU : MArithR<0x05, "msubu">;
// Logical
def AND : LogicR<0x24, "and", and>;
@ -485,6 +466,12 @@ def MTLO : MoveFromTo<0x13, "mtlo">;
//def CLO : CountLeading<0x21, "clo">;
//def CLZ : CountLeading<0x20, "clz">;
// MADD*/MSUB* are not part of MipsI either.
//def MADD : MArithR<0x00, "madd">;
//def MADDU : MArithR<0x01, "maddu">;
//def MSUB : MArithR<0x04, "msub">;
//def MSUBU : MArithR<0x05, "msubu">;
// No operation
let addr=0 in
def NOP : FJ<0, (outs), (ins), "nop", [], IIAlu>;
@ -529,9 +516,8 @@ def : Pat<(MipsJmpLink CPURegs:$dst),
// GlobalAddress, Constant Pool, ExternalSymbol, and JumpTable
def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
def : Pat<(MipsAdd CPURegs:$hi, (MipsLo tglobaladdr:$lo)),
def : Pat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)),
(ADDiu CPURegs:$hi, tglobaladdr:$lo)>;
def : Pat<(MipsLoadAddr tglobaladdr:$in), (LA tglobaladdr:$in)>;
// Mips does not have not, so we increase the operation
def : Pat<(not CPURegs:$in),
@ -544,6 +530,9 @@ def : Pat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
def : Pat<(truncstorei1 CPURegs:$src, addr:$addr),
(SB CPURegs:$src, addr:$addr)>;
// some peepholes
def : Pat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
///
/// brcond patterns
///

View File

@ -33,11 +33,6 @@ private:
/// the Return Address must be saved
int RAStackOffset;
/// When PIC is used the GP must be saved on the stack
/// on the function prologue, so a reference to its stack
/// location must be kept.
int GPStackOffset;
/// MipsFIHolder - Holds a FrameIndex and it's Stack Pointer Offset
struct MipsFIHolder {
@ -48,6 +43,13 @@ private:
: FI(FrameIndex), SPOffset(StackPointerOffset) {}
};
/// When PIC is used the GP must be saved on the stack
/// on the function prologue and must be reloaded from this
/// stack location after every call. A reference to its stack
/// location and frame index must be kept to be used on
/// emitPrologue and processFunctionBeforeFrameFinalized.
MipsFIHolder GPHolder;
// On LowerFORMAL_ARGUMENTS the stack size is unknown,
// so the Stack Pointer Offset calculation of "not in
// register arguments" must be postponed to emitPrologue.
@ -64,7 +66,7 @@ private:
public:
MipsFunctionInfo(MachineFunction& MF)
: FPStackOffset(0), RAStackOffset(0),
: FPStackOffset(0), RAStackOffset(0), GPHolder(-1,-1),
HasLoadArgs(false), HasStoreVarArgs(false)
{}
@ -74,8 +76,10 @@ public:
int getRAStackOffset() const { return RAStackOffset; }
void setRAStackOffset(int Off) { RAStackOffset = Off; }
int getGPStackOffset() const { return GPStackOffset; }
void setGPStackOffset(int Off) { GPStackOffset = Off; }
int getGPStackOffset() const { return GPHolder.SPOffset; }
int getGPFI() const { return GPHolder.FI; }
void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; }
void setGPFI(int FI) { GPHolder.FI = FI; }
int getTopSavedRegOffset() const {
return (RAStackOffset > FPStackOffset) ?

View File

@ -203,6 +203,12 @@ foldMemoryOperand(MachineInstr* MI, unsigned OpNum, int FI) const
return NewMI;
}
MachineInstr *MipsRegisterInfo::
foldMemoryOperand(MachineInstr* MI, unsigned OpNum,
MachineInstr* LoadMI) const {
return NULL;
}
//===----------------------------------------------------------------------===//
//
// Callee Saved Registers methods
@ -453,7 +459,6 @@ emitPrologue(MachineFunction &MF) const
if ((isPIC) && (MFI->hasCalls()))
BuildMI(MBB, MBBI, TII.get(Mips::CPRESTORE))
.addImm(MipsFI->getGPStackOffset());
}
void MipsRegisterInfo::
@ -498,6 +503,17 @@ emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const
void MipsRegisterInfo::
processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
// Set the SPOffset on the FI where GP must be saved/loaded.
MachineFrameInfo *MFI = MF.getFrameInfo();
if (MFI->hasCalls()) {
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
#ifndef NDEBUG
DOUT << "processFunctionBeforeFrameFinalized\n";
DOUT << "GPOffset :" << MipsFI->getGPStackOffset() << "\n";
DOUT << "FI :" << MipsFI->getGPFI() << "\n";
#endif
MFI->setObjectOffset(MipsFI->getGPFI(), MipsFI->getGPStackOffset());
}
}
unsigned MipsRegisterInfo::

View File

@ -59,9 +59,7 @@ struct MipsRegisterInfo : public MipsGenRegisterInfo {
int FrameIndex) const;
MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum,
MachineInstr* LoadMI) const {
return 0;
}
MachineInstr* LoadMI) const;
void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
unsigned DestReg, unsigned SrcReg,

View File

@ -35,6 +35,9 @@ createTargetAsmInfo() const
// On function prologue, the stack is created by decrementing
// its pointer. Once decremented, all references are done with positive
// offset from the stack/frame pointer, so StackGrowsUp is used.
// When using CodeModel::Large the behaviour
//
//
MipsTargetMachine::
MipsTargetMachine(const Module &M, const std::string &FS):
Subtarget(*this, M, FS), DataLayout("E-p:32:32:32"),
@ -43,6 +46,8 @@ MipsTargetMachine(const Module &M, const std::string &FS):
{
if (getRelocationModel() != Reloc::Static)
setRelocationModel(Reloc::PIC_);
if (getCodeModel() == CodeModel::Default)
setCodeModel(CodeModel::Small);
}
// return 0 and must specify -march to gen MIPS code.