1 ; Test saving and restoring of call-saved FPRs.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5 ; This function should require all FPRs, but no other spill slots.
6 ; We need to save and restore 8 of the 16 FPRs, so the frame size
7 ; should be exactly 8 * 8 = 64. The CFA offset is 160
8 ; (the caller-allocated part of the frame) + 64.
9 define void @f1(ptr %ptr) {
11 ; CHECK: aghi %r15, -64
12 ; CHECK: .cfi_def_cfa_offset 224
13 ; CHECK: std %f8, 56(%r15)
14 ; CHECK: std %f9, 48(%r15)
15 ; CHECK: std %f10, 40(%r15)
16 ; CHECK: std %f11, 32(%r15)
17 ; CHECK: std %f12, 24(%r15)
18 ; CHECK: std %f13, 16(%r15)
19 ; CHECK: std %f14, 8(%r15)
20 ; CHECK: std %f15, 0(%r15)
21 ; CHECK: .cfi_offset %f8, -168
22 ; CHECK: .cfi_offset %f9, -176
23 ; CHECK: .cfi_offset %f10, -184
24 ; CHECK: .cfi_offset %f11, -192
25 ; CHECK: .cfi_offset %f12, -200
26 ; CHECK: .cfi_offset %f13, -208
27 ; CHECK: .cfi_offset %f14, -216
28 ; CHECK: .cfi_offset %f15, -224
29 ; ...main function body...
30 ; CHECK: ld %f8, 56(%r15)
31 ; CHECK: ld %f9, 48(%r15)
32 ; CHECK: ld %f10, 40(%r15)
33 ; CHECK: ld %f11, 32(%r15)
34 ; CHECK: ld %f12, 24(%r15)
35 ; CHECK: ld %f13, 16(%r15)
36 ; CHECK: ld %f14, 8(%r15)
37 ; CHECK: ld %f15, 0(%r15)
38 ; CHECK: aghi %r15, 64
40 %l0 = load volatile float, ptr %ptr
41 %l1 = load volatile float, ptr %ptr
42 %l2 = load volatile float, ptr %ptr
43 %l3 = load volatile float, ptr %ptr
44 %l4 = load volatile float, ptr %ptr
45 %l5 = load volatile float, ptr %ptr
46 %l6 = load volatile float, ptr %ptr
47 %l7 = load volatile float, ptr %ptr
48 %l8 = load volatile float, ptr %ptr
49 %l9 = load volatile float, ptr %ptr
50 %l10 = load volatile float, ptr %ptr
51 %l11 = load volatile float, ptr %ptr
52 %l12 = load volatile float, ptr %ptr
53 %l13 = load volatile float, ptr %ptr
54 %l14 = load volatile float, ptr %ptr
55 %l15 = load volatile float, ptr %ptr
56 %add0 = fadd float %l0, %l0
57 %add1 = fadd float %l1, %add0
58 %add2 = fadd float %l2, %add1
59 %add3 = fadd float %l3, %add2
60 %add4 = fadd float %l4, %add3
61 %add5 = fadd float %l5, %add4
62 %add6 = fadd float %l6, %add5
63 %add7 = fadd float %l7, %add6
64 %add8 = fadd float %l8, %add7
65 %add9 = fadd float %l9, %add8
66 %add10 = fadd float %l10, %add9
67 %add11 = fadd float %l11, %add10
68 %add12 = fadd float %l12, %add11
69 %add13 = fadd float %l13, %add12
70 %add14 = fadd float %l14, %add13
71 %add15 = fadd float %l15, %add14
72 store volatile float %add0, ptr %ptr
73 store volatile float %add1, ptr %ptr
74 store volatile float %add2, ptr %ptr
75 store volatile float %add3, ptr %ptr
76 store volatile float %add4, ptr %ptr
77 store volatile float %add5, ptr %ptr
78 store volatile float %add6, ptr %ptr
79 store volatile float %add7, ptr %ptr
80 store volatile float %add8, ptr %ptr
81 store volatile float %add9, ptr %ptr
82 store volatile float %add10, ptr %ptr
83 store volatile float %add11, ptr %ptr
84 store volatile float %add12, ptr %ptr
85 store volatile float %add13, ptr %ptr
86 store volatile float %add14, ptr %ptr
87 store volatile float %add15, ptr %ptr
91 ; Like f1, but requires one fewer FPR. We allocate in numerical order,
92 ; so %f15 is the one that gets dropped.
93 define void @f2(ptr %ptr) {
95 ; CHECK: aghi %r15, -56
96 ; CHECK: .cfi_def_cfa_offset 216
97 ; CHECK: std %f8, 48(%r15)
98 ; CHECK: std %f9, 40(%r15)
99 ; CHECK: std %f10, 32(%r15)
100 ; CHECK: std %f11, 24(%r15)
101 ; CHECK: std %f12, 16(%r15)
102 ; CHECK: std %f13, 8(%r15)
103 ; CHECK: std %f14, 0(%r15)
104 ; CHECK: .cfi_offset %f8, -168
105 ; CHECK: .cfi_offset %f9, -176
106 ; CHECK: .cfi_offset %f10, -184
107 ; CHECK: .cfi_offset %f11, -192
108 ; CHECK: .cfi_offset %f12, -200
109 ; CHECK: .cfi_offset %f13, -208
110 ; CHECK: .cfi_offset %f14, -216
112 ; ...main function body...
113 ; CHECK: ld %f8, 48(%r15)
114 ; CHECK: ld %f9, 40(%r15)
115 ; CHECK: ld %f10, 32(%r15)
116 ; CHECK: ld %f11, 24(%r15)
117 ; CHECK: ld %f12, 16(%r15)
118 ; CHECK: ld %f13, 8(%r15)
119 ; CHECK: ld %f14, 0(%r15)
120 ; CHECK: aghi %r15, 56
122 %l0 = load volatile float, ptr %ptr
123 %l1 = load volatile float, ptr %ptr
124 %l2 = load volatile float, ptr %ptr
125 %l3 = load volatile float, ptr %ptr
126 %l4 = load volatile float, ptr %ptr
127 %l5 = load volatile float, ptr %ptr
128 %l6 = load volatile float, ptr %ptr
129 %l7 = load volatile float, ptr %ptr
130 %l8 = load volatile float, ptr %ptr
131 %l9 = load volatile float, ptr %ptr
132 %l10 = load volatile float, ptr %ptr
133 %l11 = load volatile float, ptr %ptr
134 %l12 = load volatile float, ptr %ptr
135 %l13 = load volatile float, ptr %ptr
136 %l14 = load volatile float, ptr %ptr
137 %add0 = fadd float %l0, %l0
138 %add1 = fadd float %l1, %add0
139 %add2 = fadd float %l2, %add1
140 %add3 = fadd float %l3, %add2
141 %add4 = fadd float %l4, %add3
142 %add5 = fadd float %l5, %add4
143 %add6 = fadd float %l6, %add5
144 %add7 = fadd float %l7, %add6
145 %add8 = fadd float %l8, %add7
146 %add9 = fadd float %l9, %add8
147 %add10 = fadd float %l10, %add9
148 %add11 = fadd float %l11, %add10
149 %add12 = fadd float %l12, %add11
150 %add13 = fadd float %l13, %add12
151 %add14 = fadd float %l14, %add13
152 store volatile float %add0, ptr %ptr
153 store volatile float %add1, ptr %ptr
154 store volatile float %add2, ptr %ptr
155 store volatile float %add3, ptr %ptr
156 store volatile float %add4, ptr %ptr
157 store volatile float %add5, ptr %ptr
158 store volatile float %add6, ptr %ptr
159 store volatile float %add7, ptr %ptr
160 store volatile float %add8, ptr %ptr
161 store volatile float %add9, ptr %ptr
162 store volatile float %add10, ptr %ptr
163 store volatile float %add11, ptr %ptr
164 store volatile float %add12, ptr %ptr
165 store volatile float %add13, ptr %ptr
166 store volatile float %add14, ptr %ptr
170 ; Like f1, but should require only one call-saved FPR.
171 define void @f3(ptr %ptr) {
173 ; CHECK: aghi %r15, -8
174 ; CHECK: .cfi_def_cfa_offset 168
175 ; CHECK: std %f8, 0(%r15)
176 ; CHECK: .cfi_offset %f8, -168
184 ; ...main function body...
185 ; CHECK: ld %f8, 0(%r15)
186 ; CHECK: aghi %r15, 8
188 %l0 = load volatile float, ptr %ptr
189 %l1 = load volatile float, ptr %ptr
190 %l2 = load volatile float, ptr %ptr
191 %l3 = load volatile float, ptr %ptr
192 %l4 = load volatile float, ptr %ptr
193 %l5 = load volatile float, ptr %ptr
194 %l6 = load volatile float, ptr %ptr
195 %l7 = load volatile float, ptr %ptr
196 %l8 = load volatile float, ptr %ptr
197 %add0 = fadd float %l0, %l0
198 %add1 = fadd float %l1, %add0
199 %add2 = fadd float %l2, %add1
200 %add3 = fadd float %l3, %add2
201 %add4 = fadd float %l4, %add3
202 %add5 = fadd float %l5, %add4
203 %add6 = fadd float %l6, %add5
204 %add7 = fadd float %l7, %add6
205 %add8 = fadd float %l8, %add7
206 store volatile float %add0, ptr %ptr
207 store volatile float %add1, ptr %ptr
208 store volatile float %add2, ptr %ptr
209 store volatile float %add3, ptr %ptr
210 store volatile float %add4, ptr %ptr
211 store volatile float %add5, ptr %ptr
212 store volatile float %add6, ptr %ptr
213 store volatile float %add7, ptr %ptr
214 store volatile float %add8, ptr %ptr
218 ; This function should use all call-clobbered FPRs but no call-saved ones.
219 ; It shouldn't need to create a frame.
220 define void @f4(ptr %ptr) {
232 %l0 = load volatile float, ptr %ptr
233 %l1 = load volatile float, ptr %ptr
234 %l2 = load volatile float, ptr %ptr
235 %l3 = load volatile float, ptr %ptr
236 %l4 = load volatile float, ptr %ptr
237 %l5 = load volatile float, ptr %ptr
238 %l6 = load volatile float, ptr %ptr
239 %l7 = load volatile float, ptr %ptr
240 %add0 = fadd float %l0, %l0
241 %add1 = fadd float %l1, %add0
242 %add2 = fadd float %l2, %add1
243 %add3 = fadd float %l3, %add2
244 %add4 = fadd float %l4, %add3
245 %add5 = fadd float %l5, %add4
246 %add6 = fadd float %l6, %add5
247 %add7 = fadd float %l7, %add6
248 store volatile float %add0, ptr %ptr
249 store volatile float %add1, ptr %ptr
250 store volatile float %add2, ptr %ptr
251 store volatile float %add3, ptr %ptr
252 store volatile float %add4, ptr %ptr
253 store volatile float %add5, ptr %ptr
254 store volatile float %add6, ptr %ptr
255 store volatile float %add7, ptr %ptr