diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index c9ee2d0059a9fe..2564ddc5f2e5ca 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -2129,7 +2129,7 @@ let Predicates = [HasSVEorSME] in { defm CNTH_XPiI : sve_int_count<0b010, "cnth", int_aarch64_sve_cnth>; defm CNTW_XPiI : sve_int_count<0b100, "cntw", int_aarch64_sve_cntw>; defm CNTD_XPiI : sve_int_count<0b110, "cntd", int_aarch64_sve_cntd>; - defm CNTP_XPP : sve_int_pcount_pred<0b0000, "cntp", int_aarch64_sve_cntp>; + defm CNTP_XPP : sve_int_pcount_pred<0b000, "cntp", int_aarch64_sve_cntp>; def : Pat<(i64 (AArch64CttzElts nxv16i1:$Op1)), (CNTP_XPP_B (BRKB_PPzP (PTRUE_B 31), PPR:$Op1), @@ -4304,6 +4304,9 @@ let Predicates = [HasSVE2p2orSME2p2] in { def SXTW_ZPzZ_D : sve_int_un_pred_arit_z<0b11, 0b1000, "sxtw", ZPR64>; def UXTW_ZPzZ_D : sve_int_un_pred_arit_z<0b11, 0b1010, "uxtw", ZPR64>; + // SVE predicate count + defm FIRSTP_XPP : sve_int_pcount_pred_tmp<0b001, "firstp">; + defm LASTP_XPP : sve_int_pcount_pred_tmp<0b010, "lastp">; } // End HasSME2p2orSVE2p2 //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 3637a63684a0de..9fa184c545705b 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -1046,7 +1046,7 @@ multiclass sve_int_count_v opc, string asm, (!cast(NAME # "_D") ZPR64:$Zdn, PPRAny:$Pm), 0>; } -class sve_int_pcount_pred sz8_64, bits<4> opc, string asm, +class sve_int_pcount_pred sz8_64, bits<3> opc, string asm, PPRRegOp pprty> : I<(outs GPR64:$Rd), (ins PPRAny:$Pg, pprty:$Pn), asm, "\t$Rd, $Pg, $Pn", @@ -1058,17 +1058,17 @@ class sve_int_pcount_pred sz8_64, bits<4> opc, string asm, let Inst{31-24} = 0b00100101; let Inst{23-22} = sz8_64; let Inst{21-19} = 0b100; - let Inst{18-16} = opc{3-1}; + let Inst{18-16} = opc{2-0}; let Inst{15-14} = 0b10; let Inst{13-10} = Pg; - let Inst{9} = opc{0}; + let Inst{9} = 0b0; let Inst{8-5} = Pn; let Inst{4-0} = Rd; let hasSideEffects = 0; } -multiclass sve_int_pcount_pred opc, string asm, +multiclass sve_int_pcount_pred opc, string asm, SDPatternOperator int_op> { def _B : sve_int_pcount_pred<0b00, opc, asm, PPR8>; def _H : sve_int_pcount_pred<0b01, opc, asm, PPR16>; @@ -1081,6 +1081,12 @@ multiclass sve_int_pcount_pred opc, string asm, def : SVE_2_Op_Pat(NAME # _D)>; } +multiclass sve_int_pcount_pred_tmp opc, string asm> { + def _B : sve_int_pcount_pred<0b00, opc, asm, PPR8>; + def _H : sve_int_pcount_pred<0b01, opc, asm, PPR16>; + def _S : sve_int_pcount_pred<0b10, opc, asm, PPR32>; + def _D : sve_int_pcount_pred<0b11, opc, asm, PPR64>; +} //===----------------------------------------------------------------------===// // SVE Element Count Group //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/AArch64/SVE2p2/firstp-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/firstp-diagnostics.s new file mode 100644 index 00000000000000..4309fd49ecf79f --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p2/firstp-diagnostics.s @@ -0,0 +1,32 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s + +// ------------------------------------------------------------------------- // +// Invalid predicate operand + +firstp x0, p15, p0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register. +// CHECK-NEXT: firstp x0, p15, p0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +firstp x0, p15.b, p0.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register. +// CHECK-NEXT: firstp x0, p15.b, p0.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +firstp x0, p15.q, p0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register. +// CHECK-NEXT: firstp x0, p15.q, p0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// ------------------------------------------------------------------------- // +// Invalid register types + +firstp sp, p15, p0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: firstp sp, p15, p0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +firstp w0, p15, p0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: firstp w0, p15, p0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SVE2p2/firstp.s b/llvm/test/MC/AArch64/SVE2p2/firstp.s new file mode 100644 index 00000000000000..629bee5576fc7d --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p2/firstp.s @@ -0,0 +1,87 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %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=+sve2p2 < %s \ +// RUN: | llvm-objdump -d --mattr=+sve2p2 - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p2 < %s \ +// RUN: | llvm-objdump -d --mattr=-sme2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sve2p2 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +firstp x0, p0, p0.b // 00100101-00100001-10000000-00000000 +// CHECK-INST: firstp x0, p0, p0.b +// CHECK-ENCODING: [0x00,0x80,0x21,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25218000 + +firstp x23, p11, p13.b // 00100101-00100001-10101101-10110111 +// CHECK-INST: firstp x23, p11, p13.b +// CHECK-ENCODING: [0xb7,0xad,0x21,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 2521adb7 + +firstp xzr, p15, p15.b // 00100101-00100001-10111101-11111111 +// CHECK-INST: firstp xzr, p15, p15.b +// CHECK-ENCODING: [0xff,0xbd,0x21,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 2521bdff + +firstp x0, p0, p0.h // 00100101-01100001-10000000-00000000 +// CHECK-INST: firstp x0, p0, p0.h +// CHECK-ENCODING: [0x00,0x80,0x61,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25618000 + +firstp x23, p11, p13.h // 00100101-01100001-10101101-10110111 +// CHECK-INST: firstp x23, p11, p13.h +// CHECK-ENCODING: [0xb7,0xad,0x61,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 2561adb7 + +firstp xzr, p15, p15.h // 00100101-01100001-10111101-11111111 +// CHECK-INST: firstp xzr, p15, p15.h +// CHECK-ENCODING: [0xff,0xbd,0x61,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 2561bdff + +firstp x0, p0, p0.s // 00100101-10100001-10000000-00000000 +// CHECK-INST: firstp x0, p0, p0.s +// CHECK-ENCODING: [0x00,0x80,0xa1,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25a18000 + +firstp x23, p11, p13.s // 00100101-10100001-10101101-10110111 +// CHECK-INST: firstp x23, p11, p13.s +// CHECK-ENCODING: [0xb7,0xad,0xa1,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25a1adb7 + +firstp xzr, p15, p15.s // 00100101-10100001-10111101-11111111 +// CHECK-INST: firstp xzr, p15, p15.s +// CHECK-ENCODING: [0xff,0xbd,0xa1,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25a1bdff + +firstp x0, p0, p0.d // 00100101-11100001-10000000-00000000 +// CHECK-INST: firstp x0, p0, p0.d +// CHECK-ENCODING: [0x00,0x80,0xe1,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25e18000 + +firstp x23, p11, p13.d // 00100101-11100001-10101101-10110111 +// CHECK-INST: firstp x23, p11, p13.d +// CHECK-ENCODING: [0xb7,0xad,0xe1,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25e1adb7 + +firstp xzr, p15, p15.d // 00100101-11100001-10111101-11111111 +// CHECK-INST: firstp xzr, p15, p15.d +// CHECK-ENCODING: [0xff,0xbd,0xe1,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25e1bdff \ No newline at end of file diff --git a/llvm/test/MC/AArch64/SVE2p2/lastp-diagnostics.s b/llvm/test/MC/AArch64/SVE2p2/lastp-diagnostics.s new file mode 100644 index 00000000000000..e277bdbc6aa8b3 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p2/lastp-diagnostics.s @@ -0,0 +1,32 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 2>&1 < %s| FileCheck %s + +// ------------------------------------------------------------------------- // +// Invalid predicate operand + +lastp x0, p15, p0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register. +// CHECK-NEXT: lastp x0, p15, p0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +lastp x0, p15.b, p0.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register. +// CHECK-NEXT: lastp x0, p15.b, p0.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +lastp x0, p15.q, p0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register. +// CHECK-NEXT: lastp x0, p15.q, p0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// ------------------------------------------------------------------------- // +// Invalid register types + +lastp sp, p15, p0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: lastp sp, p15, p0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +lastp w0, p15, p0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: lastp w0, p15, p0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: \ No newline at end of file diff --git a/llvm/test/MC/AArch64/SVE2p2/lastp.s b/llvm/test/MC/AArch64/SVE2p2/lastp.s new file mode 100644 index 00000000000000..1ffa0a7d1fcc19 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2p2/lastp.s @@ -0,0 +1,87 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %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=+sve2p2 < %s \ +// RUN: | llvm-objdump -d --mattr=+sve2p2 - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2p2 < %s \ +// RUN: | llvm-objdump -d --mattr=-sme2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p2 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sve2p2 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +lastp x0, p0, p0.b // 00100101-00100010-10000000-00000000 +// CHECK-INST: lastp x0, p0, p0.b +// CHECK-ENCODING: [0x00,0x80,0x22,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25228000 + +lastp x23, p11, p13.b // 00100101-00100010-10101101-10110111 +// CHECK-INST: lastp x23, p11, p13.b +// CHECK-ENCODING: [0xb7,0xad,0x22,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 2522adb7 + +lastp xzr, p15, p15.b // 00100101-00100010-10111101-11111111 +// CHECK-INST: lastp xzr, p15, p15.b +// CHECK-ENCODING: [0xff,0xbd,0x22,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 2522bdff + +lastp x0, p0, p0.h // 00100101-01100010-10000000-00000000 +// CHECK-INST: lastp x0, p0, p0.h +// CHECK-ENCODING: [0x00,0x80,0x62,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25628000 + +lastp x23, p11, p13.h // 00100101-01100010-10101101-10110111 +// CHECK-INST: lastp x23, p11, p13.h +// CHECK-ENCODING: [0xb7,0xad,0x62,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 2562adb7 + +lastp xzr, p15, p15.h // 00100101-01100010-10111101-11111111 +// CHECK-INST: lastp xzr, p15, p15.h +// CHECK-ENCODING: [0xff,0xbd,0x62,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 2562bdff + +lastp x0, p0, p0.s // 00100101-10100010-10000000-00000000 +// CHECK-INST: lastp x0, p0, p0.s +// CHECK-ENCODING: [0x00,0x80,0xa2,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25a28000 + +lastp x23, p11, p13.s // 00100101-10100010-10101101-10110111 +// CHECK-INST: lastp x23, p11, p13.s +// CHECK-ENCODING: [0xb7,0xad,0xa2,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25a2adb7 + +lastp xzr, p15, p15.s // 00100101-10100010-10111101-11111111 +// CHECK-INST: lastp xzr, p15, p15.s +// CHECK-ENCODING: [0xff,0xbd,0xa2,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25a2bdff + +lastp x0, p0, p0.d // 00100101-11100010-10000000-00000000 +// CHECK-INST: lastp x0, p0, p0.d +// CHECK-ENCODING: [0x00,0x80,0xe2,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25e28000 + +lastp x23, p11, p13.d // 00100101-11100010-10101101-10110111 +// CHECK-INST: lastp x23, p11, p13.d +// CHECK-ENCODING: [0xb7,0xad,0xe2,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25e2adb7 + +lastp xzr, p15, p15.d // 00100101-11100010-10111101-11111111 +// CHECK-INST: lastp xzr, p15, p15.d +// CHECK-ENCODING: [0xff,0xbd,0xe2,0x25] +// CHECK-ERROR: instruction requires: sme2p2 or sve2p2 +// CHECK-UNKNOWN: 25e2bdff \ No newline at end of file