Home | History | Annotate | Download | only in SystemZ
      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