diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198480-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262261-llvm-r198480-sparc.diff | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198480-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198480-sparc.diff new file mode 100644 index 0000000..b3e1362 --- /dev/null +++ b/contrib/llvm/patches/patch-r262261-llvm-r198480-sparc.diff @@ -0,0 +1,213 @@ +Pull in r198480 from upstream llvm trunk (by Venkatraman Govindaraju): + + [SparcV9]: Implement RETURNADDR and FRAMEADDR lowering in SPARC64. + +Introduced here: http://svn.freebsd.org/changeset/base/262261 + +Index: lib/Target/Sparc/SparcISelLowering.cpp +=================================================================== +--- lib/Target/Sparc/SparcISelLowering.cpp ++++ lib/Target/Sparc/SparcISelLowering.cpp +@@ -2415,7 +2415,8 @@ static SDValue getFLUSHW(SDValue Op, SelectionDAG + return Chain; + } + +-static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) { ++static SDValue getFRAMEADDR(uint64_t depth, SDValue Op, SelectionDAG &DAG, ++ const SparcSubtarget *Subtarget) { + MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + MFI->setFrameAddressIsTaken(true); + +@@ -2422,32 +2423,49 @@ static SDValue getFLUSHW(SDValue Op, SelectionDAG + EVT VT = Op.getValueType(); + SDLoc dl(Op); + unsigned FrameReg = SP::I6; ++ unsigned stackBias = Subtarget->getStackPointerBias(); + +- uint64_t depth = Op.getConstantOperandVal(0); ++ SDValue FrameAddr; + +- SDValue FrameAddr; +- if (depth == 0) ++ if (depth == 0) { + FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT); +- else { +- // flush first to make sure the windowed registers' values are in stack +- SDValue Chain = getFLUSHW(Op, DAG); +- FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT); ++ if (Subtarget->is64Bit()) ++ FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr, ++ DAG.getIntPtrConstant(stackBias)); ++ return FrameAddr; ++ } + +- for (uint64_t i = 0; i != depth; ++i) { +- SDValue Ptr = DAG.getNode(ISD::ADD, +- dl, MVT::i32, +- FrameAddr, DAG.getIntPtrConstant(56)); +- FrameAddr = DAG.getLoad(MVT::i32, dl, +- Chain, +- Ptr, +- MachinePointerInfo(), false, false, false, 0); +- } ++ // flush first to make sure the windowed registers' values are in stack ++ SDValue Chain = getFLUSHW(Op, DAG); ++ FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT); ++ ++ unsigned Offset = (Subtarget->is64Bit()) ? (stackBias + 112) : 56; ++ ++ while (depth--) { ++ SDValue Ptr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr, ++ DAG.getIntPtrConstant(Offset)); ++ FrameAddr = DAG.getLoad(VT, dl, Chain, Ptr, MachinePointerInfo(), ++ false, false, false, 0); + } ++ if (Subtarget->is64Bit()) ++ FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr, ++ DAG.getIntPtrConstant(stackBias)); + return FrameAddr; + } + ++ ++static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, ++ const SparcSubtarget *Subtarget) { ++ ++ uint64_t depth = Op.getConstantOperandVal(0); ++ ++ return getFRAMEADDR(depth, Op, DAG, Subtarget); ++ ++} ++ + static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG, +- const SparcTargetLowering &TLI) { ++ const SparcTargetLowering &TLI, ++ const SparcSubtarget *Subtarget) { + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + MFI->setReturnAddressIsTaken(true); +@@ -2461,25 +2479,20 @@ static SDValue LowerRETURNADDR(SDValue Op, Selecti + unsigned RetReg = MF.addLiveIn(SP::I7, + TLI.getRegClassFor(TLI.getPointerTy())); + RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT); +- } else { +- // Need frame address to find return address of the caller. +- MFI->setFrameAddressIsTaken(true); ++ return RetAddr; ++ } + +- // flush first to make sure the windowed registers' values are in stack +- SDValue Chain = getFLUSHW(Op, DAG); +- RetAddr = DAG.getCopyFromReg(Chain, dl, SP::I6, VT); ++ // Need frame address to find return address of the caller. ++ SDValue FrameAddr = getFRAMEADDR(depth - 1, Op, DAG, Subtarget); + +- for (uint64_t i = 0; i != depth; ++i) { +- SDValue Ptr = DAG.getNode(ISD::ADD, +- dl, MVT::i32, +- RetAddr, +- DAG.getIntPtrConstant((i == depth-1)?60:56)); +- RetAddr = DAG.getLoad(MVT::i32, dl, +- Chain, +- Ptr, +- MachinePointerInfo(), false, false, false, 0); +- } +- } ++ unsigned Offset = (Subtarget->is64Bit()) ? 120 : 60; ++ SDValue Ptr = DAG.getNode(ISD::ADD, ++ dl, VT, ++ FrameAddr, ++ DAG.getIntPtrConstant(Offset)); ++ RetAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), Ptr, ++ MachinePointerInfo(), false, false, false, 0); ++ + return RetAddr; + } + +@@ -2763,8 +2776,10 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons + switch (Op.getOpcode()) { + default: llvm_unreachable("Should not custom lower this!"); + +- case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG, *this); +- case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); ++ case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG, *this, ++ Subtarget); ++ case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG, ++ Subtarget); + case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); + case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); + case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); +Index: test/CodeGen/SPARC/2011-01-11-FrameAddr.ll +=================================================================== +--- test/CodeGen/SPARC/2011-01-11-FrameAddr.ll ++++ test/CodeGen/SPARC/2011-01-11-FrameAddr.ll +@@ -2,6 +2,7 @@ + ;RUN: llc -march=sparc -mattr=v9 < %s | FileCheck %s -check-prefix=V9 + ;RUN: llc -march=sparc -regalloc=basic < %s | FileCheck %s -check-prefix=V8 + ;RUN: llc -march=sparc -regalloc=basic -mattr=v9 < %s | FileCheck %s -check-prefix=V9 ++;RUN: llc -march=sparcv9 < %s | FileCheck %s -check-prefix=SPARC64 + + + define i8* @frameaddr() nounwind readnone { +@@ -15,6 +16,13 @@ entry: + ;V9: save %sp, -96, %sp + ;V9: jmp %i7+8 + ;V9: restore %g0, %fp, %o0 ++ ++;SPARC64-LABEL: frameaddr ++;SPARC64: save %sp, -128, %sp ++;SPARC64: add %fp, 2047, %i0 ++;SPARC64: jmp %i7+8 ++;SPARC64: restore %g0, %g0, %g0 ++ + %0 = tail call i8* @llvm.frameaddress(i32 0) + ret i8* %0 + } +@@ -32,6 +40,14 @@ entry: + ;V9: ld [%fp+56], {{.+}} + ;V9: ld [{{.+}}+56], {{.+}} + ;V9: ld [{{.+}}+56], {{.+}} ++ ++;SPARC64-LABEL: frameaddr2 ++;SPARC64: flushw ++;SPARC64: ldx [%fp+2159], %[[R0:[goli][0-7]]] ++;SPARC64: ldx [%[[R0]]+2159], %[[R1:[goli][0-7]]] ++;SPARC64: ldx [%[[R1]]+2159], %[[R2:[goli][0-7]]] ++;SPARC64: add %[[R2]], 2047, {{.+}} ++ + %0 = tail call i8* @llvm.frameaddress(i32 3) + ret i8* %0 + } +@@ -48,6 +64,9 @@ entry: + ;V9-LABEL: retaddr: + ;V9: or %g0, %o7, {{.+}} + ++;SPARC64-LABEL: retaddr ++;SPARC64: or %g0, %o7, {{.+}} ++ + %0 = tail call i8* @llvm.returnaddress(i32 0) + ret i8* %0 + } +@@ -66,18 +85,12 @@ entry: + ;V9: ld [{{.+}}+56], {{.+}} + ;V9: ld [{{.+}}+60], {{.+}} + +-;V8LEAF-LABEL: retaddr2: +-;V8LEAF: ta 3 +-;V8LEAF: ld [%fp+56], %[[R:[goli][0-7]]] +-;V8LEAF: ld [%[[R]]+56], %[[R1:[goli][0-7]]] +-;V8LEAF: ld [%[[R1]]+60], {{.+}} ++;SPARC64-LABEL: retaddr2 ++;SPARC64: flushw ++;SPARC64: ldx [%fp+2159], %[[R0:[goli][0-7]]] ++;SPARC64: ldx [%[[R0]]+2159], %[[R1:[goli][0-7]]] ++;SPARC64: ldx [%[[R1]]+2167], {{.+}} + +-;V9LEAF-LABEL: retaddr2: +-;V9LEAF: flushw +-;V9LEAF: ld [%fp+56], %[[R:[goli][0-7]]] +-;V9LEAF: ld [%[[R]]+56], %[[R1:[goli][0-7]]] +-;V9LEAF: ld [%[[R1]]+60], {{.+}} +- + %0 = tail call i8* @llvm.returnaddress(i32 3) + ret i8* %0 + } |