Mercurial > hg > CbC > CbC_llvm
comparison test/CodeGen/SystemZ/asm-18.ll @ 0:95c75e76d11b LLVM3.4
LLVM 3.4
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 12 Dec 2013 13:56:28 +0900 |
parents | |
children | 60c9769439b8 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:95c75e76d11b |
---|---|
1 ; Test high-word operations, using "h" constraints to force a high | |
2 ; register and "r" constraints to force a low register. | |
3 ; | |
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s | |
5 | |
6 ; Test loads and stores involving mixtures of high and low registers. | |
7 define void @f1(i32 *%ptr1, i32 *%ptr2) { | |
8 ; CHECK-LABEL: f1: | |
9 ; CHECK-DAG: lfh [[REG1:%r[0-5]]], 0(%r2) | |
10 ; CHECK-DAG: l [[REG2:%r[0-5]]], 0(%r3) | |
11 ; CHECK-DAG: lfh [[REG3:%r[0-5]]], 4096(%r2) | |
12 ; CHECK-DAG: ly [[REG4:%r[0-5]]], 524284(%r3) | |
13 ; CHECK: blah [[REG1]], [[REG2]], [[REG3]], [[REG4]] | |
14 ; CHECK-DAG: stfh [[REG1]], 0(%r2) | |
15 ; CHECK-DAG: st [[REG2]], 0(%r3) | |
16 ; CHECK-DAG: stfh [[REG3]], 4096(%r2) | |
17 ; CHECK-DAG: sty [[REG4]], 524284(%r3) | |
18 ; CHECK: br %r14 | |
19 %ptr3 = getelementptr i32 *%ptr1, i64 1024 | |
20 %ptr4 = getelementptr i32 *%ptr2, i64 131071 | |
21 %old1 = load i32 *%ptr1 | |
22 %old2 = load i32 *%ptr2 | |
23 %old3 = load i32 *%ptr3 | |
24 %old4 = load i32 *%ptr4 | |
25 %res = call { i32, i32, i32, i32 } asm "blah $0, $1, $2, $3", | |
26 "=h,=r,=h,=r,0,1,2,3"(i32 %old1, i32 %old2, i32 %old3, i32 %old4) | |
27 %new1 = extractvalue { i32, i32, i32, i32 } %res, 0 | |
28 %new2 = extractvalue { i32, i32, i32, i32 } %res, 1 | |
29 %new3 = extractvalue { i32, i32, i32, i32 } %res, 2 | |
30 %new4 = extractvalue { i32, i32, i32, i32 } %res, 3 | |
31 store i32 %new1, i32 *%ptr1 | |
32 store i32 %new2, i32 *%ptr2 | |
33 store i32 %new3, i32 *%ptr3 | |
34 store i32 %new4, i32 *%ptr4 | |
35 ret void | |
36 } | |
37 | |
38 ; Test moves involving mixtures of high and low registers. | |
39 define i32 @f2(i32 %old) { | |
40 ; CHECK-LABEL: f2: | |
41 ; CHECK-DAG: risbhg [[REG1:%r[0-5]]], %r2, 0, 159, 32 | |
42 ; CHECK-DAG: lr %r3, %r2 | |
43 ; CHECK: stepa [[REG1]], %r2, %r3 | |
44 ; CHECK: risbhg {{%r[0-5]}}, [[REG1]], 0, 159, 0 | |
45 ; CHECK: stepb [[REG2:%r[0-5]]] | |
46 ; CHECK: risblg %r2, [[REG2]], 0, 159, 32 | |
47 ; CHECK: br %r14 | |
48 %tmp = call i32 asm "stepa $1, $2, $3", | |
49 "=h,0,{r2},{r3}"(i32 %old, i32 %old, i32 %old) | |
50 %new = call i32 asm "stepb $1, $2", "=&h,0,h"(i32 %tmp, i32 %tmp) | |
51 ret i32 %new | |
52 } | |
53 | |
54 ; Test sign-extending 8-bit loads into mixtures of high and low registers. | |
55 define void @f3(i8 *%ptr1, i8 *%ptr2) { | |
56 ; CHECK-LABEL: f3: | |
57 ; CHECK-DAG: lbh [[REG1:%r[0-5]]], 0(%r2) | |
58 ; CHECK-DAG: lb [[REG2:%r[0-5]]], 0(%r3) | |
59 ; CHECK-DAG: lbh [[REG3:%r[0-5]]], 4096(%r2) | |
60 ; CHECK-DAG: lb [[REG4:%r[0-5]]], 524287(%r3) | |
61 ; CHECK: blah [[REG1]], [[REG2]] | |
62 ; CHECK: br %r14 | |
63 %ptr3 = getelementptr i8 *%ptr1, i64 4096 | |
64 %ptr4 = getelementptr i8 *%ptr2, i64 524287 | |
65 %val1 = load i8 *%ptr1 | |
66 %val2 = load i8 *%ptr2 | |
67 %val3 = load i8 *%ptr3 | |
68 %val4 = load i8 *%ptr4 | |
69 %ext1 = sext i8 %val1 to i32 | |
70 %ext2 = sext i8 %val2 to i32 | |
71 %ext3 = sext i8 %val3 to i32 | |
72 %ext4 = sext i8 %val4 to i32 | |
73 call void asm sideeffect "blah $0, $1, $2, $3", | |
74 "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4) | |
75 ret void | |
76 } | |
77 | |
78 ; Test sign-extending 16-bit loads into mixtures of high and low registers. | |
79 define void @f4(i16 *%ptr1, i16 *%ptr2) { | |
80 ; CHECK-LABEL: f4: | |
81 ; CHECK-DAG: lhh [[REG1:%r[0-5]]], 0(%r2) | |
82 ; CHECK-DAG: lh [[REG2:%r[0-5]]], 0(%r3) | |
83 ; CHECK-DAG: lhh [[REG3:%r[0-5]]], 4096(%r2) | |
84 ; CHECK-DAG: lhy [[REG4:%r[0-5]]], 524286(%r3) | |
85 ; CHECK: blah [[REG1]], [[REG2]] | |
86 ; CHECK: br %r14 | |
87 %ptr3 = getelementptr i16 *%ptr1, i64 2048 | |
88 %ptr4 = getelementptr i16 *%ptr2, i64 262143 | |
89 %val1 = load i16 *%ptr1 | |
90 %val2 = load i16 *%ptr2 | |
91 %val3 = load i16 *%ptr3 | |
92 %val4 = load i16 *%ptr4 | |
93 %ext1 = sext i16 %val1 to i32 | |
94 %ext2 = sext i16 %val2 to i32 | |
95 %ext3 = sext i16 %val3 to i32 | |
96 %ext4 = sext i16 %val4 to i32 | |
97 call void asm sideeffect "blah $0, $1, $2, $3", | |
98 "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4) | |
99 ret void | |
100 } | |
101 | |
102 ; Test zero-extending 8-bit loads into mixtures of high and low registers. | |
103 define void @f5(i8 *%ptr1, i8 *%ptr2) { | |
104 ; CHECK-LABEL: f5: | |
105 ; CHECK-DAG: llch [[REG1:%r[0-5]]], 0(%r2) | |
106 ; CHECK-DAG: llc [[REG2:%r[0-5]]], 0(%r3) | |
107 ; CHECK-DAG: llch [[REG3:%r[0-5]]], 4096(%r2) | |
108 ; CHECK-DAG: llc [[REG4:%r[0-5]]], 524287(%r3) | |
109 ; CHECK: blah [[REG1]], [[REG2]] | |
110 ; CHECK: br %r14 | |
111 %ptr3 = getelementptr i8 *%ptr1, i64 4096 | |
112 %ptr4 = getelementptr i8 *%ptr2, i64 524287 | |
113 %val1 = load i8 *%ptr1 | |
114 %val2 = load i8 *%ptr2 | |
115 %val3 = load i8 *%ptr3 | |
116 %val4 = load i8 *%ptr4 | |
117 %ext1 = zext i8 %val1 to i32 | |
118 %ext2 = zext i8 %val2 to i32 | |
119 %ext3 = zext i8 %val3 to i32 | |
120 %ext4 = zext i8 %val4 to i32 | |
121 call void asm sideeffect "blah $0, $1, $2, $3", | |
122 "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4) | |
123 ret void | |
124 } | |
125 | |
126 ; Test zero-extending 16-bit loads into mixtures of high and low registers. | |
127 define void @f6(i16 *%ptr1, i16 *%ptr2) { | |
128 ; CHECK-LABEL: f6: | |
129 ; CHECK-DAG: llhh [[REG1:%r[0-5]]], 0(%r2) | |
130 ; CHECK-DAG: llh [[REG2:%r[0-5]]], 0(%r3) | |
131 ; CHECK-DAG: llhh [[REG3:%r[0-5]]], 4096(%r2) | |
132 ; CHECK-DAG: llh [[REG4:%r[0-5]]], 524286(%r3) | |
133 ; CHECK: blah [[REG1]], [[REG2]] | |
134 ; CHECK: br %r14 | |
135 %ptr3 = getelementptr i16 *%ptr1, i64 2048 | |
136 %ptr4 = getelementptr i16 *%ptr2, i64 262143 | |
137 %val1 = load i16 *%ptr1 | |
138 %val2 = load i16 *%ptr2 | |
139 %val3 = load i16 *%ptr3 | |
140 %val4 = load i16 *%ptr4 | |
141 %ext1 = zext i16 %val1 to i32 | |
142 %ext2 = zext i16 %val2 to i32 | |
143 %ext3 = zext i16 %val3 to i32 | |
144 %ext4 = zext i16 %val4 to i32 | |
145 call void asm sideeffect "blah $0, $1, $2, $3", | |
146 "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4) | |
147 ret void | |
148 } | |
149 | |
150 ; Test truncating stores of high and low registers into 8-bit memory. | |
151 define void @f7(i8 *%ptr1, i8 *%ptr2) { | |
152 ; CHECK-LABEL: f7: | |
153 ; CHECK: blah [[REG1:%r[0-5]]], [[REG2:%r[0-5]]] | |
154 ; CHECK-DAG: stch [[REG1]], 0(%r2) | |
155 ; CHECK-DAG: stc [[REG2]], 0(%r3) | |
156 ; CHECK-DAG: stch [[REG1]], 4096(%r2) | |
157 ; CHECK-DAG: stcy [[REG2]], 524287(%r3) | |
158 ; CHECK: br %r14 | |
159 %res = call { i32, i32 } asm "blah $0, $1", "=h,=r"() | |
160 %res1 = extractvalue { i32, i32 } %res, 0 | |
161 %res2 = extractvalue { i32, i32 } %res, 1 | |
162 %trunc1 = trunc i32 %res1 to i8 | |
163 %trunc2 = trunc i32 %res2 to i8 | |
164 %ptr3 = getelementptr i8 *%ptr1, i64 4096 | |
165 %ptr4 = getelementptr i8 *%ptr2, i64 524287 | |
166 store i8 %trunc1, i8 *%ptr1 | |
167 store i8 %trunc2, i8 *%ptr2 | |
168 store i8 %trunc1, i8 *%ptr3 | |
169 store i8 %trunc2, i8 *%ptr4 | |
170 ret void | |
171 } | |
172 | |
173 ; Test truncating stores of high and low registers into 16-bit memory. | |
174 define void @f8(i16 *%ptr1, i16 *%ptr2) { | |
175 ; CHECK-LABEL: f8: | |
176 ; CHECK: blah [[REG1:%r[0-5]]], [[REG2:%r[0-5]]] | |
177 ; CHECK-DAG: sthh [[REG1]], 0(%r2) | |
178 ; CHECK-DAG: sth [[REG2]], 0(%r3) | |
179 ; CHECK-DAG: sthh [[REG1]], 4096(%r2) | |
180 ; CHECK-DAG: sthy [[REG2]], 524286(%r3) | |
181 ; CHECK: br %r14 | |
182 %res = call { i32, i32 } asm "blah $0, $1", "=h,=r"() | |
183 %res1 = extractvalue { i32, i32 } %res, 0 | |
184 %res2 = extractvalue { i32, i32 } %res, 1 | |
185 %trunc1 = trunc i32 %res1 to i16 | |
186 %trunc2 = trunc i32 %res2 to i16 | |
187 %ptr3 = getelementptr i16 *%ptr1, i64 2048 | |
188 %ptr4 = getelementptr i16 *%ptr2, i64 262143 | |
189 store i16 %trunc1, i16 *%ptr1 | |
190 store i16 %trunc2, i16 *%ptr2 | |
191 store i16 %trunc1, i16 *%ptr3 | |
192 store i16 %trunc2, i16 *%ptr4 | |
193 ret void | |
194 } | |
195 | |
196 ; Test zero extensions from 8 bits between mixtures of high and low registers. | |
197 define i32 @f9(i8 %val1, i8 %val2) { | |
198 ; CHECK-LABEL: f9: | |
199 ; CHECK-DAG: risbhg [[REG1:%r[0-5]]], %r2, 24, 159, 32 | |
200 ; CHECK-DAG: llcr [[REG2:%r[0-5]]], %r3 | |
201 ; CHECK: stepa [[REG1]], [[REG2]] | |
202 ; CHECK: risbhg [[REG3:%r[0-5]]], [[REG1]], 24, 159, 0 | |
203 ; CHECK: stepb [[REG3]] | |
204 ; CHECK: risblg %r2, [[REG3]], 24, 159, 32 | |
205 ; CHECK: br %r14 | |
206 %ext1 = zext i8 %val1 to i32 | |
207 %ext2 = zext i8 %val2 to i32 | |
208 %val3 = call i8 asm sideeffect "stepa $0, $1", "=h,0,r"(i32 %ext1, i32 %ext2) | |
209 %ext3 = zext i8 %val3 to i32 | |
210 %val4 = call i8 asm sideeffect "stepb $0", "=h,0"(i32 %ext3) | |
211 %ext4 = zext i8 %val4 to i32 | |
212 ret i32 %ext4 | |
213 } | |
214 | |
215 ; Test zero extensions from 16 bits between mixtures of high and low registers. | |
216 define i32 @f10(i16 %val1, i16 %val2) { | |
217 ; CHECK-LABEL: f10: | |
218 ; CHECK-DAG: risbhg [[REG1:%r[0-5]]], %r2, 16, 159, 32 | |
219 ; CHECK-DAG: llhr [[REG2:%r[0-5]]], %r3 | |
220 ; CHECK: stepa [[REG1]], [[REG2]] | |
221 ; CHECK: risbhg [[REG3:%r[0-5]]], [[REG1]], 16, 159, 0 | |
222 ; CHECK: stepb [[REG3]] | |
223 ; CHECK: risblg %r2, [[REG3]], 16, 159, 32 | |
224 ; CHECK: br %r14 | |
225 %ext1 = zext i16 %val1 to i32 | |
226 %ext2 = zext i16 %val2 to i32 | |
227 %val3 = call i16 asm sideeffect "stepa $0, $1", "=h,0,r"(i32 %ext1, i32 %ext2) | |
228 %ext3 = zext i16 %val3 to i32 | |
229 %val4 = call i16 asm sideeffect "stepb $0", "=h,0"(i32 %ext3) | |
230 %ext4 = zext i16 %val4 to i32 | |
231 ret i32 %ext4 | |
232 } | |
233 | |
234 ; Test loads of 16-bit constants into mixtures of high and low registers. | |
235 define void @f11() { | |
236 ; CHECK-LABEL: f11: | |
237 ; CHECK-DAG: iihf [[REG1:%r[0-5]]], 4294934529 | |
238 ; CHECK-DAG: lhi [[REG2:%r[0-5]]], -32768 | |
239 ; CHECK-DAG: llihl [[REG3:%r[0-5]]], 32766 | |
240 ; CHECK-DAG: lhi [[REG4:%r[0-5]]], 32767 | |
241 ; CHECK: blah [[REG1]], [[REG2]], [[REG3]], [[REG4]] | |
242 ; CHECK: br %r14 | |
243 call void asm sideeffect "blah $0, $1, $2, $3", | |
244 "h,r,h,r"(i32 -32767, i32 -32768, | |
245 i32 32766, i32 32767) | |
246 ret void | |
247 } | |
248 | |
249 ; Test loads of unsigned constants into mixtures of high and low registers. | |
250 ; For stepc, we expect the h and r operands to be paired by the register | |
251 ; allocator. It doesn't really matter which comes first: LLILL/IIHF would | |
252 ; be just as good. | |
253 define void @f12() { | |
254 ; CHECK-LABEL: f12: | |
255 ; CHECK-DAG: llihl [[REG1:%r[0-5]]], 32768 | |
256 ; CHECK-DAG: llihl [[REG2:%r[0-5]]], 65535 | |
257 ; CHECK-DAG: llihh [[REG3:%r[0-5]]], 1 | |
258 ; CHECK-DAG: llihh [[REG4:%r[0-5]]], 65535 | |
259 ; CHECK: stepa [[REG1]], [[REG2]], [[REG3]], [[REG4]] | |
260 ; CHECK-DAG: llill [[REG1:%r[0-5]]], 32769 | |
261 ; CHECK-DAG: llill [[REG2:%r[0-5]]], 65534 | |
262 ; CHECK-DAG: llilh [[REG3:%r[0-5]]], 2 | |
263 ; CHECK-DAG: llilh [[REG4:%r[0-5]]], 65534 | |
264 ; CHECK: stepb [[REG1]], [[REG2]], [[REG3]], [[REG4]] | |
265 ; CHECK-DAG: llihl [[REG1:%r[0-5]]], 32770 | |
266 ; CHECK-DAG: iilf [[REG1]], 65533 | |
267 ; CHECK-DAG: llihh [[REG2:%r[0-5]]], 4 | |
268 ; CHECK-DAG: iilf [[REG2]], 524288 | |
269 ; CHECK: stepc [[REG1]], [[REG1]], [[REG2]], [[REG2]] | |
270 ; CHECK-DAG: iihf [[REG1:%r[0-5]]], 3294967296 | |
271 ; CHECK-DAG: iilf [[REG2:%r[0-5]]], 4294567296 | |
272 ; CHECK-DAG: iihf [[REG3:%r[0-5]]], 1000000000 | |
273 ; CHECK-DAG: iilf [[REG4:%r[0-5]]], 400000 | |
274 ; CHECK: stepd [[REG1]], [[REG2]], [[REG3]], [[REG4]] | |
275 ; CHECK: br %r14 | |
276 call void asm sideeffect "stepa $0, $1, $2, $3", | |
277 "h,h,h,h"(i32 32768, i32 65535, | |
278 i32 65536, i32 -65536) | |
279 call void asm sideeffect "stepb $0, $1, $2, $3", | |
280 "r,r,r,r"(i32 32769, i32 65534, | |
281 i32 131072, i32 -131072) | |
282 call void asm sideeffect "stepc $0, $1, $2, $3", | |
283 "h,r,h,r"(i32 32770, i32 65533, | |
284 i32 262144, i32 524288) | |
285 call void asm sideeffect "stepd $0, $1, $2, $3", | |
286 "h,r,h,r"(i32 -1000000000, i32 -400000, | |
287 i32 1000000000, i32 400000) | |
288 ret void | |
289 } | |
290 | |
291 ; Test selects involving high registers. | |
292 define void @f13(i32 %x, i32 %y) { | |
293 ; CHECK-LABEL: f13: | |
294 ; CHECK: llihl [[REG:%r[0-5]]], 0 | |
295 ; CHECK: cije %r2, 0 | |
296 ; CHECK: iihf [[REG]], 2102030405 | |
297 ; CHECK: blah [[REG]] | |
298 ; CHECK: br %r14 | |
299 %cmp = icmp eq i32 %x, 0 | |
300 %val = select i1 %cmp, i32 0, i32 2102030405 | |
301 call void asm sideeffect "blah $0", "h"(i32 %val) | |
302 ret void | |
303 } | |
304 | |
305 ; Test selects involving low registers. | |
306 define void @f14(i32 %x, i32 %y) { | |
307 ; CHECK-LABEL: f14: | |
308 ; CHECK: lhi [[REG:%r[0-5]]], 0 | |
309 ; CHECK: cije %r2, 0 | |
310 ; CHECK: iilf [[REG]], 2102030405 | |
311 ; CHECK: blah [[REG]] | |
312 ; CHECK: br %r14 | |
313 %cmp = icmp eq i32 %x, 0 | |
314 %val = select i1 %cmp, i32 0, i32 2102030405 | |
315 call void asm sideeffect "blah $0", "r"(i32 %val) | |
316 ret void | |
317 } | |
318 | |
319 ; Test immediate insertion involving high registers. | |
320 define void @f15() { | |
321 ; CHECK-LABEL: f15: | |
322 ; CHECK: stepa [[REG:%r[0-5]]] | |
323 ; CHECK: iihh [[REG]], 4660 | |
324 ; CHECK: stepb [[REG]] | |
325 ; CHECK: iihl [[REG]], 34661 | |
326 ; CHECK: stepc [[REG]] | |
327 ; CHECK: br %r14 | |
328 %res1 = call i32 asm "stepa $0", "=h"() | |
329 %and1 = and i32 %res1, 65535 | |
330 %or1 = or i32 %and1, 305397760 | |
331 %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %or1) | |
332 %and2 = and i32 %res2, -65536 | |
333 %or2 = or i32 %and2, 34661 | |
334 call void asm sideeffect "stepc $0", "h"(i32 %or2) | |
335 ret void | |
336 } | |
337 | |
338 ; Test immediate insertion involving low registers. | |
339 define void @f16() { | |
340 ; CHECK-LABEL: f16: | |
341 ; CHECK: stepa [[REG:%r[0-5]]] | |
342 ; CHECK: iilh [[REG]], 4660 | |
343 ; CHECK: stepb [[REG]] | |
344 ; CHECK: iill [[REG]], 34661 | |
345 ; CHECK: stepc [[REG]] | |
346 ; CHECK: br %r14 | |
347 %res1 = call i32 asm "stepa $0", "=r"() | |
348 %and1 = and i32 %res1, 65535 | |
349 %or1 = or i32 %and1, 305397760 | |
350 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %or1) | |
351 %and2 = and i32 %res2, -65536 | |
352 %or2 = or i32 %and2, 34661 | |
353 call void asm sideeffect "stepc $0", "r"(i32 %or2) | |
354 ret void | |
355 } | |
356 | |
357 ; Test immediate OR involving high registers. | |
358 define void @f17() { | |
359 ; CHECK-LABEL: f17: | |
360 ; CHECK: stepa [[REG:%r[0-5]]] | |
361 ; CHECK: oihh [[REG]], 4660 | |
362 ; CHECK: stepb [[REG]] | |
363 ; CHECK: oihl [[REG]], 34661 | |
364 ; CHECK: stepc [[REG]] | |
365 ; CHECK: oihf [[REG]], 12345678 | |
366 ; CHECK: stepd [[REG]] | |
367 ; CHECK: br %r14 | |
368 %res1 = call i32 asm "stepa $0", "=h"() | |
369 %or1 = or i32 %res1, 305397760 | |
370 %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %or1) | |
371 %or2 = or i32 %res2, 34661 | |
372 %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %or2) | |
373 %or3 = or i32 %res3, 12345678 | |
374 call void asm sideeffect "stepd $0", "h"(i32 %or3) | |
375 ret void | |
376 } | |
377 | |
378 ; Test immediate OR involving low registers. | |
379 define void @f18() { | |
380 ; CHECK-LABEL: f18: | |
381 ; CHECK: stepa [[REG:%r[0-5]]] | |
382 ; CHECK: oilh [[REG]], 4660 | |
383 ; CHECK: stepb [[REG]] | |
384 ; CHECK: oill [[REG]], 34661 | |
385 ; CHECK: stepc [[REG]] | |
386 ; CHECK: oilf [[REG]], 12345678 | |
387 ; CHECK: stepd [[REG]] | |
388 ; CHECK: br %r14 | |
389 %res1 = call i32 asm "stepa $0", "=r"() | |
390 %or1 = or i32 %res1, 305397760 | |
391 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %or1) | |
392 %or2 = or i32 %res2, 34661 | |
393 %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %or2) | |
394 %or3 = or i32 %res3, 12345678 | |
395 call void asm sideeffect "stepd $0", "r"(i32 %or3) | |
396 ret void | |
397 } | |
398 | |
399 ; Test immediate XOR involving high registers. | |
400 define void @f19() { | |
401 ; CHECK-LABEL: f19: | |
402 ; CHECK: stepa [[REG:%r[0-5]]] | |
403 ; CHECK: xihf [[REG]], 305397760 | |
404 ; CHECK: stepb [[REG]] | |
405 ; CHECK: xihf [[REG]], 34661 | |
406 ; CHECK: stepc [[REG]] | |
407 ; CHECK: xihf [[REG]], 12345678 | |
408 ; CHECK: stepd [[REG]] | |
409 ; CHECK: br %r14 | |
410 %res1 = call i32 asm "stepa $0", "=h"() | |
411 %xor1 = xor i32 %res1, 305397760 | |
412 %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %xor1) | |
413 %xor2 = xor i32 %res2, 34661 | |
414 %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %xor2) | |
415 %xor3 = xor i32 %res3, 12345678 | |
416 call void asm sideeffect "stepd $0", "h"(i32 %xor3) | |
417 ret void | |
418 } | |
419 | |
420 ; Test immediate XOR involving low registers. | |
421 define void @f20() { | |
422 ; CHECK-LABEL: f20: | |
423 ; CHECK: stepa [[REG:%r[0-5]]] | |
424 ; CHECK: xilf [[REG]], 305397760 | |
425 ; CHECK: stepb [[REG]] | |
426 ; CHECK: xilf [[REG]], 34661 | |
427 ; CHECK: stepc [[REG]] | |
428 ; CHECK: xilf [[REG]], 12345678 | |
429 ; CHECK: stepd [[REG]] | |
430 ; CHECK: br %r14 | |
431 %res1 = call i32 asm "stepa $0", "=r"() | |
432 %xor1 = xor i32 %res1, 305397760 | |
433 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %xor1) | |
434 %xor2 = xor i32 %res2, 34661 | |
435 %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %xor2) | |
436 %xor3 = xor i32 %res3, 12345678 | |
437 call void asm sideeffect "stepd $0", "r"(i32 %xor3) | |
438 ret void | |
439 } | |
440 | |
441 ; Test two-operand immediate AND involving high registers. | |
442 define void @f21() { | |
443 ; CHECK-LABEL: f21: | |
444 ; CHECK: stepa [[REG:%r[0-5]]] | |
445 ; CHECK: nihh [[REG]], 4096 | |
446 ; CHECK: stepb [[REG]] | |
447 ; CHECK: nihl [[REG]], 57536 | |
448 ; CHECK: stepc [[REG]] | |
449 ; CHECK: nihf [[REG]], 12345678 | |
450 ; CHECK: stepd [[REG]] | |
451 ; CHECK: br %r14 | |
452 %res1 = call i32 asm "stepa $0", "=h"() | |
453 %and1 = and i32 %res1, 268500991 | |
454 %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %and1) | |
455 %and2 = and i32 %res2, -8000 | |
456 %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %and2) | |
457 %and3 = and i32 %res3, 12345678 | |
458 call void asm sideeffect "stepd $0", "h"(i32 %and3) | |
459 ret void | |
460 } | |
461 | |
462 ; Test two-operand immediate AND involving low registers. | |
463 define void @f22() { | |
464 ; CHECK-LABEL: f22: | |
465 ; CHECK: stepa [[REG:%r[0-5]]] | |
466 ; CHECK: nilh [[REG]], 4096 | |
467 ; CHECK: stepb [[REG]] | |
468 ; CHECK: nill [[REG]], 57536 | |
469 ; CHECK: stepc [[REG]] | |
470 ; CHECK: nilf [[REG]], 12345678 | |
471 ; CHECK: stepd [[REG]] | |
472 ; CHECK: br %r14 | |
473 %res1 = call i32 asm "stepa $0", "=r"() | |
474 %and1 = and i32 %res1, 268500991 | |
475 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %and1) | |
476 %and2 = and i32 %res2, -8000 | |
477 %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %and2) | |
478 %and3 = and i32 %res3, 12345678 | |
479 call void asm sideeffect "stepd $0", "r"(i32 %and3) | |
480 ret void | |
481 } | |
482 | |
483 ; Test three-operand immediate AND involving mixtures of low and high registers. | |
484 define i32 @f23(i32 %old) { | |
485 ; CHECK-LABEL: f23: | |
486 ; CHECK-DAG: risblg [[REG1:%r[0-5]]], %r2, 28, 158, 0 | |
487 ; CHECK-DAG: risbhg [[REG2:%r[0-5]]], %r2, 24, 158, 32 | |
488 ; CHECK: stepa %r2, [[REG1]], [[REG2]] | |
489 ; CHECK-DAG: risbhg [[REG3:%r[0-5]]], [[REG2]], 25, 159, 0 | |
490 ; CHECK-DAG: risblg %r2, [[REG2]], 24, 152, 32 | |
491 ; CHECK: stepb [[REG2]], [[REG3]], %r2 | |
492 ; CHECK: br %r14 | |
493 %and1 = and i32 %old, 14 | |
494 %and2 = and i32 %old, 254 | |
495 %res1 = call i32 asm "stepa $1, $2, $3", | |
496 "=h,r,r,0"(i32 %old, i32 %and1, i32 %and2) | |
497 %and3 = and i32 %res1, 127 | |
498 %and4 = and i32 %res1, 128 | |
499 %res2 = call i32 asm "stepb $1, $2, $3", | |
500 "=r,h,h,0"(i32 %res1, i32 %and3, i32 %and4) | |
501 ret i32 %res2 | |
502 } | |
503 | |
504 ; Test RISB[LH]G insertions involving mixtures of high and low registers. | |
505 define i32 @f24(i32 %old) { | |
506 ; CHECK-LABEL: f24: | |
507 ; CHECK-DAG: risblg [[REG1:%r[0-5]]], %r2, 28, 158, 1 | |
508 ; CHECK-DAG: risbhg [[REG2:%r[0-5]]], %r2, 24, 158, 29 | |
509 ; CHECK: stepa %r2, [[REG1]], [[REG2]] | |
510 ; CHECK-DAG: risbhg [[REG3:%r[0-5]]], [[REG2]], 25, 159, 62 | |
511 ; CHECK-DAG: risblg %r2, [[REG2]], 24, 152, 37 | |
512 ; CHECK: stepb [[REG2]], [[REG3]], %r2 | |
513 ; CHECK: br %r14 | |
514 %shift1 = shl i32 %old, 1 | |
515 %and1 = and i32 %shift1, 14 | |
516 %shift2 = lshr i32 %old, 3 | |
517 %and2 = and i32 %shift2, 254 | |
518 %res1 = call i32 asm "stepa $1, $2, $3", | |
519 "=h,r,r,0"(i32 %old, i32 %and1, i32 %and2) | |
520 %shift3 = lshr i32 %res1, 2 | |
521 %and3 = and i32 %shift3, 127 | |
522 %shift4 = shl i32 %res1, 5 | |
523 %and4 = and i32 %shift4, 128 | |
524 %res2 = call i32 asm "stepb $1, $2, $3", | |
525 "=r,h,h,0"(i32 %res1, i32 %and3, i32 %and4) | |
526 ret i32 %res2 | |
527 } | |
528 | |
529 ; Test TMxx involving mixtures of high and low registers. | |
530 define i32 @f25(i32 %old) { | |
531 ; CHECK-LABEL: f25: | |
532 ; CHECK-DAG: tmll %r2, 1 | |
533 ; CHECK-DAG: tmlh %r2, 1 | |
534 ; CHECK: stepa [[REG1:%r[0-5]]], | |
535 ; CHECK-DAG: tmhl [[REG1]], 1 | |
536 ; CHECK-DAG: tmhh [[REG1]], 1 | |
537 ; CHECK: stepb %r2, | |
538 ; CHECK: br %r14 | |
539 %and1 = and i32 %old, 1 | |
540 %and2 = and i32 %old, 65536 | |
541 %cmp1 = icmp eq i32 %and1, 0 | |
542 %cmp2 = icmp eq i32 %and2, 0 | |
543 %sel1 = select i1 %cmp1, i32 100, i32 200 | |
544 %sel2 = select i1 %cmp2, i32 100, i32 200 | |
545 %res1 = call i32 asm "stepa $0, $1, $2", | |
546 "=h,r,r"(i32 %sel1, i32 %sel2) | |
547 %and3 = and i32 %res1, 1 | |
548 %and4 = and i32 %res1, 65536 | |
549 %cmp3 = icmp eq i32 %and3, 0 | |
550 %cmp4 = icmp eq i32 %and4, 0 | |
551 %sel3 = select i1 %cmp3, i32 100, i32 200 | |
552 %sel4 = select i1 %cmp4, i32 100, i32 200 | |
553 %res2 = call i32 asm "stepb $0, $1, $2", | |
554 "=r,h,h"(i32 %sel3, i32 %sel4) | |
555 ret i32 %res2 | |
556 } | |
557 | |
558 ; Test two-operand halfword immediate addition involving high registers. | |
559 define void @f26() { | |
560 ; CHECK-LABEL: f26: | |
561 ; CHECK: stepa [[REG:%r[0-5]]] | |
562 ; CHECK: aih [[REG]], -32768 | |
563 ; CHECK: stepb [[REG]] | |
564 ; CHECK: aih [[REG]], 1 | |
565 ; CHECK: stepc [[REG]] | |
566 ; CHECK: aih [[REG]], 32767 | |
567 ; CHECK: stepd [[REG]] | |
568 ; CHECK: br %r14 | |
569 %res1 = call i32 asm "stepa $0", "=h"() | |
570 %add1 = add i32 %res1, -32768 | |
571 %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %add1) | |
572 %add2 = add i32 %res2, 1 | |
573 %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %add2) | |
574 %add3 = add i32 %res3, 32767 | |
575 call void asm sideeffect "stepd $0", "h"(i32 %add3) | |
576 ret void | |
577 } | |
578 | |
579 ; Test two-operand halfword immediate addition involving low registers. | |
580 define void @f27() { | |
581 ; CHECK-LABEL: f27: | |
582 ; CHECK: stepa [[REG:%r[0-5]]] | |
583 ; CHECK: ahi [[REG]], -32768 | |
584 ; CHECK: stepb [[REG]] | |
585 ; CHECK: ahi [[REG]], 1 | |
586 ; CHECK: stepc [[REG]] | |
587 ; CHECK: ahi [[REG]], 32767 | |
588 ; CHECK: stepd [[REG]] | |
589 ; CHECK: br %r14 | |
590 %res1 = call i32 asm "stepa $0", "=r"() | |
591 %add1 = add i32 %res1, -32768 | |
592 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %add1) | |
593 %add2 = add i32 %res2, 1 | |
594 %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %add2) | |
595 %add3 = add i32 %res3, 32767 | |
596 call void asm sideeffect "stepd $0", "r"(i32 %add3) | |
597 ret void | |
598 } | |
599 | |
600 ; Test three-operand halfword immediate addition involving mixtures of low | |
601 ; and high registers. RISBHG/AIH would be OK too, instead of AHIK/RISBHG. | |
602 define i32 @f28(i32 %old) { | |
603 ; CHECK-LABEL: f28: | |
604 ; CHECK: ahik [[REG1:%r[0-5]]], %r2, 14 | |
605 ; CHECK: stepa %r2, [[REG1]] | |
606 ; CHECK: ahik [[TMP:%r[0-5]]], [[REG1]], 254 | |
607 ; CHECK: risbhg [[REG2:%r[0-5]]], [[TMP]], 0, 159, 32 | |
608 ; CHECK: stepb [[REG1]], [[REG2]] | |
609 ; CHECK: risbhg [[REG3:%r[0-5]]], [[REG2]], 0, 159, 0 | |
610 ; CHECK: aih [[REG3]], 127 | |
611 ; CHECK: stepc [[REG2]], [[REG3]] | |
612 ; CHECK: risblg %r2, [[REG3]], 0, 159, 32 | |
613 ; CHECK: ahi %r2, 128 | |
614 ; CHECK: stepd [[REG3]], %r2 | |
615 ; CHECK: br %r14 | |
616 %add1 = add i32 %old, 14 | |
617 %res1 = call i32 asm "stepa $1, $2", | |
618 "=r,r,0"(i32 %old, i32 %add1) | |
619 %add2 = add i32 %res1, 254 | |
620 %res2 = call i32 asm "stepb $1, $2", | |
621 "=h,r,0"(i32 %res1, i32 %add2) | |
622 %add3 = add i32 %res2, 127 | |
623 %res3 = call i32 asm "stepc $1, $2", | |
624 "=h,h,0"(i32 %res2, i32 %add3) | |
625 %add4 = add i32 %res3, 128 | |
626 %res4 = call i32 asm "stepd $1, $2", | |
627 "=r,h,0"(i32 %res3, i32 %add4) | |
628 ret i32 %res4 | |
629 } | |
630 | |
631 ; Test large immediate addition involving high registers. | |
632 define void @f29() { | |
633 ; CHECK-LABEL: f29: | |
634 ; CHECK: stepa [[REG:%r[0-5]]] | |
635 ; CHECK: aih [[REG]], -32769 | |
636 ; CHECK: stepb [[REG]] | |
637 ; CHECK: aih [[REG]], 32768 | |
638 ; CHECK: stepc [[REG]] | |
639 ; CHECK: aih [[REG]], 1000000000 | |
640 ; CHECK: stepd [[REG]] | |
641 ; CHECK: br %r14 | |
642 %res1 = call i32 asm "stepa $0", "=h"() | |
643 %add1 = add i32 %res1, -32769 | |
644 %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %add1) | |
645 %add2 = add i32 %res2, 32768 | |
646 %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %add2) | |
647 %add3 = add i32 %res3, 1000000000 | |
648 call void asm sideeffect "stepd $0", "h"(i32 %add3) | |
649 ret void | |
650 } | |
651 | |
652 ; Test large immediate addition involving low registers. | |
653 define void @f30() { | |
654 ; CHECK-LABEL: f30: | |
655 ; CHECK: stepa [[REG:%r[0-5]]] | |
656 ; CHECK: afi [[REG]], -32769 | |
657 ; CHECK: stepb [[REG]] | |
658 ; CHECK: afi [[REG]], 32768 | |
659 ; CHECK: stepc [[REG]] | |
660 ; CHECK: afi [[REG]], 1000000000 | |
661 ; CHECK: stepd [[REG]] | |
662 ; CHECK: br %r14 | |
663 %res1 = call i32 asm "stepa $0", "=r"() | |
664 %add1 = add i32 %res1, -32769 | |
665 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %add1) | |
666 %add2 = add i32 %res2, 32768 | |
667 %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %add2) | |
668 %add3 = add i32 %res3, 1000000000 | |
669 call void asm sideeffect "stepd $0", "r"(i32 %add3) | |
670 ret void | |
671 } | |
672 | |
673 ; Test large immediate comparison involving high registers. | |
674 define i32 @f31() { | |
675 ; CHECK-LABEL: f31: | |
676 ; CHECK: stepa [[REG1:%r[0-5]]] | |
677 ; CHECK: cih [[REG1]], 1000000000 | |
678 ; CHECK: stepb [[REG2:%r[0-5]]] | |
679 ; CHECK: clih [[REG2]], 1000000000 | |
680 ; CHECK: br %r14 | |
681 %res1 = call i32 asm "stepa $0", "=h"() | |
682 %cmp1 = icmp sle i32 %res1, 1000000000 | |
683 %sel1 = select i1 %cmp1, i32 0, i32 1 | |
684 %res2 = call i32 asm "stepb $0, $1", "=h,r"(i32 %sel1) | |
685 %cmp2 = icmp ule i32 %res2, 1000000000 | |
686 %sel2 = select i1 %cmp2, i32 0, i32 1 | |
687 ret i32 %sel2 | |
688 } | |
689 | |
690 ; Test large immediate comparison involving low registers. | |
691 define i32 @f32() { | |
692 ; CHECK-LABEL: f32: | |
693 ; CHECK: stepa [[REG1:%r[0-5]]] | |
694 ; CHECK: cfi [[REG1]], 1000000000 | |
695 ; CHECK: stepb [[REG2:%r[0-5]]] | |
696 ; CHECK: clfi [[REG2]], 1000000000 | |
697 ; CHECK: br %r14 | |
698 %res1 = call i32 asm "stepa $0", "=r"() | |
699 %cmp1 = icmp sle i32 %res1, 1000000000 | |
700 %sel1 = select i1 %cmp1, i32 0, i32 1 | |
701 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %sel1) | |
702 %cmp2 = icmp ule i32 %res2, 1000000000 | |
703 %sel2 = select i1 %cmp2, i32 0, i32 1 | |
704 ret i32 %sel2 | |
705 } | |
706 | |
707 ; Test memory comparison involving high registers. | |
708 define void @f33(i32 *%ptr1, i32 *%ptr2) { | |
709 ; CHECK-LABEL: f33: | |
710 ; CHECK: stepa [[REG1:%r[0-5]]] | |
711 ; CHECK: chf [[REG1]], 0(%r2) | |
712 ; CHECK: stepb [[REG2:%r[0-5]]] | |
713 ; CHECK: clhf [[REG2]], 0(%r3) | |
714 ; CHECK: br %r14 | |
715 %res1 = call i32 asm "stepa $0", "=h"() | |
716 %load1 = load i32 *%ptr1 | |
717 %cmp1 = icmp sle i32 %res1, %load1 | |
718 %sel1 = select i1 %cmp1, i32 0, i32 1 | |
719 %res2 = call i32 asm "stepb $0, $1", "=h,r"(i32 %sel1) | |
720 %load2 = load i32 *%ptr2 | |
721 %cmp2 = icmp ule i32 %res2, %load2 | |
722 %sel2 = select i1 %cmp2, i32 0, i32 1 | |
723 store i32 %sel2, i32 *%ptr1 | |
724 ret void | |
725 } | |
726 | |
727 ; Test memory comparison involving low registers. | |
728 define void @f34(i32 *%ptr1, i32 *%ptr2) { | |
729 ; CHECK-LABEL: f34: | |
730 ; CHECK: stepa [[REG1:%r[0-5]]] | |
731 ; CHECK: c [[REG1]], 0(%r2) | |
732 ; CHECK: stepb [[REG2:%r[0-5]]] | |
733 ; CHECK: cl [[REG2]], 0(%r3) | |
734 ; CHECK: br %r14 | |
735 %res1 = call i32 asm "stepa $0", "=r"() | |
736 %load1 = load i32 *%ptr1 | |
737 %cmp1 = icmp sle i32 %res1, %load1 | |
738 %sel1 = select i1 %cmp1, i32 0, i32 1 | |
739 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %sel1) | |
740 %load2 = load i32 *%ptr2 | |
741 %cmp2 = icmp ule i32 %res2, %load2 | |
742 %sel2 = select i1 %cmp2, i32 0, i32 1 | |
743 store i32 %sel2, i32 *%ptr1 | |
744 ret void | |
745 } |