Mercurial > hg > CbC > CbC_llvm
comparison llvm/test/CodeGen/SPARC/32abi.ll @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
147:c2174574ed3a | 150:1d019706d866 |
---|---|
1 ; 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 | |
4 | |
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 | |
20 define 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] | |
28 store volatile i8 %a0, i8* %a4 | |
29 store volatile i8 %a1, i8* %a4 | |
30 %p16 = bitcast i8* %a4 to i16* | |
31 store volatile i16 %a2, i16* %p16 | |
32 %p32 = bitcast i8* %a4 to i32* | |
33 store volatile i32 %a3, i32* %p32 | |
34 %pp = bitcast i8* %a4 to i8** | |
35 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 | |
39 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 | |
50 define 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: | |
59 ; HARD: save %sp, -120, %sp | |
60 ; HARD: mov %i5, %g2 | |
61 ; HARD-NEXT: ld [%fp+92], %g3 | |
62 ; HARD-NEXT: mov %i4, %i5 | |
63 ; HARD-NEXT: ! kill | |
64 ; HARD-NEXT: std %g2, [%fp+-24] | |
65 ; HARD-NEXT: mov %i3, %i4 | |
66 ; HARD-NEXT: std %i4, [%fp+-16] | |
67 ; HARD-NEXT: ! kill | |
68 ; 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 | |
91 ; SOFT-NEXT: mov %o0, %o2 | |
92 ; SOFT-NEXT: mov %o1, %o3 | |
93 ; SOFT-NEXT: mov %i0, %o0 | |
94 ; SOFT-NEXT: mov %i1, %o1 | |
95 ; SOFT-NEXT: call __adddf3 | |
96 ; SOFT-NEXT: nop | |
97 ; SOFT-NEXT: mov %o0, %o2 | |
98 ; SOFT-NEXT: mov %o1, %o3 | |
99 ; SOFT-NEXT: mov %i3, %o0 | |
100 ; SOFT-NEXT: mov %i4, %o1 | |
101 ; SOFT-NEXT: call __adddf3 | |
102 ; SOFT-NEXT: nop | |
103 ; SOFT-NEXT: mov %o0, %o2 | |
104 ; SOFT-NEXT: mov %o1, %o3 | |
105 ; SOFT-NEXT: mov %i5, %o0 | |
106 ; SOFT-NEXT: mov %l3, %o1 | |
107 ; SOFT-NEXT: call __adddf3 | |
108 ; SOFT-NEXT: nop | |
109 ; SOFT-NEXT: mov %o0, %o2 | |
110 ; SOFT-NEXT: mov %o1, %o3 | |
111 ; SOFT-NEXT: mov %l1, %o0 | |
112 ; SOFT-NEXT: mov %l2, %o1 | |
113 ; 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 | |
127 define 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: | |
144 ; 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 | |
151 ; HARD-NEXT: mov %i1, %o3 | |
152 ; HARD-NEXT: mov %o1, %o4 | |
153 ; HARD-NEXT: mov %i1, %o5 | |
154 ; 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] | |
168 ; CHECK: restore | |
169 define 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 | |
181 ; 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 | |
185 ; 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 | |
189 ; CHECK-BE-NEXT: addcc %l0, %i1, %i1 | |
190 ; CHECK-BE-NEXT: addxcc %i5, %i0, %i0 | |
191 ; CHECK-BE-NEXT: addcc %g3, %i1, %i1 | |
192 ; CHECK-BE-NEXT: addxcc %g4, %i0, %i0 | |
193 ; CHECK-BE-NEXT: addcc %g2, %i1, %i1 | |
194 ; CHECK-BE-NEXT: addxcc %i0, 0, %i0 | |
195 ; | |
196 ; 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 | |
200 ; 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 | |
205 ; CHECK-LE-NEXT: addxcc %l0, %i1, %i1 | |
206 ; CHECK-LE-NEXT: addcc %g3, %i0, %i0 | |
207 ; CHECK-LE-NEXT: addxcc %g4, %i1, %i1 | |
208 ; CHECK-LE-NEXT: addcc %g2, %i0, %i0 | |
209 ; CHECK-LE-NEXT: addxcc %i1, 0, %i1 | |
210 ; CHECK-NEXT: restore | |
211 | |
212 | |
213 define 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 | |
245 define 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 } |