From: Sander de Smalen Date: Sun, 29 Jul 2018 08:00:16 +0000 (+0000) Subject: [AArch64][SVE] Asm: Instructions to perform serialized operations. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=32d3bbcc6c7c0499f027154a417d2312715ea8a4;p=llvm [AArch64][SVE] Asm: Instructions to perform serialized operations. The instructions added in this patch permit active elements within a vector to be processed sequentially without unpacking the vector. PFIRST Set the first active element to true. PNEXT Find next active element in predicate. CTERMEQ Compare and terminate loop when equal. CTERMNE Compare and terminate loop when not equal. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338210 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AArch64/AArch64SVEInstrInfo.td b/lib/Target/AArch64/AArch64SVEInstrInfo.td index e0013529a26..1a14d4a424e 100644 --- a/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -241,6 +241,8 @@ let Predicates = [HasSVE] in { def PTEST_PP : sve_int_ptest<0b010000, "ptest">; def PFALSE : sve_int_pfalse<0b000000, "pfalse">; + defm PFIRST : sve_int_pfirst<0b00000, "pfirst">; + defm PNEXT : sve_int_pnext<0b00110, "pnext">; def AND_PPzPP : sve_int_pred_log<0b0000, "and">; def BIC_PPzPP : sve_int_pred_log<0b0001, "bic">; @@ -749,6 +751,11 @@ let Predicates = [HasSVE] in { defm FCMEQ_PPzZ0 : sve_fp_2op_p_pd<0b100, "fcmeq">; defm FCMNE_PPzZ0 : sve_fp_2op_p_pd<0b110, "fcmne">; + def CTERMEQ_WW : sve_int_cterm<0b0, 0b0, "ctermeq", GPR32>; + def CTERMNE_WW : sve_int_cterm<0b0, 0b1, "ctermne", GPR32>; + def CTERMEQ_XX : sve_int_cterm<0b1, 0b0, "ctermeq", GPR64>; + def CTERMNE_XX : sve_int_cterm<0b1, 0b1, "ctermne", GPR64>; + def RDVLI_XI : sve_int_read_vl_a<0b0, 0b11111, "rdvl">; def ADDVL_XXI : sve_int_arith_vl<0b0, "addvl">; def ADDPL_XXI : sve_int_arith_vl<0b1, "addpl">; diff --git a/lib/Target/AArch64/SVEInstrFormats.td b/lib/Target/AArch64/SVEInstrFormats.td index b00af930dc1..445a191c48d 100644 --- a/lib/Target/AArch64/SVEInstrFormats.td +++ b/lib/Target/AArch64/SVEInstrFormats.td @@ -321,6 +321,38 @@ class sve_int_ptest opc, string asm> let Defs = [NZCV]; } +class sve_int_pfirst_next sz8_64, bits<5> opc, string asm, + PPRRegOp pprty> +: I<(outs pprty:$Pdn), (ins PPRAny:$Pg, pprty:$_Pdn), + asm, "\t$Pdn, $Pg, $_Pdn", + "", + []>, Sched<[]> { + bits<4> Pdn; + bits<4> Pg; + let Inst{31-24} = 0b00100101; + let Inst{23-22} = sz8_64; + let Inst{21-19} = 0b011; + let Inst{18-16} = opc{4-2}; + let Inst{15-11} = 0b11000; + let Inst{10-9} = opc{1-0}; + let Inst{8-5} = Pg; + let Inst{4} = 0; + let Inst{3-0} = Pdn; + + let Constraints = "$Pdn = $_Pdn"; + let Defs = [NZCV]; +} + +multiclass sve_int_pfirst opc, string asm> { + def : sve_int_pfirst_next<0b01, opc, asm, PPR8>; +} + +multiclass sve_int_pnext opc, string asm> { + def _B : sve_int_pfirst_next<0b00, opc, asm, PPR8>; + def _H : sve_int_pfirst_next<0b01, opc, asm, PPR16>; + def _S : sve_int_pfirst_next<0b10, opc, asm, PPR32>; + def _D : sve_int_pfirst_next<0b11, opc, asm, PPR64>; +} //===----------------------------------------------------------------------===// // SVE Predicate Count Group @@ -2123,6 +2155,30 @@ multiclass sve_int_ucmp_vi opc, string asm> { } +//===----------------------------------------------------------------------===// +// SVE Integer Compare - Scalars Group +//===----------------------------------------------------------------------===// + +class sve_int_cterm +: I<(outs), (ins rt:$Rn, rt:$Rm), + asm, "\t$Rn, $Rm", + "", + []>, Sched<[]> { + bits<5> Rm; + bits<5> Rn; + let Inst{31-23} = 0b001001011; + let Inst{22} = sz; + let Inst{21} = 0b1; + let Inst{20-16} = Rm; + let Inst{15-10} = 0b001000; + let Inst{9-5} = Rn; + let Inst{4} = opc; + let Inst{3-0} = 0b0000; + + let Defs = [NZCV]; +} + + //===----------------------------------------------------------------------===// // SVE Floating Point Fast Reduction Group //===----------------------------------------------------------------------===// diff --git a/test/MC/AArch64/SVE/ctermeq-diagnostics.s b/test/MC/AArch64/SVE/ctermeq-diagnostics.s new file mode 100644 index 00000000000..74afc10cb57 --- /dev/null +++ b/test/MC/AArch64/SVE/ctermeq-diagnostics.s @@ -0,0 +1,25 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + + +// ------------------------------------------------------------------------- // +// Invalid scalar registers + +ctermeq w30, wsp +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ctermeq w30, wsp +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ctermeq w30, x0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ctermeq w30, x0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ctermeq wsp, w30 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ctermeq wsp, w30 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ctermeq x0, w30 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ctermeq x0, w30 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/ctermeq.s b/test/MC/AArch64/SVE/ctermeq.s new file mode 100644 index 00000000000..3dfac002350 --- /dev/null +++ b/test/MC/AArch64/SVE/ctermeq.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 + +ctermeq w30, wzr +// CHECK-INST: ctermeq w30, wzr +// CHECK-ENCODING: [0xc0,0x23,0xbf,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: c0 23 bf 25 + +ctermeq wzr, w30 +// CHECK-INST: ctermeq wzr, w30 +// CHECK-ENCODING: [0xe0,0x23,0xbe,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 23 be 25 + +ctermeq x30, xzr +// CHECK-INST: ctermeq x30, xzr +// CHECK-ENCODING: [0xc0,0x23,0xff,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: c0 23 ff 25 + +ctermeq xzr, x30 +// CHECK-INST: ctermeq xzr, x30 +// CHECK-ENCODING: [0xe0,0x23,0xfe,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 23 fe 25 diff --git a/test/MC/AArch64/SVE/ctermne-diagnostics.s b/test/MC/AArch64/SVE/ctermne-diagnostics.s new file mode 100644 index 00000000000..96346f44449 --- /dev/null +++ b/test/MC/AArch64/SVE/ctermne-diagnostics.s @@ -0,0 +1,25 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + + +// ------------------------------------------------------------------------- // +// Invalid scalar registers + +ctermne w30, wsp +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ctermne w30, wsp +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ctermne w30, x0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ctermne w30, x0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ctermne wsp, w30 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ctermne wsp, w30 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +ctermne x0, w30 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: ctermne x0, w30 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/ctermne.s b/test/MC/AArch64/SVE/ctermne.s new file mode 100644 index 00000000000..54dc5e23a9c --- /dev/null +++ b/test/MC/AArch64/SVE/ctermne.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 + +ctermne w30, wzr +// CHECK-INST: ctermne w30, wzr +// CHECK-ENCODING: [0xd0,0x23,0xbf,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: d0 23 bf 25 + +ctermne wzr, w30 +// CHECK-INST: ctermne wzr, w30 +// CHECK-ENCODING: [0xf0,0x23,0xbe,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: f0 23 be 25 + +ctermne x30, xzr +// CHECK-INST: ctermne x30, xzr +// CHECK-ENCODING: [0xd0,0x23,0xff,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: d0 23 ff 25 + +ctermne xzr, x30 +// CHECK-INST: ctermne xzr, x30 +// CHECK-ENCODING: [0xf0,0x23,0xfe,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: f0 23 fe 25 diff --git a/test/MC/AArch64/SVE/pfirst-diagnostics.s b/test/MC/AArch64/SVE/pfirst-diagnostics.s new file mode 100644 index 00000000000..6ed891a59f2 --- /dev/null +++ b/test/MC/AArch64/SVE/pfirst-diagnostics.s @@ -0,0 +1,19 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + + +// ------------------------------------------------------------------------- // +// Only .b is supported + +pfirst p0.h, p15, p0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register +// CHECK-NEXT: pfirst p0.h, p15, p0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Tied operands must match + +pfirst p0.b, p15, p1.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register +// CHECK-NEXT: pfirst p0.b, p15, p1.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/pfirst.s b/test/MC/AArch64/SVE/pfirst.s new file mode 100644 index 00000000000..8090bf72a0e --- /dev/null +++ b/test/MC/AArch64/SVE/pfirst.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 + +pfirst p0.b, p15, p0.b +// CHECK-INST: pfirst p0.b, p15, p0.b +// CHECK-ENCODING: [0xe0,0xc1,0x58,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 c1 58 25 + +pfirst p15.b, p15, p15.b +// CHECK-INST: pfirst p15.b, p15, p15.b +// CHECK-ENCODING: [0xef,0xc1,0x58,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ef c1 58 25 diff --git a/test/MC/AArch64/SVE/pnext-diagnostics.s b/test/MC/AArch64/SVE/pnext-diagnostics.s new file mode 100644 index 00000000000..e8ee5669dfe --- /dev/null +++ b/test/MC/AArch64/SVE/pnext-diagnostics.s @@ -0,0 +1,10 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + + +// ------------------------------------------------------------------------- // +// Tied operands must match + +pnext p0.b, p15, p1.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register +// CHECK-NEXT: pnext p0.b, p15, p1.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/pnext.s b/test/MC/AArch64/SVE/pnext.s new file mode 100644 index 00000000000..3d788deb05c --- /dev/null +++ b/test/MC/AArch64/SVE/pnext.s @@ -0,0 +1,38 @@ +// 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 + +pnext p15.b, p15, p15.b +// CHECK-INST: pnext p15.b, p15, p15.b +// CHECK-ENCODING: [0xef,0xc5,0x19,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ef c5 19 25 + +pnext p0.b, p15, p0.b +// CHECK-INST: pnext p0.b, p15, p0.b +// CHECK-ENCODING: [0xe0,0xc5,0x19,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 c5 19 25 + +pnext p0.h, p15, p0.h +// CHECK-INST: pnext p0.h, p15, p0.h +// CHECK-ENCODING: [0xe0,0xc5,0x59,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 c5 59 25 + +pnext p0.s, p15, p0.s +// CHECK-INST: pnext p0.s, p15, p0.s +// CHECK-ENCODING: [0xe0,0xc5,0x99,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 c5 99 25 + +pnext p0.d, p15, p0.d +// CHECK-INST: pnext p0.d, p15, p0.d +// CHECK-ENCODING: [0xe0,0xc5,0xd9,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 c5 d9 25