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