mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
implement __builtin_return_addr(0) on ppc.
llvm-svn: 44700
This commit is contained in:
parent
1024cda0bd
commit
e16166b78d
@ -3036,8 +3036,8 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||
case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG);
|
||||
case ISD::MUL: return LowerMUL(Op, DAG);
|
||||
|
||||
// Frame & Return address. Currently unimplemented
|
||||
case ISD::RETURNADDR: break;
|
||||
// Frame & Return address.
|
||||
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
|
||||
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
|
||||
}
|
||||
return SDOperand();
|
||||
@ -3576,8 +3576,36 @@ bool PPCTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
SDOperand PPCTargetLowering::LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG)
|
||||
{
|
||||
SDOperand PPCTargetLowering::LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG) {
|
||||
// Depths > 0 not supported yet!
|
||||
if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
|
||||
return SDOperand();
|
||||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
|
||||
int RAIdx = FuncInfo->getReturnAddrSaveIndex();
|
||||
if (RAIdx == 0) {
|
||||
bool isPPC64 = PPCSubTarget.isPPC64();
|
||||
int Offset =
|
||||
PPCFrameInfo::getReturnSaveOffset(isPPC64, PPCSubTarget.isMachoABI());
|
||||
|
||||
// Set up a frame object for the return address.
|
||||
RAIdx = MF.getFrameInfo()->CreateFixedObject(isPPC64 ? 8 : 4, Offset);
|
||||
|
||||
// Remember it for next time.
|
||||
FuncInfo->setReturnAddrSaveIndex(RAIdx);
|
||||
|
||||
// Make sure the function really does not optimize away the store of the RA
|
||||
// to the stack.
|
||||
FuncInfo->setLRStoreRequired();
|
||||
}
|
||||
|
||||
// Just load the return address off the stack.
|
||||
SDOperand RetAddrFI = DAG.getFrameIndex(RAIdx, getPointerTy());
|
||||
return DAG.getLoad(getPointerTy(), DAG.getEntryNode(), RetAddrFI, NULL, 0);
|
||||
}
|
||||
|
||||
SDOperand PPCTargetLowering::LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG) {
|
||||
// Depths > 0 not supported yet!
|
||||
if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
|
||||
return SDOperand();
|
||||
|
@ -288,6 +288,7 @@ namespace llvm {
|
||||
/// the offset of the target addressing mode.
|
||||
virtual bool isLegalAddressImmediate(GlobalValue *GV) const;
|
||||
|
||||
SDOperand LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG);
|
||||
SDOperand LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG);
|
||||
};
|
||||
}
|
||||
|
@ -27,18 +27,29 @@ private:
|
||||
/// when using frame pointers (dyna_add, dyna_sub.)
|
||||
int FramePointerSaveIndex;
|
||||
|
||||
/// UsesLR - Indicates whether LR is used in the current function.
|
||||
/// ReturnAddrSaveIndex - Frame index of where the return address is stored.
|
||||
///
|
||||
int ReturnAddrSaveIndex;
|
||||
|
||||
/// UsesLR - Indicates whether LR is used in the current function. This is
|
||||
/// only valid after the initial scan of the function by PEI.
|
||||
bool UsesLR;
|
||||
|
||||
/// LRStoreRequired - The bool indicates whether there is some explicit use of
|
||||
/// the LR/LR8 stack slot that is not obvious from scanning the code. This
|
||||
/// requires that the code generator produce a store of LR to the stack on
|
||||
/// entry, even though LR may otherwise apparently not be used.
|
||||
bool LRStoreRequired;
|
||||
public:
|
||||
PPCFunctionInfo(MachineFunction& MF)
|
||||
: FramePointerSaveIndex(0)
|
||||
{}
|
||||
PPCFunctionInfo(MachineFunction &MF)
|
||||
: FramePointerSaveIndex(0), ReturnAddrSaveIndex(0), LRStoreRequired(false){}
|
||||
|
||||
int getFramePointerSaveIndex() const { return FramePointerSaveIndex; }
|
||||
void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; }
|
||||
|
||||
int getReturnAddrSaveIndex() const { return ReturnAddrSaveIndex; }
|
||||
void setReturnAddrSaveIndex(int idx) { ReturnAddrSaveIndex = idx; }
|
||||
|
||||
/// UsesLR - This is set when the prolog/epilog inserter does its initial scan
|
||||
/// of the function, it is true if the LR/LR8 register is ever explicitly
|
||||
/// accessed/clobbered in the machine function (e.g. by calls and movpctolr,
|
||||
@ -46,6 +57,9 @@ public:
|
||||
void setUsesLR(bool U) { UsesLR = U; }
|
||||
bool usesLR() const { return UsesLR; }
|
||||
|
||||
void setLRStoreRequired() { LRStoreRequired = true; }
|
||||
bool isLRStoreRequired() const { return LRStoreRequired; }
|
||||
|
||||
};
|
||||
|
||||
} // end of namespace llvm
|
||||
|
@ -646,9 +646,14 @@ bool PPCRegisterInfo::hasFP(const MachineFunction &MF) const {
|
||||
}
|
||||
|
||||
/// MustSaveLR - Return true if this function requires that we save the LR
|
||||
/// register onto the stack in the prolog and restore it in the epilog of the function.
|
||||
/// register onto the stack in the prolog and restore it in the epilog of the
|
||||
/// function.
|
||||
static bool MustSaveLR(const MachineFunction &MF) {
|
||||
return MF.getInfo<PPCFunctionInfo>()->usesLR() ||
|
||||
const PPCFunctionInfo *MFI = MF.getInfo<PPCFunctionInfo>();
|
||||
|
||||
// We need an save/restore of LR if there is any use/def of LR explicitly, or
|
||||
// if there is some use of the LR stack slot (e.g. for builtin_return_address.
|
||||
return MFI->usesLR() || MFI->isLRStoreRequired() ||
|
||||
// FIXME: Anything that has a call should clobber the LR register,
|
||||
// isn't this redundant??
|
||||
MF.getFrameInfo()->hasCalls();
|
||||
|
@ -3,7 +3,6 @@
|
||||
TODO:
|
||||
* gpr0 allocation
|
||||
* implement do-loop -> bdnz transform
|
||||
* __builtin_return_address not supported on PPC
|
||||
|
||||
===-------------------------------------------------------------------------===
|
||||
|
||||
|
14
test/CodeGen/PowerPC/retaddr.ll
Normal file
14
test/CodeGen/PowerPC/retaddr.ll
Normal file
@ -0,0 +1,14 @@
|
||||
; RUN: llvm-as < %s | llc -march=ppc32 | grep mflr
|
||||
; RUN: llvm-as < %s | llc -march=ppc32 | grep lwz
|
||||
|
||||
target triple = "powerpc-apple-darwin8"
|
||||
|
||||
define void @foo(i8** %X) {
|
||||
entry:
|
||||
%tmp = tail call i8* @llvm.returnaddress( i32 0 ) ; <i8*> [#uses=1]
|
||||
store i8* %tmp, i8** %X, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i8* @llvm.returnaddress(i32)
|
||||
|
Loading…
x
Reference in New Issue
Block a user