blob: 10d8ff7c9aee93cc8ed2e0bf8bd9b7684e08ca68 [file] [log] [blame]
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +00001; RUN: llc < %s -march=sparcv9 -disable-sparc-delay-filler | FileCheck %s
Jakob Stoklund Olesen1f25fe52013-04-06 18:32:12 +00002
3; CHECK: intarg
4; CHECK: stb %i0, [%i4]
5; CHECK: stb %i1, [%i4]
6; CHECK: sth %i2, [%i4]
7; CHECK: st %i3, [%i4]
8; CHECK: stx %i4, [%i4]
9; CHECK: st %i5, [%i4]
Jakob Stoklund Olesen2b9355f2013-04-06 21:38:57 +000010; CHECK: ld [%fp+2227], [[R:%[gilo][0-7]]]
Jakob Stoklund Olesen1f25fe52013-04-06 18:32:12 +000011; CHECK: st [[R]], [%i4]
Jakob Stoklund Olesen2b9355f2013-04-06 21:38:57 +000012; CHECK: ldx [%fp+2231], [[R:%[gilo][0-7]]]
Jakob Stoklund Olesen1f25fe52013-04-06 18:32:12 +000013; CHECK: stx [[R]], [%i4]
14define void @intarg(i8 %a0, ; %i0
15 i8 %a1, ; %i1
16 i16 %a2, ; %i2
17 i32 %a3, ; %i3
18 i8* %a4, ; %i4
19 i32 %a5, ; %i5
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +000020 i32 signext %a6, ; [%fp+BIAS+176]
Jakob Stoklund Olesen1f25fe52013-04-06 18:32:12 +000021 i8* %a7) { ; [%fp+BIAS+184]
22 store i8 %a0, i8* %a4
23 store i8 %a1, i8* %a4
24 %p16 = bitcast i8* %a4 to i16*
25 store i16 %a2, i16* %p16
26 %p32 = bitcast i8* %a4 to i32*
27 store i32 %a3, i32* %p32
28 %pp = bitcast i8* %a4 to i8**
29 store i8* %a4, i8** %pp
30 store i32 %a5, i32* %p32
31 store i32 %a6, i32* %p32
32 store i8* %a7, i8** %pp
33 ret void
34}
35
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +000036; CHECK: call_intarg
37; Sign-extend and store the full 64 bits.
38; CHECK: sra %i0, 0, [[R:%[gilo][0-7]]]
39; CHECK: stx [[R]], [%sp+2223]
40; Use %o0-%o5 for outgoing arguments
41; CHECK: or %g0, 5, %o5
42; CHECK: call intarg
43define void @call_intarg(i32 %i0, i8* %i1) {
44 call void @intarg(i8 0, i8 1, i16 2, i32 3, i8* undef, i32 5, i32 %i0, i8* %i1)
45 ret void
46}
47
Jakob Stoklund Olesen1f25fe52013-04-06 18:32:12 +000048; CHECK: floatarg
49; CHECK: fstod %f1,
50; CHECK: faddd %f2,
51; CHECK: faddd %f4,
52; CHECK: faddd %f6,
Jakob Stoklund Olesen2b9355f2013-04-06 21:38:57 +000053; CHECK: ld [%fp+2307], [[F:%f[0-9]+]]
Jakob Stoklund Olesen1f25fe52013-04-06 18:32:12 +000054; CHECK: fadds %f31, [[F]]
55define double @floatarg(float %a0, ; %f1
56 double %a1, ; %d2
57 double %a2, ; %d4
58 double %a3, ; %d6
59 float %a4, ; %f9
60 float %a5, ; %f11
61 float %a6, ; %f13
62 float %a7, ; %f15
63 float %a8, ; %f17
64 float %a9, ; %f19
65 float %a10, ; %f21
66 float %a11, ; %f23
67 float %a12, ; %f25
68 float %a13, ; %f27
69 float %a14, ; %f29
70 float %a15, ; %f31
71 float %a16, ; [%fp+BIAS+256] (using 8 bytes)
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +000072 double %a17) { ; [%fp+BIAS+264] (using 8 bytes)
Jakob Stoklund Olesen1f25fe52013-04-06 18:32:12 +000073 %d0 = fpext float %a0 to double
74 %s1 = fadd double %a1, %d0
75 %s2 = fadd double %a2, %s1
76 %s3 = fadd double %a3, %s2
77 %s16 = fadd float %a15, %a16
78 %d16 = fpext float %s16 to double
79 %s17 = fadd double %d16, %s3
80 ret double %s17
81}
82
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +000083; CHECK: call_floatarg
84; Store 4 bytes, right-aligned in slot.
85; CHECK: st %f1, [%sp+2307]
86; Store 8 bytes in full slot.
87; CHECK: std %f2, [%sp+2311]
88; CHECK: fmovd %f2, %f4
89; CHECK: call floatarg
90define void @call_floatarg(float %f1, double %d2, float %f5, double *%p) {
91 %r = call double @floatarg(float %f5, double %d2, double %d2, double %d2,
92 float %f5, float %f5, float %f5, float %f5,
93 float %f5, float %f5, float %f5, float %f5,
94 float %f5, float %f5, float %f5, float %f5,
95 float %f1, double %d2)
96 store double %r, double* %p
97 ret void
98}
99
Jakob Stoklund Olesen1f25fe52013-04-06 18:32:12 +0000100; CHECK: mixedarg
101; CHECK: fstod %f3
102; CHECK: faddd %f6
103; CHECK: faddd %f16
Jakob Stoklund Olesen2b9355f2013-04-06 21:38:57 +0000104; CHECK: ldx [%fp+2231]
105; CHECK: ldx [%fp+2247]
Jakob Stoklund Olesen1f25fe52013-04-06 18:32:12 +0000106define void @mixedarg(i8 %a0, ; %i0
107 float %a1, ; %f3
108 i16 %a2, ; %i2
109 double %a3, ; %d6
110 i13 %a4, ; %i4
111 float %a5, ; %f11
112 i64 %a6, ; [%fp+BIAS+176]
113 double *%a7, ; [%fp+BIAS+184]
114 double %a8, ; %d16
115 i16* %a9) { ; [%fp+BIAS+200]
116 %d1 = fpext float %a1 to double
117 %s3 = fadd double %a3, %d1
118 %s8 = fadd double %a8, %s3
119 store double %s8, double* %a7
120 store i16 %a2, i16* %a9
121 ret void
122}
123
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +0000124; CHECK: call_mixedarg
125; CHECK: stx %i2, [%sp+2247]
126; CHECK: stx %i0, [%sp+2223]
127; CHECK: fmovd %f2, %f6
128; CHECK: fmovd %f2, %f16
129; CHECK: call mixedarg
130define void @call_mixedarg(i64 %i0, double %f2, i16* %i2) {
131 call void @mixedarg(i8 undef,
132 float undef,
133 i16 undef,
134 double %f2,
135 i13 undef,
136 float undef,
137 i64 %i0,
138 double* undef,
139 double %f2,
140 i16* %i2)
141 ret void
142}
143
Jakob Stoklund Olesen1f25fe52013-04-06 18:32:12 +0000144; The inreg attribute is used to indicate 32-bit sized struct elements that
145; share an 8-byte slot.
146; CHECK: inreg_fi
147; CHECK: fstoi %f1
148; CHECK: srlx %i0, 32, [[R:%[gilo][0-7]]]
149; CHECK: sub [[R]],
150define i32 @inreg_fi(i32 inreg %a0, ; high bits of %i0
151 float inreg %a1) { ; %f1
152 %b1 = fptosi float %a1 to i32
153 %rv = sub i32 %a0, %b1
154 ret i32 %rv
155}
156
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +0000157; CHECK: call_inreg_fi
158; CHECK: sllx %i1, 32, %o0
159; CHECK: fmovs %f5, %f1
160; CHECK: call inreg_fi
161define void @call_inreg_fi(i32* %p, i32 %i1, float %f5) {
162 %x = call i32 @inreg_fi(i32 %i1, float %f5)
163 ret void
164}
165
Jakob Stoklund Olesen1f25fe52013-04-06 18:32:12 +0000166; CHECK: inreg_ff
167; CHECK: fsubs %f0, %f1, %f1
168define float @inreg_ff(float inreg %a0, ; %f0
169 float inreg %a1) { ; %f1
170 %rv = fsub float %a0, %a1
171 ret float %rv
172}
173
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +0000174; CHECK: call_inreg_ff
175; CHECK: fmovs %f3, %f0
176; CHECK: fmovs %f5, %f1
177; CHECK: call inreg_ff
178define void @call_inreg_ff(i32* %p, float %f3, float %f5) {
179 %x = call float @inreg_ff(float %f3, float %f5)
180 ret void
181}
182
Jakob Stoklund Olesen1f25fe52013-04-06 18:32:12 +0000183; CHECK: inreg_if
184; CHECK: fstoi %f0
185; CHECK: sub %i0
186define i32 @inreg_if(float inreg %a0, ; %f0
187 i32 inreg %a1) { ; low bits of %i0
188 %b0 = fptosi float %a0 to i32
189 %rv = sub i32 %a1, %b0
190 ret i32 %rv
191}
192
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +0000193; CHECK: call_inreg_if
194; CHECK: fmovs %f3, %f0
195; CHECK: or %g0, %i2, %o0
196; CHECK: call inreg_if
197define void @call_inreg_if(i32* %p, float %f3, i32 %i2) {
198 %x = call i32 @inreg_if(float %f3, i32 %i2)
199 ret void
200}
201
Jakob Stoklund Olesen1f25fe52013-04-06 18:32:12 +0000202; The frontend shouldn't do this. Just pass i64 instead.
203; CHECK: inreg_ii
204; CHECK: srlx %i0, 32, [[R:%[gilo][0-7]]]
205; CHECK: sub %i0, [[R]], %i0
206define i32 @inreg_ii(i32 inreg %a0, ; high bits of %i0
207 i32 inreg %a1) { ; low bits of %i0
208 %rv = sub i32 %a1, %a0
209 ret i32 %rv
210}
Jakob Stoklund Olesen53d4bcf2013-04-06 23:57:33 +0000211
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +0000212; CHECK: call_inreg_ii
213; CHECK: srl %i2, 0, [[R2:%[gilo][0-7]]]
214; CHECK: sllx %i1, 32, [[R1:%[gilo][0-7]]]
215; CHECK: or [[R1]], [[R2]], %o0
216; CHECK: call inreg_ii
217define void @call_inreg_ii(i32* %p, i32 %i1, i32 %i2) {
218 %x = call i32 @inreg_ii(i32 %i1, i32 %i2)
219 ret void
220}
221
Jakob Stoklund Olesen53d4bcf2013-04-06 23:57:33 +0000222; Structs up to 32 bytes in size can be returned in registers.
223; CHECK: ret_i64_pair
224; CHECK: ldx [%i2], %i0
225; CHECK: ldx [%i3], %i1
226define { i64, i64 } @ret_i64_pair(i32 %a0, i32 %a1, i64* %p, i64* %q) {
227 %r1 = load i64* %p
228 %rv1 = insertvalue { i64, i64 } undef, i64 %r1, 0
229 store i64 0, i64* %p
230 %r2 = load i64* %q
231 %rv2 = insertvalue { i64, i64 } %rv1, i64 %r2, 1
232 ret { i64, i64 } %rv2
233}
234
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +0000235; CHECK: call_ret_i64_pair
236; CHECK: call ret_i64_pair
237; CHECK: stx %o0, [%i0]
238; CHECK: stx %o1, [%i0]
239define void @call_ret_i64_pair(i64* %i0) {
240 %rv = call { i64, i64 } @ret_i64_pair(i32 undef, i32 undef,
241 i64* undef, i64* undef)
242 %e0 = extractvalue { i64, i64 } %rv, 0
243 store i64 %e0, i64* %i0
244 %e1 = extractvalue { i64, i64 } %rv, 1
245 store i64 %e1, i64* %i0
246 ret void
247}
248
Jakob Stoklund Olesen53d4bcf2013-04-06 23:57:33 +0000249; This is not a C struct, each member uses 8 bytes.
250; CHECK: ret_i32_float_pair
251; CHECK: ld [%i2], %i0
252; CHECK: ld [%i3], %f3
253define { i32, float } @ret_i32_float_pair(i32 %a0, i32 %a1,
254 i32* %p, float* %q) {
255 %r1 = load i32* %p
256 %rv1 = insertvalue { i32, float } undef, i32 %r1, 0
257 store i32 0, i32* %p
258 %r2 = load float* %q
259 %rv2 = insertvalue { i32, float } %rv1, float %r2, 1
260 ret { i32, float } %rv2
261}
262
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +0000263; CHECK: call_ret_i32_float_pair
264; CHECK: call ret_i32_float_pair
265; CHECK: st %o0, [%i0]
266; CHECK: st %f3, [%i1]
267define void @call_ret_i32_float_pair(i32* %i0, float* %i1) {
268 %rv = call { i32, float } @ret_i32_float_pair(i32 undef, i32 undef,
269 i32* undef, float* undef)
270 %e0 = extractvalue { i32, float } %rv, 0
271 store i32 %e0, i32* %i0
272 %e1 = extractvalue { i32, float } %rv, 1
273 store float %e1, float* %i1
274 ret void
275}
276
Jakob Stoklund Olesen53d4bcf2013-04-06 23:57:33 +0000277; This is a C struct, each member uses 4 bytes.
278; CHECK: ret_i32_float_packed
279; CHECK: ld [%i2], [[R:%[gilo][0-7]]]
280; CHECK: sllx [[R]], 32, %i0
281; CHECK: ld [%i3], %f1
282define inreg { i32, float } @ret_i32_float_packed(i32 %a0, i32 %a1,
283 i32* %p, float* %q) {
284 %r1 = load i32* %p
285 %rv1 = insertvalue { i32, float } undef, i32 %r1, 0
286 store i32 0, i32* %p
287 %r2 = load float* %q
288 %rv2 = insertvalue { i32, float } %rv1, float %r2, 1
289 ret { i32, float } %rv2
290}
291
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +0000292; CHECK: call_ret_i32_float_packed
293; CHECK: call ret_i32_float_packed
294; CHECK: srlx %o0, 32, [[R:%[gilo][0-7]]]
295; CHECK: st [[R]], [%i0]
296; CHECK: st %f1, [%i1]
297define void @call_ret_i32_float_packed(i32* %i0, float* %i1) {
298 %rv = call { i32, float } @ret_i32_float_packed(i32 undef, i32 undef,
299 i32* undef, float* undef)
300 %e0 = extractvalue { i32, float } %rv, 0
301 store i32 %e0, i32* %i0
302 %e1 = extractvalue { i32, float } %rv, 1
303 store float %e1, float* %i1
304 ret void
305}
306
Jakob Stoklund Olesen53d4bcf2013-04-06 23:57:33 +0000307; The C frontend should use i64 to return { i32, i32 } structs, but verify that
308; we don't miscompile thi case where both struct elements are placed in %i0.
309; CHECK: ret_i32_packed
310; CHECK: ld [%i2], [[R1:%[gilo][0-7]]]
311; CHECK: ld [%i3], [[R2:%[gilo][0-7]]]
312; CHECK: sllx [[R2]], 32, [[R3:%[gilo][0-7]]]
313; CHECK: or [[R3]], [[R1]], %i0
314define inreg { i32, i32 } @ret_i32_packed(i32 %a0, i32 %a1,
315 i32* %p, i32* %q) {
316 %r1 = load i32* %p
317 %rv1 = insertvalue { i32, i32 } undef, i32 %r1, 1
318 store i32 0, i32* %p
319 %r2 = load i32* %q
320 %rv2 = insertvalue { i32, i32 } %rv1, i32 %r2, 0
321 ret { i32, i32 } %rv2
322}
323
Jakob Stoklund Olesen18fdb392013-04-07 19:10:57 +0000324; CHECK: call_ret_i32_packed
325; CHECK: call ret_i32_packed
326; CHECK: srlx %o0, 32, [[R:%[gilo][0-7]]]
327; CHECK: st [[R]], [%i0]
328; CHECK: st %o0, [%i1]
329define void @call_ret_i32_packed(i32* %i0, i32* %i1) {
330 %rv = call { i32, i32 } @ret_i32_packed(i32 undef, i32 undef,
331 i32* undef, i32* undef)
332 %e0 = extractvalue { i32, i32 } %rv, 0
333 store i32 %e0, i32* %i0
334 %e1 = extractvalue { i32, i32 } %rv, 1
335 store i32 %e1, i32* %i1
336 ret void
337}
338
Jakob Stoklund Olesen53d4bcf2013-04-06 23:57:33 +0000339; The return value must be sign-extended to 64 bits.
340; CHECK: ret_sext
341; CHECK: sra %i0, 0, %i0
342define signext i32 @ret_sext(i32 %a0) {
343 ret i32 %a0
344}
345
346; CHECK: ret_zext
347; CHECK: srl %i0, 0, %i0
348define zeroext i32 @ret_zext(i32 %a0) {
349 ret i32 %a0
350}
351
352; CHECK: ret_nosext
353; CHECK-NOT: sra
354define signext i32 @ret_nosext(i32 signext %a0) {
355 ret i32 %a0
356}
357
358; CHECK: ret_nozext
359; CHECK-NOT: srl
360define signext i32 @ret_nozext(i32 signext %a0) {
361 ret i32 %a0
362}