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 -mtriple=s390x-linux-gnu -mcpu=z196 -no-integrated-as | 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, i32 *%ptr1, i64 1024
     20   %ptr4 = getelementptr i32, i32 *%ptr2, i64 131071
     21   %old1 = load i32 , i32 *%ptr1
     22   %old2 = load i32 , i32 *%ptr2
     23   %old3 = load i32 , i32 *%ptr3
     24   %old4 = load i32 , 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, i8 *%ptr1, i64 4096
     64   %ptr4 = getelementptr i8, i8 *%ptr2, i64 524287
     65   %val1 = load i8 , i8 *%ptr1
     66   %val2 = load i8 , i8 *%ptr2
     67   %val3 = load i8 , i8 *%ptr3
     68   %val4 = load i8 , 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, i16 *%ptr1, i64 2048
     88   %ptr4 = getelementptr i16, i16 *%ptr2, i64 262143
     89   %val1 = load i16 , i16 *%ptr1
     90   %val2 = load i16 , i16 *%ptr2
     91   %val3 = load i16 , i16 *%ptr3
     92   %val4 = load i16 , 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, i8 *%ptr1, i64 4096
    112   %ptr4 = getelementptr i8, i8 *%ptr2, i64 524287
    113   %val1 = load i8 , i8 *%ptr1
    114   %val2 = load i8 , i8 *%ptr2
    115   %val3 = load i8 , i8 *%ptr3
    116   %val4 = load i8 , 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, i16 *%ptr1, i64 2048
    136   %ptr4 = getelementptr i16, i16 *%ptr2, i64 262143
    137   %val1 = load i16 , i16 *%ptr1
    138   %val2 = load i16 , i16 *%ptr2
    139   %val3 = load i16 , i16 *%ptr3
    140   %val4 = load i16 , 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, i8 *%ptr1, i64 4096
    165   %ptr4 = getelementptr i8, 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, i16 *%ptr1, i64 2048
    188   %ptr4 = getelementptr i16, 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 , 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 , 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 , 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 , 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