blob: b5f75b1982e021c4c0d361215ef6fb98d745372b [file] [log] [blame]
Chris Dewhurst68388a02016-05-18 09:14:13 +00001; RUN: llc < %s -march=sparc -disable-sparc-delay-filler -disable-sparc-leaf-proc | FileCheck %s --check-prefix=CHECK --check-prefix=HARD --check-prefix=CHECK-BE
2; RUN: llc < %s -march=sparcel -disable-sparc-delay-filler -disable-sparc-leaf-proc | FileCheck %s --check-prefix=CHECK --check-prefix=HARD --check-prefix=CHECK-LE
3; RUN: llc < %s -march=sparc -disable-sparc-delay-filler -disable-sparc-leaf-proc -mattr=soft-float | FileCheck %s --check-prefix=CHECK --check-prefix=SOFT --check-prefix=CHECK-BE
James Y Knight33beb242015-12-15 19:23:12 +00004
5; CHECK-LABEL: intarg:
6; The save/restore frame is not strictly necessary here, but we would need to
7; refer to %o registers instead.
8; CHECK: save %sp, -96, %sp
9; CHECK: ld [%fp+96], [[R2:%[gilo][0-7]]]
10; CHECK: ld [%fp+92], [[R1:%[gilo][0-7]]]
11; CHECK: stb %i0, [%i4]
12; CHECK: stb %i1, [%i4]
13; CHECK: sth %i2, [%i4]
14; CHECK: st %i3, [%i4]
15; CHECK: st %i4, [%i4]
16; CHECK: st %i5, [%i4]
17; CHECK: st [[R1]], [%i4]
18; CHECK: st [[R2]], [%i4]
19; CHECK: restore
20define void @intarg(i8 %a0, ; %i0
21 i8 %a1, ; %i1
22 i16 %a2, ; %i2
23 i32 %a3, ; %i3
24 i8* %a4, ; %i4
25 i32 %a5, ; %i5
26 i32 signext %a6, ; [%fp+92]
27 i8* %a7) { ; [%fp+96]
Nirav Daveda8f2212017-05-16 19:43:56 +000028 store volatile i8 %a0, i8* %a4
29 store volatile i8 %a1, i8* %a4
James Y Knight33beb242015-12-15 19:23:12 +000030 %p16 = bitcast i8* %a4 to i16*
Nirav Daveda8f2212017-05-16 19:43:56 +000031 store volatile i16 %a2, i16* %p16
James Y Knight33beb242015-12-15 19:23:12 +000032 %p32 = bitcast i8* %a4 to i32*
Nirav Daveda8f2212017-05-16 19:43:56 +000033 store volatile i32 %a3, i32* %p32
James Y Knight33beb242015-12-15 19:23:12 +000034 %pp = bitcast i8* %a4 to i8**
Nirav Daveda8f2212017-05-16 19:43:56 +000035 store volatile i8* %a4, i8** %pp
36 store volatile i32 %a5, i32* %p32
37 store volatile i32 %a6, i32* %p32
38 store volatile i8* %a7, i8** %pp
James Y Knight33beb242015-12-15 19:23:12 +000039 ret void
40}
41
42; CHECK-LABEL: call_intarg:
43; CHECK: save %sp, -104, %sp
44; Use %o0-%o5 for outgoing arguments
45; CHECK: mov 5, %o5
46; CHECK: st %i0, [%sp+92]
47; CHECK: call intarg
48; CHECK-NOT: add %sp
49; CHECK: restore
50define void @call_intarg(i32 %i0, i8* %i1) {
51 call void @intarg(i8 0, i8 1, i16 2, i32 3, i8* undef, i32 5, i32 %i0, i8* %i1)
52 ret void
53}
54
55;; Verify doubles starting with an even reg, starting with an odd reg,
56;; straddling the boundary of regs and mem, and floats in regs and mem.
57;
58; CHECK-LABEL: floatarg:
Chris Dewhurst68388a02016-05-18 09:14:13 +000059; HARD: save %sp, -120, %sp
60; HARD: mov %i5, %g2
61; HARD-NEXT: ld [%fp+92], %g3
62; HARD-NEXT: mov %i4, %i5
Matthias Braun152e7c82016-07-09 00:19:07 +000063; HARD-NEXT: ! kill
Chris Dewhurst68388a02016-05-18 09:14:13 +000064; HARD-NEXT: std %g2, [%fp+-24]
65; HARD-NEXT: mov %i3, %i4
66; HARD-NEXT: std %i4, [%fp+-16]
Matthias Braun152e7c82016-07-09 00:19:07 +000067; HARD-NEXT: ! kill
Chris Dewhurst68388a02016-05-18 09:14:13 +000068; HARD-NEXT: std %i0, [%fp+-8]
69; HARD-NEXT: st %i2, [%fp+-28]
70; HARD-NEXT: ld [%fp+104], %f0
71; HARD-NEXT: ldd [%fp+96], %f2
72; HARD-NEXT: ld [%fp+-28], %f1
73; HARD-NEXT: ldd [%fp+-8], %f4
74; HARD-NEXT: ldd [%fp+-16], %f6
75; HARD-NEXT: ldd [%fp+-24], %f8
76; HARD-NEXT: fstod %f1, %f10
77; HARD-NEXT: faddd %f4, %f10, %f4
78; HARD-NEXT: faddd %f6, %f4, %f4
79; HARD-NEXT: faddd %f8, %f4, %f4
80; HARD-NEXT: faddd %f2, %f4, %f2
81; HARD-NEXT: fstod %f0, %f0
82; HARD-NEXT: faddd %f0, %f2, %f0
83; SOFT: save %sp, -96, %sp
84; SOFT: ld [%fp+104], %l0
85; SOFT-NEXT: ld [%fp+96], %l1
86; SOFT-NEXT: ld [%fp+100], %l2
87; SOFT-NEXT: ld [%fp+92], %l3
88; SOFT-NEXT: mov %i2, %o0
89; SOFT-NEXT: call __extendsfdf2
90; SOFT-NEXT: nop
Jonas Paulsson8ff07732018-02-24 08:24:31 +000091; SOFT-NEXT: mov %o0, %o2
92; SOFT-NEXT: mov %o1, %o3
Chris Dewhurst68388a02016-05-18 09:14:13 +000093; SOFT-NEXT: mov %i0, %o0
94; SOFT-NEXT: mov %i1, %o1
Chris Dewhurst68388a02016-05-18 09:14:13 +000095; SOFT-NEXT: call __adddf3
96; SOFT-NEXT: nop
Jonas Paulsson8ff07732018-02-24 08:24:31 +000097; SOFT-NEXT: mov %o0, %o2
98; SOFT-NEXT: mov %o1, %o3
Chris Dewhurst68388a02016-05-18 09:14:13 +000099; SOFT-NEXT: mov %i3, %o0
100; SOFT-NEXT: mov %i4, %o1
Chris Dewhurst68388a02016-05-18 09:14:13 +0000101; SOFT-NEXT: call __adddf3
102; SOFT-NEXT: nop
Jonas Paulsson8ff07732018-02-24 08:24:31 +0000103; SOFT-NEXT: mov %o0, %o2
104; SOFT-NEXT: mov %o1, %o3
Chris Dewhurst68388a02016-05-18 09:14:13 +0000105; SOFT-NEXT: mov %i5, %o0
106; SOFT-NEXT: mov %l3, %o1
Chris Dewhurst68388a02016-05-18 09:14:13 +0000107; SOFT-NEXT: call __adddf3
108; SOFT-NEXT: nop
Jonas Paulsson8ff07732018-02-24 08:24:31 +0000109; SOFT-NEXT: mov %o0, %o2
110; SOFT-NEXT: mov %o1, %o3
Chris Dewhurst68388a02016-05-18 09:14:13 +0000111; SOFT-NEXT: mov %l1, %o0
112; SOFT-NEXT: mov %l2, %o1
Chris Dewhurst68388a02016-05-18 09:14:13 +0000113; SOFT-NEXT: call __adddf3
114; SOFT-NEXT: nop
115; SOFT-NEXT: mov %o0, %i0
116; SOFT-NEXT: mov %o1, %i1
117; SOFT-NEXT: mov %l0, %o0
118; SOFT-NEXT: call __extendsfdf2
119; SOFT-NEXT: nop
120; SOFT-NEXT: mov %i0, %o2
121; SOFT-NEXT: mov %i1, %o3
122; SOFT-NEXT: call __adddf3
123; SOFT-NEXT: nop
124; SOFT-NEXT: mov %o0, %i0
125; SOFT-NEXT: mov %o1, %i1
126; CHECK: restore
James Y Knight33beb242015-12-15 19:23:12 +0000127define double @floatarg(double %a0, ; %i0,%i1
128 float %a1, ; %i2
129 double %a2, ; %i3, %i4
130 double %a3, ; %i5, [%fp+92] (using 4 bytes)
131 double %a4, ; [%fp+96] (using 8 bytes)
132 float %a5) { ; [%fp+104] (using 4 bytes)
133 %d1 = fpext float %a1 to double
134 %s1 = fadd double %a0, %d1
135 %s2 = fadd double %a2, %s1
136 %s3 = fadd double %a3, %s2
137 %s4 = fadd double %a4, %s3
138 %d5 = fpext float %a5 to double
139 %s5 = fadd double %d5, %s4
140 ret double %s5
141}
142
143; CHECK-LABEL: call_floatarg:
Chris Dewhurst68388a02016-05-18 09:14:13 +0000144; HARD: save %sp, -112, %sp
145; HARD: mov %i2, %o1
146; HARD-NEXT: mov %i1, %o0
147; HARD-NEXT: st %i0, [%sp+104]
148; HARD-NEXT: std %o0, [%sp+96]
149; HARD-NEXT: st %o1, [%sp+92]
150; HARD-NEXT: mov %i0, %o2
Geoff Berrya2b90112018-02-27 16:59:10 +0000151; HARD-NEXT: mov %i1, %o3
Chris Dewhurst68388a02016-05-18 09:14:13 +0000152; HARD-NEXT: mov %o1, %o4
Geoff Berrya2b90112018-02-27 16:59:10 +0000153; HARD-NEXT: mov %i1, %o5
Chris Dewhurst68388a02016-05-18 09:14:13 +0000154; HARD-NEXT: call floatarg
155; HARD: std %f0, [%i4]
156; SOFT: st %i0, [%sp+104]
157; SOFT-NEXT: st %i2, [%sp+100]
158; SOFT-NEXT: st %i1, [%sp+96]
159; SOFT-NEXT: st %i2, [%sp+92]
160; SOFT-NEXT: mov %i1, %o0
161; SOFT-NEXT: mov %i2, %o1
162; SOFT-NEXT: mov %i0, %o2
163; SOFT-NEXT: mov %i1, %o3
164; SOFT-NEXT: mov %i2, %o4
165; SOFT-NEXT: mov %i1, %o5
166; SOFT-NEXT: call floatarg
167; SOFT: std %o0, [%i4]
James Y Knight33beb242015-12-15 19:23:12 +0000168; CHECK: restore
169define void @call_floatarg(float %f1, double %d2, float %f5, double *%p) {
170 %r = call double @floatarg(double %d2, float %f1, double %d2, double %d2,
171 double %d2, float %f1)
172 store double %r, double* %p
173 ret void
174}
175
176;; i64 arguments should effectively work the same as double: split
177;; into two locations. This is different for little-endian vs big
178;; endian, since the 64-bit math needs to be split
179; CHECK-LABEL: i64arg:
180; CHECK: save %sp, -96, %sp
Vedant Kumaree4bfca2018-05-01 19:26:15 +0000181; CHECK-BE: ld [%fp+104], %g2
182; CHECK-BE-NEXT: ld [%fp+100], %g3
183; CHECK-BE-NEXT: ld [%fp+96], %g4
184; CHECK-BE-NEXT: ld [%fp+92], %l0
James Y Knight33beb242015-12-15 19:23:12 +0000185; CHECK-BE-NEXT: addcc %i1, %i2, %i1
186; CHECK-BE-NEXT: addxcc %i0, 0, %i0
187; CHECK-BE-NEXT: addcc %i4, %i1, %i1
188; CHECK-BE-NEXT: addxcc %i3, %i0, %i0
Vedant Kumaree4bfca2018-05-01 19:26:15 +0000189; CHECK-BE-NEXT: addcc %l0, %i1, %i1
James Y Knight33beb242015-12-15 19:23:12 +0000190; CHECK-BE-NEXT: addxcc %i5, %i0, %i0
Vedant Kumaree4bfca2018-05-01 19:26:15 +0000191; CHECK-BE-NEXT: addcc %g3, %i1, %i1
192; CHECK-BE-NEXT: addxcc %g4, %i0, %i0
James Y Knight33beb242015-12-15 19:23:12 +0000193; CHECK-BE-NEXT: addcc %g2, %i1, %i1
James Y Knight33beb242015-12-15 19:23:12 +0000194; CHECK-BE-NEXT: addxcc %i0, 0, %i0
195;
Vedant Kumaree4bfca2018-05-01 19:26:15 +0000196; CHECK-LE: ld [%fp+104], %g2
197; CHECK-LE-NEXT: ld [%fp+96], %g3
198; CHECK-LE-NEXT: ld [%fp+100], %g4
199; CHECK-LE-NEXT: ld [%fp+92], %l0
James Y Knight33beb242015-12-15 19:23:12 +0000200; CHECK-LE-NEXT: addcc %i0, %i2, %i0
201; CHECK-LE-NEXT: addxcc %i1, 0, %i1
202; CHECK-LE-NEXT: addcc %i3, %i0, %i0
203; CHECK-LE-NEXT: addxcc %i4, %i1, %i1
204; CHECK-LE-NEXT: addcc %i5, %i0, %i0
Vedant Kumaree4bfca2018-05-01 19:26:15 +0000205; CHECK-LE-NEXT: addxcc %l0, %i1, %i1
206; CHECK-LE-NEXT: addcc %g3, %i0, %i0
James Y Knight33beb242015-12-15 19:23:12 +0000207; CHECK-LE-NEXT: addxcc %g4, %i1, %i1
208; CHECK-LE-NEXT: addcc %g2, %i0, %i0
James Y Knight33beb242015-12-15 19:23:12 +0000209; CHECK-LE-NEXT: addxcc %i1, 0, %i1
210; CHECK-NEXT: restore
211
212
213define i64 @i64arg(i64 %a0, ; %i0,%i1
214 i32 %a1, ; %i2
215 i64 %a2, ; %i3, %i4
216 i64 %a3, ; %i5, [%fp+92] (using 4 bytes)
217 i64 %a4, ; [%fp+96] (using 8 bytes)
218 i32 %a5) { ; [%fp+104] (using 4 bytes)
219 %a1L = zext i32 %a1 to i64
220 %s1 = add i64 %a0, %a1L
221 %s2 = add i64 %a2, %s1
222 %s3 = add i64 %a3, %s2
223 %s4 = add i64 %a4, %s3
224 %a5L = zext i32 %a5 to i64
225 %s5 = add i64 %a5L, %s4
226 ret i64 %s5
227}
228
229; CHECK-LABEL: call_i64arg:
230; CHECK: save %sp, -112, %sp
231; CHECK: st %i0, [%sp+104]
232; CHECK-NEXT: st %i2, [%sp+100]
233; CHECK-NEXT: st %i1, [%sp+96]
234; CHECK-NEXT: st %i2, [%sp+92]
235; CHECK-NEXT: mov %i1, %o0
236; CHECK-NEXT: mov %i2, %o1
237; CHECK-NEXT: mov %i0, %o2
238; CHECK-NEXT: mov %i1, %o3
239; CHECK-NEXT: mov %i2, %o4
240; CHECK-NEXT: mov %i1, %o5
241; CHECK-NEXT: call i64arg
242; CHECK: std %o0, [%i3]
243; CHECK-NEXT: restore
244
245define void @call_i64arg(i32 %a0, i64 %a1, i64* %p) {
246 %r = call i64 @i64arg(i64 %a1, i32 %a0, i64 %a1, i64 %a1, i64 %a1, i32 %a0)
247 store i64 %r, i64* %p
248 ret void
249}