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. 8 define 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. 40 define 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. 56 define 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. 80 define 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. 104 define 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. 128 define 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. 152 define 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. 175 define 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. 198 define 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. 217 define 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. 236 define 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. 254 define 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. 294 define 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. 310 define 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. 325 define 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. 344 define 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. 363 define 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. 384 define 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. 405 define 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. 426 define 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. 447 define 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. 468 define 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. 489 define 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. 510 define 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. 535 define 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. 564 define 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. 585 define 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. 607 define 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. 637 define 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. 658 define 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. 679 define 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. 696 define 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. 713 define 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. 733 define 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. 753 define 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. 789 define 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 824 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone 825 826