patch-r262261-llvm-r198480-sparc.diff revision 269012
1Pull in r198480 from upstream llvm trunk (by Venkatraman Govindaraju):
2
3  [SparcV9]: Implement RETURNADDR and FRAMEADDR lowering in SPARC64. 
4
5Introduced here: http://svnweb.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