From ec229abb9b01cedd4c7706e5829a3bf875537bef Mon Sep 17 00:00:00 2001 From: Sander de Smalen Date: Tue, 17 Jul 2018 08:52:45 +0000 Subject: [PATCH] [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. llvm-svn: 337253 --- llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td | 1 + llvm/lib/Target/AArch64/SVEInstrFormats.td | 25 ++++++++++++++++++++ llvm/test/MC/AArch64/SVE/splice-diagnostics.s | 27 ++++++++++++++++++++++ llvm/test/MC/AArch64/SVE/splice.s | 32 ++++++++++++++++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 llvm/test/MC/AArch64/SVE/splice-diagnostics.s create mode 100644 llvm/test/MC/AArch64/SVE/splice.s diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index c3885c6..1edc369 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/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/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 0d5b8b1..2c37be6 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/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/llvm/test/MC/AArch64/SVE/splice-diagnostics.s b/llvm/test/MC/AArch64/SVE/splice-diagnostics.s new file mode 100644 index 0000000..dbac740 --- /dev/null +++ b/llvm/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/llvm/test/MC/AArch64/SVE/splice.s b/llvm/test/MC/AArch64/SVE/splice.s new file mode 100644 index 0000000..a213b76 --- /dev/null +++ b/llvm/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 -- 2.7.4