1 ; Test high-word operations, using "h" constraints to force a high
2 ; register and "r" constraints to force a low register.
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
6 ; Test loads and stores involving mixtures of high and low registers.
7 define void @f1(i32 *%ptr1, i32 *%ptr2) {
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)
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
38 ; Test moves involving mixtures of high and low registers.
39 define i32 @f2(i32 %old) {
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
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)
54 ; Test sign-extending 8-bit loads into mixtures of high and low registers.
55 define void @f3(i8 *%ptr1, i8 *%ptr2) {
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]]
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)
78 ; Test sign-extending 16-bit loads into mixtures of high and low registers.
79 define void @f4(i16 *%ptr1, i16 *%ptr2) {
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]]
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)
102 ; Test zero-extending 8-bit loads into mixtures of high and low registers.
103 define void @f5(i8 *%ptr1, i8 *%ptr2) {
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]]
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)
126 ; Test zero-extending 16-bit loads into mixtures of high and low registers.
127 define void @f6(i16 *%ptr1, i16 *%ptr2) {
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]]
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)
150 ; Test truncating stores of high and low registers into 8-bit memory.
151 define void @f7(i8 *%ptr1, i8 *%ptr2) {
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)
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
173 ; Test truncating stores of high and low registers into 16-bit memory.
174 define void @f8(i16 *%ptr1, i16 *%ptr2) {
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)
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
196 ; Test zero extensions from 8 bits between mixtures of high and low registers.
197 define i32 @f9(i8 %val1, i8 %val2) {
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
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
215 ; Test zero extensions from 16 bits between mixtures of high and low registers.
216 define i32 @f10(i16 %val1, i16 %val2) {
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
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