diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index c29364c82f6..38f3974d9a4 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -2700,7 +2700,7 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { // Frame & Return address. Currently unimplemented case ISD::RETURNADDR: break; - case ISD::FRAMEADDR: break; + case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); } return SDOperand(); } @@ -3171,3 +3171,25 @@ bool PPCTargetLowering::isLegalAddressImmediate(int64_t V) const { bool PPCTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const { return TargetLowering::isLegalAddressImmediate(GV); } + +SDOperand PPCTargetLowering::LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG) +{ + // Depths > 0 not supported yet! + if (cast(Op.getOperand(0))->getValue() > 0) + return SDOperand(); + + MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + bool isPPC64 = PtrVT == MVT::i64; + + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + bool is31 = (NoFramePointerElim || MFI->hasVarSizedObjects()) + && MFI->getStackSize(); + + if (isPPC64) + return DAG.getCopyFromReg(DAG.getEntryNode(), is31 ? PPC::X31 : PPC::X1, + MVT::i32); + else + return DAG.getCopyFromReg(DAG.getEntryNode(), is31 ? PPC::R31 : PPC::R1, + MVT::i32); +} diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index 676e0bc6fc8..009ceb0d966 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -240,6 +240,8 @@ namespace llvm { /// as the offset of the target addressing mode. virtual bool isLegalAddressImmediate(int64_t V) const; virtual bool isLegalAddressImmediate(llvm::GlobalValue*) const; + + SDOperand LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG); }; }