1; Test saving and restoring of call-saved FPRs.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
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 160 + 8 * 8 = 224.  The CFA offset is 160
8; (the caller-allocated part of the frame) + 224.
9define void @f1(float *%ptr) {
10; CHECK-LABEL: f1:
11; CHECK: aghi %r15, -224
12; CHECK: .cfi_def_cfa_offset 384
13; CHECK: std %f8, 216(%r15)
14; CHECK: std %f9, 208(%r15)
15; CHECK: std %f10, 200(%r15)
16; CHECK: std %f11, 192(%r15)
17; CHECK: std %f12, 184(%r15)
18; CHECK: std %f13, 176(%r15)
19; CHECK: std %f14, 168(%r15)
20; CHECK: std %f15, 160(%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, 216(%r15)
31; CHECK: ld %f9, 208(%r15)
32; CHECK: ld %f10, 200(%r15)
33; CHECK: ld %f11, 192(%r15)
34; CHECK: ld %f12, 184(%r15)
35; CHECK: ld %f13, 176(%r15)
36; CHECK: ld %f14, 168(%r15)
37; CHECK: ld %f15, 160(%r15)
38; CHECK: aghi %r15, 224
39; CHECK: br %r14
40  %l0 = load volatile float *%ptr
41  %l1 = load volatile float *%ptr
42  %l2 = load volatile float *%ptr
43  %l3 = load volatile float *%ptr
44  %l4 = load volatile float *%ptr
45  %l5 = load volatile float *%ptr
46  %l6 = load volatile float *%ptr
47  %l7 = load volatile float *%ptr
48  %l8 = load volatile float *%ptr
49  %l9 = load volatile float *%ptr
50  %l10 = load volatile float *%ptr
51  %l11 = load volatile float *%ptr
52  %l12 = load volatile float *%ptr
53  %l13 = load volatile float *%ptr
54  %l14 = load volatile float *%ptr
55  %l15 = load volatile float *%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, float *%ptr
73  store volatile float %add1, float *%ptr
74  store volatile float %add2, float *%ptr
75  store volatile float %add3, float *%ptr
76  store volatile float %add4, float *%ptr
77  store volatile float %add5, float *%ptr
78  store volatile float %add6, float *%ptr
79  store volatile float %add7, float *%ptr
80  store volatile float %add8, float *%ptr
81  store volatile float %add9, float *%ptr
82  store volatile float %add10, float *%ptr
83  store volatile float %add11, float *%ptr
84  store volatile float %add12, float *%ptr
85  store volatile float %add13, float *%ptr
86  store volatile float %add14, float *%ptr
87  store volatile float %add15, float *%ptr
88  ret void
89}
90
91; Like f1, but requires one fewer FPR.  We allocate in numerical order,
92; so %f15 is the one that gets dropped.
93define void @f2(float *%ptr) {
94; CHECK-LABEL: f2:
95; CHECK: aghi %r15, -216
96; CHECK: .cfi_def_cfa_offset 376
97; CHECK: std %f8, 208(%r15)
98; CHECK: std %f9, 200(%r15)
99; CHECK: std %f10, 192(%r15)
100; CHECK: std %f11, 184(%r15)
101; CHECK: std %f12, 176(%r15)
102; CHECK: std %f13, 168(%r15)
103; CHECK: std %f14, 160(%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
111; CHECK-NOT: %f15
112; ...main function body...
113; CHECK: ld %f8, 208(%r15)
114; CHECK: ld %f9, 200(%r15)
115; CHECK: ld %f10, 192(%r15)
116; CHECK: ld %f11, 184(%r15)
117; CHECK: ld %f12, 176(%r15)
118; CHECK: ld %f13, 168(%r15)
119; CHECK: ld %f14, 160(%r15)
120; CHECK: aghi %r15, 216
121; CHECK: br %r14
122  %l0 = load volatile float *%ptr
123  %l1 = load volatile float *%ptr
124  %l2 = load volatile float *%ptr
125  %l3 = load volatile float *%ptr
126  %l4 = load volatile float *%ptr
127  %l5 = load volatile float *%ptr
128  %l6 = load volatile float *%ptr
129  %l7 = load volatile float *%ptr
130  %l8 = load volatile float *%ptr
131  %l9 = load volatile float *%ptr
132  %l10 = load volatile float *%ptr
133  %l11 = load volatile float *%ptr
134  %l12 = load volatile float *%ptr
135  %l13 = load volatile float *%ptr
136  %l14 = load volatile float *%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, float *%ptr
153  store volatile float %add1, float *%ptr
154  store volatile float %add2, float *%ptr
155  store volatile float %add3, float *%ptr
156  store volatile float %add4, float *%ptr
157  store volatile float %add5, float *%ptr
158  store volatile float %add6, float *%ptr
159  store volatile float %add7, float *%ptr
160  store volatile float %add8, float *%ptr
161  store volatile float %add9, float *%ptr
162  store volatile float %add10, float *%ptr
163  store volatile float %add11, float *%ptr
164  store volatile float %add12, float *%ptr
165  store volatile float %add13, float *%ptr
166  store volatile float %add14, float *%ptr
167  ret void
168}
169
170; Like f1, but should require only one call-saved FPR.
171define void @f3(float *%ptr) {
172; CHECK-LABEL: f3:
173; CHECK: aghi %r15, -168
174; CHECK: .cfi_def_cfa_offset 328
175; CHECK: std %f8, 160(%r15)
176; CHECK: .cfi_offset %f8, -168
177; CHECK-NOT: %f9
178; CHECK-NOT: %f10
179; CHECK-NOT: %f11
180; CHECK-NOT: %f12
181; CHECK-NOT: %f13
182; CHECK-NOT: %f14
183; CHECK-NOT: %f15
184; ...main function body...
185; CHECK: ld %f8, 160(%r15)
186; CHECK: aghi %r15, 168
187; CHECK: br %r14
188  %l0 = load volatile float *%ptr
189  %l1 = load volatile float *%ptr
190  %l2 = load volatile float *%ptr
191  %l3 = load volatile float *%ptr
192  %l4 = load volatile float *%ptr
193  %l5 = load volatile float *%ptr
194  %l6 = load volatile float *%ptr
195  %l7 = load volatile float *%ptr
196  %l8 = load volatile float *%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, float *%ptr
207  store volatile float %add1, float *%ptr
208  store volatile float %add2, float *%ptr
209  store volatile float %add3, float *%ptr
210  store volatile float %add4, float *%ptr
211  store volatile float %add5, float *%ptr
212  store volatile float %add6, float *%ptr
213  store volatile float %add7, float *%ptr
214  store volatile float %add8, float *%ptr
215  ret void
216}
217
218; This function should use all call-clobbered FPRs but no call-saved ones.
219; It shouldn't need to create a frame.
220define void @f4(float *%ptr) {
221; CHECK-LABEL: f4:
222; CHECK-NOT: %r15
223; CHECK-NOT: %f8
224; CHECK-NOT: %f9
225; CHECK-NOT: %f10
226; CHECK-NOT: %f11
227; CHECK-NOT: %f12
228; CHECK-NOT: %f13
229; CHECK-NOT: %f14
230; CHECK-NOT: %f15
231; CHECK: br %r14
232  %l0 = load volatile float *%ptr
233  %l1 = load volatile float *%ptr
234  %l2 = load volatile float *%ptr
235  %l3 = load volatile float *%ptr
236  %l4 = load volatile float *%ptr
237  %l5 = load volatile float *%ptr
238  %l6 = load volatile float *%ptr
239  %l7 = load volatile float *%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, float *%ptr
249  store volatile float %add1, float *%ptr
250  store volatile float %add2, float *%ptr
251  store volatile float %add3, float *%ptr
252  store volatile float %add4, float *%ptr
253  store volatile float %add5, float *%ptr
254  store volatile float %add6, float *%ptr
255  store volatile float %add7, float *%ptr
256  ret void
257}
258