summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorSander de Smalen <sander.desmalen@arm.com>2018-07-20 09:00:44 +0000
committerSander de Smalen <sander.desmalen@arm.com>2018-07-20 09:00:44 +0000
commit33f588acb9b1203451de4948ff6f0e8ae58c5516 (patch)
tree4c5d831391307d5afe80852be332c7e38cd85e71 /llvm
parent3ed7f81ce1fd45513dc1727a7e04d79472606188 (diff)
downloadbcm5719-llvm-33f588acb9b1203451de4948ff6f0e8ae58c5516.tar.gz
bcm5719-llvm-33f588acb9b1203451de4948ff6f0e8ae58c5516.zip
[AArch64][SVE] Asm: Support for bit/byte reverse operations.
This patch adds the following instructions: RBIT reverse bits within each active elemnt (predicated), e.g. rbit z0.d, p0/m, z1.d for 8, 16, 32 and 64 bit elements. REV reverse order of elements in data/predicate vector (unpredicated), e.g. rev z0.d, z1.d rev p0.d, p1.d for 8, 16, 32 and 64 bit elements. REVB reverse order of bytes within each active element, e.g. revb z0.d, p0/m, z1.d for 16, 32 and 64 bit elements. REVH reverse order of 16-bit half-words within each active element, e.g. revh z0.d, p0/m, z1.d for 32 and 64 bit elements. REVW reverse order of 32-bit words within each active element, e.g. revw z0.d, p0/m, z1.d for 64 bit elements. llvm-svn: 337534
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td8
-rw-r--r--llvm/lib/Target/AArch64/SVEInstrFormats.td86
-rw-r--r--llvm/test/MC/AArch64/SVE/rbit-diagnostics.s10
-rw-r--r--llvm/test/MC/AArch64/SVE/rbit.s32
-rw-r--r--llvm/test/MC/AArch64/SVE/rev.s32
-rw-r--r--llvm/test/MC/AArch64/SVE/revb-diagnostics.s19
-rw-r--r--llvm/test/MC/AArch64/SVE/revb.s26
-rw-r--r--llvm/test/MC/AArch64/SVE/revh-diagnostics.s24
-rw-r--r--llvm/test/MC/AArch64/SVE/revh.s20
-rw-r--r--llvm/test/MC/AArch64/SVE/revw-diagnostics.s29
-rw-r--r--llvm/test/MC/AArch64/SVE/revw.s14
11 files changed, 300 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 028cb3bc9f6..d40f7d8046b 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -180,6 +180,14 @@ let Predicates = [HasSVE] in {
defm INSR_ZV : sve_int_perm_insrv<"insr">;
def EXT_ZZI : sve_int_perm_extract_i<"ext">;
+ defm RBIT_ZPmZ : sve_int_perm_rev_rbit<"rbit">;
+ defm REVB_ZPmZ : sve_int_perm_rev_revb<"revb">;
+ defm REVH_ZPmZ : sve_int_perm_rev_revh<"revh">;
+ defm REVW_ZPmZ : sve_int_perm_rev_revw<"revw">;
+
+ defm REV_PP : sve_int_perm_reverse_p<"rev">;
+ defm REV_ZZ : sve_int_perm_reverse_z<"rev">;
+
defm SUNPKLO_ZZ : sve_int_perm_unpk<0b00, "sunpklo">;
defm SUNPKHI_ZZ : sve_int_perm_unpk<0b01, "sunpkhi">;
defm UUNPKLO_ZZ : sve_int_perm_unpk<0b10, "uunpklo">;
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index e90e30940d9..c334b1f8df7 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -658,6 +658,49 @@ multiclass sve_int_perm_tbl<string asm> {
(!cast<Instruction>(NAME # _D) ZPR64:$Zd, ZPR64:$Zn, ZPR64:$Zm), 0>;
}
+class sve_int_perm_reverse_z<bits<2> sz8_64, string asm, ZPRRegOp zprty>
+: I<(outs zprty:$Zd), (ins zprty:$Zn),
+ asm, "\t$Zd, $Zn",
+ "",
+ []>, Sched<[]> {
+ bits<5> Zd;
+ bits<5> Zn;
+ let Inst{31-24} = 0b00000101;
+ let Inst{23-22} = sz8_64;
+ let Inst{21-10} = 0b111000001110;
+ let Inst{9-5} = Zn;
+ let Inst{4-0} = Zd;
+}
+
+multiclass sve_int_perm_reverse_z<string asm> {
+ def _B : sve_int_perm_reverse_z<0b00, asm, ZPR8>;
+ def _H : sve_int_perm_reverse_z<0b01, asm, ZPR16>;
+ def _S : sve_int_perm_reverse_z<0b10, asm, ZPR32>;
+ def _D : sve_int_perm_reverse_z<0b11, asm, ZPR64>;
+}
+
+class sve_int_perm_reverse_p<bits<2> sz8_64, string asm, PPRRegOp pprty>
+: I<(outs pprty:$Pd), (ins pprty:$Pn),
+ asm, "\t$Pd, $Pn",
+ "",
+ []>, Sched<[]> {
+ bits<4> Pd;
+ bits<4> Pn;
+ let Inst{31-24} = 0b00000101;
+ let Inst{23-22} = sz8_64;
+ let Inst{21-9} = 0b1101000100000;
+ let Inst{8-5} = Pn;
+ let Inst{4} = 0b0;
+ let Inst{3-0} = Pd;
+}
+
+multiclass sve_int_perm_reverse_p<string asm> {
+ def _B : sve_int_perm_reverse_p<0b00, asm, PPR8>;
+ def _H : sve_int_perm_reverse_p<0b01, asm, PPR16>;
+ def _S : sve_int_perm_reverse_p<0b10, asm, PPR32>;
+ def _D : sve_int_perm_reverse_p<0b11, asm, PPR64>;
+}
+
class sve_int_perm_unpk<bits<2> sz16_64, bits<2> opc, string asm,
ZPRRegOp zprty1, ZPRRegOp zprty2>
: I<(outs zprty1:$Zd), (ins zprty2:$Zn),
@@ -2971,6 +3014,49 @@ multiclass sve_int_perm_splice<string asm> {
def _D : sve_int_perm_splice<0b11, asm, ZPR64>;
}
+class sve_int_perm_rev<bits<2> sz8_64, bits<2> opc, string asm,
+ ZPRRegOp zprty>
+: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
+ asm, "\t$Zd, $Pg/m, $Zn",
+ "",
+ []>, Sched<[]> {
+ bits<5> Zd;
+ bits<3> Pg;
+ bits<5> Zn;
+ let Inst{31-24} = 0b00000101;
+ let Inst{23-22} = sz8_64;
+ let Inst{21-18} = 0b1001;
+ let Inst{17-16} = opc;
+ let Inst{15-13} = 0b100;
+ let Inst{12-10} = Pg;
+ let Inst{9-5} = Zn;
+ let Inst{4-0} = Zd;
+
+ let Constraints = "$Zd = $_Zd";
+}
+
+multiclass sve_int_perm_rev_rbit<string asm> {
+ def _B : sve_int_perm_rev<0b00, 0b11, asm, ZPR8>;
+ def _H : sve_int_perm_rev<0b01, 0b11, asm, ZPR16>;
+ def _S : sve_int_perm_rev<0b10, 0b11, asm, ZPR32>;
+ def _D : sve_int_perm_rev<0b11, 0b11, asm, ZPR64>;
+}
+
+multiclass sve_int_perm_rev_revb<string asm> {
+ def _H : sve_int_perm_rev<0b01, 0b00, asm, ZPR16>;
+ def _S : sve_int_perm_rev<0b10, 0b00, asm, ZPR32>;
+ def _D : sve_int_perm_rev<0b11, 0b00, asm, ZPR64>;
+}
+
+multiclass sve_int_perm_rev_revh<string asm> {
+ def _S : sve_int_perm_rev<0b10, 0b01, asm, ZPR32>;
+ def _D : sve_int_perm_rev<0b11, 0b01, asm, ZPR64>;
+}
+
+multiclass sve_int_perm_rev_revw<string asm> {
+ def _D : sve_int_perm_rev<0b11, 0b10, asm, ZPR64>;
+}
+
class sve_int_perm_cpy_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,
RegisterClass srcRegType>
: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegType:$Rn),
diff --git a/llvm/test/MC/AArch64/SVE/rbit-diagnostics.s b/llvm/test/MC/AArch64/SVE/rbit-diagnostics.s
new file mode 100644
index 00000000000..0ee9e3e60b9
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE/rbit-diagnostics.s
@@ -0,0 +1,10 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s
+
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+rbit z0.d, p8/m, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7].
+// CHECK-NEXT: rbit z0.d, p8/m, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SVE/rbit.s b/llvm/test/MC/AArch64/SVE/rbit.s
new file mode 100644
index 00000000000..9d017d9ce45
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE/rbit.s
@@ -0,0 +1,32 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
+// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
+// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+
+rbit z0.b, p7/m, z31.b
+// CHECK-INST: rbit z0.b, p7/m, z31.b
+// CHECK-ENCODING: [0xe0,0x9f,0x27,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 9f 27 05 <unknown>
+
+rbit z0.h, p7/m, z31.h
+// CHECK-INST: rbit z0.h, p7/m, z31.h
+// CHECK-ENCODING: [0xe0,0x9f,0x67,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 9f 67 05 <unknown>
+
+rbit z0.s, p7/m, z31.s
+// CHECK-INST: rbit z0.s, p7/m, z31.s
+// CHECK-ENCODING: [0xe0,0x9f,0xa7,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 9f a7 05 <unknown>
+
+rbit z0.d, p7/m, z31.d
+// CHECK-INST: rbit z0.d, p7/m, z31.d
+// CHECK-ENCODING: [0xe0,0x9f,0xe7,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 9f e7 05 <unknown>
diff --git a/llvm/test/MC/AArch64/SVE/rev.s b/llvm/test/MC/AArch64/SVE/rev.s
new file mode 100644
index 00000000000..bc68fbbddd4
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE/rev.s
@@ -0,0 +1,32 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
+// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
+// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+
+rev z0.b, z31.b
+// CHECK-INST: rev z0.b, z31.b
+// CHECK-ENCODING: [0xe0,0x3b,0x38,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 3b 38 05 <unknown>
+
+rev z0.h, z31.h
+// CHECK-INST: rev z0.h, z31.h
+// CHECK-ENCODING: [0xe0,0x3b,0x78,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 3b 78 05 <unknown>
+
+rev z0.s, z31.s
+// CHECK-INST: rev z0.s, z31.s
+// CHECK-ENCODING: [0xe0,0x3b,0xb8,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 3b b8 05 <unknown>
+
+rev z0.d, z31.d
+// CHECK-INST: rev z0.d, z31.d
+// CHECK-ENCODING: [0xe0,0x3b,0xf8,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 3b f8 05 <unknown>
diff --git a/llvm/test/MC/AArch64/SVE/revb-diagnostics.s b/llvm/test/MC/AArch64/SVE/revb-diagnostics.s
new file mode 100644
index 00000000000..9b201e0c1f1
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE/revb-diagnostics.s
@@ -0,0 +1,19 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s
+
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+revb z0.d, p8/m, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7].
+// CHECK-NEXT: revb z0.d, p8/m, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+
+// ------------------------------------------------------------------------- //
+// Invalid element size
+
+revb z0.b, p0/m, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revb z0.b, p0/m, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SVE/revb.s b/llvm/test/MC/AArch64/SVE/revb.s
new file mode 100644
index 00000000000..b80f9a5d049
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE/revb.s
@@ -0,0 +1,26 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
+// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
+// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+
+revb z0.h, p7/m, z31.h
+// CHECK-INST: revb z0.h, p7/m, z31.h
+// CHECK-ENCODING: [0xe0,0x9f,0x64,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 9f 64 05 <unknown>
+
+revb z0.s, p7/m, z31.s
+// CHECK-INST: revb z0.s, p7/m, z31.s
+// CHECK-ENCODING: [0xe0,0x9f,0xa4,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 9f a4 05 <unknown>
+
+revb z0.d, p7/m, z31.d
+// CHECK-INST: revb z0.d, p7/m, z31.d
+// CHECK-ENCODING: [0xe0,0x9f,0xe4,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 9f e4 05 <unknown>
diff --git a/llvm/test/MC/AArch64/SVE/revh-diagnostics.s b/llvm/test/MC/AArch64/SVE/revh-diagnostics.s
new file mode 100644
index 00000000000..8795b239fac
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE/revh-diagnostics.s
@@ -0,0 +1,24 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s
+
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+revh z0.d, p8/m, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7].
+// CHECK-NEXT: revh z0.d, p8/m, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+
+// ------------------------------------------------------------------------- //
+// Invalid element size
+
+revh z0.b, p0/m, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revh z0.b, p0/m, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revh z0.h, p0/m, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revh z0.h, p0/m, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SVE/revh.s b/llvm/test/MC/AArch64/SVE/revh.s
new file mode 100644
index 00000000000..8332461a1e6
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE/revh.s
@@ -0,0 +1,20 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
+// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
+// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+
+revh z0.s, p7/m, z31.s
+// CHECK-INST: revh z0.s, p7/m, z31.s
+// CHECK-ENCODING: [0xe0,0x9f,0xa5,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 9f a5 05 <unknown>
+
+revh z0.d, p7/m, z31.d
+// CHECK-INST: revh z0.d, p7/m, z31.d
+// CHECK-ENCODING: [0xe0,0x9f,0xe5,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 9f e5 05 <unknown>
diff --git a/llvm/test/MC/AArch64/SVE/revw-diagnostics.s b/llvm/test/MC/AArch64/SVE/revw-diagnostics.s
new file mode 100644
index 00000000000..95f3cbba1b8
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE/revw-diagnostics.s
@@ -0,0 +1,29 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s
+
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+revw z0.d, p8/m, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7].
+// CHECK-NEXT: revw z0.d, p8/m, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+
+// ------------------------------------------------------------------------- //
+// Invalid element size
+
+revw z0.b, p0/m, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revw z0.b, p0/m, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revw z0.h, p0/m, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revw z0.h, p0/m, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revw z0.s, p0/m, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revw z0.s, p0/m, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SVE/revw.s b/llvm/test/MC/AArch64/SVE/revw.s
new file mode 100644
index 00000000000..095e2aacd87
--- /dev/null
+++ b/llvm/test/MC/AArch64/SVE/revw.s
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
+// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \
+// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+
+revw z0.d, p7/m, z31.d
+// CHECK-INST: revw z0.d, p7/m, z31.d
+// CHECK-ENCODING: [0xe0,0x9f,0xe6,0x05]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: e0 9f e6 05 <unknown>
OpenPOWER on IntegriCloud