From 8262df3aa49feaae18a86d21ed8a20427d638218 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Tue, 9 Oct 2007 03:15:11 +0000 Subject: [PATCH] Position Independent Code (PIC) support [3] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42780 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 51 ++++++++++++++++++---------- lib/Target/Mips/MipsISelLowering.h | 5 ++- lib/Target/Mips/MipsRegisterInfo.cpp | 15 ++++++-- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index a63da4c1d1b..5b4ee2602a8 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(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 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(); + 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(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(Callee)) Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy()); - } else - if (ExternalSymbolSDNode *S = dyn_cast(Callee)) + else if (ExternalSymbolSDNode *S = dyn_cast(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 5ec37bf0085..2d230a7ceb3 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 8ab5e0e0880..2e872932ace 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(); 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:: -- 2.34.1