blob: 1c125fc472884df3bd97308f852fbcc79fb507d8 [file] [log] [blame]
Richard Sandiford0755c932013-10-01 11:26:28 +00001; Test high-word operations, using "h" constraints to force a high
2; register and "r" constraints to force a low register.
3;
Jonas Paulsson28fa48d2015-10-10 07:20:23 +00004; RUN: llc < %s -verify-machineinstrs -mtriple=s390x-linux-gnu -mcpu=z196 \
5; RUN: -no-integrated-as | FileCheck %s
Richard Sandiford0755c932013-10-01 11:26:28 +00006
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
David Blaikie79e6c742015-02-27 19:29:02 +000020 %ptr3 = getelementptr i32, i32 *%ptr1, i64 1024
21 %ptr4 = getelementptr i32, i32 *%ptr2, i64 131071
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000022 %old1 = load i32, i32 *%ptr1
23 %old2 = load i32, i32 *%ptr2
24 %old3 = load i32, i32 *%ptr3
25 %old4 = load i32, i32 *%ptr4
Richard Sandiford0755c932013-10-01 11:26:28 +000026 %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}
Richard Sandiford89e160d2013-10-01 12:11:47 +000054
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
David Blaikie79e6c742015-02-27 19:29:02 +000064 %ptr3 = getelementptr i8, i8 *%ptr1, i64 4096
65 %ptr4 = getelementptr i8, i8 *%ptr2, i64 524287
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000066 %val1 = load i8, i8 *%ptr1
67 %val2 = load i8, i8 *%ptr2
68 %val3 = load i8, i8 *%ptr3
69 %val4 = load i8, i8 *%ptr4
Richard Sandiford89e160d2013-10-01 12:11:47 +000070 %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
David Blaikie79e6c742015-02-27 19:29:02 +000088 %ptr3 = getelementptr i16, i16 *%ptr1, i64 2048
89 %ptr4 = getelementptr i16, i16 *%ptr2, i64 262143
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000090 %val1 = load i16, i16 *%ptr1
91 %val2 = load i16, i16 *%ptr2
92 %val3 = load i16, i16 *%ptr3
93 %val4 = load i16, i16 *%ptr4
Richard Sandiford89e160d2013-10-01 12:11:47 +000094 %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}
Richard Sandiford0d46b1a2013-10-01 12:19:08 +0000102
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
David Blaikie79e6c742015-02-27 19:29:02 +0000112 %ptr3 = getelementptr i8, i8 *%ptr1, i64 4096
113 %ptr4 = getelementptr i8, i8 *%ptr2, i64 524287
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000114 %val1 = load i8, i8 *%ptr1
115 %val2 = load i8, i8 *%ptr2
116 %val3 = load i8, i8 *%ptr3
117 %val4 = load i8, i8 *%ptr4
Richard Sandiford0d46b1a2013-10-01 12:19:08 +0000118 %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
David Blaikie79e6c742015-02-27 19:29:02 +0000136 %ptr3 = getelementptr i16, i16 *%ptr1, i64 2048
137 %ptr4 = getelementptr i16, i16 *%ptr2, i64 262143
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000138 %val1 = load i16, i16 *%ptr1
139 %val2 = load i16, i16 *%ptr2
140 %val3 = load i16, i16 *%ptr3
141 %val4 = load i16, i16 *%ptr4
Richard Sandiford0d46b1a2013-10-01 12:19:08 +0000142 %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}
Richard Sandiford5469c392013-10-01 12:22:49 +0000150
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
David Blaikie79e6c742015-02-27 19:29:02 +0000165 %ptr3 = getelementptr i8, i8 *%ptr1, i64 4096
166 %ptr4 = getelementptr i8, i8 *%ptr2, i64 524287
Richard Sandiford5469c392013-10-01 12:22:49 +0000167 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
David Blaikie79e6c742015-02-27 19:29:02 +0000188 %ptr3 = getelementptr i16, i16 *%ptr1, i64 2048
189 %ptr4 = getelementptr i16, i16 *%ptr2, i64 262143
Richard Sandiford5469c392013-10-01 12:22:49 +0000190 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}
Richard Sandiford21235a22013-10-01 12:49:07 +0000196
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}
Richard Sandiford01240232013-10-01 13:02:28 +0000234
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}
Richard Sandiford7c5c0ea2013-10-01 13:10:16 +0000291
292; Test selects involving high registers.
Ulrich Weigandfb566862018-04-30 15:49:27 +0000293; Note that we prefer to use a LOCR and move the result to a high register.
Richard Sandiford7c5c0ea2013-10-01 13:10:16 +0000294define void @f13(i32 %x, i32 %y) {
295; CHECK-LABEL: f13:
Ulrich Weigandfb566862018-04-30 15:49:27 +0000296; 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
Richard Sandiford7c5c0ea2013-10-01 13:10:16 +0000301; CHECK: blah [[REG]]
302; CHECK: br %r14
Kyle Buttefe56fe2017-01-11 19:55:19 +0000303 %cmp = icmp eq i32 %x, 0
Richard Sandiford7c5c0ea2013-10-01 13:10:16 +0000304 %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:
Ulrich Weigandfb566862018-04-30 15:49:27 +0000312; 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]]
Richard Sandiford7c5c0ea2013-10-01 13:10:16 +0000316; CHECK: blah [[REG]]
317; CHECK: br %r14
Kyle Buttefe56fe2017-01-11 19:55:19 +0000318 %cmp = icmp eq i32 %x, 0
Richard Sandiford7c5c0ea2013-10-01 13:10:16 +0000319 %val = select i1 %cmp, i32 0, i32 2102030405
320 call void asm sideeffect "blah $0", "r"(i32 %val)
321 ret void
322}
Richard Sandiford1a569312013-10-01 13:18:56 +0000323
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}
Richard Sandiford6e96ac62013-10-01 13:22:41 +0000361
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}
Richard Sandiford5718dac2013-10-01 14:08:44 +0000403
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}
Richard Sandiford70284282013-10-01 14:20:41 +0000445
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}
Richard Sandiford3ad5a152013-10-01 14:36:20 +0000508
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}
Richard Sandiford2cac7632013-10-01 14:41:52 +0000533
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}
Richard Sandiford42a694f2013-10-01 14:53:46 +0000562
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}
Richard Sandiforda9ac0e02013-10-01 14:56:23 +0000677
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}
Richard Sandifordb63e3002013-10-01 15:00:44 +0000711
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"()
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000721 %load1 = load i32, i32 *%ptr1
Richard Sandifordb63e3002013-10-01 15:00:44 +0000722 %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)
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000725 %load2 = load i32, i32 *%ptr2
Richard Sandifordb63e3002013-10-01 15:00:44 +0000726 %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"()
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000741 %load1 = load i32, i32 *%ptr1
Richard Sandifordb63e3002013-10-01 15:00:44 +0000742 %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)
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000745 %load2 = load i32, i32 *%ptr2
Richard Sandifordb63e3002013-10-01 15:00:44 +0000746 %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}
Ulrich Weigandc3ec80f2018-04-30 17:54:28 +0000751
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