• 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.
293; Note that we prefer to use a LOCR and move the result to a high register.
294define void @f13(i32 %x, i32 %y) {
295; CHECK-LABEL: f13:
296; CHECK-DAG: chi %r2, 0
297; CHECK-DAG: iilf [[REG1:%r[0-5]]], 2102030405
298; CHECK-DAG: lhi [[REG2:%r[0-5]]], 0
299; CHECK: locre [[REG1]], [[REG2]]
300; CHECK: risbhg [[REG:%r[0-5]]], [[REG1]], 0, 159, 32
301; CHECK: blah [[REG]]
302; CHECK: br %r14
303  %cmp = icmp eq i32 %x, 0
304  %val = select i1 %cmp, i32 0, i32 2102030405
305  call void asm sideeffect "blah $0", "h"(i32 %val)
306  ret void
307}
308
309; Test selects involving low registers.
310define void @f14(i32 %x, i32 %y) {
311; CHECK-LABEL: f14:
312; CHECK-DAG: chi %r2, 0
313; CHECK-DAG: iilf [[REG:%r[0-5]]], 2102030405
314; CHECK-DAG: lhi [[REG1:%r[0-5]]], 0
315; CHECK: locre [[REG]], [[REG1]]
316; CHECK: blah [[REG]]
317; CHECK: br %r14
318  %cmp = icmp eq i32 %x, 0
319  %val = select i1 %cmp, i32 0, i32 2102030405
320  call void asm sideeffect "blah $0", "r"(i32 %val)
321  ret void
322}
323
324; Test immediate insertion involving high registers.
325define void @f15() {
326; CHECK-LABEL: f15:
327; CHECK: stepa [[REG:%r[0-5]]]
328; CHECK: iihh [[REG]], 4660
329; CHECK: stepb [[REG]]
330; CHECK: iihl [[REG]], 34661
331; CHECK: stepc [[REG]]
332; CHECK: br %r14
333  %res1 = call i32 asm "stepa $0", "=h"()
334  %and1 = and i32 %res1, 65535
335  %or1 = or i32 %and1, 305397760
336  %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %or1)
337  %and2 = and i32 %res2, -65536
338  %or2 = or i32 %and2, 34661
339  call void asm sideeffect "stepc $0", "h"(i32 %or2)
340  ret void
341}
342
343; Test immediate insertion involving low registers.
344define void @f16() {
345; CHECK-LABEL: f16:
346; CHECK: stepa [[REG:%r[0-5]]]
347; CHECK: iilh [[REG]], 4660
348; CHECK: stepb [[REG]]
349; CHECK: iill [[REG]], 34661
350; CHECK: stepc [[REG]]
351; CHECK: br %r14
352  %res1 = call i32 asm "stepa $0", "=r"()
353  %and1 = and i32 %res1, 65535
354  %or1 = or i32 %and1, 305397760
355  %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %or1)
356  %and2 = and i32 %res2, -65536
357  %or2 = or i32 %and2, 34661
358  call void asm sideeffect "stepc $0", "r"(i32 %or2)
359  ret void
360}
361
362; Test immediate OR involving high registers.
363define void @f17() {
364; CHECK-LABEL: f17:
365; CHECK: stepa [[REG:%r[0-5]]]
366; CHECK: oihh [[REG]], 4660
367; CHECK: stepb [[REG]]
368; CHECK: oihl [[REG]], 34661
369; CHECK: stepc [[REG]]
370; CHECK: oihf [[REG]], 12345678
371; CHECK: stepd [[REG]]
372; CHECK: br %r14
373  %res1 = call i32 asm "stepa $0", "=h"()
374  %or1 = or i32 %res1, 305397760
375  %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %or1)
376  %or2 = or i32 %res2, 34661
377  %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %or2)
378  %or3 = or i32 %res3, 12345678
379  call void asm sideeffect "stepd $0", "h"(i32 %or3)
380  ret void
381}
382
383; Test immediate OR involving low registers.
384define void @f18() {
385; CHECK-LABEL: f18:
386; CHECK: stepa [[REG:%r[0-5]]]
387; CHECK: oilh [[REG]], 4660
388; CHECK: stepb [[REG]]
389; CHECK: oill [[REG]], 34661
390; CHECK: stepc [[REG]]
391; CHECK: oilf [[REG]], 12345678
392; CHECK: stepd [[REG]]
393; CHECK: br %r14
394  %res1 = call i32 asm "stepa $0", "=r"()
395  %or1 = or i32 %res1, 305397760
396  %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %or1)
397  %or2 = or i32 %res2, 34661
398  %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %or2)
399  %or3 = or i32 %res3, 12345678
400  call void asm sideeffect "stepd $0", "r"(i32 %or3)
401  ret void
402}
403
404; Test immediate XOR involving high registers.
405define void @f19() {
406; CHECK-LABEL: f19:
407; CHECK: stepa [[REG:%r[0-5]]]
408; CHECK: xihf [[REG]], 305397760
409; CHECK: stepb [[REG]]
410; CHECK: xihf [[REG]], 34661
411; CHECK: stepc [[REG]]
412; CHECK: xihf [[REG]], 12345678
413; CHECK: stepd [[REG]]
414; CHECK: br %r14
415  %res1 = call i32 asm "stepa $0", "=h"()
416  %xor1 = xor i32 %res1, 305397760
417  %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %xor1)
418  %xor2 = xor i32 %res2, 34661
419  %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %xor2)
420  %xor3 = xor i32 %res3, 12345678
421  call void asm sideeffect "stepd $0", "h"(i32 %xor3)
422  ret void
423}
424
425; Test immediate XOR involving low registers.
426define void @f20() {
427; CHECK-LABEL: f20:
428; CHECK: stepa [[REG:%r[0-5]]]
429; CHECK: xilf [[REG]], 305397760
430; CHECK: stepb [[REG]]
431; CHECK: xilf [[REG]], 34661
432; CHECK: stepc [[REG]]
433; CHECK: xilf [[REG]], 12345678
434; CHECK: stepd [[REG]]
435; CHECK: br %r14
436  %res1 = call i32 asm "stepa $0", "=r"()
437  %xor1 = xor i32 %res1, 305397760
438  %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %xor1)
439  %xor2 = xor i32 %res2, 34661
440  %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %xor2)
441  %xor3 = xor i32 %res3, 12345678
442  call void asm sideeffect "stepd $0", "r"(i32 %xor3)
443  ret void
444}
445
446; Test two-operand immediate AND involving high registers.
447define void @f21() {
448; CHECK-LABEL: f21:
449; CHECK: stepa [[REG:%r[0-5]]]
450; CHECK: nihh [[REG]], 4096
451; CHECK: stepb [[REG]]
452; CHECK: nihl [[REG]], 57536
453; CHECK: stepc [[REG]]
454; CHECK: nihf [[REG]], 12345678
455; CHECK: stepd [[REG]]
456; CHECK: br %r14
457  %res1 = call i32 asm "stepa $0", "=h"()
458  %and1 = and i32 %res1, 268500991
459  %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %and1)
460  %and2 = and i32 %res2, -8000
461  %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %and2)
462  %and3 = and i32 %res3, 12345678
463  call void asm sideeffect "stepd $0", "h"(i32 %and3)
464  ret void
465}
466
467; Test two-operand immediate AND involving low registers.
468define void @f22() {
469; CHECK-LABEL: f22:
470; CHECK: stepa [[REG:%r[0-5]]]
471; CHECK: nilh [[REG]], 4096
472; CHECK: stepb [[REG]]
473; CHECK: nill [[REG]], 57536
474; CHECK: stepc [[REG]]
475; CHECK: nilf [[REG]], 12345678
476; CHECK: stepd [[REG]]
477; CHECK: br %r14
478  %res1 = call i32 asm "stepa $0", "=r"()
479  %and1 = and i32 %res1, 268500991
480  %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %and1)
481  %and2 = and i32 %res2, -8000
482  %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %and2)
483  %and3 = and i32 %res3, 12345678
484  call void asm sideeffect "stepd $0", "r"(i32 %and3)
485  ret void
486}
487
488; Test three-operand immediate AND involving mixtures of low and high registers.
489define i32 @f23(i32 %old) {
490; CHECK-LABEL: f23:
491; CHECK-DAG: risblg [[REG1:%r[0-5]]], %r2, 28, 158, 0
492; CHECK-DAG: risbhg [[REG2:%r[0-5]]], %r2, 24, 158, 32
493; CHECK: stepa %r2, [[REG1]], [[REG2]]
494; CHECK-DAG: risbhg [[REG3:%r[0-5]]], [[REG2]], 25, 159, 0
495; CHECK-DAG: risblg %r2, [[REG2]], 24, 152, 32
496; CHECK: stepb [[REG2]], [[REG3]], %r2
497; CHECK: br %r14
498  %and1 = and i32 %old, 14
499  %and2 = and i32 %old, 254
500  %res1 = call i32 asm "stepa $1, $2, $3",
501                       "=h,r,r,0"(i32 %old, i32 %and1, i32 %and2)
502  %and3 = and i32 %res1, 127
503  %and4 = and i32 %res1, 128
504  %res2 = call i32 asm "stepb $1, $2, $3",
505                       "=r,h,h,0"(i32 %res1, i32 %and3, i32 %and4)
506  ret i32 %res2
507}
508
509; Test RISB[LH]G insertions involving mixtures of high and low registers.
510define i32 @f24(i32 %old) {
511; CHECK-LABEL: f24:
512; CHECK-DAG: risblg [[REG1:%r[0-5]]], %r2, 28, 158, 1
513; CHECK-DAG: risbhg [[REG2:%r[0-5]]], %r2, 24, 158, 29
514; CHECK: stepa %r2, [[REG1]], [[REG2]]
515; CHECK-DAG: risbhg [[REG3:%r[0-5]]], [[REG2]], 25, 159, 62
516; CHECK-DAG: risblg %r2, [[REG2]], 24, 152, 37
517; CHECK: stepb [[REG2]], [[REG3]], %r2
518; CHECK: br %r14
519  %shift1 = shl i32 %old, 1
520  %and1 = and i32 %shift1, 14
521  %shift2 = lshr i32 %old, 3
522  %and2 = and i32 %shift2, 254
523  %res1 = call i32 asm "stepa $1, $2, $3",
524                       "=h,r,r,0"(i32 %old, i32 %and1, i32 %and2)
525  %shift3 = lshr i32 %res1, 2
526  %and3 = and i32 %shift3, 127
527  %shift4 = shl i32 %res1, 5
528  %and4 = and i32 %shift4, 128
529  %res2 = call i32 asm "stepb $1, $2, $3",
530                       "=r,h,h,0"(i32 %res1, i32 %and3, i32 %and4)
531  ret i32 %res2
532}
533
534; Test TMxx involving mixtures of high and low registers.
535define i32 @f25(i32 %old) {
536; CHECK-LABEL: f25:
537; CHECK-DAG: tmll %r2, 1
538; CHECK-DAG: tmlh %r2, 1
539; CHECK: stepa [[REG1:%r[0-5]]],
540; CHECK-DAG: tmhl [[REG1]], 1
541; CHECK-DAG: tmhh [[REG1]], 1
542; CHECK: stepb %r2,
543; CHECK: br %r14
544  %and1 = and i32 %old, 1
545  %and2 = and i32 %old, 65536
546  %cmp1 = icmp eq i32 %and1, 0
547  %cmp2 = icmp eq i32 %and2, 0
548  %sel1 = select i1 %cmp1, i32 100, i32 200
549  %sel2 = select i1 %cmp2, i32 100, i32 200
550  %res1 = call i32 asm "stepa $0, $1, $2",
551                       "=h,r,r"(i32 %sel1, i32 %sel2)
552  %and3 = and i32 %res1, 1
553  %and4 = and i32 %res1, 65536
554  %cmp3 = icmp eq i32 %and3, 0
555  %cmp4 = icmp eq i32 %and4, 0
556  %sel3 = select i1 %cmp3, i32 100, i32 200
557  %sel4 = select i1 %cmp4, i32 100, i32 200
558  %res2 = call i32 asm "stepb $0, $1, $2",
559                       "=r,h,h"(i32 %sel3, i32 %sel4)
560  ret i32 %res2
561}
562
563; Test two-operand halfword immediate addition involving high registers.
564define void @f26() {
565; CHECK-LABEL: f26:
566; CHECK: stepa [[REG:%r[0-5]]]
567; CHECK: aih [[REG]], -32768
568; CHECK: stepb [[REG]]
569; CHECK: aih [[REG]], 1
570; CHECK: stepc [[REG]]
571; CHECK: aih [[REG]], 32767
572; CHECK: stepd [[REG]]
573; CHECK: br %r14
574  %res1 = call i32 asm "stepa $0", "=h"()
575  %add1 = add i32 %res1, -32768
576  %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %add1)
577  %add2 = add i32 %res2, 1
578  %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %add2)
579  %add3 = add i32 %res3, 32767
580  call void asm sideeffect "stepd $0", "h"(i32 %add3)
581  ret void
582}
583
584; Test two-operand halfword immediate addition involving low registers.
585define void @f27() {
586; CHECK-LABEL: f27:
587; CHECK: stepa [[REG:%r[0-5]]]
588; CHECK: ahi [[REG]], -32768
589; CHECK: stepb [[REG]]
590; CHECK: ahi [[REG]], 1
591; CHECK: stepc [[REG]]
592; CHECK: ahi [[REG]], 32767
593; CHECK: stepd [[REG]]
594; CHECK: br %r14
595  %res1 = call i32 asm "stepa $0", "=r"()
596  %add1 = add i32 %res1, -32768
597  %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %add1)
598  %add2 = add i32 %res2, 1
599  %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %add2)
600  %add3 = add i32 %res3, 32767
601  call void asm sideeffect "stepd $0", "r"(i32 %add3)
602  ret void
603}
604
605; Test three-operand halfword immediate addition involving mixtures of low
606; and high registers.  RISBHG/AIH would be OK too, instead of AHIK/RISBHG.
607define i32 @f28(i32 %old) {
608; CHECK-LABEL: f28:
609; CHECK: ahik [[REG1:%r[0-5]]], %r2, 14
610; CHECK: stepa %r2, [[REG1]]
611; CHECK: ahik [[TMP:%r[0-5]]], [[REG1]], 254
612; CHECK: risbhg [[REG2:%r[0-5]]], [[TMP]], 0, 159, 32
613; CHECK: stepb [[REG1]], [[REG2]]
614; CHECK: risbhg [[REG3:%r[0-5]]], [[REG2]], 0, 159, 0
615; CHECK: aih [[REG3]], 127
616; CHECK: stepc [[REG2]], [[REG3]]
617; CHECK: risblg %r2, [[REG3]], 0, 159, 32
618; CHECK: ahi %r2, 128
619; CHECK: stepd [[REG3]], %r2
620; CHECK: br %r14
621  %add1 = add i32 %old, 14
622  %res1 = call i32 asm "stepa $1, $2",
623                       "=r,r,0"(i32 %old, i32 %add1)
624  %add2 = add i32 %res1, 254
625  %res2 = call i32 asm "stepb $1, $2",
626                       "=h,r,0"(i32 %res1, i32 %add2)
627  %add3 = add i32 %res2, 127
628  %res3 = call i32 asm "stepc $1, $2",
629                       "=h,h,0"(i32 %res2, i32 %add3)
630  %add4 = add i32 %res3, 128
631  %res4 = call i32 asm "stepd $1, $2",
632                       "=r,h,0"(i32 %res3, i32 %add4)
633  ret i32 %res4
634}
635
636; Test large immediate addition involving high registers.
637define void @f29() {
638; CHECK-LABEL: f29:
639; CHECK: stepa [[REG:%r[0-5]]]
640; CHECK: aih [[REG]], -32769
641; CHECK: stepb [[REG]]
642; CHECK: aih [[REG]], 32768
643; CHECK: stepc [[REG]]
644; CHECK: aih [[REG]], 1000000000
645; CHECK: stepd [[REG]]
646; CHECK: br %r14
647  %res1 = call i32 asm "stepa $0", "=h"()
648  %add1 = add i32 %res1, -32769
649  %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %add1)
650  %add2 = add i32 %res2, 32768
651  %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %add2)
652  %add3 = add i32 %res3, 1000000000
653  call void asm sideeffect "stepd $0", "h"(i32 %add3)
654  ret void
655}
656
657; Test large immediate addition involving low registers.
658define void @f30() {
659; CHECK-LABEL: f30:
660; CHECK: stepa [[REG:%r[0-5]]]
661; CHECK: afi [[REG]], -32769
662; CHECK: stepb [[REG]]
663; CHECK: afi [[REG]], 32768
664; CHECK: stepc [[REG]]
665; CHECK: afi [[REG]], 1000000000
666; CHECK: stepd [[REG]]
667; CHECK: br %r14
668  %res1 = call i32 asm "stepa $0", "=r"()
669  %add1 = add i32 %res1, -32769
670  %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %add1)
671  %add2 = add i32 %res2, 32768
672  %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %add2)
673  %add3 = add i32 %res3, 1000000000
674  call void asm sideeffect "stepd $0", "r"(i32 %add3)
675  ret void
676}
677
678; Test large immediate comparison involving high registers.
679define i32 @f31() {
680; CHECK-LABEL: f31:
681; CHECK: stepa [[REG1:%r[0-5]]]
682; CHECK: cih [[REG1]], 1000000000
683; CHECK: stepb [[REG2:%r[0-5]]]
684; CHECK: clih [[REG2]], 1000000000
685; CHECK: br %r14
686  %res1 = call i32 asm "stepa $0", "=h"()
687  %cmp1 = icmp sle i32 %res1, 1000000000
688  %sel1 = select i1 %cmp1, i32 0, i32 1
689  %res2 = call i32 asm "stepb $0, $1", "=h,r"(i32 %sel1)
690  %cmp2 = icmp ule i32 %res2, 1000000000
691  %sel2 = select i1 %cmp2, i32 0, i32 1
692  ret i32 %sel2
693}
694
695; Test large immediate comparison involving low registers.
696define i32 @f32() {
697; CHECK-LABEL: f32:
698; CHECK: stepa [[REG1:%r[0-5]]]
699; CHECK: cfi [[REG1]], 1000000000
700; CHECK: stepb [[REG2:%r[0-5]]]
701; CHECK: clfi [[REG2]], 1000000000
702; CHECK: br %r14
703  %res1 = call i32 asm "stepa $0", "=r"()
704  %cmp1 = icmp sle i32 %res1, 1000000000
705  %sel1 = select i1 %cmp1, i32 0, i32 1
706  %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %sel1)
707  %cmp2 = icmp ule i32 %res2, 1000000000
708  %sel2 = select i1 %cmp2, i32 0, i32 1
709  ret i32 %sel2
710}
711
712; Test memory comparison involving high registers.
713define void @f33(i32 *%ptr1, i32 *%ptr2) {
714; CHECK-LABEL: f33:
715; CHECK: stepa [[REG1:%r[0-5]]]
716; CHECK: chf [[REG1]], 0(%r2)
717; CHECK: stepb [[REG2:%r[0-5]]]
718; CHECK: clhf [[REG2]], 0(%r3)
719; CHECK: br %r14
720  %res1 = call i32 asm "stepa $0", "=h"()
721  %load1 = load i32, i32 *%ptr1
722  %cmp1 = icmp sle i32 %res1, %load1
723  %sel1 = select i1 %cmp1, i32 0, i32 1
724  %res2 = call i32 asm "stepb $0, $1", "=h,r"(i32 %sel1)
725  %load2 = load i32, i32 *%ptr2
726  %cmp2 = icmp ule i32 %res2, %load2
727  %sel2 = select i1 %cmp2, i32 0, i32 1
728  store i32 %sel2, i32 *%ptr1
729  ret void
730}
731
732; Test memory comparison involving low registers.
733define void @f34(i32 *%ptr1, i32 *%ptr2) {
734; CHECK-LABEL: f34:
735; CHECK: stepa [[REG1:%r[0-5]]]
736; CHECK: c [[REG1]], 0(%r2)
737; CHECK: stepb [[REG2:%r[0-5]]]
738; CHECK: cl [[REG2]], 0(%r3)
739; CHECK: br %r14
740  %res1 = call i32 asm "stepa $0", "=r"()
741  %load1 = load i32, i32 *%ptr1
742  %cmp1 = icmp sle i32 %res1, %load1
743  %sel1 = select i1 %cmp1, i32 0, i32 1
744  %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %sel1)
745  %load2 = load i32, i32 *%ptr2
746  %cmp2 = icmp ule i32 %res2, %load2
747  %sel2 = select i1 %cmp2, i32 0, i32 1
748  store i32 %sel2, i32 *%ptr1
749  ret void
750}
751
752; Test immediate addition with overflow involving high registers.
753define void @f35() {
754; CHECK-LABEL: f35:
755; CHECK: stepa [[REG:%r[0-5]]]
756; CHECK: aih [[REG]], -32768
757; CHECK: ipm [[REGCC:%r[0-5]]]
758; CHECK: afi [[REGCC]], 1342177280
759; CHECK: srl [[REGCC]], 31
760; CHECK: stepb [[REG]], [[REGCC]]
761; CHECK: aih [[REG]], 1
762; CHECK: ipm [[REGCC:%r[0-5]]]
763; CHECK: afi [[REGCC]], 1342177280
764; CHECK: srl [[REGCC]], 31
765; CHECK: stepc [[REG]], [[REGCC]]
766; CHECK: aih [[REG]], 32767
767; CHECK: ipm [[REGCC:%r[0-5]]]
768; CHECK: afi [[REGCC]], 1342177280
769; CHECK: srl [[REGCC]], 31
770; CHECK: stepd [[REG]], [[REGCC]]
771; CHECK: br %r14
772  %res1 = call i32 asm "stepa $0", "=h"()
773  %t1 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res1, i32 -32768)
774  %val1 = extractvalue {i32, i1} %t1, 0
775  %obit1 = extractvalue {i32, i1} %t1, 1
776  %res2 = call i32 asm "stepb $0, $2", "=h,h,d"(i32 %val1, i1 %obit1)
777  %t2 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res2, i32 1)
778  %val2 = extractvalue {i32, i1} %t2, 0
779  %obit2 = extractvalue {i32, i1} %t2, 1
780  %res3 = call i32 asm "stepc $0, $2", "=h,h,d"(i32 %val2, i1 %obit2)
781  %t3 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res3, i32 32767)
782  %val3 = extractvalue {i32, i1} %t3, 0
783  %obit3 = extractvalue {i32, i1} %t3, 1
784  call void asm sideeffect "stepd $0, $1", "h,d"(i32 %val3, i1 %obit3)
785  ret void
786}
787
788; Test large immediate addition with overflow involving high registers.
789define void @f36() {
790; CHECK-LABEL: f36:
791; CHECK: stepa [[REG:%r[0-5]]]
792; CHECK: aih [[REG]], -2147483648
793; CHECK: ipm [[REGCC:%r[0-5]]]
794; CHECK: afi [[REGCC]], 1342177280
795; CHECK: srl [[REGCC]], 31
796; CHECK: stepb [[REG]], [[REGCC]]
797; CHECK: aih [[REG]], 1
798; CHECK: ipm [[REGCC:%r[0-5]]]
799; CHECK: afi [[REGCC]], 1342177280
800; CHECK: srl [[REGCC]], 31
801; CHECK: stepc [[REG]], [[REGCC]]
802; CHECK: aih [[REG]], 2147483647
803; CHECK: ipm [[REGCC:%r[0-5]]]
804; CHECK: afi [[REGCC]], 1342177280
805; CHECK: srl [[REGCC]], 31
806; CHECK: stepd [[REG]], [[REGCC]]
807; CHECK: br %r14
808  %res1 = call i32 asm "stepa $0", "=h"()
809  %t1 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res1, i32 -2147483648)
810  %val1 = extractvalue {i32, i1} %t1, 0
811  %obit1 = extractvalue {i32, i1} %t1, 1
812  %res2 = call i32 asm "stepb $0, $2", "=h,h,d"(i32 %val1, i1 %obit1)
813  %t2 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res2, i32 1)
814  %val2 = extractvalue {i32, i1} %t2, 0
815  %obit2 = extractvalue {i32, i1} %t2, 1
816  %res3 = call i32 asm "stepc $0, $2", "=h,h,d"(i32 %val2, i1 %obit2)
817  %t3 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res3, i32 2147483647)
818  %val3 = extractvalue {i32, i1} %t3, 0
819  %obit3 = extractvalue {i32, i1} %t3, 1
820  call void asm sideeffect "stepd $0, $1", "h,d"(i32 %val3, i1 %obit3)
821  ret void
822}
823
824declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
825
826