diff --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td @@ -74,4 +74,15 @@ defm LD1_MXIPXX : sme_mem_ld_ss<"ld1">; defm ST1_MXIPXX : sme_mem_st_ss<"st1">; +//===----------------------------------------------------------------------===// +// SVE2 instructions +//===----------------------------------------------------------------------===// + +def REVD_ZPmZ : sve2_int_perm_revd<"revd">; + +defm SCLAMP_ZZZ : sve2_clamp<"sclamp", 0b0>; +defm UCLAMP_ZZZ : sve2_clamp<"uclamp", 0b1>; + +defm DUP_PPzPRI : sve2_int_perm_dup_p<"dup">; + } // End let Predicates = [HasSME] diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -3567,6 +3567,13 @@ RegNum, RegKind::SVEPredicateVector, ElementWidth, S, getLoc(), getContext())); + if (getLexer().is(AsmToken::LBrac)) { + // Indexed predicate, there's no comma so try parse the next operand + // immediately. + if (parseOperand(Operands, false, false)) + return MatchOperand_NoMatch; + } + // Not all predicates are followed by a '/m' or '/z'. MCAsmParser &Parser = getParser(); if (Parser.getTok().isNot(AsmToken::Slash)) diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td --- a/llvm/lib/Target/AArch64/SMEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td @@ -394,3 +394,108 @@ defm _V : sme_mem_st_v_ss; } +//===----------------------------------------------------------------------===// +// SVE2 Instructions +//===----------------------------------------------------------------------===// + +class sve2_int_perm_revd + : I<(outs ZPR128:$Zd), (ins ZPR128:$_Zd, PPR3bAny:$Pg, ZPR128:$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} = 0b00; // size + let Inst{21-13} = 0b101110100; + let Inst{12-10} = Pg; + let Inst{9-5} = Zn; + let Inst{4-0} = Zd; + + let Constraints = "$Zd = $_Zd"; + let DestructiveInstType = DestructiveUnary; + let ElementSize = ZPR128.ElementSize; +} + +class sve2_clamp sz, bit U, ZPRRegOp zpr_ty> + : I<(outs zpr_ty:$Zd), (ins zpr_ty:$Zn, zpr_ty:$Zm, zpr_ty:$_Zd), + asm, "\t$Zd, $Zn, $Zm", "", []>, + Sched<[]> { + bits<5> Zm; + bits<5> Zn; + bits<5> Zd; + let Inst{31-24} = 0b01000100; + let Inst{23-22} = sz; + let Inst{21} = 0b0; + let Inst{20-16} = Zm; + let Inst{15-11} = 0b11000; + let Inst{10} = U; + let Inst{9-5} = Zn; + let Inst{4-0} = Zd; + + let Constraints = "$Zd = $_Zd"; + let DestructiveInstType = DestructiveOther; + let ElementSize = zpr_ty.ElementSize; +} + +multiclass sve2_clamp { + def _B : sve2_clamp; + def _H : sve2_clamp; + def _S : sve2_clamp; + def _D : sve2_clamp; +} + +class sve2_int_perm_dup_p + : I<(outs ppr_ty:$Pd), (ins PPRAny:$Pg, ppr_ty:$Pn, + MatrixIndexGPR32Op12_15:$Rm, imm_ty:$imm), + asm, "\t$Pd, $Pg/z, $Pn[$Rm, $imm]", "", []>, + Sched<[]> { + bits<2> Rm; + bits<4> Pg; + bits<4> Pn; + bits<4> Pd; + let Inst{31-24} = 0b00100101; + let Inst{21} = 0b1; + let Inst{17-16} = Rm; + let Inst{15-14} = 0b01; + let Inst{13-10} = Pg; + let Inst{9} = 0b0; + let Inst{8-5} = Pn; + let Inst{4} = 0b0; + let Inst{3-0} = Pd; +} + +multiclass sve2_int_perm_dup_p { + def _B : sve2_int_perm_dup_p { + bits<4> imm; + let Inst{23-22} = imm{3-2}; + let Inst{20-19} = imm{1-0}; + let Inst{18} = 0b1; + } + def _H : sve2_int_perm_dup_p { + bits<3> imm; + let Inst{23-22} = imm{2-1}; + let Inst{20} = imm{0}; + let Inst{19-18} = 0b10; + } + def _S : sve2_int_perm_dup_p { + bits<2> imm; + let Inst{23-22} = imm{1-0}; + let Inst{20-18} = 0b100; + } + def _D : sve2_int_perm_dup_p { + bits<1> imm; + let Inst{23} = imm; + let Inst{22} = 0b1; + let Inst{20-18} = 0b000; + } + + def : InstAlias<"dup\t$Pd, $Pg/z, $Pn[$Rm]", + (!cast(NAME # _B) PPR8:$Pd, PPRAny:$Pg, PPR8:$Pn, MatrixIndexGPR32Op12_15:$Rm, 0), 1>; + def : InstAlias<"dup\t$Pd, $Pg/z, $Pn[$Rm]", + (!cast(NAME # _H) PPR16:$Pd, PPRAny:$Pg, PPR16:$Pn, MatrixIndexGPR32Op12_15:$Rm, 0), 1>; + def : InstAlias<"dup\t$Pd, $Pg/z, $Pn[$Rm]", + (!cast(NAME # _S) PPR32:$Pd, PPRAny:$Pg, PPR32:$Pn, MatrixIndexGPR32Op12_15:$Rm, 0), 1>; + def : InstAlias<"dup\t$Pd, $Pg/z, $Pn[$Rm]", + (!cast(NAME # _D) PPR64:$Pd, PPRAny:$Pg, PPR64:$Pn, MatrixIndexGPR32Op12_15:$Rm, 0), 1>; +} diff --git a/llvm/test/MC/AArch64/SME/dup-diagnostics.s b/llvm/test/MC/AArch64/SME/dup-diagnostics.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME/dup-diagnostics.s @@ -0,0 +1,58 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme 2>&1 < %s| FileCheck %s + +// ------------------------------------------------------------------------- // +// Invalid predicate + +// wrong predication qualifier, expected /z. +dup p0.b, p0/m, p0.b[w12] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: dup p0.b, p0/m, p0.b[w12] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// mismatched element type +dup p0.b, p0/z, p0.h[w12] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register. +// CHECK-NEXT: dup p0.b, p0/z, p0.h[w12] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// missing element type suffix +dup p0.b, p0/z, p0[w12] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register. +// CHECK-NEXT: dup p0.b, p0/z, p0[w12] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// ------------------------------------------------------------------------- // +// Invalid index base register register (w12-w15) + +dup p0.b, p0/z, p0.b[w11] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: dup p0.b, p0/z, p0.b[w11] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dup p0.b, p0/z, p0.b[w16] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: dup p0.b, p0/z, p0.b[w16] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid immediates + +dup p0.b, p0/z, p0.b[w12, #16] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 15]. +// CHECK-NEXT: dup p0.b, p0/z, p0.b[w12, #16] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dup p0.h, p0/z, p0.h[w12, #8] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 7]. +// CHECK-NEXT: dup p0.h, p0/z, p0.h[w12, #8] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dup p0.s, p0/z, p0.s[w12, #4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 3]. +// CHECK-NEXT: dup p0.s, p0/z, p0.s[w12, #4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +dup p0.d, p0/z, p0.d[w12, #2] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 1]. +// CHECK-NEXT: dup p0.d, p0/z, p0.d[w12, #2] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SME/dup.s b/llvm/test/MC/AArch64/SME/dup.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME/dup.s @@ -0,0 +1,121 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %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=+sme < %s \ +// RUN: | llvm-objdump -d --mattr=+sme - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// --------------------------------------------------------------------------// +// 8-bit + +dup p0.b, p0/z, p0.b[w12] +// CHECK-INST: dup p0.b, p0/z, p0.b[w12] +// CHECK-ENCODING: [0x00,0x40,0x24,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 00 40 24 25 + +dup p5.b, p5/z, p10.b[w13, #6] +// CHECK-INST: dup p5.b, p5/z, p10.b[w13, #6] +// CHECK-ENCODING: [0x45,0x55,0x75,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 45 55 75 25 + +dup p7.b, p11/z, p13.b[w12, #5] +// CHECK-INST: dup p7.b, p11/z, p13.b[w12, #5] +// CHECK-ENCODING: [0xa7,0x6d,0x6c,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: a7 6d 6c 25 + +dup p15.b, p15/z, p15.b[w15, #15] +// CHECK-INST: dup p15.b, p15/z, p15.b[w15, #15] +// CHECK-ENCODING: [0xef,0x7d,0xff,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: ef 7d ff 25 + +// --------------------------------------------------------------------------// +// 16-bit + +dup p0.h, p0/z, p0.h[w12] +// CHECK-INST: dup p0.h, p0/z, p0.h[w12] +// CHECK-ENCODING: [0x00,0x40,0x28,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 00 40 28 25 + +dup p5.h, p5/z, p10.h[w13, #3] +// CHECK-INST: dup p5.h, p5/z, p10.h[w13, #3] +// CHECK-ENCODING: [0x45,0x55,0x79,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 45 55 79 25 + +dup p7.h, p11/z, p13.h[w12, #2] +// CHECK-INST: dup p7.h, p11/z, p13.h[w12, #2] +// CHECK-ENCODING: [0xa7,0x6d,0x68,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: a7 6d 68 25 + +dup p15.h, p15/z, p15.h[w15, #7] +// CHECK-INST: dup p15.h, p15/z, p15.h[w15, #7] +// CHECK-ENCODING: [0xef,0x7d,0xfb,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: ef 7d fb 25 + +// --------------------------------------------------------------------------// +// 32-bit + +dup p0.s, p0/z, p0.s[w12] +// CHECK-INST: dup p0.s, p0/z, p0.s[w12] +// CHECK-ENCODING: [0x00,0x40,0x30,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 00 40 30 25 + +dup p5.s, p5/z, p10.s[w13, #1] +// CHECK-INST: dup p5.s, p5/z, p10.s[w13, #1] +// CHECK-ENCODING: [0x45,0x55,0x71,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 45 55 71 25 + +dup p7.s, p11/z, p13.s[w12, #1] +// CHECK-INST: dup p7.s, p11/z, p13.s[w12, #1] +// CHECK-ENCODING: [0xa7,0x6d,0x70,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: a7 6d 70 25 + +dup p15.s, p15/z, p15.s[w15, #3] +// CHECK-INST: dup p15.s, p15/z, p15.s[w15, #3] +// CHECK-ENCODING: [0xef,0x7d,0xf3,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: ef 7d f3 25 + +// --------------------------------------------------------------------------// +// 64-bit + +dup p0.d, p0/z, p0.d[w12] +// CHECK-INST: dup p0.d, p0/z, p0.d[w12] +// CHECK-ENCODING: [0x00,0x40,0x60,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 00 40 60 25 + +dup p5.d, p5/z, p10.d[w13] +// CHECK-INST: dup p5.d, p5/z, p10.d[w13] +// CHECK-ENCODING: [0x45,0x55,0x61,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 45 55 61 25 + +dup p7.d, p11/z, p13.d[w12] +// CHECK-INST: dup p7.d, p11/z, p13.d[w12] +// CHECK-ENCODING: [0xa7,0x6d,0x60,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: a7 6d 60 25 + +dup p15.d, p15/z, p15.d[w15, #1] +// CHECK-INST: dup p15.d, p15/z, p15.d[w15, #1] +// CHECK-ENCODING: [0xef,0x7d,0xe3,0x25] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: ef 7d e3 25 diff --git a/llvm/test/MC/AArch64/SME/revd-diagnostics.s b/llvm/test/MC/AArch64/SME/revd-diagnostics.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME/revd-diagnostics.s @@ -0,0 +1,29 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme 2>&1 < %s| FileCheck %s + +// ------------------------------------------------------------------------- // +// Invalid predicate + +// invalid range (expected: p0-p7) +revd z0.q, p8/m, z0.q +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: revd z0.q, p8/m, z0.q +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// wrong predication qualifier, expected /m. +revd z0.q, p0/z, z0.q +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: revd z0.q, p0/z, z0.q +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// ------------------------------------------------------------------------- // +// Invalid ZPR element width + +revd z0.b, p0/m, z0.q +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: revd z0.b, p0/m, z0.q +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +revd z0.q, p0/m, z0.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: revd z0.q, p0/m, z0.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SME/revd.s b/llvm/test/MC/AArch64/SME/revd.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME/revd.s @@ -0,0 +1,52 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %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=+sme < %s \ +// RUN: | llvm-objdump -d --mattr=+sme - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +revd z0.q, p0/m, z0.q +// CHECK-INST: revd z0.q, p0/m, z0.q +// CHECK-ENCODING: [0x00,0x80,0x2e,0x05] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 00 80 2e 05 + +revd z21.q, p5/m, z10.q +// CHECK-INST: revd z21.q, p5/m, z10.q +// CHECK-ENCODING: [0x55,0x95,0x2e,0x05] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 55 95 2e 05 + +revd z23.q, p3/m, z13.q +// CHECK-INST: revd z23.q, p3/m, z13.q +// CHECK-ENCODING: [0xb7,0x8d,0x2e,0x05] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 8d 2e 05 + +revd z31.q, p7/m, z31.q +// CHECK-INST: revd z31.q, p7/m, z31.q +// CHECK-ENCODING: [0xff,0x9f,0x2e,0x05] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: ff 9f 2e 05 + +// --------------------------------------------------------------------------// +// Test compatibility with MOVPRFX instruction. + +movprfx z21, z25 +// CHECK-INST: movprfx z21, z25 +// CHECK-ENCODING: [0x35,0xbf,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 35 bf 20 04 + +revd z21.q, p5/m, z10.q +// CHECK-INST: revd z21.q, p5/m, z10.q +// CHECK-ENCODING: [0x55,0x95,0x2e,0x05] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 55 95 2e 05 diff --git a/llvm/test/MC/AArch64/SME/sclamp-diagnostics.s b/llvm/test/MC/AArch64/SME/sclamp-diagnostics.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME/sclamp-diagnostics.s @@ -0,0 +1,23 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme 2>&1 < %s| FileCheck %s + +// ------------------------------------------------------------------------- // +// Mismatched element width + +sclamp z0.b, z1.h, z2.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sclamp z0.b, z1.h, z2.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sclamp z0.b, z1.b, z2.q +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sclamp z0.b, z1.b, z2.q +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Test incompatibility with predicated MOVPRFX instruction. + +movprfx z0.b, p0/z, z1.b +sclamp z0.b, z1.b, z2.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a predicated movprfx, suggest using unpredicated movprfx +// CHECK-NEXT: sclamp z0.b, z1.b, z2.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SME/sclamp.s b/llvm/test/MC/AArch64/SME/sclamp.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME/sclamp.s @@ -0,0 +1,172 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %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=+sme < %s \ +// RUN: | llvm-objdump -d --mattr=+sme - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// --------------------------------------------------------------------------// +// 8-bit + +sclamp z0.b, z0.b, z0.b +// CHECK-INST: sclamp z0.b, z0.b, z0.b +// CHECK-ENCODING: [0x00,0xc0,0x00,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 00 c0 00 44 + +sclamp z21.b, z10.b, z21.b +// CHECK-INST: sclamp z21.b, z10.b, z21.b +// CHECK-ENCODING: [0x55,0xc1,0x15,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 55 c1 15 44 + +sclamp z23.b, z13.b, z8.b +// CHECK-INST: sclamp z23.b, z13.b, z8.b +// CHECK-ENCODING: [0xb7,0xc1,0x08,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c1 08 44 + +sclamp z31.b, z31.b, z31.b +// CHECK-INST: sclamp z31.b, z31.b, z31.b +// CHECK-ENCODING: [0xff,0xc3,0x1f,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: ff c3 1f 44 + +// --------------------------------------------------------------------------// +// 16-bit + +sclamp z0.h, z0.h, z0.h +// CHECK-INST: sclamp z0.h, z0.h, z0.h +// CHECK-ENCODING: [0x00,0xc0,0x40,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 00 c0 40 44 + +sclamp z21.h, z10.h, z21.h +// CHECK-INST: sclamp z21.h, z10.h, z21.h +// CHECK-ENCODING: [0x55,0xc1,0x55,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 55 c1 55 44 + +sclamp z23.h, z13.h, z8.h +// CHECK-INST: sclamp z23.h, z13.h, z8.h +// CHECK-ENCODING: [0xb7,0xc1,0x48,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c1 48 44 + +sclamp z31.h, z31.h, z31.h +// CHECK-INST: sclamp z31.h, z31.h, z31.h +// CHECK-ENCODING: [0xff,0xc3,0x5f,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: ff c3 5f 44 + +// --------------------------------------------------------------------------// +// 32-bit + +sclamp z0.s, z0.s, z0.s +// CHECK-INST: sclamp z0.s, z0.s, z0.s +// CHECK-ENCODING: [0x00,0xc0,0x80,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 00 c0 80 44 + +sclamp z21.s, z10.s, z21.s +// CHECK-INST: sclamp z21.s, z10.s, z21.s +// CHECK-ENCODING: [0x55,0xc1,0x95,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 55 c1 95 44 + +sclamp z23.s, z13.s, z8.s +// CHECK-INST: sclamp z23.s, z13.s, z8.s +// CHECK-ENCODING: [0xb7,0xc1,0x88,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c1 88 44 + +sclamp z31.s, z31.s, z31.s +// CHECK-INST: sclamp z31.s, z31.s, z31.s +// CHECK-ENCODING: [0xff,0xc3,0x9f,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: ff c3 9f 44 + +// --------------------------------------------------------------------------// +// 64-bit + +sclamp z0.d, z0.d, z0.d +// CHECK-INST: sclamp z0.d, z0.d, z0.d +// CHECK-ENCODING: [0x00,0xc0,0xc0,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 00 c0 c0 44 + +sclamp z21.d, z10.d, z21.d +// CHECK-INST: sclamp z21.d, z10.d, z21.d +// CHECK-ENCODING: [0x55,0xc1,0xd5,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 55 c1 d5 44 + +sclamp z23.d, z13.d, z8.d +// CHECK-INST: sclamp z23.d, z13.d, z8.d +// CHECK-ENCODING: [0xb7,0xc1,0xc8,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c1 c8 44 + +sclamp z31.d, z31.d, z31.d +// CHECK-INST: sclamp z31.d, z31.d, z31.d +// CHECK-ENCODING: [0xff,0xc3,0xdf,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: ff c3 df 44 + +// --------------------------------------------------------------------------// +// Test compatibility with MOVPRFX instruction. + +movprfx z23, z27 +// CHECK-INST: movprfx z23, z27 +// CHECK-ENCODING: [0x77,0xbf,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 77 bf 20 04 + +sclamp z23.b, z13.b, z8.b +// CHECK-INST: sclamp z23.b, z13.b, z8.b +// CHECK-ENCODING: [0xb7,0xc1,0x08,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c1 08 44 + +movprfx z23, z27 +// CHECK-INST: movprfx z23, z27 +// CHECK-ENCODING: [0x77,0xbf,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 77 bf 20 04 + +sclamp z23.h, z13.h, z8.h +// CHECK-INST: sclamp z23.h, z13.h, z8.h +// CHECK-ENCODING: [0xb7,0xc1,0x48,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c1 48 44 + +movprfx z23, z27 +// CHECK-INST: movprfx z23, z27 +// CHECK-ENCODING: [0x77,0xbf,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 77 bf 20 04 + +sclamp z23.s, z13.s, z8.s +// CHECK-INST: sclamp z23.s, z13.s, z8.s +// CHECK-ENCODING: [0xb7,0xc1,0x88,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c1 88 44 + +movprfx z23, z27 +// CHECK-INST: movprfx z23, z27 +// CHECK-ENCODING: [0x77,0xbf,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 77 bf 20 04 + +sclamp z23.d, z13.d, z8.d +// CHECK-INST: sclamp z23.d, z13.d, z8.d +// CHECK-ENCODING: [0xb7,0xc1,0xc8,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c1 c8 44 diff --git a/llvm/test/MC/AArch64/SME/uclamp-diagnostics.s b/llvm/test/MC/AArch64/SME/uclamp-diagnostics.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME/uclamp-diagnostics.s @@ -0,0 +1,23 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme 2>&1 < %s| FileCheck %s + +// ------------------------------------------------------------------------- // +// Mismatched element width + +sclamp z0.b, z1.h, z2.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sclamp z0.b, z1.h, z2.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sclamp z0.b, z1.b, z2.q +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sclamp z0.b, z1.b, z2.q +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Test incompatibility with predicated MOVPRFX instruction. + +movprfx z0.b, p0/z, z1.b +uclamp z0.b, z1.b, z2.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a predicated movprfx, suggest using unpredicated movprfx +// CHECK-NEXT: uclamp z0.b, z1.b, z2.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SME/uclamp.s b/llvm/test/MC/AArch64/SME/uclamp.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME/uclamp.s @@ -0,0 +1,172 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %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=+sme < %s \ +// RUN: | llvm-objdump -d --mattr=+sme - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// --------------------------------------------------------------------------// +// 8-bit + +uclamp z0.b, z0.b, z0.b +// CHECK-INST: uclamp z0.b, z0.b, z0.b +// CHECK-ENCODING: [0x00,0xc4,0x00,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 00 c4 00 44 + +uclamp z21.b, z10.b, z21.b +// CHECK-INST: uclamp z21.b, z10.b, z21.b +// CHECK-ENCODING: [0x55,0xc5,0x15,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 55 c5 15 44 + +uclamp z23.b, z13.b, z8.b +// CHECK-INST: uclamp z23.b, z13.b, z8.b +// CHECK-ENCODING: [0xb7,0xc5,0x08,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c5 08 44 + +uclamp z31.b, z31.b, z31.b +// CHECK-INST: uclamp z31.b, z31.b, z31.b +// CHECK-ENCODING: [0xff,0xc7,0x1f,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: ff c7 1f 44 + +// --------------------------------------------------------------------------// +// 16-bit + +uclamp z0.h, z0.h, z0.h +// CHECK-INST: uclamp z0.h, z0.h, z0.h +// CHECK-ENCODING: [0x00,0xc4,0x40,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 00 c4 40 44 + +uclamp z21.h, z10.h, z21.h +// CHECK-INST: uclamp z21.h, z10.h, z21.h +// CHECK-ENCODING: [0x55,0xc5,0x55,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 55 c5 55 44 + +uclamp z23.h, z13.h, z8.h +// CHECK-INST: uclamp z23.h, z13.h, z8.h +// CHECK-ENCODING: [0xb7,0xc5,0x48,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c5 48 44 + +uclamp z31.h, z31.h, z31.h +// CHECK-INST: uclamp z31.h, z31.h, z31.h +// CHECK-ENCODING: [0xff,0xc7,0x5f,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: ff c7 5f 44 + +// --------------------------------------------------------------------------// +// 32-bit + +uclamp z0.s, z0.s, z0.s +// CHECK-INST: uclamp z0.s, z0.s, z0.s +// CHECK-ENCODING: [0x00,0xc4,0x80,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 00 c4 80 44 + +uclamp z21.s, z10.s, z21.s +// CHECK-INST: uclamp z21.s, z10.s, z21.s +// CHECK-ENCODING: [0x55,0xc5,0x95,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 55 c5 95 44 + +uclamp z23.s, z13.s, z8.s +// CHECK-INST: uclamp z23.s, z13.s, z8.s +// CHECK-ENCODING: [0xb7,0xc5,0x88,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c5 88 44 + +uclamp z31.s, z31.s, z31.s +// CHECK-INST: uclamp z31.s, z31.s, z31.s +// CHECK-ENCODING: [0xff,0xc7,0x9f,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: ff c7 9f 44 + +// --------------------------------------------------------------------------// +// 64-bit + +uclamp z0.d, z0.d, z0.d +// CHECK-INST: uclamp z0.d, z0.d, z0.d +// CHECK-ENCODING: [0x00,0xc4,0xc0,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 00 c4 c0 44 + +uclamp z21.d, z10.d, z21.d +// CHECK-INST: uclamp z21.d, z10.d, z21.d +// CHECK-ENCODING: [0x55,0xc5,0xd5,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 55 c5 d5 44 + +uclamp z23.d, z13.d, z8.d +// CHECK-INST: uclamp z23.d, z13.d, z8.d +// CHECK-ENCODING: [0xb7,0xc5,0xc8,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c5 c8 44 + +uclamp z31.d, z31.d, z31.d +// CHECK-INST: uclamp z31.d, z31.d, z31.d +// CHECK-ENCODING: [0xff,0xc7,0xdf,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: ff c7 df 44 + +// --------------------------------------------------------------------------// +// Test compatibility with MOVPRFX instruction. + +movprfx z23, z27 +// CHECK-INST: movprfx z23, z27 +// CHECK-ENCODING: [0x77,0xbf,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 77 bf 20 04 + +uclamp z23.b, z13.b, z8.b +// CHECK-INST: uclamp z23.b, z13.b, z8.b +// CHECK-ENCODING: [0xb7,0xc5,0x08,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c5 08 44 + +movprfx z23, z27 +// CHECK-INST: movprfx z23, z27 +// CHECK-ENCODING: [0x77,0xbf,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 77 bf 20 04 + +uclamp z23.h, z13.h, z8.h +// CHECK-INST: uclamp z23.h, z13.h, z8.h +// CHECK-ENCODING: [0xb7,0xc5,0x48,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c5 48 44 + +movprfx z23, z27 +// CHECK-INST: movprfx z23, z27 +// CHECK-ENCODING: [0x77,0xbf,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 77 bf 20 04 + +uclamp z23.s, z13.s, z8.s +// CHECK-INST: uclamp z23.s, z13.s, z8.s +// CHECK-ENCODING: [0xb7,0xc5,0x88,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c5 88 44 + +movprfx z23, z27 +// CHECK-INST: movprfx z23, z27 +// CHECK-ENCODING: [0x77,0xbf,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 77 bf 20 04 + +uclamp z23.d, z13.d, z8.d +// CHECK-INST: uclamp z23.d, z13.d, z8.d +// CHECK-ENCODING: [0xb7,0xc5,0xc8,0x44] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: b7 c5 c8 44