mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-16 05:41:45 +00:00
Position Independent Code (PIC) support [3]
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42780 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0a6040063f
commit
8262df3aa4
@ -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));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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::
|
||||
|
Loading…
x
Reference in New Issue
Block a user