Richard Sandiford | 0755c93 | 2013-10-01 11:26:28 +0000 | [diff] [blame] | 1 | ; Test high-word operations, using "h" constraints to force a high |
| 2 | ; register and "r" constraints to force a low register. |
| 3 | ; |
Jonas Paulsson | 28fa48d | 2015-10-10 07:20:23 +0000 | [diff] [blame] | 4 | ; RUN: llc < %s -verify-machineinstrs -mtriple=s390x-linux-gnu -mcpu=z196 \ |
| 5 | ; RUN: -no-integrated-as | FileCheck %s |
Richard Sandiford | 0755c93 | 2013-10-01 11:26:28 +0000 | [diff] [blame] | 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 |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 20 | %ptr3 = getelementptr i32, i32 *%ptr1, i64 1024 |
| 21 | %ptr4 = getelementptr i32, i32 *%ptr2, i64 131071 |
Ulrich Weigand | 9dd23b8 | 2018-07-20 12:12:10 +0000 | [diff] [blame] | 22 | %old1 = load i32, i32 *%ptr1 |
| 23 | %old2 = load i32, i32 *%ptr2 |
| 24 | %old3 = load i32, i32 *%ptr3 |
| 25 | %old4 = load i32, i32 *%ptr4 |
Richard Sandiford | 0755c93 | 2013-10-01 11:26:28 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 89e160d | 2013-10-01 12:11:47 +0000 | [diff] [blame] | 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 |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 64 | %ptr3 = getelementptr i8, i8 *%ptr1, i64 4096 |
| 65 | %ptr4 = getelementptr i8, i8 *%ptr2, i64 524287 |
Ulrich Weigand | 9dd23b8 | 2018-07-20 12:12:10 +0000 | [diff] [blame] | 66 | %val1 = load i8, i8 *%ptr1 |
| 67 | %val2 = load i8, i8 *%ptr2 |
| 68 | %val3 = load i8, i8 *%ptr3 |
| 69 | %val4 = load i8, i8 *%ptr4 |
Richard Sandiford | 89e160d | 2013-10-01 12:11:47 +0000 | [diff] [blame] | 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 |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 88 | %ptr3 = getelementptr i16, i16 *%ptr1, i64 2048 |
| 89 | %ptr4 = getelementptr i16, i16 *%ptr2, i64 262143 |
Ulrich Weigand | 9dd23b8 | 2018-07-20 12:12:10 +0000 | [diff] [blame] | 90 | %val1 = load i16, i16 *%ptr1 |
| 91 | %val2 = load i16, i16 *%ptr2 |
| 92 | %val3 = load i16, i16 *%ptr3 |
| 93 | %val4 = load i16, i16 *%ptr4 |
Richard Sandiford | 89e160d | 2013-10-01 12:11:47 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 0d46b1a | 2013-10-01 12:19:08 +0000 | [diff] [blame] | 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 |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 112 | %ptr3 = getelementptr i8, i8 *%ptr1, i64 4096 |
| 113 | %ptr4 = getelementptr i8, i8 *%ptr2, i64 524287 |
Ulrich Weigand | 9dd23b8 | 2018-07-20 12:12:10 +0000 | [diff] [blame] | 114 | %val1 = load i8, i8 *%ptr1 |
| 115 | %val2 = load i8, i8 *%ptr2 |
| 116 | %val3 = load i8, i8 *%ptr3 |
| 117 | %val4 = load i8, i8 *%ptr4 |
Richard Sandiford | 0d46b1a | 2013-10-01 12:19:08 +0000 | [diff] [blame] | 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 |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 136 | %ptr3 = getelementptr i16, i16 *%ptr1, i64 2048 |
| 137 | %ptr4 = getelementptr i16, i16 *%ptr2, i64 262143 |
Ulrich Weigand | 9dd23b8 | 2018-07-20 12:12:10 +0000 | [diff] [blame] | 138 | %val1 = load i16, i16 *%ptr1 |
| 139 | %val2 = load i16, i16 *%ptr2 |
| 140 | %val3 = load i16, i16 *%ptr3 |
| 141 | %val4 = load i16, i16 *%ptr4 |
Richard Sandiford | 0d46b1a | 2013-10-01 12:19:08 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 5469c39 | 2013-10-01 12:22:49 +0000 | [diff] [blame] | 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 |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 165 | %ptr3 = getelementptr i8, i8 *%ptr1, i64 4096 |
| 166 | %ptr4 = getelementptr i8, i8 *%ptr2, i64 524287 |
Richard Sandiford | 5469c39 | 2013-10-01 12:22:49 +0000 | [diff] [blame] | 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 |
David Blaikie | 79e6c74 | 2015-02-27 19:29:02 +0000 | [diff] [blame] | 188 | %ptr3 = getelementptr i16, i16 *%ptr1, i64 2048 |
| 189 | %ptr4 = getelementptr i16, i16 *%ptr2, i64 262143 |
Richard Sandiford | 5469c39 | 2013-10-01 12:22:49 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 21235a2 | 2013-10-01 12:49:07 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 0124023 | 2013-10-01 13:02:28 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 7c5c0ea | 2013-10-01 13:10:16 +0000 | [diff] [blame] | 291 | |
| 292 | ; Test selects involving high registers. |
Ulrich Weigand | fb56686 | 2018-04-30 15:49:27 +0000 | [diff] [blame] | 293 | ; Note that we prefer to use a LOCR and move the result to a high register. |
Richard Sandiford | 7c5c0ea | 2013-10-01 13:10:16 +0000 | [diff] [blame] | 294 | define void @f13(i32 %x, i32 %y) { |
| 295 | ; CHECK-LABEL: f13: |
Ulrich Weigand | fb56686 | 2018-04-30 15:49:27 +0000 | [diff] [blame] | 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 |
Richard Sandiford | 7c5c0ea | 2013-10-01 13:10:16 +0000 | [diff] [blame] | 301 | ; CHECK: blah [[REG]] |
| 302 | ; CHECK: br %r14 |
Kyle Butt | efe56fe | 2017-01-11 19:55:19 +0000 | [diff] [blame] | 303 | %cmp = icmp eq i32 %x, 0 |
Richard Sandiford | 7c5c0ea | 2013-10-01 13:10:16 +0000 | [diff] [blame] | 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: |
Ulrich Weigand | fb56686 | 2018-04-30 15:49:27 +0000 | [diff] [blame] | 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]] |
Richard Sandiford | 7c5c0ea | 2013-10-01 13:10:16 +0000 | [diff] [blame] | 316 | ; CHECK: blah [[REG]] |
| 317 | ; CHECK: br %r14 |
Kyle Butt | efe56fe | 2017-01-11 19:55:19 +0000 | [diff] [blame] | 318 | %cmp = icmp eq i32 %x, 0 |
Richard Sandiford | 7c5c0ea | 2013-10-01 13:10:16 +0000 | [diff] [blame] | 319 | %val = select i1 %cmp, i32 0, i32 2102030405 |
| 320 | call void asm sideeffect "blah $0", "r"(i32 %val) |
| 321 | ret void |
| 322 | } |
Richard Sandiford | 1a56931 | 2013-10-01 13:18:56 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 6e96ac6 | 2013-10-01 13:22:41 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 5718dac | 2013-10-01 14:08:44 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 7028428 | 2013-10-01 14:20:41 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 3ad5a15 | 2013-10-01 14:36:20 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 2cac763 | 2013-10-01 14:41:52 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 42a694f | 2013-10-01 14:53:46 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | a9ac0e0 | 2013-10-01 14:56:23 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | b63e300 | 2013-10-01 15:00:44 +0000 | [diff] [blame] | 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"() |
Ulrich Weigand | 9dd23b8 | 2018-07-20 12:12:10 +0000 | [diff] [blame] | 721 | %load1 = load i32, i32 *%ptr1 |
Richard Sandiford | b63e300 | 2013-10-01 15:00:44 +0000 | [diff] [blame] | 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) |
Ulrich Weigand | 9dd23b8 | 2018-07-20 12:12:10 +0000 | [diff] [blame] | 725 | %load2 = load i32, i32 *%ptr2 |
Richard Sandiford | b63e300 | 2013-10-01 15:00:44 +0000 | [diff] [blame] | 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"() |
Ulrich Weigand | 9dd23b8 | 2018-07-20 12:12:10 +0000 | [diff] [blame] | 741 | %load1 = load i32, i32 *%ptr1 |
Richard Sandiford | b63e300 | 2013-10-01 15:00:44 +0000 | [diff] [blame] | 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) |
Ulrich Weigand | 9dd23b8 | 2018-07-20 12:12:10 +0000 | [diff] [blame] | 745 | %load2 = load i32, i32 *%ptr2 |
Richard Sandiford | b63e300 | 2013-10-01 15:00:44 +0000 | [diff] [blame] | 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 | } |
Ulrich Weigand | c3ec80f | 2018-04-30 17:54:28 +0000 | [diff] [blame] | 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 | |