patch-r262261-llvm-r198480-sparc.diff revision 269012
1263320SdimPull in r198480 from upstream llvm trunk (by Venkatraman Govindaraju): 2263320Sdim 3263320Sdim [SparcV9]: Implement RETURNADDR and FRAMEADDR lowering in SPARC64. 4263320Sdim 5269012SemasteIntroduced here: http://svnweb.freebsd.org/changeset/base/262261 6263320Sdim 7263320SdimIndex: lib/Target/Sparc/SparcISelLowering.cpp 8263320Sdim=================================================================== 9263320Sdim--- lib/Target/Sparc/SparcISelLowering.cpp 10263320Sdim+++ lib/Target/Sparc/SparcISelLowering.cpp 11263320Sdim@@ -2415,7 +2415,8 @@ static SDValue getFLUSHW(SDValue Op, SelectionDAG 12263320Sdim return Chain; 13263320Sdim } 14263320Sdim 15263320Sdim-static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) { 16263320Sdim+static SDValue getFRAMEADDR(uint64_t depth, SDValue Op, SelectionDAG &DAG, 17263320Sdim+ const SparcSubtarget *Subtarget) { 18263320Sdim MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 19263320Sdim MFI->setFrameAddressIsTaken(true); 20263320Sdim 21263320Sdim@@ -2422,32 +2423,49 @@ static SDValue getFLUSHW(SDValue Op, SelectionDAG 22263320Sdim EVT VT = Op.getValueType(); 23263320Sdim SDLoc dl(Op); 24263320Sdim unsigned FrameReg = SP::I6; 25263320Sdim+ unsigned stackBias = Subtarget->getStackPointerBias(); 26263320Sdim 27263320Sdim- uint64_t depth = Op.getConstantOperandVal(0); 28263320Sdim+ SDValue FrameAddr; 29263320Sdim 30263320Sdim- SDValue FrameAddr; 31263320Sdim- if (depth == 0) 32263320Sdim+ if (depth == 0) { 33263320Sdim FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT); 34263320Sdim- else { 35263320Sdim- // flush first to make sure the windowed registers' values are in stack 36263320Sdim- SDValue Chain = getFLUSHW(Op, DAG); 37263320Sdim- FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT); 38263320Sdim+ if (Subtarget->is64Bit()) 39263320Sdim+ FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr, 40263320Sdim+ DAG.getIntPtrConstant(stackBias)); 41263320Sdim+ return FrameAddr; 42263320Sdim+ } 43263320Sdim 44263320Sdim- for (uint64_t i = 0; i != depth; ++i) { 45263320Sdim- SDValue Ptr = DAG.getNode(ISD::ADD, 46263320Sdim- dl, MVT::i32, 47263320Sdim- FrameAddr, DAG.getIntPtrConstant(56)); 48263320Sdim- FrameAddr = DAG.getLoad(MVT::i32, dl, 49263320Sdim- Chain, 50263320Sdim- Ptr, 51263320Sdim- MachinePointerInfo(), false, false, false, 0); 52263320Sdim- } 53263320Sdim+ // flush first to make sure the windowed registers' values are in stack 54263320Sdim+ SDValue Chain = getFLUSHW(Op, DAG); 55263320Sdim+ FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT); 56263320Sdim+ 57263320Sdim+ unsigned Offset = (Subtarget->is64Bit()) ? (stackBias + 112) : 56; 58263320Sdim+ 59263320Sdim+ while (depth--) { 60263320Sdim+ SDValue Ptr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr, 61263320Sdim+ DAG.getIntPtrConstant(Offset)); 62263320Sdim+ FrameAddr = DAG.getLoad(VT, dl, Chain, Ptr, MachinePointerInfo(), 63263320Sdim+ false, false, false, 0); 64263320Sdim } 65263320Sdim+ if (Subtarget->is64Bit()) 66263320Sdim+ FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr, 67263320Sdim+ DAG.getIntPtrConstant(stackBias)); 68263320Sdim return FrameAddr; 69263320Sdim } 70263320Sdim 71263320Sdim+ 72263320Sdim+static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, 73263320Sdim+ const SparcSubtarget *Subtarget) { 74263320Sdim+ 75263320Sdim+ uint64_t depth = Op.getConstantOperandVal(0); 76263320Sdim+ 77263320Sdim+ return getFRAMEADDR(depth, Op, DAG, Subtarget); 78263320Sdim+ 79263320Sdim+} 80263320Sdim+ 81263320Sdim static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG, 82263320Sdim- const SparcTargetLowering &TLI) { 83263320Sdim+ const SparcTargetLowering &TLI, 84263320Sdim+ const SparcSubtarget *Subtarget) { 85263320Sdim MachineFunction &MF = DAG.getMachineFunction(); 86263320Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 87263320Sdim MFI->setReturnAddressIsTaken(true); 88263320Sdim@@ -2461,25 +2479,20 @@ static SDValue LowerRETURNADDR(SDValue Op, Selecti 89263320Sdim unsigned RetReg = MF.addLiveIn(SP::I7, 90263320Sdim TLI.getRegClassFor(TLI.getPointerTy())); 91263320Sdim RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT); 92263320Sdim- } else { 93263320Sdim- // Need frame address to find return address of the caller. 94263320Sdim- MFI->setFrameAddressIsTaken(true); 95263320Sdim+ return RetAddr; 96263320Sdim+ } 97263320Sdim 98263320Sdim- // flush first to make sure the windowed registers' values are in stack 99263320Sdim- SDValue Chain = getFLUSHW(Op, DAG); 100263320Sdim- RetAddr = DAG.getCopyFromReg(Chain, dl, SP::I6, VT); 101263320Sdim+ // Need frame address to find return address of the caller. 102263320Sdim+ SDValue FrameAddr = getFRAMEADDR(depth - 1, Op, DAG, Subtarget); 103263320Sdim 104263320Sdim- for (uint64_t i = 0; i != depth; ++i) { 105263320Sdim- SDValue Ptr = DAG.getNode(ISD::ADD, 106263320Sdim- dl, MVT::i32, 107263320Sdim- RetAddr, 108263320Sdim- DAG.getIntPtrConstant((i == depth-1)?60:56)); 109263320Sdim- RetAddr = DAG.getLoad(MVT::i32, dl, 110263320Sdim- Chain, 111263320Sdim- Ptr, 112263320Sdim- MachinePointerInfo(), false, false, false, 0); 113263320Sdim- } 114263320Sdim- } 115263320Sdim+ unsigned Offset = (Subtarget->is64Bit()) ? 120 : 60; 116263320Sdim+ SDValue Ptr = DAG.getNode(ISD::ADD, 117263320Sdim+ dl, VT, 118263320Sdim+ FrameAddr, 119263320Sdim+ DAG.getIntPtrConstant(Offset)); 120263320Sdim+ RetAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), Ptr, 121263320Sdim+ MachinePointerInfo(), false, false, false, 0); 122263320Sdim+ 123263320Sdim return RetAddr; 124263320Sdim } 125263320Sdim 126263320Sdim@@ -2763,8 +2776,10 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons 127263320Sdim switch (Op.getOpcode()) { 128263320Sdim default: llvm_unreachable("Should not custom lower this!"); 129263320Sdim 130263320Sdim- case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG, *this); 131263320Sdim- case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 132263320Sdim+ case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG, *this, 133263320Sdim+ Subtarget); 134263320Sdim+ case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG, 135263320Sdim+ Subtarget); 136263320Sdim case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); 137263320Sdim case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 138263320Sdim case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); 139263320SdimIndex: test/CodeGen/SPARC/2011-01-11-FrameAddr.ll 140263320Sdim=================================================================== 141263320Sdim--- test/CodeGen/SPARC/2011-01-11-FrameAddr.ll 142263320Sdim+++ test/CodeGen/SPARC/2011-01-11-FrameAddr.ll 143263320Sdim@@ -2,6 +2,7 @@ 144263320Sdim ;RUN: llc -march=sparc -mattr=v9 < %s | FileCheck %s -check-prefix=V9 145263320Sdim ;RUN: llc -march=sparc -regalloc=basic < %s | FileCheck %s -check-prefix=V8 146263320Sdim ;RUN: llc -march=sparc -regalloc=basic -mattr=v9 < %s | FileCheck %s -check-prefix=V9 147263320Sdim+;RUN: llc -march=sparcv9 < %s | FileCheck %s -check-prefix=SPARC64 148263320Sdim 149263320Sdim 150263320Sdim define i8* @frameaddr() nounwind readnone { 151263320Sdim@@ -15,6 +16,13 @@ entry: 152263320Sdim ;V9: save %sp, -96, %sp 153263320Sdim ;V9: jmp %i7+8 154263320Sdim ;V9: restore %g0, %fp, %o0 155263320Sdim+ 156263320Sdim+;SPARC64-LABEL: frameaddr 157263320Sdim+;SPARC64: save %sp, -128, %sp 158263320Sdim+;SPARC64: add %fp, 2047, %i0 159263320Sdim+;SPARC64: jmp %i7+8 160263320Sdim+;SPARC64: restore %g0, %g0, %g0 161263320Sdim+ 162263320Sdim %0 = tail call i8* @llvm.frameaddress(i32 0) 163263320Sdim ret i8* %0 164263320Sdim } 165263320Sdim@@ -32,6 +40,14 @@ entry: 166263320Sdim ;V9: ld [%fp+56], {{.+}} 167263320Sdim ;V9: ld [{{.+}}+56], {{.+}} 168263320Sdim ;V9: ld [{{.+}}+56], {{.+}} 169263320Sdim+ 170263320Sdim+;SPARC64-LABEL: frameaddr2 171263320Sdim+;SPARC64: flushw 172263320Sdim+;SPARC64: ldx [%fp+2159], %[[R0:[goli][0-7]]] 173263320Sdim+;SPARC64: ldx [%[[R0]]+2159], %[[R1:[goli][0-7]]] 174263320Sdim+;SPARC64: ldx [%[[R1]]+2159], %[[R2:[goli][0-7]]] 175263320Sdim+;SPARC64: add %[[R2]], 2047, {{.+}} 176263320Sdim+ 177263320Sdim %0 = tail call i8* @llvm.frameaddress(i32 3) 178263320Sdim ret i8* %0 179263320Sdim } 180263320Sdim@@ -48,6 +64,9 @@ entry: 181263320Sdim ;V9-LABEL: retaddr: 182263320Sdim ;V9: or %g0, %o7, {{.+}} 183263320Sdim 184263320Sdim+;SPARC64-LABEL: retaddr 185263320Sdim+;SPARC64: or %g0, %o7, {{.+}} 186263320Sdim+ 187263320Sdim %0 = tail call i8* @llvm.returnaddress(i32 0) 188263320Sdim ret i8* %0 189263320Sdim } 190263320Sdim@@ -66,18 +85,12 @@ entry: 191263320Sdim ;V9: ld [{{.+}}+56], {{.+}} 192263320Sdim ;V9: ld [{{.+}}+60], {{.+}} 193263320Sdim 194263320Sdim-;V8LEAF-LABEL: retaddr2: 195263320Sdim-;V8LEAF: ta 3 196263320Sdim-;V8LEAF: ld [%fp+56], %[[R:[goli][0-7]]] 197263320Sdim-;V8LEAF: ld [%[[R]]+56], %[[R1:[goli][0-7]]] 198263320Sdim-;V8LEAF: ld [%[[R1]]+60], {{.+}} 199263320Sdim+;SPARC64-LABEL: retaddr2 200263320Sdim+;SPARC64: flushw 201263320Sdim+;SPARC64: ldx [%fp+2159], %[[R0:[goli][0-7]]] 202263320Sdim+;SPARC64: ldx [%[[R0]]+2159], %[[R1:[goli][0-7]]] 203263320Sdim+;SPARC64: ldx [%[[R1]]+2167], {{.+}} 204263320Sdim 205263320Sdim-;V9LEAF-LABEL: retaddr2: 206263320Sdim-;V9LEAF: flushw 207263320Sdim-;V9LEAF: ld [%fp+56], %[[R:[goli][0-7]]] 208263320Sdim-;V9LEAF: ld [%[[R]]+56], %[[R1:[goli][0-7]]] 209263320Sdim-;V9LEAF: ld [%[[R1]]+60], {{.+}} 210263320Sdim- 211263320Sdim %0 = tail call i8* @llvm.returnaddress(i32 3) 212263320Sdim ret i8* %0 213263320Sdim } 214