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