patch-r262261-llvm-r198480-sparc.diff revision 263765
1Pull in r198480 from upstream llvm trunk (by Venkatraman Govindaraju): 2 3 [SparcV9]: Implement RETURNADDR and FRAMEADDR lowering in SPARC64. 4 5Introduced here: http://svn.freebsd.org/changeset/base/262261 6 7Index: lib/Target/Sparc/SparcISelLowering.cpp 8=================================================================== 9--- lib/Target/Sparc/SparcISelLowering.cpp 10+++ lib/Target/Sparc/SparcISelLowering.cpp 11@@ -2415,7 +2415,8 @@ static SDValue getFLUSHW(SDValue Op, SelectionDAG 12 return Chain; 13 } 14 15-static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) { 16+static SDValue getFRAMEADDR(uint64_t depth, SDValue Op, SelectionDAG &DAG, 17+ const SparcSubtarget *Subtarget) { 18 MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 19 MFI->setFrameAddressIsTaken(true); 20 21@@ -2422,32 +2423,49 @@ static SDValue getFLUSHW(SDValue Op, SelectionDAG 22 EVT VT = Op.getValueType(); 23 SDLoc dl(Op); 24 unsigned FrameReg = SP::I6; 25+ unsigned stackBias = Subtarget->getStackPointerBias(); 26 27- uint64_t depth = Op.getConstantOperandVal(0); 28+ SDValue FrameAddr; 29 30- SDValue FrameAddr; 31- if (depth == 0) 32+ if (depth == 0) { 33 FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT); 34- else { 35- // flush first to make sure the windowed registers' values are in stack 36- SDValue Chain = getFLUSHW(Op, DAG); 37- FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT); 38+ if (Subtarget->is64Bit()) 39+ FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr, 40+ DAG.getIntPtrConstant(stackBias)); 41+ return FrameAddr; 42+ } 43 44- for (uint64_t i = 0; i != depth; ++i) { 45- SDValue Ptr = DAG.getNode(ISD::ADD, 46- dl, MVT::i32, 47- FrameAddr, DAG.getIntPtrConstant(56)); 48- FrameAddr = DAG.getLoad(MVT::i32, dl, 49- Chain, 50- Ptr, 51- MachinePointerInfo(), false, false, false, 0); 52- } 53+ // flush first to make sure the windowed registers' values are in stack 54+ SDValue Chain = getFLUSHW(Op, DAG); 55+ FrameAddr = DAG.getCopyFromReg(Chain, dl, FrameReg, VT); 56+ 57+ unsigned Offset = (Subtarget->is64Bit()) ? (stackBias + 112) : 56; 58+ 59+ while (depth--) { 60+ SDValue Ptr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr, 61+ DAG.getIntPtrConstant(Offset)); 62+ FrameAddr = DAG.getLoad(VT, dl, Chain, Ptr, MachinePointerInfo(), 63+ false, false, false, 0); 64 } 65+ if (Subtarget->is64Bit()) 66+ FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr, 67+ DAG.getIntPtrConstant(stackBias)); 68 return FrameAddr; 69 } 70 71+ 72+static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, 73+ const SparcSubtarget *Subtarget) { 74+ 75+ uint64_t depth = Op.getConstantOperandVal(0); 76+ 77+ return getFRAMEADDR(depth, Op, DAG, Subtarget); 78+ 79+} 80+ 81 static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG, 82- const SparcTargetLowering &TLI) { 83+ const SparcTargetLowering &TLI, 84+ const SparcSubtarget *Subtarget) { 85 MachineFunction &MF = DAG.getMachineFunction(); 86 MachineFrameInfo *MFI = MF.getFrameInfo(); 87 MFI->setReturnAddressIsTaken(true); 88@@ -2461,25 +2479,20 @@ static SDValue LowerRETURNADDR(SDValue Op, Selecti 89 unsigned RetReg = MF.addLiveIn(SP::I7, 90 TLI.getRegClassFor(TLI.getPointerTy())); 91 RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT); 92- } else { 93- // Need frame address to find return address of the caller. 94- MFI->setFrameAddressIsTaken(true); 95+ return RetAddr; 96+ } 97 98- // flush first to make sure the windowed registers' values are in stack 99- SDValue Chain = getFLUSHW(Op, DAG); 100- RetAddr = DAG.getCopyFromReg(Chain, dl, SP::I6, VT); 101+ // Need frame address to find return address of the caller. 102+ SDValue FrameAddr = getFRAMEADDR(depth - 1, Op, DAG, Subtarget); 103 104- for (uint64_t i = 0; i != depth; ++i) { 105- SDValue Ptr = DAG.getNode(ISD::ADD, 106- dl, MVT::i32, 107- RetAddr, 108- DAG.getIntPtrConstant((i == depth-1)?60:56)); 109- RetAddr = DAG.getLoad(MVT::i32, dl, 110- Chain, 111- Ptr, 112- MachinePointerInfo(), false, false, false, 0); 113- } 114- } 115+ unsigned Offset = (Subtarget->is64Bit()) ? 120 : 60; 116+ SDValue Ptr = DAG.getNode(ISD::ADD, 117+ dl, VT, 118+ FrameAddr, 119+ DAG.getIntPtrConstant(Offset)); 120+ RetAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), Ptr, 121+ MachinePointerInfo(), false, false, false, 0); 122+ 123 return RetAddr; 124 } 125 126@@ -2763,8 +2776,10 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons 127 switch (Op.getOpcode()) { 128 default: llvm_unreachable("Should not custom lower this!"); 129 130- case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG, *this); 131- case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 132+ case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG, *this, 133+ Subtarget); 134+ case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG, 135+ Subtarget); 136 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); 137 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 138 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); 139Index: test/CodeGen/SPARC/2011-01-11-FrameAddr.ll 140=================================================================== 141--- test/CodeGen/SPARC/2011-01-11-FrameAddr.ll 142+++ test/CodeGen/SPARC/2011-01-11-FrameAddr.ll 143@@ -2,6 +2,7 @@ 144 ;RUN: llc -march=sparc -mattr=v9 < %s | FileCheck %s -check-prefix=V9 145 ;RUN: llc -march=sparc -regalloc=basic < %s | FileCheck %s -check-prefix=V8 146 ;RUN: llc -march=sparc -regalloc=basic -mattr=v9 < %s | FileCheck %s -check-prefix=V9 147+;RUN: llc -march=sparcv9 < %s | FileCheck %s -check-prefix=SPARC64 148 149 150 define i8* @frameaddr() nounwind readnone { 151@@ -15,6 +16,13 @@ entry: 152 ;V9: save %sp, -96, %sp 153 ;V9: jmp %i7+8 154 ;V9: restore %g0, %fp, %o0 155+ 156+;SPARC64-LABEL: frameaddr 157+;SPARC64: save %sp, -128, %sp 158+;SPARC64: add %fp, 2047, %i0 159+;SPARC64: jmp %i7+8 160+;SPARC64: restore %g0, %g0, %g0 161+ 162 %0 = tail call i8* @llvm.frameaddress(i32 0) 163 ret i8* %0 164 } 165@@ -32,6 +40,14 @@ entry: 166 ;V9: ld [%fp+56], {{.+}} 167 ;V9: ld [{{.+}}+56], {{.+}} 168 ;V9: ld [{{.+}}+56], {{.+}} 169+ 170+;SPARC64-LABEL: frameaddr2 171+;SPARC64: flushw 172+;SPARC64: ldx [%fp+2159], %[[R0:[goli][0-7]]] 173+;SPARC64: ldx [%[[R0]]+2159], %[[R1:[goli][0-7]]] 174+;SPARC64: ldx [%[[R1]]+2159], %[[R2:[goli][0-7]]] 175+;SPARC64: add %[[R2]], 2047, {{.+}} 176+ 177 %0 = tail call i8* @llvm.frameaddress(i32 3) 178 ret i8* %0 179 } 180@@ -48,6 +64,9 @@ entry: 181 ;V9-LABEL: retaddr: 182 ;V9: or %g0, %o7, {{.+}} 183 184+;SPARC64-LABEL: retaddr 185+;SPARC64: or %g0, %o7, {{.+}} 186+ 187 %0 = tail call i8* @llvm.returnaddress(i32 0) 188 ret i8* %0 189 } 190@@ -66,18 +85,12 @@ entry: 191 ;V9: ld [{{.+}}+56], {{.+}} 192 ;V9: ld [{{.+}}+60], {{.+}} 193 194-;V8LEAF-LABEL: retaddr2: 195-;V8LEAF: ta 3 196-;V8LEAF: ld [%fp+56], %[[R:[goli][0-7]]] 197-;V8LEAF: ld [%[[R]]+56], %[[R1:[goli][0-7]]] 198-;V8LEAF: ld [%[[R1]]+60], {{.+}} 199+;SPARC64-LABEL: retaddr2 200+;SPARC64: flushw 201+;SPARC64: ldx [%fp+2159], %[[R0:[goli][0-7]]] 202+;SPARC64: ldx [%[[R0]]+2159], %[[R1:[goli][0-7]]] 203+;SPARC64: ldx [%[[R1]]+2167], {{.+}} 204 205-;V9LEAF-LABEL: retaddr2: 206-;V9LEAF: flushw 207-;V9LEAF: ld [%fp+56], %[[R:[goli][0-7]]] 208-;V9LEAF: ld [%[[R]]+56], %[[R1:[goli][0-7]]] 209-;V9LEAF: ld [%[[R1]]+60], {{.+}} 210- 211 %0 = tail call i8* @llvm.returnaddress(i32 3) 212 ret i8* %0 213 } 214