diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2013-12-22 00:04:03 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2013-12-22 00:04:03 +0000 |
| commit | f8af5cf600354830d4ccf59732403f0f073eccb9 (patch) | |
| tree | 2ba0398b4c42ad4f55561327538044fd2c925a8b /test/CodeGen/SystemZ/asm-18.ll | |
| parent | 59d6cff90eecf31cb3dd860c4e786674cfdd42eb (diff) | |
Notes
Diffstat (limited to 'test/CodeGen/SystemZ/asm-18.ll')
| -rw-r--r-- | test/CodeGen/SystemZ/asm-18.ll | 745 |
1 files changed, 745 insertions, 0 deletions
diff --git a/test/CodeGen/SystemZ/asm-18.ll b/test/CodeGen/SystemZ/asm-18.ll new file mode 100644 index 000000000000..d60654b7863d --- /dev/null +++ b/test/CodeGen/SystemZ/asm-18.ll @@ -0,0 +1,745 @@ +; Test high-word operations, using "h" constraints to force a high +; register and "r" constraints to force a low register. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s + +; Test loads and stores involving mixtures of high and low registers. +define void @f1(i32 *%ptr1, i32 *%ptr2) { +; CHECK-LABEL: f1: +; CHECK-DAG: lfh [[REG1:%r[0-5]]], 0(%r2) +; CHECK-DAG: l [[REG2:%r[0-5]]], 0(%r3) +; CHECK-DAG: lfh [[REG3:%r[0-5]]], 4096(%r2) +; CHECK-DAG: ly [[REG4:%r[0-5]]], 524284(%r3) +; CHECK: blah [[REG1]], [[REG2]], [[REG3]], [[REG4]] +; CHECK-DAG: stfh [[REG1]], 0(%r2) +; CHECK-DAG: st [[REG2]], 0(%r3) +; CHECK-DAG: stfh [[REG3]], 4096(%r2) +; CHECK-DAG: sty [[REG4]], 524284(%r3) +; CHECK: br %r14 + %ptr3 = getelementptr i32 *%ptr1, i64 1024 + %ptr4 = getelementptr i32 *%ptr2, i64 131071 + %old1 = load i32 *%ptr1 + %old2 = load i32 *%ptr2 + %old3 = load i32 *%ptr3 + %old4 = load i32 *%ptr4 + %res = call { i32, i32, i32, i32 } asm "blah $0, $1, $2, $3", + "=h,=r,=h,=r,0,1,2,3"(i32 %old1, i32 %old2, i32 %old3, i32 %old4) + %new1 = extractvalue { i32, i32, i32, i32 } %res, 0 + %new2 = extractvalue { i32, i32, i32, i32 } %res, 1 + %new3 = extractvalue { i32, i32, i32, i32 } %res, 2 + %new4 = extractvalue { i32, i32, i32, i32 } %res, 3 + store i32 %new1, i32 *%ptr1 + store i32 %new2, i32 *%ptr2 + store i32 %new3, i32 *%ptr3 + store i32 %new4, i32 *%ptr4 + ret void +} + +; Test moves involving mixtures of high and low registers. +define i32 @f2(i32 %old) { +; CHECK-LABEL: f2: +; CHECK-DAG: risbhg [[REG1:%r[0-5]]], %r2, 0, 159, 32 +; CHECK-DAG: lr %r3, %r2 +; CHECK: stepa [[REG1]], %r2, %r3 +; CHECK: risbhg {{%r[0-5]}}, [[REG1]], 0, 159, 0 +; CHECK: stepb [[REG2:%r[0-5]]] +; CHECK: risblg %r2, [[REG2]], 0, 159, 32 +; CHECK: br %r14 + %tmp = call i32 asm "stepa $1, $2, $3", + "=h,0,{r2},{r3}"(i32 %old, i32 %old, i32 %old) + %new = call i32 asm "stepb $1, $2", "=&h,0,h"(i32 %tmp, i32 %tmp) + ret i32 %new +} + +; Test sign-extending 8-bit loads into mixtures of high and low registers. +define void @f3(i8 *%ptr1, i8 *%ptr2) { +; CHECK-LABEL: f3: +; CHECK-DAG: lbh [[REG1:%r[0-5]]], 0(%r2) +; CHECK-DAG: lb [[REG2:%r[0-5]]], 0(%r3) +; CHECK-DAG: lbh [[REG3:%r[0-5]]], 4096(%r2) +; CHECK-DAG: lb [[REG4:%r[0-5]]], 524287(%r3) +; CHECK: blah [[REG1]], [[REG2]] +; CHECK: br %r14 + %ptr3 = getelementptr i8 *%ptr1, i64 4096 + %ptr4 = getelementptr i8 *%ptr2, i64 524287 + %val1 = load i8 *%ptr1 + %val2 = load i8 *%ptr2 + %val3 = load i8 *%ptr3 + %val4 = load i8 *%ptr4 + %ext1 = sext i8 %val1 to i32 + %ext2 = sext i8 %val2 to i32 + %ext3 = sext i8 %val3 to i32 + %ext4 = sext i8 %val4 to i32 + call void asm sideeffect "blah $0, $1, $2, $3", + "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4) + ret void +} + +; Test sign-extending 16-bit loads into mixtures of high and low registers. +define void @f4(i16 *%ptr1, i16 *%ptr2) { +; CHECK-LABEL: f4: +; CHECK-DAG: lhh [[REG1:%r[0-5]]], 0(%r2) +; CHECK-DAG: lh [[REG2:%r[0-5]]], 0(%r3) +; CHECK-DAG: lhh [[REG3:%r[0-5]]], 4096(%r2) +; CHECK-DAG: lhy [[REG4:%r[0-5]]], 524286(%r3) +; CHECK: blah [[REG1]], [[REG2]] +; CHECK: br %r14 + %ptr3 = getelementptr i16 *%ptr1, i64 2048 + %ptr4 = getelementptr i16 *%ptr2, i64 262143 + %val1 = load i16 *%ptr1 + %val2 = load i16 *%ptr2 + %val3 = load i16 *%ptr3 + %val4 = load i16 *%ptr4 + %ext1 = sext i16 %val1 to i32 + %ext2 = sext i16 %val2 to i32 + %ext3 = sext i16 %val3 to i32 + %ext4 = sext i16 %val4 to i32 + call void asm sideeffect "blah $0, $1, $2, $3", + "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4) + ret void +} + +; Test zero-extending 8-bit loads into mixtures of high and low registers. +define void @f5(i8 *%ptr1, i8 *%ptr2) { +; CHECK-LABEL: f5: +; CHECK-DAG: llch [[REG1:%r[0-5]]], 0(%r2) +; CHECK-DAG: llc [[REG2:%r[0-5]]], 0(%r3) +; CHECK-DAG: llch [[REG3:%r[0-5]]], 4096(%r2) +; CHECK-DAG: llc [[REG4:%r[0-5]]], 524287(%r3) +; CHECK: blah [[REG1]], [[REG2]] +; CHECK: br %r14 + %ptr3 = getelementptr i8 *%ptr1, i64 4096 + %ptr4 = getelementptr i8 *%ptr2, i64 524287 + %val1 = load i8 *%ptr1 + %val2 = load i8 *%ptr2 + %val3 = load i8 *%ptr3 + %val4 = load i8 *%ptr4 + %ext1 = zext i8 %val1 to i32 + %ext2 = zext i8 %val2 to i32 + %ext3 = zext i8 %val3 to i32 + %ext4 = zext i8 %val4 to i32 + call void asm sideeffect "blah $0, $1, $2, $3", + "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4) + ret void +} + +; Test zero-extending 16-bit loads into mixtures of high and low registers. +define void @f6(i16 *%ptr1, i16 *%ptr2) { +; CHECK-LABEL: f6: +; CHECK-DAG: llhh [[REG1:%r[0-5]]], 0(%r2) +; CHECK-DAG: llh [[REG2:%r[0-5]]], 0(%r3) +; CHECK-DAG: llhh [[REG3:%r[0-5]]], 4096(%r2) +; CHECK-DAG: llh [[REG4:%r[0-5]]], 524286(%r3) +; CHECK: blah [[REG1]], [[REG2]] +; CHECK: br %r14 + %ptr3 = getelementptr i16 *%ptr1, i64 2048 + %ptr4 = getelementptr i16 *%ptr2, i64 262143 + %val1 = load i16 *%ptr1 + %val2 = load i16 *%ptr2 + %val3 = load i16 *%ptr3 + %val4 = load i16 *%ptr4 + %ext1 = zext i16 %val1 to i32 + %ext2 = zext i16 %val2 to i32 + %ext3 = zext i16 %val3 to i32 + %ext4 = zext i16 %val4 to i32 + call void asm sideeffect "blah $0, $1, $2, $3", + "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4) + ret void +} + +; Test truncating stores of high and low registers into 8-bit memory. +define void @f7(i8 *%ptr1, i8 *%ptr2) { +; CHECK-LABEL: f7: +; CHECK: blah [[REG1:%r[0-5]]], [[REG2:%r[0-5]]] +; CHECK-DAG: stch [[REG1]], 0(%r2) +; CHECK-DAG: stc [[REG2]], 0(%r3) +; CHECK-DAG: stch [[REG1]], 4096(%r2) +; CHECK-DAG: stcy [[REG2]], 524287(%r3) +; CHECK: br %r14 + %res = call { i32, i32 } asm "blah $0, $1", "=h,=r"() + %res1 = extractvalue { i32, i32 } %res, 0 + %res2 = extractvalue { i32, i32 } %res, 1 + %trunc1 = trunc i32 %res1 to i8 + %trunc2 = trunc i32 %res2 to i8 + %ptr3 = getelementptr i8 *%ptr1, i64 4096 + %ptr4 = getelementptr i8 *%ptr2, i64 524287 + store i8 %trunc1, i8 *%ptr1 + store i8 %trunc2, i8 *%ptr2 + store i8 %trunc1, i8 *%ptr3 + store i8 %trunc2, i8 *%ptr4 + ret void +} + +; Test truncating stores of high and low registers into 16-bit memory. +define void @f8(i16 *%ptr1, i16 *%ptr2) { +; CHECK-LABEL: f8: +; CHECK: blah [[REG1:%r[0-5]]], [[REG2:%r[0-5]]] +; CHECK-DAG: sthh [[REG1]], 0(%r2) +; CHECK-DAG: sth [[REG2]], 0(%r3) +; CHECK-DAG: sthh [[REG1]], 4096(%r2) +; CHECK-DAG: sthy [[REG2]], 524286(%r3) +; CHECK: br %r14 + %res = call { i32, i32 } asm "blah $0, $1", "=h,=r"() + %res1 = extractvalue { i32, i32 } %res, 0 + %res2 = extractvalue { i32, i32 } %res, 1 + %trunc1 = trunc i32 %res1 to i16 + %trunc2 = trunc i32 %res2 to i16 + %ptr3 = getelementptr i16 *%ptr1, i64 2048 + %ptr4 = getelementptr i16 *%ptr2, i64 262143 + store i16 %trunc1, i16 *%ptr1 + store i16 %trunc2, i16 *%ptr2 + store i16 %trunc1, i16 *%ptr3 + store i16 %trunc2, i16 *%ptr4 + ret void +} + +; Test zero extensions from 8 bits between mixtures of high and low registers. +define i32 @f9(i8 %val1, i8 %val2) { +; CHECK-LABEL: f9: +; CHECK-DAG: risbhg [[REG1:%r[0-5]]], %r2, 24, 159, 32 +; CHECK-DAG: llcr [[REG2:%r[0-5]]], %r3 +; CHECK: stepa [[REG1]], [[REG2]] +; CHECK: risbhg [[REG3:%r[0-5]]], [[REG1]], 24, 159, 0 +; CHECK: stepb [[REG3]] +; CHECK: risblg %r2, [[REG3]], 24, 159, 32 +; CHECK: br %r14 + %ext1 = zext i8 %val1 to i32 + %ext2 = zext i8 %val2 to i32 + %val3 = call i8 asm sideeffect "stepa $0, $1", "=h,0,r"(i32 %ext1, i32 %ext2) + %ext3 = zext i8 %val3 to i32 + %val4 = call i8 asm sideeffect "stepb $0", "=h,0"(i32 %ext3) + %ext4 = zext i8 %val4 to i32 + ret i32 %ext4 +} + +; Test zero extensions from 16 bits between mixtures of high and low registers. +define i32 @f10(i16 %val1, i16 %val2) { +; CHECK-LABEL: f10: +; CHECK-DAG: risbhg [[REG1:%r[0-5]]], %r2, 16, 159, 32 +; CHECK-DAG: llhr [[REG2:%r[0-5]]], %r3 +; CHECK: stepa [[REG1]], [[REG2]] +; CHECK: risbhg [[REG3:%r[0-5]]], [[REG1]], 16, 159, 0 +; CHECK: stepb [[REG3]] +; CHECK: risblg %r2, [[REG3]], 16, 159, 32 +; CHECK: br %r14 + %ext1 = zext i16 %val1 to i32 + %ext2 = zext i16 %val2 to i32 + %val3 = call i16 asm sideeffect "stepa $0, $1", "=h,0,r"(i32 %ext1, i32 %ext2) + %ext3 = zext i16 %val3 to i32 + %val4 = call i16 asm sideeffect "stepb $0", "=h,0"(i32 %ext3) + %ext4 = zext i16 %val4 to i32 + ret i32 %ext4 +} + +; Test loads of 16-bit constants into mixtures of high and low registers. +define void @f11() { +; CHECK-LABEL: f11: +; CHECK-DAG: iihf [[REG1:%r[0-5]]], 4294934529 +; CHECK-DAG: lhi [[REG2:%r[0-5]]], -32768 +; CHECK-DAG: llihl [[REG3:%r[0-5]]], 32766 +; CHECK-DAG: lhi [[REG4:%r[0-5]]], 32767 +; CHECK: blah [[REG1]], [[REG2]], [[REG3]], [[REG4]] +; CHECK: br %r14 + call void asm sideeffect "blah $0, $1, $2, $3", + "h,r,h,r"(i32 -32767, i32 -32768, + i32 32766, i32 32767) + ret void +} + +; Test loads of unsigned constants into mixtures of high and low registers. +; For stepc, we expect the h and r operands to be paired by the register +; allocator. It doesn't really matter which comes first: LLILL/IIHF would +; be just as good. +define void @f12() { +; CHECK-LABEL: f12: +; CHECK-DAG: llihl [[REG1:%r[0-5]]], 32768 +; CHECK-DAG: llihl [[REG2:%r[0-5]]], 65535 +; CHECK-DAG: llihh [[REG3:%r[0-5]]], 1 +; CHECK-DAG: llihh [[REG4:%r[0-5]]], 65535 +; CHECK: stepa [[REG1]], [[REG2]], [[REG3]], [[REG4]] +; CHECK-DAG: llill [[REG1:%r[0-5]]], 32769 +; CHECK-DAG: llill [[REG2:%r[0-5]]], 65534 +; CHECK-DAG: llilh [[REG3:%r[0-5]]], 2 +; CHECK-DAG: llilh [[REG4:%r[0-5]]], 65534 +; CHECK: stepb [[REG1]], [[REG2]], [[REG3]], [[REG4]] +; CHECK-DAG: llihl [[REG1:%r[0-5]]], 32770 +; CHECK-DAG: iilf [[REG1]], 65533 +; CHECK-DAG: llihh [[REG2:%r[0-5]]], 4 +; CHECK-DAG: iilf [[REG2]], 524288 +; CHECK: stepc [[REG1]], [[REG1]], [[REG2]], [[REG2]] +; CHECK-DAG: iihf [[REG1:%r[0-5]]], 3294967296 +; CHECK-DAG: iilf [[REG2:%r[0-5]]], 4294567296 +; CHECK-DAG: iihf [[REG3:%r[0-5]]], 1000000000 +; CHECK-DAG: iilf [[REG4:%r[0-5]]], 400000 +; CHECK: stepd [[REG1]], [[REG2]], [[REG3]], [[REG4]] +; CHECK: br %r14 + call void asm sideeffect "stepa $0, $1, $2, $3", + "h,h,h,h"(i32 32768, i32 65535, + i32 65536, i32 -65536) + call void asm sideeffect "stepb $0, $1, $2, $3", + "r,r,r,r"(i32 32769, i32 65534, + i32 131072, i32 -131072) + call void asm sideeffect "stepc $0, $1, $2, $3", + "h,r,h,r"(i32 32770, i32 65533, + i32 262144, i32 524288) + call void asm sideeffect "stepd $0, $1, $2, $3", + "h,r,h,r"(i32 -1000000000, i32 -400000, + i32 1000000000, i32 400000) + ret void +} + +; Test selects involving high registers. +define void @f13(i32 %x, i32 %y) { +; CHECK-LABEL: f13: +; CHECK: llihl [[REG:%r[0-5]]], 0 +; CHECK: cije %r2, 0 +; CHECK: iihf [[REG]], 2102030405 +; CHECK: blah [[REG]] +; CHECK: br %r14 + %cmp = icmp eq i32 %x, 0 + %val = select i1 %cmp, i32 0, i32 2102030405 + call void asm sideeffect "blah $0", "h"(i32 %val) + ret void +} + +; Test selects involving low registers. +define void @f14(i32 %x, i32 %y) { +; CHECK-LABEL: f14: +; CHECK: lhi [[REG:%r[0-5]]], 0 +; CHECK: cije %r2, 0 +; CHECK: iilf [[REG]], 2102030405 +; CHECK: blah [[REG]] +; CHECK: br %r14 + %cmp = icmp eq i32 %x, 0 + %val = select i1 %cmp, i32 0, i32 2102030405 + call void asm sideeffect "blah $0", "r"(i32 %val) + ret void +} + +; Test immediate insertion involving high registers. +define void @f15() { +; CHECK-LABEL: f15: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: iihh [[REG]], 4660 +; CHECK: stepb [[REG]] +; CHECK: iihl [[REG]], 34661 +; CHECK: stepc [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=h"() + %and1 = and i32 %res1, 65535 + %or1 = or i32 %and1, 305397760 + %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %or1) + %and2 = and i32 %res2, -65536 + %or2 = or i32 %and2, 34661 + call void asm sideeffect "stepc $0", "h"(i32 %or2) + ret void +} + +; Test immediate insertion involving low registers. +define void @f16() { +; CHECK-LABEL: f16: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: iilh [[REG]], 4660 +; CHECK: stepb [[REG]] +; CHECK: iill [[REG]], 34661 +; CHECK: stepc [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=r"() + %and1 = and i32 %res1, 65535 + %or1 = or i32 %and1, 305397760 + %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %or1) + %and2 = and i32 %res2, -65536 + %or2 = or i32 %and2, 34661 + call void asm sideeffect "stepc $0", "r"(i32 %or2) + ret void +} + +; Test immediate OR involving high registers. +define void @f17() { +; CHECK-LABEL: f17: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: oihh [[REG]], 4660 +; CHECK: stepb [[REG]] +; CHECK: oihl [[REG]], 34661 +; CHECK: stepc [[REG]] +; CHECK: oihf [[REG]], 12345678 +; CHECK: stepd [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=h"() + %or1 = or i32 %res1, 305397760 + %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %or1) + %or2 = or i32 %res2, 34661 + %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %or2) + %or3 = or i32 %res3, 12345678 + call void asm sideeffect "stepd $0", "h"(i32 %or3) + ret void +} + +; Test immediate OR involving low registers. +define void @f18() { +; CHECK-LABEL: f18: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: oilh [[REG]], 4660 +; CHECK: stepb [[REG]] +; CHECK: oill [[REG]], 34661 +; CHECK: stepc [[REG]] +; CHECK: oilf [[REG]], 12345678 +; CHECK: stepd [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=r"() + %or1 = or i32 %res1, 305397760 + %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %or1) + %or2 = or i32 %res2, 34661 + %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %or2) + %or3 = or i32 %res3, 12345678 + call void asm sideeffect "stepd $0", "r"(i32 %or3) + ret void +} + +; Test immediate XOR involving high registers. +define void @f19() { +; CHECK-LABEL: f19: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: xihf [[REG]], 305397760 +; CHECK: stepb [[REG]] +; CHECK: xihf [[REG]], 34661 +; CHECK: stepc [[REG]] +; CHECK: xihf [[REG]], 12345678 +; CHECK: stepd [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=h"() + %xor1 = xor i32 %res1, 305397760 + %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %xor1) + %xor2 = xor i32 %res2, 34661 + %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %xor2) + %xor3 = xor i32 %res3, 12345678 + call void asm sideeffect "stepd $0", "h"(i32 %xor3) + ret void +} + +; Test immediate XOR involving low registers. +define void @f20() { +; CHECK-LABEL: f20: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: xilf [[REG]], 305397760 +; CHECK: stepb [[REG]] +; CHECK: xilf [[REG]], 34661 +; CHECK: stepc [[REG]] +; CHECK: xilf [[REG]], 12345678 +; CHECK: stepd [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=r"() + %xor1 = xor i32 %res1, 305397760 + %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %xor1) + %xor2 = xor i32 %res2, 34661 + %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %xor2) + %xor3 = xor i32 %res3, 12345678 + call void asm sideeffect "stepd $0", "r"(i32 %xor3) + ret void +} + +; Test two-operand immediate AND involving high registers. +define void @f21() { +; CHECK-LABEL: f21: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: nihh [[REG]], 4096 +; CHECK: stepb [[REG]] +; CHECK: nihl [[REG]], 57536 +; CHECK: stepc [[REG]] +; CHECK: nihf [[REG]], 12345678 +; CHECK: stepd [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=h"() + %and1 = and i32 %res1, 268500991 + %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %and1) + %and2 = and i32 %res2, -8000 + %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %and2) + %and3 = and i32 %res3, 12345678 + call void asm sideeffect "stepd $0", "h"(i32 %and3) + ret void +} + +; Test two-operand immediate AND involving low registers. +define void @f22() { +; CHECK-LABEL: f22: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: nilh [[REG]], 4096 +; CHECK: stepb [[REG]] +; CHECK: nill [[REG]], 57536 +; CHECK: stepc [[REG]] +; CHECK: nilf [[REG]], 12345678 +; CHECK: stepd [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=r"() + %and1 = and i32 %res1, 268500991 + %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %and1) + %and2 = and i32 %res2, -8000 + %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %and2) + %and3 = and i32 %res3, 12345678 + call void asm sideeffect "stepd $0", "r"(i32 %and3) + ret void +} + +; Test three-operand immediate AND involving mixtures of low and high registers. +define i32 @f23(i32 %old) { +; CHECK-LABEL: f23: +; CHECK-DAG: risblg [[REG1:%r[0-5]]], %r2, 28, 158, 0 +; CHECK-DAG: risbhg [[REG2:%r[0-5]]], %r2, 24, 158, 32 +; CHECK: stepa %r2, [[REG1]], [[REG2]] +; CHECK-DAG: risbhg [[REG3:%r[0-5]]], [[REG2]], 25, 159, 0 +; CHECK-DAG: risblg %r2, [[REG2]], 24, 152, 32 +; CHECK: stepb [[REG2]], [[REG3]], %r2 +; CHECK: br %r14 + %and1 = and i32 %old, 14 + %and2 = and i32 %old, 254 + %res1 = call i32 asm "stepa $1, $2, $3", + "=h,r,r,0"(i32 %old, i32 %and1, i32 %and2) + %and3 = and i32 %res1, 127 + %and4 = and i32 %res1, 128 + %res2 = call i32 asm "stepb $1, $2, $3", + "=r,h,h,0"(i32 %res1, i32 %and3, i32 %and4) + ret i32 %res2 +} + +; Test RISB[LH]G insertions involving mixtures of high and low registers. +define i32 @f24(i32 %old) { +; CHECK-LABEL: f24: +; CHECK-DAG: risblg [[REG1:%r[0-5]]], %r2, 28, 158, 1 +; CHECK-DAG: risbhg [[REG2:%r[0-5]]], %r2, 24, 158, 29 +; CHECK: stepa %r2, [[REG1]], [[REG2]] +; CHECK-DAG: risbhg [[REG3:%r[0-5]]], [[REG2]], 25, 159, 62 +; CHECK-DAG: risblg %r2, [[REG2]], 24, 152, 37 +; CHECK: stepb [[REG2]], [[REG3]], %r2 +; CHECK: br %r14 + %shift1 = shl i32 %old, 1 + %and1 = and i32 %shift1, 14 + %shift2 = lshr i32 %old, 3 + %and2 = and i32 %shift2, 254 + %res1 = call i32 asm "stepa $1, $2, $3", + "=h,r,r,0"(i32 %old, i32 %and1, i32 %and2) + %shift3 = lshr i32 %res1, 2 + %and3 = and i32 %shift3, 127 + %shift4 = shl i32 %res1, 5 + %and4 = and i32 %shift4, 128 + %res2 = call i32 asm "stepb $1, $2, $3", + "=r,h,h,0"(i32 %res1, i32 %and3, i32 %and4) + ret i32 %res2 +} + +; Test TMxx involving mixtures of high and low registers. +define i32 @f25(i32 %old) { +; CHECK-LABEL: f25: +; CHECK-DAG: tmll %r2, 1 +; CHECK-DAG: tmlh %r2, 1 +; CHECK: stepa [[REG1:%r[0-5]]], +; CHECK-DAG: tmhl [[REG1]], 1 +; CHECK-DAG: tmhh [[REG1]], 1 +; CHECK: stepb %r2, +; CHECK: br %r14 + %and1 = and i32 %old, 1 + %and2 = and i32 %old, 65536 + %cmp1 = icmp eq i32 %and1, 0 + %cmp2 = icmp eq i32 %and2, 0 + %sel1 = select i1 %cmp1, i32 100, i32 200 + %sel2 = select i1 %cmp2, i32 100, i32 200 + %res1 = call i32 asm "stepa $0, $1, $2", + "=h,r,r"(i32 %sel1, i32 %sel2) + %and3 = and i32 %res1, 1 + %and4 = and i32 %res1, 65536 + %cmp3 = icmp eq i32 %and3, 0 + %cmp4 = icmp eq i32 %and4, 0 + %sel3 = select i1 %cmp3, i32 100, i32 200 + %sel4 = select i1 %cmp4, i32 100, i32 200 + %res2 = call i32 asm "stepb $0, $1, $2", + "=r,h,h"(i32 %sel3, i32 %sel4) + ret i32 %res2 +} + +; Test two-operand halfword immediate addition involving high registers. +define void @f26() { +; CHECK-LABEL: f26: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: aih [[REG]], -32768 +; CHECK: stepb [[REG]] +; CHECK: aih [[REG]], 1 +; CHECK: stepc [[REG]] +; CHECK: aih [[REG]], 32767 +; CHECK: stepd [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=h"() + %add1 = add i32 %res1, -32768 + %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %add1) + %add2 = add i32 %res2, 1 + %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %add2) + %add3 = add i32 %res3, 32767 + call void asm sideeffect "stepd $0", "h"(i32 %add3) + ret void +} + +; Test two-operand halfword immediate addition involving low registers. +define void @f27() { +; CHECK-LABEL: f27: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: ahi [[REG]], -32768 +; CHECK: stepb [[REG]] +; CHECK: ahi [[REG]], 1 +; CHECK: stepc [[REG]] +; CHECK: ahi [[REG]], 32767 +; CHECK: stepd [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=r"() + %add1 = add i32 %res1, -32768 + %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %add1) + %add2 = add i32 %res2, 1 + %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %add2) + %add3 = add i32 %res3, 32767 + call void asm sideeffect "stepd $0", "r"(i32 %add3) + ret void +} + +; Test three-operand halfword immediate addition involving mixtures of low +; and high registers. RISBHG/AIH would be OK too, instead of AHIK/RISBHG. +define i32 @f28(i32 %old) { +; CHECK-LABEL: f28: +; CHECK: ahik [[REG1:%r[0-5]]], %r2, 14 +; CHECK: stepa %r2, [[REG1]] +; CHECK: ahik [[TMP:%r[0-5]]], [[REG1]], 254 +; CHECK: risbhg [[REG2:%r[0-5]]], [[TMP]], 0, 159, 32 +; CHECK: stepb [[REG1]], [[REG2]] +; CHECK: risbhg [[REG3:%r[0-5]]], [[REG2]], 0, 159, 0 +; CHECK: aih [[REG3]], 127 +; CHECK: stepc [[REG2]], [[REG3]] +; CHECK: risblg %r2, [[REG3]], 0, 159, 32 +; CHECK: ahi %r2, 128 +; CHECK: stepd [[REG3]], %r2 +; CHECK: br %r14 + %add1 = add i32 %old, 14 + %res1 = call i32 asm "stepa $1, $2", + "=r,r,0"(i32 %old, i32 %add1) + %add2 = add i32 %res1, 254 + %res2 = call i32 asm "stepb $1, $2", + "=h,r,0"(i32 %res1, i32 %add2) + %add3 = add i32 %res2, 127 + %res3 = call i32 asm "stepc $1, $2", + "=h,h,0"(i32 %res2, i32 %add3) + %add4 = add i32 %res3, 128 + %res4 = call i32 asm "stepd $1, $2", + "=r,h,0"(i32 %res3, i32 %add4) + ret i32 %res4 +} + +; Test large immediate addition involving high registers. +define void @f29() { +; CHECK-LABEL: f29: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: aih [[REG]], -32769 +; CHECK: stepb [[REG]] +; CHECK: aih [[REG]], 32768 +; CHECK: stepc [[REG]] +; CHECK: aih [[REG]], 1000000000 +; CHECK: stepd [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=h"() + %add1 = add i32 %res1, -32769 + %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %add1) + %add2 = add i32 %res2, 32768 + %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %add2) + %add3 = add i32 %res3, 1000000000 + call void asm sideeffect "stepd $0", "h"(i32 %add3) + ret void +} + +; Test large immediate addition involving low registers. +define void @f30() { +; CHECK-LABEL: f30: +; CHECK: stepa [[REG:%r[0-5]]] +; CHECK: afi [[REG]], -32769 +; CHECK: stepb [[REG]] +; CHECK: afi [[REG]], 32768 +; CHECK: stepc [[REG]] +; CHECK: afi [[REG]], 1000000000 +; CHECK: stepd [[REG]] +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=r"() + %add1 = add i32 %res1, -32769 + %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %add1) + %add2 = add i32 %res2, 32768 + %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %add2) + %add3 = add i32 %res3, 1000000000 + call void asm sideeffect "stepd $0", "r"(i32 %add3) + ret void +} + +; Test large immediate comparison involving high registers. +define i32 @f31() { +; CHECK-LABEL: f31: +; CHECK: stepa [[REG1:%r[0-5]]] +; CHECK: cih [[REG1]], 1000000000 +; CHECK: stepb [[REG2:%r[0-5]]] +; CHECK: clih [[REG2]], 1000000000 +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=h"() + %cmp1 = icmp sle i32 %res1, 1000000000 + %sel1 = select i1 %cmp1, i32 0, i32 1 + %res2 = call i32 asm "stepb $0, $1", "=h,r"(i32 %sel1) + %cmp2 = icmp ule i32 %res2, 1000000000 + %sel2 = select i1 %cmp2, i32 0, i32 1 + ret i32 %sel2 +} + +; Test large immediate comparison involving low registers. +define i32 @f32() { +; CHECK-LABEL: f32: +; CHECK: stepa [[REG1:%r[0-5]]] +; CHECK: cfi [[REG1]], 1000000000 +; CHECK: stepb [[REG2:%r[0-5]]] +; CHECK: clfi [[REG2]], 1000000000 +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=r"() + %cmp1 = icmp sle i32 %res1, 1000000000 + %sel1 = select i1 %cmp1, i32 0, i32 1 + %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %sel1) + %cmp2 = icmp ule i32 %res2, 1000000000 + %sel2 = select i1 %cmp2, i32 0, i32 1 + ret i32 %sel2 +} + +; Test memory comparison involving high registers. +define void @f33(i32 *%ptr1, i32 *%ptr2) { +; CHECK-LABEL: f33: +; CHECK: stepa [[REG1:%r[0-5]]] +; CHECK: chf [[REG1]], 0(%r2) +; CHECK: stepb [[REG2:%r[0-5]]] +; CHECK: clhf [[REG2]], 0(%r3) +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=h"() + %load1 = load i32 *%ptr1 + %cmp1 = icmp sle i32 %res1, %load1 + %sel1 = select i1 %cmp1, i32 0, i32 1 + %res2 = call i32 asm "stepb $0, $1", "=h,r"(i32 %sel1) + %load2 = load i32 *%ptr2 + %cmp2 = icmp ule i32 %res2, %load2 + %sel2 = select i1 %cmp2, i32 0, i32 1 + store i32 %sel2, i32 *%ptr1 + ret void +} + +; Test memory comparison involving low registers. +define void @f34(i32 *%ptr1, i32 *%ptr2) { +; CHECK-LABEL: f34: +; CHECK: stepa [[REG1:%r[0-5]]] +; CHECK: c [[REG1]], 0(%r2) +; CHECK: stepb [[REG2:%r[0-5]]] +; CHECK: cl [[REG2]], 0(%r3) +; CHECK: br %r14 + %res1 = call i32 asm "stepa $0", "=r"() + %load1 = load i32 *%ptr1 + %cmp1 = icmp sle i32 %res1, %load1 + %sel1 = select i1 %cmp1, i32 0, i32 1 + %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %sel1) + %load2 = load i32 *%ptr2 + %cmp2 = icmp ule i32 %res2, %load2 + %sel2 = select i1 %cmp2, i32 0, i32 1 + store i32 %sel2, i32 *%ptr1 + ret void +} |
