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 }