From: Robert Lytton Date: Mon, 6 Jan 2014 14:20:53 +0000 (+0000) Subject: XCore target: Lower RETURNADDR X-Git-Tag: android-x86-7.1-r4~66332 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=12ad7cd730cb0575a6d03cccd6073af8e9486f3f;p=android-x86%2Fexternal-llvm.git XCore target: Lower RETURNADDR Only handles a depth of zero (the same as FRAMEADDR) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198613 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp index c6cbf51202c..65568c96543 100644 --- a/lib/Target/XCore/XCoreISelLowering.cpp +++ b/lib/Target/XCore/XCoreISelLowering.cpp @@ -212,6 +212,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::ADD: case ISD::SUB: return ExpandADDSUB(Op.getNode(), DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); + case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG); case ISD::ADJUST_TRAMPOLINE: return LowerADJUST_TRAMPOLINE(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); @@ -792,18 +793,40 @@ LowerVASTART(SDValue Op, SelectionDAG &DAG) const SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const { - SDLoc dl(Op); + // This nodes represent llvm.frameaddress on the DAG. + // It takes one operand, the index of the frame address to return. + // An index of zero corresponds to the current function's frame address. + // An index of one to the parent's frame address, and so on. // Depths > 0 not supported yet! if (cast(Op.getOperand(0))->getZExtValue() > 0) return SDValue(); MachineFunction &MF = DAG.getMachineFunction(); const TargetRegisterInfo *RegInfo = getTargetMachine().getRegisterInfo(); - return DAG.getCopyFromReg(DAG.getEntryNode(), dl, + return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), RegInfo->getFrameRegister(MF), MVT::i32); } SDValue XCoreTargetLowering:: +LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const { + // This nodes represent llvm.returnaddress on the DAG. + // It takes one operand, the index of the return address to return. + // An index of zero corresponds to the current function's return address. + // An index of one to the parent's return address, and so on. + // Depths > 0 not supported yet! + if (cast(Op.getOperand(0))->getZExtValue() > 0) + return SDValue(); + + MachineFunction &MF = DAG.getMachineFunction(); + XCoreFunctionInfo *XFI = MF.getInfo(); + int FI = XFI->createLRSpillSlot(MF); + SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); + return DAG.getLoad(getPointerTy(), SDLoc(Op), DAG.getEntryNode(), FIN, + MachinePointerInfo::getFixedStack(FI), false, false, + false, 0); +} + +SDValue XCoreTargetLowering:: LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const { return Op.getOperand(0); } diff --git a/lib/Target/XCore/XCoreISelLowering.h b/lib/Target/XCore/XCoreISelLowering.h index bc08497b12e..a6dd2260246 100644 --- a/lib/Target/XCore/XCoreISelLowering.h +++ b/lib/Target/XCore/XCoreISelLowering.h @@ -158,6 +158,7 @@ namespace llvm { SDValue LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; diff --git a/test/CodeGen/XCore/llvm-intrinsics.ll b/test/CodeGen/XCore/llvm-intrinsics.ll new file mode 100644 index 00000000000..14b299d46e8 --- /dev/null +++ b/test/CodeGen/XCore/llvm-intrinsics.ll @@ -0,0 +1,46 @@ +; RUN: llc < %s -march=xcore | FileCheck %s + +declare i8* @llvm.frameaddress(i32) nounwind readnone +define i8* @FA0() nounwind { +entry: +; CHECK-LABEL: FA0 +; CHECK: ldaw r0, sp[0] +; CHECK-NEXT: retsp 0 + %0 = call i8* @llvm.frameaddress(i32 0) + ret i8* %0 +} + +define i8* @FA1() nounwind { +entry: +; CHECK-LABEL: FA1 +; CHECK: entsp 100 +; CHECK-NEXT: ldaw r0, sp[0] +; CHECK-NEXT: retsp 100 + %0 = alloca [100 x i32] + %1 = call i8* @llvm.frameaddress(i32 0) + ret i8* %1 +} + + +declare i8* @llvm.returnaddress(i32) nounwind readnone +define i8* @RA0() nounwind { +entry: +; CHECK-LABEL: RA0 +; CHECK: stw lr, sp[0] +; CHECK-NEXT: ldw r0, sp[0] +; CHECK-NEXT: ldw lr, sp[0] +; CHECK-NEXT: retsp 0 + %0 = call i8* @llvm.returnaddress(i32 0) + ret i8* %0 +} + +define i8* @RA1() nounwind { +entry: +; CHECK-LABEL: RA1 +; CHECK: entsp 100 +; CHECK-NEXT: ldw r0, sp[100] +; CHECK-NEXT: retsp 100 + %0 = alloca [100 x i32] + %1 = call i8* @llvm.returnaddress(i32 0) + ret i8* %1 +}