1 Pull in r198480 from upstream llvm trunk (by Venkatraman Govindaraju):
3 [SparcV9]: Implement RETURNADDR and FRAMEADDR lowering in SPARC64.
5 Introduced here: http://svn.freebsd.org/changeset/base/262261
7 Index: 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
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);
21 @@ -2422,32 +2423,49 @@ static SDValue getFLUSHW(SDValue Op, SelectionDAG
22 EVT VT = Op.getValueType();
24 unsigned FrameReg = SP::I6;
25 + unsigned stackBias = Subtarget->getStackPointerBias();
27 - uint64_t depth = Op.getConstantOperandVal(0);
33 FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
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));
44 - for (uint64_t i = 0; i != depth; ++i) {
45 - SDValue Ptr = DAG.getNode(ISD::ADD,
47 - FrameAddr, DAG.getIntPtrConstant(56));
48 - FrameAddr = DAG.getLoad(MVT::i32, dl,
51 - MachinePointerInfo(), false, false, false, 0);
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);
57 + unsigned Offset = (Subtarget->is64Bit()) ? (stackBias + 112) : 56;
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);
65 + if (Subtarget->is64Bit())
66 + FrameAddr = DAG.getNode(ISD::ADD, dl, VT, FrameAddr,
67 + DAG.getIntPtrConstant(stackBias));
72 +static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG,
73 + const SparcSubtarget *Subtarget) {
75 + uint64_t depth = Op.getConstantOperandVal(0);
77 + return getFRAMEADDR(depth, Op, DAG, Subtarget);
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);
93 - // Need frame address to find return address of the caller.
94 - MFI->setFrameAddressIsTaken(true);
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);
104 - for (uint64_t i = 0; i != depth; ++i) {
105 - SDValue Ptr = DAG.getNode(ISD::ADD,
108 - DAG.getIntPtrConstant((i == depth-1)?60:56));
109 - RetAddr = DAG.getLoad(MVT::i32, dl,
112 - MachinePointerInfo(), false, false, false, 0);
115 + unsigned Offset = (Subtarget->is64Bit()) ? 120 : 60;
116 + SDValue Ptr = DAG.getNode(ISD::ADD,
119 + DAG.getIntPtrConstant(Offset));
120 + RetAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), Ptr,
121 + MachinePointerInfo(), false, false, false, 0);
126 @@ -2763,8 +2776,10 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons
127 switch (Op.getOpcode()) {
128 default: llvm_unreachable("Should not custom lower this!");
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,
134 + case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG,
136 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
137 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
138 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
139 Index: 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
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
150 define i8* @frameaddr() nounwind readnone {
151 @@ -15,6 +16,13 @@ entry:
152 ;V9: save %sp, -96, %sp
154 ;V9: restore %g0, %fp, %o0
156 +;SPARC64-LABEL: frameaddr
157 +;SPARC64: save %sp, -128, %sp
158 +;SPARC64: add %fp, 2047, %i0
160 +;SPARC64: restore %g0, %g0, %g0
162 %0 = tail call i8* @llvm.frameaddress(i32 0)
165 @@ -32,6 +40,14 @@ entry:
166 ;V9: ld [%fp+56], {{.+}}
167 ;V9: ld [{{.+}}+56], {{.+}}
168 ;V9: ld [{{.+}}+56], {{.+}}
170 +;SPARC64-LABEL: frameaddr2
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, {{.+}}
177 %0 = tail call i8* @llvm.frameaddress(i32 3)
180 @@ -48,6 +64,9 @@ entry:
182 ;V9: or %g0, %o7, {{.+}}
184 +;SPARC64-LABEL: retaddr
185 +;SPARC64: or %g0, %o7, {{.+}}
187 %0 = tail call i8* @llvm.returnaddress(i32 0)
190 @@ -66,18 +85,12 @@ entry:
191 ;V9: ld [{{.+}}+56], {{.+}}
192 ;V9: ld [{{.+}}+60], {{.+}}
194 -;V8LEAF-LABEL: retaddr2:
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
201 +;SPARC64: ldx [%fp+2159], %[[R0:[goli][0-7]]]
202 +;SPARC64: ldx [%[[R0]]+2159], %[[R1:[goli][0-7]]]
203 +;SPARC64: ldx [%[[R1]]+2167], {{.+}}
205 -;V9LEAF-LABEL: retaddr2:
207 -;V9LEAF: ld [%fp+56], %[[R:[goli][0-7]]]
208 -;V9LEAF: ld [%[[R]]+56], %[[R1:[goli][0-7]]]
209 -;V9LEAF: ld [%[[R1]]+60], {{.+}}
211 %0 = tail call i8* @llvm.returnaddress(i32 3)