From: Sander de Smalen Date: Tue, 17 Jul 2018 08:52:45 +0000 (+0000) Subject: [AArch64][SVE] Asm: Support for SPLICE instruction. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6151dbec9310eb6831feb46d6f9d9e1b52a7757e;p=llvm [AArch64][SVE] Asm: Support for SPLICE instruction. The SPLICE instruction splices two vectors into one vector using a predicate. It copies the active elements from the first vector, and then fills the remaining elements with the low-numbered elements from the second vector. The instruction has the following form, e.g. splice z0.b, p0, z0.b, z1.b for 8-bit elements. It also supports 16, 32 and 64-bit elements. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337253 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AArch64/AArch64SVEInstrInfo.td b/lib/Target/AArch64/AArch64SVEInstrInfo.td index c3885c6d7e9..1edc36944a1 100644 --- a/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -112,6 +112,7 @@ let Predicates = [HasSVE] in { // Select elements from either vector (predicated) defm SEL_ZPZZ : sve_int_sel_vvv<"sel">; + defm SPLICE_ZPZ : sve_int_perm_splice<"splice">; defm COMPACT_ZPZ : sve_int_perm_compact<"compact">; defm INSR_ZR : sve_int_perm_insrs<"insr">; defm INSR_ZV : sve_int_perm_insrv<"insr">; diff --git a/lib/Target/AArch64/SVEInstrFormats.td b/lib/Target/AArch64/SVEInstrFormats.td index 0d5b8b13b8e..2c37be691bb 100644 --- a/lib/Target/AArch64/SVEInstrFormats.td +++ b/lib/Target/AArch64/SVEInstrFormats.td @@ -2610,6 +2610,31 @@ multiclass sve_int_perm_last_v { def _D : sve_int_perm_last_v<0b11, ab, asm, ZPR64, FPR64>; } +class sve_int_perm_splice sz8_64, string asm, ZPRRegOp zprty> +: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm), + asm, "\t$Zdn, $Pg, $_Zdn, $Zm", + "", + []>, Sched<[]> { + bits<3> Pg; + bits<5> Zdn; + bits<5> Zm; + let Inst{31-24} = 0b00000101; + let Inst{23-22} = sz8_64; + let Inst{21-13} = 0b101100100; + let Inst{12-10} = Pg; + let Inst{9-5} = Zm; + let Inst{4-0} = Zdn; + + let Constraints = "$Zdn = $_Zdn"; +} + +multiclass sve_int_perm_splice { + def _B : sve_int_perm_splice<0b00, asm, ZPR8>; + def _H : sve_int_perm_splice<0b01, asm, ZPR16>; + def _S : sve_int_perm_splice<0b10, asm, ZPR32>; + def _D : sve_int_perm_splice<0b11, asm, ZPR64>; +} + class sve_int_perm_cpy_r sz8_64, string asm, ZPRRegOp zprty, RegisterClass srcRegType> : I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegType:$Rn), diff --git a/test/MC/AArch64/SVE/splice-diagnostics.s b/test/MC/AArch64/SVE/splice-diagnostics.s new file mode 100644 index 00000000000..dbac7403c4c --- /dev/null +++ b/test/MC/AArch64/SVE/splice-diagnostics.s @@ -0,0 +1,27 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + +// ------------------------------------------------------------------------- // +// Tied operands must match + +splice z0.b, p0, z1.b, z2.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register +// CHECK-NEXT: splice z0.b, p0, z1.b, z2.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Invalid element widths. + +splice z0.b, p0, z0.b, z2.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: splice z0.b, p0, z0.b, z2.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Invalid predicate + +splice z0.b, p8, z0.b, z1.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: splice z0.b, p8, z0.b, z1.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/splice.s b/test/MC/AArch64/SVE/splice.s new file mode 100644 index 00000000000..a213b76d509 --- /dev/null +++ b/test/MC/AArch64/SVE/splice.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 + +splice z31.b, p7, z31.b, z31.b +// CHECK-INST: splice z31.b, p7, z31.b, z31.b +// CHECK-ENCODING: [0xff,0x9f,0x2c,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff 9f 2c 05 + +splice z31.h, p7, z31.h, z31.h +// CHECK-INST: splice z31.h, p7, z31.h, z31.h +// CHECK-ENCODING: [0xff,0x9f,0x6c,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff 9f 6c 05 + +splice z31.s, p7, z31.s, z31.s +// CHECK-INST: splice z31.s, p7, z31.s, z31.s +// CHECK-ENCODING: [0xff,0x9f,0xac,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff 9f ac 05 + +splice z31.d, p7, z31.d, z31.d +// CHECK-INST: splice z31.d, p7, z31.d, z31.d +// CHECK-ENCODING: [0xff,0x9f,0xec,0x05] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff 9f ec 05