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 -no-integrated-as | FileCheck %s
5
6; Test loads and stores involving mixtures of high and low registers.
7define 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.
39define 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.
55define 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.
79define 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.
103define 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.
127define 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.
151define 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.
174define 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.
197define 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.
216define 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.
235define 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.
253define 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.
292define 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.
306define 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.
320define 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.
339define 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.
358define 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.
379define 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.
400define 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.
421define 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.
442define 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.
463define 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.
484define 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.
505define 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.
530define 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.
559define 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.
580define 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.
602define 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.
632define 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.
653define 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.
674define 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.
691define 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.
708define 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.
728define 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}
746