aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2007-10-09 03:15:11 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2007-10-09 03:15:11 +0000
commit9857994c0aba62afe3c41aa742cb24c682d0f7a6 (patch)
tree34c2d80693d9f5bac537de5aaa2f497642f85df1 /lib
parent5f8e1117a74a67a47890b04f906c71efc9bf17da (diff)
downloadexternal_llvm-9857994c0aba62afe3c41aa742cb24c682d0f7a6.zip
external_llvm-9857994c0aba62afe3c41aa742cb24c682d0f7a6.tar.gz
external_llvm-9857994c0aba62afe3c41aa742cb24c682d0f7a6.tar.bz2
Position Independent Code (PIC) support [3]
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42780 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp51
-rw-r--r--lib/Target/Mips/MipsISelLowering.h5
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.cpp15
3 files changed, 51 insertions, 20 deletions
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index a63da4c..5b4ee26 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -44,6 +44,7 @@ getTargetNodeName(unsigned Opcode) const
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;
}
}
@@ -146,18 +147,25 @@ AddLiveIn(MachineFunction &MF, unsigned PReg, TargetRegisterClass *RC)
SDOperand MipsTargetLowering::
LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG)
{
+ SDOperand ResNode;
GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
- const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::i32, MVT::Flag);
- SDOperand Ops[] = { GA };
+ // 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 Ops[] = { GA };
- SDOperand Hi = DAG.getNode(MipsISD::Hi, VTs, 2, Ops, 1);
- SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, GA);
+ SDOperand Hi = DAG.getNode(MipsISD::Hi, VTs, 2, Ops, 1);
+ SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, GA);
- SDOperand InFlag = Hi.getValue(1);
- return DAG.getNode(MipsISD::Add, MVT::i32, Lo, Hi, InFlag);
+ SDOperand InFlag = Hi.getValue(1);
+ ResNode = DAG.getNode(MipsISD::Add, MVT::i32, Lo, Hi, InFlag);
+ } else
+ ResNode = DAG.getNode(MipsISD::LoadAddr, MVT::i32, GA);
+
+ return ResNode;
}
SDOperand MipsTargetLowering::
@@ -236,6 +244,7 @@ LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC)
SmallVector<SDOperand, 8> MemOpChains;
SDOperand StackPtr;
+ unsigned LastStackLoc=0;
// Walk the register/memloc assignments, inserting copies/loads.
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
@@ -273,8 +282,9 @@ LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC)
// Create the frame index object for this incoming parameter
// This guarantees that when allocating Local Area the firsts
// 16 bytes which are alwayes reserved won't be overwritten.
+ LastStackLoc = (16 + VA.getLocMemOffset());
int FI = MFI->CreateFixedObject(MVT::getSizeInBits(VA.getValVT())/8,
- (16 + VA.getLocMemOffset()));
+ LastStackLoc);
SDOperand PtrOff = DAG.getFrameIndex(FI,getPointerTy());
@@ -284,6 +294,14 @@ 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())
@@ -301,13 +319,13 @@ LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC)
InFlag = Chain.getValue(1);
}
- // If the callee is a GlobalAddress node (quite common, every direct
- // call is) turn it into a TargetGlobalAddress node so that legalize
- // doesn't hack it.
- if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
+ // 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
+ if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
- } else
- if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
+ else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
// MipsJmpLink = #chain, #target_address, #opt_in_flags...
@@ -543,8 +561,7 @@ LowerRET(SDOperand Op, SelectionDAG &DAG)
// ISD::RET => ret chain, (regnum1,val1), ...
// So i*2+1 index only the regnums
- Chain = DAG.getCopyToReg(Chain, VA.getLocReg(),
- Op.getOperand(i*2+1), Flag);
+ Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
// guarantee that all emitted copies are
// stuck together, avoiding something bad
@@ -554,10 +571,10 @@ LowerRET(SDOperand Op, SelectionDAG &DAG)
// Return on Mips is always a "jr $ra"
if (Flag.Val)
return DAG.getNode(MipsISD::Ret, MVT::Other,
- Chain, DAG.getRegister(Mips::RA, MVT::i32), Flag);
+ Chain, DAG.getRegister(Mips::RA, MVT::i32), Flag);
else // Return Void
return DAG.getNode(MipsISD::Ret, MVT::Other,
- Chain, DAG.getRegister(Mips::RA, MVT::i32));
+ Chain, DAG.getRegister(Mips::RA, MVT::i32));
}
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h
index 5ec37bf..2d230a7 100644
--- a/lib/Target/Mips/MipsISelLowering.h
+++ b/lib/Target/Mips/MipsISelLowering.h
@@ -41,7 +41,10 @@ namespace llvm {
Ret,
// Need to support addition with a input flag
- Add
+ Add,
+
+ // Used on PIC Code to load global addresses
+ LoadAddr
};
}
diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp
index 8ab5e0e..2e87293 100644
--- a/lib/Target/Mips/MipsRegisterInfo.cpp
+++ b/lib/Target/Mips/MipsRegisterInfo.cpp
@@ -369,9 +369,10 @@ emitPrologue(MachineFunction &MF) const
MachineFrameInfo *MFI = MF.getFrameInfo();
MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
MachineBasicBlock::iterator MBBI = MBB.begin();
+ bool isPIC = (MF.getTarget().getRelocationModel() == Reloc::PIC_);
- // Replace the dummy '0' SPOffset by the negative offsets, as
- // explained on LowerFORMAL_ARGUMENTS
+ // Replace the dummy '0' SPOffset by the negative
+ // offsets, as explained on LowerFORMAL_ARGUMENTS
MipsFI->adjustLoadArgsFI(MFI);
MipsFI->adjustStoreVarArgsFI(MFI);
@@ -421,6 +422,10 @@ 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);
+
// Adjust stack : addi sp, sp, (-imm)
BuildMI(MBB, MBBI, TII.get(Mips::ADDiu), Mips::SP)
.addReg(Mips::SP).addImm(-NumBytes);
@@ -443,6 +448,12 @@ emitPrologue(MachineFunction &MF) const
BuildMI(MBB, MBBI, TII.get(Mips::ADDu), Mips::FP)
.addReg(Mips::SP).addReg(Mips::ZERO);
}
+
+ // PIC speficic function prologue
+ if ((isPIC) && (MFI->hasCalls()))
+ BuildMI(MBB, MBBI, TII.get(Mips::CPRESTORE))
+ .addImm(MipsFI->getGPStackOffset());
+
}
void MipsRegisterInfo::