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