diff options
| author | Bryan Chan <bryan.chan@ca.ibm.com> | 2016-05-16 20:32:22 +0000 |
|---|---|---|
| committer | Bryan Chan <bryan.chan@ca.ibm.com> | 2016-05-16 20:32:22 +0000 |
| commit | 28b759c4c8d306b972fcd593280dcc8562904295 (patch) | |
| tree | dc467e09e1d1a888bf46b046d1605642aff981ac /llvm/test | |
| parent | 7ffd0b44091ecfdbab65051e07636362939ec541 (diff) | |
| download | bcm5719-llvm-28b759c4c8d306b972fcd593280dcc8562904295.tar.gz bcm5719-llvm-28b759c4c8d306b972fcd593280dcc8562904295.zip | |
[SystemZ] Support LRVH and STRVH opcodes
Summary: On Linux, /usr/include/bits/byteswap-16.h defines __byteswap_16(x) as an inlined LRVH (Load Reversed Half-word) instruction. The SystemZ back-end did not support this opcode and the inlined assembly would cause a fatal error.
Reviewers: bryanpkc, uweigand
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D18732
llvm-svn: 269688
Diffstat (limited to 'llvm/test')
| -rw-r--r-- | llvm/test/CodeGen/SystemZ/bswap-06.ll | 99 | ||||
| -rw-r--r-- | llvm/test/CodeGen/SystemZ/bswap-07.ll | 100 | ||||
| -rw-r--r-- | llvm/test/MC/Disassembler/SystemZ/insns.txt | 60 | ||||
| -rw-r--r-- | llvm/test/MC/SystemZ/insn-good.s | 44 |
4 files changed, 303 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/SystemZ/bswap-06.ll b/llvm/test/CodeGen/SystemZ/bswap-06.ll new file mode 100644 index 00000000000..19aafe2ca17 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/bswap-06.ll @@ -0,0 +1,99 @@ +; Test 16-bit byteswaps from memory to registers. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +declare i16 @llvm.bswap.i16(i16 %a) + +; Check LRVH with no displacement. +define i16 @f1(i16 *%src) { +; CHECK-LABEL: f1: +; CHECK: lrvh %r2, 0(%r2) +; CHECK: br %r14 + %a = load i16 , i16 *%src + %swapped = call i16 @llvm.bswap.i16(i16 %a) + ret i16 %swapped +} + +; Check the high end of the aligned LRVH range. +define i16 @f2(i16 *%src) { +; CHECK-LABEL: f2: +; CHECK: lrvh %r2, 524286(%r2) +; CHECK: br %r14 + %ptr = getelementptr i16, i16 *%src, i64 262143 + %a = load i16 , i16 *%ptr + %swapped = call i16 @llvm.bswap.i16(i16 %a) + ret i16 %swapped +} + +; Check the next word up, which needs separate address logic. +; Other sequences besides this one would be OK. +define i16 @f3(i16 *%src) { +; CHECK-LABEL: f3: +; CHECK: agfi %r2, 524288 +; CHECK: lrvh %r2, 0(%r2) +; CHECK: br %r14 + %ptr = getelementptr i16, i16 *%src, i64 262144 + %a = load i16 , i16 *%ptr + %swapped = call i16 @llvm.bswap.i16(i16 %a) + ret i16 %swapped +} + +; Check the high end of the negative aligned LRVH range. +define i16 @f4(i16 *%src) { +; CHECK-LABEL: f4: +; CHECK: lrvh %r2, -2(%r2) +; CHECK: br %r14 + %ptr = getelementptr i16, i16 *%src, i64 -1 + %a = load i16 , i16 *%ptr + %swapped = call i16 @llvm.bswap.i16(i16 %a) + ret i16 %swapped +} + +; Check the low end of the LRVH range. +define i16 @f5(i16 *%src) { +; CHECK-LABEL: f5: +; CHECK: lrvh %r2, -524288(%r2) +; CHECK: br %r14 + %ptr = getelementptr i16, i16 *%src, i64 -262144 + %a = load i16 , i16 *%ptr + %swapped = call i16 @llvm.bswap.i16(i16 %a) + ret i16 %swapped +} + +; Check the next word down, which needs separate address logic. +; Other sequences besides this one would be OK. +define i16 @f6(i16 *%src) { +; CHECK-LABEL: f6: +; CHECK: agfi %r2, -524290 +; CHECK: lrvh %r2, 0(%r2) +; CHECK: br %r14 + %ptr = getelementptr i16, i16 *%src, i64 -262145 + %a = load i16 , i16 *%ptr + %swapped = call i16 @llvm.bswap.i16(i16 %a) + ret i16 %swapped +} + +; Check that LRVH allows an index. +define i16 @f7(i64 %src, i64 %index) { +; CHECK-LABEL: f7: +; CHECK: lrvh %r2, 524287({{%r3,%r2|%r2,%r3}}) +; CHECK: br %r14 + %add1 = add i64 %src, %index + %add2 = add i64 %add1, 524287 + %ptr = inttoptr i64 %add2 to i16 * + %a = load i16 , i16 *%ptr + %swapped = call i16 @llvm.bswap.i16(i16 %a) + ret i16 %swapped +} + +; Check that volatile accesses do not use LRVH, which might access the +; storage multple times. +define i16 @f8(i16 *%src) { +; CHECK-LABEL: f8: +; CHECK: lh [[REG:%r[0-5]]], 0(%r2) +; CHECK: lrvr %r2, [[REG]] +; CHECK: br %r14 + %a = load volatile i16 , i16 *%src + %swapped = call i16 @llvm.bswap.i16(i16 %a) + ret i16 %swapped +} diff --git a/llvm/test/CodeGen/SystemZ/bswap-07.ll b/llvm/test/CodeGen/SystemZ/bswap-07.ll new file mode 100644 index 00000000000..7f0a265de75 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/bswap-07.ll @@ -0,0 +1,100 @@ +; Test 32-bit byteswaps from registers to memory. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +declare i16 @llvm.bswap.i16(i16 %a) + +; Check STRVH with no displacement. +define void @f1(i16 *%dst, i16 %a) { +; CHECK-LABEL: f1: +; CHECK: strvh %r3, 0(%r2) +; CHECK: br %r14 + %swapped = call i16 @llvm.bswap.i16(i16 %a) + store i16 %swapped, i16 *%dst + ret void +} + +; Check the high end of the aligned STRVH range. +define void @f2(i16 *%dst, i16 %a) { +; CHECK-LABEL: f2: +; CHECK: strvh %r3, 524286(%r2) +; CHECK: br %r14 + %ptr = getelementptr i16, i16 *%dst, i64 262143 + %swapped = call i16 @llvm.bswap.i16(i16 %a) + store i16 %swapped, i16 *%ptr + ret void +} + +; Check the next word up, which needs separate address logic. +; Other sequences besides this one would be OK. +define void @f3(i16 *%dst, i16 %a) { +; CHECK-LABEL: f3: +; CHECK: agfi %r2, 524288 +; CHECK: strvh %r3, 0(%r2) +; CHECK: br %r14 + %ptr = getelementptr i16, i16 *%dst, i64 262144 + %swapped = call i16 @llvm.bswap.i16(i16 %a) + store i16 %swapped, i16 *%ptr + ret void +} + +; Check the high end of the negative aligned STRVH range. +define void @f4(i16 *%dst, i16 %a) { +; CHECK-LABEL: f4: +; CHECK: strvh %r3, -2(%r2) +; CHECK: br %r14 + %ptr = getelementptr i16, i16 *%dst, i64 -1 + %swapped = call i16 @llvm.bswap.i16(i16 %a) + store i16 %swapped, i16 *%ptr + ret void +} + +; Check the low end of the STRVH range. +define void @f5(i16 *%dst, i16 %a) { +; CHECK-LABEL: f5: +; CHECK: strvh %r3, -524288(%r2) +; CHECK: br %r14 + %ptr = getelementptr i16, i16 *%dst, i64 -262144 + %swapped = call i16 @llvm.bswap.i16(i16 %a) + store i16 %swapped, i16 *%ptr + ret void +} + +; Check the next word down, which needs separate address logic. +; Other sequences besides this one would be OK. +define void @f6(i16 *%dst, i16 %a) { +; CHECK-LABEL: f6: +; CHECK: agfi %r2, -524290 +; CHECK: strvh %r3, 0(%r2) +; CHECK: br %r14 + %ptr = getelementptr i16, i16 *%dst, i64 -262145 + %swapped = call i16 @llvm.bswap.i16(i16 %a) + store i16 %swapped, i16 *%ptr + ret void +} + +; Check that STRVH allows an index. +define void @f7(i64 %src, i64 %index, i16 %a) { +; CHECK-LABEL: f7: +; CHECK: strvh %r4, 524287({{%r3,%r2|%r2,%r3}}) +; CHECK: br %r14 + %add1 = add i64 %src, %index + %add2 = add i64 %add1, 524287 + %ptr = inttoptr i64 %add2 to i16 * + %swapped = call i16 @llvm.bswap.i16(i16 %a) + store i16 %swapped, i16 *%ptr + ret void +} + +; Check that volatile stores do not use STRVH, which might access the +; storage multple times. +define void @f8(i16 *%dst, i16 %a) { +; CHECK-LABEL: f8: +; CHECK: lrvr [[REG:%r[0-5]]], %r3 +; CHECK: srl [[REG]], 16 +; CHECK: sth [[REG]], 0(%r2) +; CHECK: br %r14 + %swapped = call i16 @llvm.bswap.i16(i16 %a) + store volatile i16 %swapped, i16 *%dst + ret void +} diff --git a/llvm/test/MC/Disassembler/SystemZ/insns.txt b/llvm/test/MC/Disassembler/SystemZ/insns.txt index 9998e5e40e2..54bb78a78e2 100644 --- a/llvm/test/MC/Disassembler/SystemZ/insns.txt +++ b/llvm/test/MC/Disassembler/SystemZ/insns.txt @@ -5209,6 +5209,36 @@ # CHECK: lrvr %r15, %r15 0xb9 0x1f 0x00 0xff +# CHECK: lrvh %r0, -524288 +0xe3 0x00 0x00 0x00 0x80 0x1f + +# CHECK: lrvh %r0, -1 +0xe3 0x00 0x0f 0xff 0xff 0x1f + +# CHECK: lrvh %r0, 0 +0xe3 0x00 0x00 0x00 0x00 0x1f + +# CHECK: lrvh %r0, 1 +0xe3 0x00 0x00 0x01 0x00 0x1f + +# CHECK: lrvh %r0, 524287 +0xe3 0x00 0x0f 0xff 0x7f 0x1f + +# CHECK: lrvh %r0, 0(%r1) +0xe3 0x00 0x10 0x00 0x00 0x1f + +# CHECK: lrvh %r0, 0(%r15) +0xe3 0x00 0xf0 0x00 0x00 0x1f + +# CHECK: lrvh %r0, 524287(%r1,%r15) +0xe3 0x01 0xff 0xff 0x7f 0x1f + +# CHECK: lrvh %r0, 524287(%r15,%r1) +0xe3 0x0f 0x1f 0xff 0x7f 0x1f + +# CHECK: lrvh %r15, 0 +0xe3 0xf0 0x00 0x00 0x00 0x1f + # CHECK: lrv %r0, -524288 0xe3 0x00 0x00 0x00 0x80 0x1e @@ -8500,6 +8530,36 @@ # CHECK: strvg %r15, 0 0xe3 0xf0 0x00 0x00 0x00 0x2f +# CHECK: strvh %r0, -524288 +0xe3 0x00 0x00 0x00 0x80 0x3f + +# CHECK: strvh %r0, -1 +0xe3 0x00 0x0f 0xff 0xff 0x3f + +# CHECK: strvh %r0, 0 +0xe3 0x00 0x00 0x00 0x00 0x3f + +# CHECK: strvh %r0, 1 +0xe3 0x00 0x00 0x01 0x00 0x3f + +# CHECK: strvh %r0, 524287 +0xe3 0x00 0x0f 0xff 0x7f 0x3f + +# CHECK: strvh %r0, 0(%r1) +0xe3 0x00 0x10 0x00 0x00 0x3f + +# CHECK: strvh %r0, 0(%r15) +0xe3 0x00 0xf0 0x00 0x00 0x3f + +# CHECK: strvh %r0, 524287(%r1,%r15) +0xe3 0x01 0xff 0xff 0x7f 0x3f + +# CHECK: strvh %r0, 524287(%r15,%r1) +0xe3 0x0f 0x1f 0xff 0x7f 0x3f + +# CHECK: strvh %r15, 0 +0xe3 0xf0 0x00 0x00 0x00 0x3f + # CHECK: strv %r0, -524288 0xe3 0x00 0x00 0x00 0x80 0x3e diff --git a/llvm/test/MC/SystemZ/insn-good.s b/llvm/test/MC/SystemZ/insn-good.s index 8bb99eda781..344ee138789 100644 --- a/llvm/test/MC/SystemZ/insn-good.s +++ b/llvm/test/MC/SystemZ/insn-good.s @@ -6539,6 +6539,28 @@ lrl %r7,frob@PLT lrl %r8,frob@PLT +#CHECK: lrvh %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0x1f] +#CHECK: lrvh %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0x1f] +#CHECK: lrvh %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0x1f] +#CHECK: lrvh %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0x1f] +#CHECK: lrvh %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0x1f] +#CHECK: lrvh %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0x1f] +#CHECK: lrvh %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0x1f] +#CHECK: lrvh %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0x1f] +#CHECK: lrvh %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0x1f] +#CHECK: lrvh %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0x1f] + + lrvh %r0,-524288 + lrvh %r0,-1 + lrvh %r0,0 + lrvh %r0,1 + lrvh %r0,524287 + lrvh %r0,0(%r1) + lrvh %r0,0(%r15) + lrvh %r0,524287(%r1,%r15) + lrvh %r0,524287(%r15,%r1) + lrvh %r15,0 + #CHECK: lrv %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0x1e] #CHECK: lrv %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0x1e] #CHECK: lrv %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0x1e] @@ -8965,6 +8987,28 @@ strl %r7,frob@PLT strl %r8,frob@PLT +#CHECK: strvh %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0x3f] +#CHECK: strvh %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0x3f] +#CHECK: strvh %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0x3f] +#CHECK: strvh %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0x3f] +#CHECK: strvh %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0x3f] +#CHECK: strvh %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0x3f] +#CHECK: strvh %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0x3f] +#CHECK: strvh %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0x3f] +#CHECK: strvh %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0x3f] +#CHECK: strvh %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0x3f] + + strvh %r0,-524288 + strvh %r0,-1 + strvh %r0,0 + strvh %r0,1 + strvh %r0,524287 + strvh %r0,0(%r1) + strvh %r0,0(%r15) + strvh %r0,524287(%r1,%r15) + strvh %r0,524287(%r15,%r1) + strvh %r15,0 + #CHECK: strv %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0x3e] #CHECK: strv %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0x3e] #CHECK: strv %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0x3e] |

