From: Robert Lytton Date: Mon, 6 Jan 2014 14:20:53 +0000 (+0000) Subject: XCore target: Lower RETURNADDR X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dec798751a0a7dc36b559fae920ab916bbe10137;p=platform%2Fupstream%2Fllvm.git XCore target: Lower RETURNADDR Only handles a depth of zero (the same as FRAMEADDR) llvm-svn: 198613 --- diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.cpp b/llvm/lib/Target/XCore/XCoreISelLowering.cpp index c6cbf51..65568c9 100644 --- a/llvm/lib/Target/XCore/XCoreISelLowering.cpp +++ b/llvm/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/llvm/lib/Target/XCore/XCoreISelLowering.h b/llvm/lib/Target/XCore/XCoreISelLowering.h index bc08497..a6dd226 100644 --- a/llvm/lib/Target/XCore/XCoreISelLowering.h +++ b/llvm/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/llvm/test/CodeGen/XCore/llvm-intrinsics.ll b/llvm/test/CodeGen/XCore/llvm-intrinsics.ll new file mode 100644 index 0000000..14b299d --- /dev/null +++ b/llvm/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 +}