diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -1408,6 +1408,18 @@ let PrintMethod = "printMatrixIndex"; } +// SME2 vector select offset operands + +// uimm3s8 predicate +// True if the immediate is a multiple of 8 in the range [0,56]. +def UImm3s8Operand : UImmScaledMemoryIndexed<3, 8>; + +def uimm3s8 : Operand, ImmLeaf= 0 && Imm <= 56 && ((Imm % 8) == 0); }], UImmS8XForm> { + let PrintMethod = "printVectorIndex<8>"; + let ParserMatchClass = UImm3s8Operand; +} + class UImmScaledMemoryIndexedRange : AsmOperandClass { let Name = "UImm" # Width # "s" # Scale # "Range"; let DiagnosticType = "InvalidMemoryIndexedRange" # Scale # "UImm" # Width; diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -1390,6 +1390,8 @@ def ZA : AArch64Reg<0, "za", [ZAB0]>; } +def ZT0 : AArch64Reg<0, "zt0">; + // SME Register Classes let isAllocatable = 0 in { @@ -1416,6 +1418,10 @@ } } +def ZTR : RegisterClass<"AArch64", [untyped], 512, (add ZT0)> { + let Size = 512; + let DiagnosticType = "InvalidLookupTable"; +} // SME Register Operands // There are three types of SME matrix register operands: // * Tiles: 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 @@ -559,6 +559,22 @@ defm UMOPA_MPPZZ_HtoS : sme2_int_mopx_tile<"umopa", 0b100>; defm UMOPS_MPPZZ_HtoS : sme2_int_mopx_tile<"umops", 0b101>; + +def ZERO_T : sme2_zero_zt<"zero", 0b0001>; + +def LDR_TX : sme2_spill_fill_vector<"ldr", 0b01111100>; +def STR_TX : sme2_spill_fill_vector<"str", 0b11111100>; + +def MOVT_XTI : sme2_movt_zt_to_scalar<"movt", 0b0011111>; +def MOVT_TIX : sme2_movt_scalar_to_zt<"movt", 0b0011111>; + +defm LUTI2_ZTZI : sme2_luti2_vector_index<"luti2">; +defm LUTI2_2ZTZI : sme2_luti2_vector_vg2_index<"luti2">; +defm LUTI2_4ZTZI : sme2_luti2_vector_vg4_index<"luti2">; + +defm LUTI4_ZTZI : sme2_luti4_vector_index<"luti4">; +defm LUTI4_2ZTZI : sme2_luti4_vector_vg2_index<"luti4">; +defm LUTI4_4ZTZI : sme2_luti4_vector_vg4_index<"luti4">; } let Predicates = [HasSME2, HasSMEI16I64] in { 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 @@ -70,7 +70,8 @@ SVEDataVector, SVEPredicateAsCounter, SVEPredicateVector, - Matrix + Matrix, + LookupTable }; enum class MatrixKind { Array, Tile, Row, Col }; @@ -265,6 +266,7 @@ template OperandMatchResultTy tryParseGPROperand(OperandVector &Operands); + OperandMatchResultTy tryParseZTOperand(OperandVector &Operands); template OperandMatchResultTy tryParseSVEDataVector(OperandVector &Operands); template @@ -2786,9 +2788,12 @@ if ((RegNum = matchMatrixRegName(Name))) return Kind == RegKind::Matrix ? RegNum : 0; + if (Name.equals_insensitive("zt0")) + return Kind == RegKind::LookupTable ? AArch64::ZT0 : 0; + // The parsed register must be of RegKind Scalar if ((RegNum = MatchRegisterName(Name))) - return Kind == RegKind::Scalar ? RegNum : 0; + return (Kind == RegKind::Scalar) ? RegNum : 0; if (!RegNum) { // Handle a few common aliases of registers. @@ -3966,6 +3971,9 @@ if (!tryParseNeonVectorRegister(Operands)) return false; + if (tryParseZTOperand(Operands) == MatchOperand_Success) + return false; + // Otherwise try for a scalar register. if (tryParseGPROperand(Operands) == MatchOperand_Success) return false; @@ -4179,6 +4187,10 @@ llvm_unreachable("Expected a valid vector kind"); } + if (RegTok.is(AsmToken::Identifier) && ParseRes == MatchOperand_NoMatch && + RegTok.getString().equals_insensitive("zt0")) + return MatchOperand_NoMatch; + if (RegTok.isNot(AsmToken::Identifier) || ParseRes == MatchOperand_ParseFail || (ParseRes == MatchOperand_NoMatch && NoMatchIsError && @@ -4328,6 +4340,42 @@ return MatchOperand_Success; } +OperandMatchResultTy +AArch64AsmParser::tryParseZTOperand(OperandVector &Operands) { + SMLoc StartLoc = getLoc(); + const AsmToken &Tok = getTok(); + StringRef Name = Tok.getString().lower(); + + unsigned RegNum = matchRegisterNameAlias(Name, RegKind::LookupTable); + + if (RegNum == 0) + return MatchOperand_NoMatch; + + Operands.push_back(AArch64Operand::CreateReg( + RegNum, RegKind::LookupTable, StartLoc, getLoc(), getContext())); + Lex(); // Eat identifier token. + + // Check if register is followed by an index + if (parseOptionalToken(AsmToken::LBrac)) { + const MCExpr *ImmVal; + if (getParser().parseExpression(ImmVal)) + return MatchOperand_NoMatch; + const MCConstantExpr *MCE = dyn_cast(ImmVal); + if (!MCE) { + TokError("immediate value expected for vector index"); + return MatchOperand_ParseFail; + } + if (parseToken(AsmToken::RBrac, "']' expected")) + return MatchOperand_ParseFail; + + Operands.push_back(AArch64Operand::CreateImm( + MCConstantExpr::create(MCE->getValue(), getContext()), StartLoc, + getLoc(), getContext())); + } + + return MatchOperand_Success; +} + template OperandMatchResultTy AArch64AsmParser::tryParseGPROperand(OperandVector &Operands) { @@ -5434,6 +5482,8 @@ return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008]."); case Match_InvalidMemoryIndexed8UImm5: return Error(Loc, "index must be a multiple of 8 in range [0, 248]."); + case Match_InvalidMemoryIndexed8UImm3: + return Error(Loc, "index must be a multiple of 8 in range [0, 56]."); case Match_InvalidMemoryIndexed4UImm5: return Error(Loc, "index must be a multiple of 4 in range [0, 124]."); case Match_InvalidMemoryIndexed2UImm5: @@ -5762,6 +5812,8 @@ return Error(Loc, "Invalid vector list, expected list with 4 consecutive " "SVE vectors, where the first vector is a multiple of 4 " "and with matching element types"); + case Match_InvalidLookupTable: + return Error(Loc, "Invalid lookup table, expected zt0"); default: llvm_unreachable("unexpected error code!"); } @@ -6176,6 +6228,7 @@ case Match_InvalidMemoryIndexed8SImm7: case Match_InvalidMemoryIndexed16SImm7: case Match_InvalidMemoryIndexed8UImm5: + case Match_InvalidMemoryIndexed8UImm3: case Match_InvalidMemoryIndexed4UImm5: case Match_InvalidMemoryIndexed2UImm5: case Match_InvalidMemoryIndexed1UImm6: @@ -6318,6 +6371,7 @@ case Match_InvalidSVCR: case Match_InvalidMatrixIndexGPR32_12_15: case Match_InvalidMatrixIndexGPR32_8_11: + case Match_InvalidLookupTable: case Match_InvalidSVEVectorListMul2x8: case Match_InvalidSVEVectorListMul2x16: case Match_InvalidSVEVectorListMul2x32: diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -329,6 +329,9 @@ case AArch64::MPR8RegClassID: MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZAB0)); break; + case AArch64::ZTRRegClassID: + MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZT0)); + break; } } else if (Desc.OpInfo[i].OperandType == AArch64::OPERAND_IMPLICIT_IMM_0) { diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h @@ -164,6 +164,7 @@ void printTypedVectorList(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); + template void printVectorIndex(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); void printMatrixIndex(const MCInst *MI, unsigned OpNum, diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp @@ -1244,7 +1244,7 @@ O << ']'; } -template +template void AArch64InstPrinter::printImmScale(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O) { @@ -1576,10 +1576,11 @@ printVectorList(MI, OpNum, STI, O, Suffix); } +template void AArch64InstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O) { - O << "[" << MI->getOperand(OpNum).getImm() << "]"; + O << "[" << Scale * MI->getOperand(OpNum).getImm() << "]"; } void AArch64InstPrinter::printMatrixIndex(const MCInst *MI, unsigned OpNum, 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 @@ -2379,3 +2379,191 @@ multiclass sme2_bfp_mopx_tile op> { def NAME : sme_outer_product_widening_inst; } + +//===----------------------------------------------------------------------===/// +// SME2 Zero Lookup Table. +class sme2_zero_zt opc> + : I<(outs ZTR:$ZT), (ins ), + mnemonic, "\t\\{ $ZT \\}", + "", []>, Sched<[]> { + let Inst{31-4} = 0b1100000001001000000000000000; + let Inst{3-0} = opc; +} + +//===----------------------------------------------------------------------===// +// SME2 lookup table load/store +class sme2_spill_fill_vector opc> + : I, Sched<[]> { + bits<5> Rn; + let Inst{31-22} = 0b1110000100; + let Inst{21-16} = opc{7-2}; + let Inst{15-10} = 0b100000; + let Inst{9-5} = Rn; + let Inst{4-2} = 0b000; + let Inst{1-0} = opc{1-0}; + + let mayLoad = !not(opc{7}); + let mayStore = opc{7}; +} + +//===----------------------------------------------------------------------===/// +// SME2 move to/from lookup table +class sme2_movt_zt_to_scalar opc> + : I<(outs GPR64:$Rt), (ins ZTR:$ZTt, uimm3s8:$imm3), + mnemonic, "\t$Rt, $ZTt$imm3", + "", []>, Sched<[]> { + bits<3> imm3; + bits<5> Rt; + let Inst{31-15} = 0b11000000010011000; + let Inst{14-12} = imm3; + let Inst{11-5} = opc; + let Inst{4-0} = Rt; +} + +class sme2_movt_scalar_to_zt opc> + : I<(outs ZTR:$ZTt), (ins uimm3s8:$imm3, GPR64:$Rt), + mnemonic, "\t$ZTt$imm3, $Rt", + "", []>, Sched<[]> { + bits<3> imm3; + bits<5> Rt; + let Inst{31-15} = 0b11000000010011100; + let Inst{14-12} = imm3; + let Inst{11-5} = opc; + let Inst{4-0} = Rt; +} + +//===----------------------------------------------------------------------===// +// SME2 lookup table expand one register +class sme2_luti_vector_index sz, bits<7> opc, RegisterOperand vector_ty, + AsmVectorIndexOpnd index_ty, string mnemonic> + : I<(outs vector_ty:$Zd), + (ins ZTR:$ZTt, ZPRAny:$Zn, index_ty:$i), + mnemonic, "\t$Zd, $ZTt, $Zn$i", + "", []>, Sched<[]> { + bits<5> Zn; + bits<5> Zd; + let Inst{31-19} = 0b1100000011001; + let Inst{18-14} = opc{6-2}; + let Inst{13-12} = sz; + let Inst{11-10} = opc{1-0}; + let Inst{9-5} = Zn; + let Inst{4-0} = Zd; +} + +class sme2_luti2_vector_index sz, RegisterOperand vector_ty, + string mnemonic> + : sme2_luti_vector_index { + bits<4> i; + let Inst{17-14} = i; +} + +multiclass sme2_luti2_vector_index { + def _B : sme2_luti2_vector_index<0b00, ZPR8, mnemonic>; + def _H : sme2_luti2_vector_index<0b01, ZPR16, mnemonic>; + def _S : sme2_luti2_vector_index<0b10, ZPR32, mnemonic>; +} + +class sme2_luti4_vector_index sz, RegisterOperand vector_ty, + string mnemonic> + : sme2_luti_vector_index { + bits<3> i; + let Inst{16-14} = i; +} + +multiclass sme2_luti4_vector_index { + def _B : sme2_luti4_vector_index<0b00, ZPR8, mnemonic>; + def _H : sme2_luti4_vector_index<0b01, ZPR16, mnemonic>; + def _S : sme2_luti4_vector_index<0b10, ZPR32, mnemonic>; +} + +// SME2 lookup table expand two contiguous registers +class sme2_luti_vector_vg2_index sz, bits<6> opc, RegisterOperand vector_ty, + AsmVectorIndexOpnd index_ty, string mnemonic> + : I<(outs vector_ty:$Zd), + (ins ZTR:$ZTt, ZPRAny:$Zn, index_ty:$i), + mnemonic, "\t$Zd, $ZTt, $Zn$i", + "", []>, Sched<[]> { + bits<5> Zn; + bits<4> Zd; + let Inst{31-19} = 0b1100000010001; + let Inst{18-15} = opc{5-2}; + let Inst{14} = 0b1; + let Inst{13-12} = sz; + let Inst{11-10} = opc{1-0}; + let Inst{9-5} = Zn; + let Inst{4-1} = Zd; + let Inst{0} = 0b0; +} + +class sme2_luti2_vector_vg2_index sz, RegisterOperand vector_ty, + string mnemonic> + : sme2_luti_vector_vg2_index { + bits<3> i; + let Inst{17-15} = i; +} + +multiclass sme2_luti2_vector_vg2_index { + def _B : sme2_luti2_vector_vg2_index<0b00, ZZ_b_mul_r, mnemonic>; + def _H : sme2_luti2_vector_vg2_index<0b01, ZZ_h_mul_r, mnemonic>; + def _S : sme2_luti2_vector_vg2_index<0b10, ZZ_s_mul_r, mnemonic>; +} + +class sme2_luti4_vector_vg2_index sz, RegisterOperand vector_ty, + string mnemonic> + : sme2_luti_vector_vg2_index { + bits<2> i; + let Inst{16-15} = i; +} + +multiclass sme2_luti4_vector_vg2_index { + def _B : sme2_luti4_vector_vg2_index<0b00, ZZ_b_mul_r, mnemonic>; + def _H : sme2_luti4_vector_vg2_index<0b01, ZZ_h_mul_r, mnemonic>; + def _S : sme2_luti4_vector_vg2_index<0b10, ZZ_s_mul_r, mnemonic>; +} + +// SME2 lookup table expand four contiguous registers +class sme2_luti_vector_vg4_index sz, bits<5>opc, RegisterOperand vector_ty, + AsmVectorIndexOpnd index_ty, string mnemonic> + : I<(outs vector_ty:$Zd), + (ins ZTR:$ZTt, ZPRAny:$Zn, index_ty:$i), + mnemonic, "\t$Zd, $ZTt, $Zn$i", + "", []>, Sched<[]> { + bits<5> Zn; + bits<3> Zd; + let Inst{31-19} = 0b1100000010001; + let Inst{18-16} = opc{4-2}; + let Inst{15-14} = 0b10; + let Inst{13-12} = sz; + let Inst{11-10} = opc{1-0}; + let Inst{9-5} = Zn; + let Inst{4-2} = Zd; + let Inst{1-0} = 0b00; +} + +class sme2_luti2_vector_vg4_index sz, RegisterOperand vector_ty, + string mnemonic> + : sme2_luti_vector_vg4_index { + bits<2> i; + let Inst{17-16} = i; +} + +multiclass sme2_luti2_vector_vg4_index { + def _B : sme2_luti2_vector_vg4_index<0b00, ZZZZ_b_mul_r, mnemonic>; + def _H : sme2_luti2_vector_vg4_index<0b01, ZZZZ_h_mul_r, mnemonic>; + def _S : sme2_luti2_vector_vg4_index<0b10, ZZZZ_s_mul_r, mnemonic>; +} + +class sme2_luti4_vector_vg4_index sz, RegisterOperand vector_ty, + string mnemonic> + : sme2_luti_vector_vg4_index { + bits<1> i; + let Inst{16} = i; +} + +multiclass sme2_luti4_vector_vg4_index { + def _H : sme2_luti4_vector_vg4_index<0b01, ZZZZ_h_mul_r, mnemonic>; + def _S : sme2_luti4_vector_vg4_index<0b10, ZZZZ_s_mul_r, mnemonic>; +} diff --git a/llvm/test/MC/AArch64/SME2/ldr-diagnostics.s b/llvm/test/MC/AArch64/SME2/ldr-diagnostics.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2/ldr-diagnostics.s @@ -0,0 +1,6 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 2>&1 < %s| FileCheck %s + +ldr zt1, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid lookup table, expected zt0 +// CHECK-NEXT: ldr zt1, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SME2/ldr.s b/llvm/test/MC/AArch64/SME2/ldr.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2/ldr.s @@ -0,0 +1,38 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %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=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2 - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=-sme2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + + +ldr zt0, [x0] // 11100001-00011111-10000000-00000000 +// CHECK-INST: ldr zt0, [x0] +// CHECK-ENCODING: [0x00,0x80,0x1f,0xe1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: e11f8000 + +ldr zt0, [x10] // 11100001-00011111-10000001-01000000 +// CHECK-INST: ldr zt0, [x10] +// CHECK-ENCODING: [0x40,0x81,0x1f,0xe1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: e11f8140 + +ldr zt0, [x13] // 11100001-00011111-10000001-10100000 +// CHECK-INST: ldr zt0, [x13] +// CHECK-ENCODING: [0xa0,0x81,0x1f,0xe1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: e11f81a0 + +ldr zt0, [sp] // 11100001-00011111-10000011-11100000 +// CHECK-INST: ldr zt0, [sp] +// CHECK-ENCODING: [0xe0,0x83,0x1f,0xe1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: e11f83e0 + diff --git a/llvm/test/MC/AArch64/SME2/luti2-diagnostics.s b/llvm/test/MC/AArch64/SME2/luti2-diagnostics.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2/luti2-diagnostics.s @@ -0,0 +1,60 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 2>&1 < %s | FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid lane indices + +luti2 z0.h, zt0, z0[16] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: luti2 z0.h, zt0, z0[16] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti2 z0.s, zt0, z0[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15]. +// CHECK-NEXT: luti2 z0.s, zt0, z0[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti2 {z0.b-z1.b}, zt0, z0[8] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7]. +// CHECK-NEXT: luti2 {z0.b-z1.b}, zt0, z0[8] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti2 {z0.h-z1.h}, zt0, z0[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7]. +// CHECK-NEXT: luti2 {z0.h-z1.h}, zt0, z0[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti2 {z0.s-z3.s}, zt0, z0[4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3]. +// CHECK-NEXT: luti2 {z0.s-z3.s}, zt0, z0[4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti2 {z0.b-z3.b}, zt0, z0[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3]. +// CHECK-NEXT: luti2 {z0.b-z3.b}, zt0, z0[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector lists + +luti2 {z0.h-z2.h}, zt0, z0[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: luti2 {z0.h-z2.h}, zt0, z0[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti2 {z1.s-z2.s}, zt0, z0[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types +// CHECK-NEXT: luti2 {z1.s-z2.s}, zt0, z0[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti2 {z1.s-z4.s}, zt0, z0[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types +// CHECK-NEXT: luti2 {z1.s-z4.s}, zt0, z0[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector suffix + +luti2 {z0.d-z1.d}, zt0, z0[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: luti2 {z0.d-z1.d}, zt0, z0[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SME2/luti2.s b/llvm/test/MC/AArch64/SME2/luti2.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2/luti2.s @@ -0,0 +1,238 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %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=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2 - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=-sme2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + + +luti2 z0.h, zt0, z0[0] // 11000000-11001100-00010000-00000000 +// CHECK-INST: luti2 z0.h, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x10,0xcc,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cc1000 + +luti2 z21.h, zt0, z10[5] // 11000000-11001101-01010001-01010101 +// CHECK-INST: luti2 z21.h, zt0, z10[5] +// CHECK-ENCODING: [0x55,0x51,0xcd,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cd5155 + +luti2 z23.h, zt0, z13[3] // 11000000-11001100-11010001-10110111 +// CHECK-INST: luti2 z23.h, zt0, z13[3] +// CHECK-ENCODING: [0xb7,0xd1,0xcc,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0ccd1b7 + +luti2 z31.h, zt0, z31[15] // 11000000-11001111-11010011-11111111 +// CHECK-INST: luti2 z31.h, zt0, z31[15] +// CHECK-ENCODING: [0xff,0xd3,0xcf,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cfd3ff + + +luti2 z0.s, zt0, z0[0] // 11000000-11001100-00100000-00000000 +// CHECK-INST: luti2 z0.s, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x20,0xcc,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cc2000 + +luti2 z21.s, zt0, z10[5] // 11000000-11001101-01100001-01010101 +// CHECK-INST: luti2 z21.s, zt0, z10[5] +// CHECK-ENCODING: [0x55,0x61,0xcd,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cd6155 + +luti2 z23.s, zt0, z13[3] // 11000000-11001100-11100001-10110111 +// CHECK-INST: luti2 z23.s, zt0, z13[3] +// CHECK-ENCODING: [0xb7,0xe1,0xcc,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cce1b7 + +luti2 z31.s, zt0, z31[15] // 11000000-11001111-11100011-11111111 +// CHECK-INST: luti2 z31.s, zt0, z31[15] +// CHECK-ENCODING: [0xff,0xe3,0xcf,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cfe3ff + + +luti2 z0.b, zt0, z0[0] // 11000000-11001100-00000000-00000000 +// CHECK-INST: luti2 z0.b, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x00,0xcc,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cc0000 + +luti2 z21.b, zt0, z10[5] // 11000000-11001101-01000001-01010101 +// CHECK-INST: luti2 z21.b, zt0, z10[5] +// CHECK-ENCODING: [0x55,0x41,0xcd,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cd4155 + +luti2 z23.b, zt0, z13[3] // 11000000-11001100-11000001-10110111 +// CHECK-INST: luti2 z23.b, zt0, z13[3] +// CHECK-ENCODING: [0xb7,0xc1,0xcc,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0ccc1b7 + +luti2 z31.b, zt0, z31[15] // 11000000-11001111-11000011-11111111 +// CHECK-INST: luti2 z31.b, zt0, z31[15] +// CHECK-ENCODING: [0xff,0xc3,0xcf,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cfc3ff + + +luti2 {z0.h - z1.h}, zt0, z0[0] // 11000000-10001100-01010000-00000000 +// CHECK-INST: luti2 { z0.h, z1.h }, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x50,0x8c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08c5000 + +luti2 {z20.h - z21.h}, zt0, z10[2] // 11000000-10001101-01010001-01010100 +// CHECK-INST: luti2 { z20.h, z21.h }, zt0, z10[2] +// CHECK-ENCODING: [0x54,0x51,0x8d,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08d5154 + +luti2 {z22.h - z23.h}, zt0, z13[1] // 11000000-10001100-11010001-10110110 +// CHECK-INST: luti2 { z22.h, z23.h }, zt0, z13[1] +// CHECK-ENCODING: [0xb6,0xd1,0x8c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08cd1b6 + +luti2 {z30.h - z31.h}, zt0, z31[7] // 11000000-10001111-11010011-11111110 +// CHECK-INST: luti2 { z30.h, z31.h }, zt0, z31[7] +// CHECK-ENCODING: [0xfe,0xd3,0x8f,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08fd3fe + + +luti2 {z0.s - z1.s}, zt0, z0[0] // 11000000-10001100-01100000-00000000 +// CHECK-INST: luti2 { z0.s, z1.s }, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x60,0x8c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08c6000 + +luti2 {z20.s - z21.s}, zt0, z10[2] // 11000000-10001101-01100001-01010100 +// CHECK-INST: luti2 { z20.s, z21.s }, zt0, z10[2] +// CHECK-ENCODING: [0x54,0x61,0x8d,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08d6154 + +luti2 {z22.s - z23.s}, zt0, z13[1] // 11000000-10001100-11100001-10110110 +// CHECK-INST: luti2 { z22.s, z23.s }, zt0, z13[1] +// CHECK-ENCODING: [0xb6,0xe1,0x8c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08ce1b6 + +luti2 {z30.s - z31.s}, zt0, z31[7] // 11000000-10001111-11100011-11111110 +// CHECK-INST: luti2 { z30.s, z31.s }, zt0, z31[7] +// CHECK-ENCODING: [0xfe,0xe3,0x8f,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08fe3fe + + +luti2 {z0.b - z1.b}, zt0, z0[0] // 11000000-10001100-01000000-00000000 +// CHECK-INST: luti2 { z0.b, z1.b }, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x40,0x8c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08c4000 + +luti2 {z20.b - z21.b}, zt0, z10[2] // 11000000-10001101-01000001-01010100 +// CHECK-INST: luti2 { z20.b, z21.b }, zt0, z10[2] +// CHECK-ENCODING: [0x54,0x41,0x8d,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08d4154 + +luti2 {z22.b - z23.b}, zt0, z13[1] // 11000000-10001100-11000001-10110110 +// CHECK-INST: luti2 { z22.b, z23.b }, zt0, z13[1] +// CHECK-ENCODING: [0xb6,0xc1,0x8c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08cc1b6 + +luti2 {z30.b - z31.b}, zt0, z31[7] // 11000000-10001111-11000011-11111110 +// CHECK-INST: luti2 { z30.b, z31.b }, zt0, z31[7] +// CHECK-ENCODING: [0xfe,0xc3,0x8f,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08fc3fe + + +luti2 {z0.h - z3.h}, zt0, z0[0] // 11000000-10001100-10010000-00000000 +// CHECK-INST: luti2 { z0.h - z3.h }, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x90,0x8c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08c9000 + +luti2 {z20.h - z23.h}, zt0, z10[1] // 11000000-10001101-10010001-01010100 +// CHECK-INST: luti2 { z20.h - z23.h }, zt0, z10[1] +// CHECK-ENCODING: [0x54,0x91,0x8d,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08d9154 + +luti2 {z20.h - z23.h}, zt0, z13[0] // 11000000-10001100-10010001-10110100 +// CHECK-INST: luti2 { z20.h - z23.h }, zt0, z13[0] +// CHECK-ENCODING: [0xb4,0x91,0x8c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08c91b4 + +luti2 {z28.h - z31.h}, zt0, z31[3] // 11000000-10001111-10010011-11111100 +// CHECK-INST: luti2 { z28.h - z31.h }, zt0, z31[3] +// CHECK-ENCODING: [0xfc,0x93,0x8f,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08f93fc + + +luti2 {z0.s - z3.s}, zt0, z0[0] // 11000000-10001100-10100000-00000000 +// CHECK-INST: luti2 { z0.s - z3.s }, zt0, z0[0] +// CHECK-ENCODING: [0x00,0xa0,0x8c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08ca000 + +luti2 {z20.s - z23.s}, zt0, z10[1] // 11000000-10001101-10100001-01010100 +// CHECK-INST: luti2 { z20.s - z23.s }, zt0, z10[1] +// CHECK-ENCODING: [0x54,0xa1,0x8d,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08da154 + +luti2 {z20.s - z23.s}, zt0, z13[0] // 11000000-10001100-10100001-10110100 +// CHECK-INST: luti2 { z20.s - z23.s }, zt0, z13[0] +// CHECK-ENCODING: [0xb4,0xa1,0x8c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08ca1b4 + +luti2 {z28.s - z31.s}, zt0, z31[3] // 11000000-10001111-10100011-11111100 +// CHECK-INST: luti2 { z28.s - z31.s }, zt0, z31[3] +// CHECK-ENCODING: [0xfc,0xa3,0x8f,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08fa3fc + + +luti2 {z0.b - z3.b}, zt0, z0[0] // 11000000-10001100-10000000-00000000 +// CHECK-INST: luti2 { z0.b - z3.b }, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x80,0x8c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08c8000 + +luti2 {z20.b - z23.b}, zt0, z10[1] // 11000000-10001101-10000001-01010100 +// CHECK-INST: luti2 { z20.b - z23.b }, zt0, z10[1] +// CHECK-ENCODING: [0x54,0x81,0x8d,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08d8154 + +luti2 {z20.b - z23.b}, zt0, z13[0] // 11000000-10001100-10000001-10110100 +// CHECK-INST: luti2 { z20.b - z23.b }, zt0, z13[0] +// CHECK-ENCODING: [0xb4,0x81,0x8c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08c81b4 + +luti2 {z28.b - z31.b}, zt0, z31[3] // 11000000-10001111-10000011-11111100 +// CHECK-INST: luti2 { z28.b - z31.b }, zt0, z31[3] +// CHECK-ENCODING: [0xfc,0x83,0x8f,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08f83fc + diff --git a/llvm/test/MC/AArch64/SME2/luti4-diagnostics.s b/llvm/test/MC/AArch64/SME2/luti4-diagnostics.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2/luti4-diagnostics.s @@ -0,0 +1,60 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 2>&1 < %s | FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid lane indices + +luti4 z0.h, zt0, z0[8] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7]. +// CHECK-NEXT: luti4 z0.h, zt0, z0[8] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti4 z0.s, zt0, z0[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7]. +// CHECK-NEXT: luti4 z0.s, zt0, z0[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti4 {z0.b-z1.b}, zt0, z0[4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3]. +// CHECK-NEXT: luti4 {z0.b-z1.b}, zt0, z0[4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti4 {z0.h-z1.h}, zt0, z0[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3]. +// CHECK-NEXT: luti4 {z0.h-z1.h}, zt0, z0[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti4 {z0.s-z3.s}, zt0, z0[2] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 1]. +// CHECK-NEXT: luti4 {z0.s-z3.s}, zt0, z0[2] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti4 {z0.h-z3.h}, zt0, z0[-1] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 1]. +// CHECK-NEXT: luti4 {z0.h-z3.h}, zt0, z0[-1] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector lists + +luti4 {z0.h-z2.h}, zt0, z0[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: luti4 {z0.h-z2.h}, zt0, z0[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti4 {z1.s-z2.s}, zt0, z0[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types +// CHECK-NEXT: luti4 {z1.s-z2.s}, zt0, z0[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +luti4 {z1.s-z4.s}, zt0, z0[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types +// CHECK-NEXT: luti4 {z1.s-z4.s}, zt0, z0[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector suffix + +luti4 {z0.d-z1.d}, zt0, z0[3] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: luti4 {z0.d-z1.d}, zt0, z0[3] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SME2/luti4.s b/llvm/test/MC/AArch64/SME2/luti4.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2/luti4.s @@ -0,0 +1,213 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %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=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2 - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=-sme2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + + +luti4 z0.h, zt0, z0[0] // 11000000-11001010-00010000-00000000 +// CHECK-INST: luti4 z0.h, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x10,0xca,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0ca1000 + +luti4 z21.h, zt0, z10[5] // 11000000-11001011-01010001-01010101 +// CHECK-INST: luti4 z21.h, zt0, z10[5] +// CHECK-ENCODING: [0x55,0x51,0xcb,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cb5155 + +luti4 z23.h, zt0, z13[3] // 11000000-11001010-11010001-10110111 +// CHECK-INST: luti4 z23.h, zt0, z13[3] +// CHECK-ENCODING: [0xb7,0xd1,0xca,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cad1b7 + +luti4 z31.h, zt0, z31[7] // 11000000-11001011-11010011-11111111 +// CHECK-INST: luti4 z31.h, zt0, z31[7] +// CHECK-ENCODING: [0xff,0xd3,0xcb,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cbd3ff + + +luti4 z0.s, zt0, z0[0] // 11000000-11001010-00100000-00000000 +// CHECK-INST: luti4 z0.s, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x20,0xca,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0ca2000 + +luti4 z21.s, zt0, z10[5] // 11000000-11001011-01100001-01010101 +// CHECK-INST: luti4 z21.s, zt0, z10[5] +// CHECK-ENCODING: [0x55,0x61,0xcb,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cb6155 + +luti4 z23.s, zt0, z13[3] // 11000000-11001010-11100001-10110111 +// CHECK-INST: luti4 z23.s, zt0, z13[3] +// CHECK-ENCODING: [0xb7,0xe1,0xca,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cae1b7 + +luti4 z31.s, zt0, z31[7] // 11000000-11001011-11100011-11111111 +// CHECK-INST: luti4 z31.s, zt0, z31[7] +// CHECK-ENCODING: [0xff,0xe3,0xcb,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cbe3ff + + +luti4 z0.b, zt0, z0[0] // 11000000-11001010-00000000-00000000 +// CHECK-INST: luti4 z0.b, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x00,0xca,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0ca0000 + +luti4 z21.b, zt0, z10[5] // 11000000-11001011-01000001-01010101 +// CHECK-INST: luti4 z21.b, zt0, z10[5] +// CHECK-ENCODING: [0x55,0x41,0xcb,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cb4155 + +luti4 z23.b, zt0, z13[3] // 11000000-11001010-11000001-10110111 +// CHECK-INST: luti4 z23.b, zt0, z13[3] +// CHECK-ENCODING: [0xb7,0xc1,0xca,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cac1b7 + +luti4 z31.b, zt0, z31[7] // 11000000-11001011-11000011-11111111 +// CHECK-INST: luti4 z31.b, zt0, z31[7] +// CHECK-ENCODING: [0xff,0xc3,0xcb,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0cbc3ff + + +luti4 {z0.h - z1.h}, zt0, z0[0] // 11000000-10001010-01010000-00000000 +// CHECK-INST: luti4 { z0.h, z1.h }, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x50,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08a5000 + +luti4 {z20.h - z21.h}, zt0, z10[2] // 11000000-10001011-01010001-01010100 +// CHECK-INST: luti4 { z20.h, z21.h }, zt0, z10[2] +// CHECK-ENCODING: [0x54,0x51,0x8b,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08b5154 + +luti4 {z22.h - z23.h}, zt0, z13[1] // 11000000-10001010-11010001-10110110 +// CHECK-INST: luti4 { z22.h, z23.h }, zt0, z13[1] +// CHECK-ENCODING: [0xb6,0xd1,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08ad1b6 + +luti4 {z30.h - z31.h}, zt0, z31[3] // 11000000-10001011-11010011-11111110 +// CHECK-INST: luti4 { z30.h, z31.h }, zt0, z31[3] +// CHECK-ENCODING: [0xfe,0xd3,0x8b,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08bd3fe + + +luti4 {z0.s - z1.s}, zt0, z0[0] // 11000000-10001010-01100000-00000000 +// CHECK-INST: luti4 { z0.s, z1.s }, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x60,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08a6000 + +luti4 {z20.s - z21.s}, zt0, z10[2] // 11000000-10001011-01100001-01010100 +// CHECK-INST: luti4 { z20.s, z21.s }, zt0, z10[2] +// CHECK-ENCODING: [0x54,0x61,0x8b,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08b6154 + +luti4 {z22.s - z23.s}, zt0, z13[1] // 11000000-10001010-11100001-10110110 +// CHECK-INST: luti4 { z22.s, z23.s }, zt0, z13[1] +// CHECK-ENCODING: [0xb6,0xe1,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08ae1b6 + +luti4 {z30.s - z31.s}, zt0, z31[3] // 11000000-10001011-11100011-11111110 +// CHECK-INST: luti4 { z30.s, z31.s }, zt0, z31[3] +// CHECK-ENCODING: [0xfe,0xe3,0x8b,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08be3fe + + +luti4 {z0.b - z1.b}, zt0, z0[0] // 11000000-10001010-01000000-00000000 +// CHECK-INST: luti4 { z0.b, z1.b }, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x40,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08a4000 + +luti4 {z20.b - z21.b}, zt0, z10[2] // 11000000-10001011-01000001-01010100 +// CHECK-INST: luti4 { z20.b, z21.b }, zt0, z10[2] +// CHECK-ENCODING: [0x54,0x41,0x8b,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08b4154 + +luti4 {z22.b - z23.b}, zt0, z13[1] // 11000000-10001010-11000001-10110110 +// CHECK-INST: luti4 { z22.b, z23.b }, zt0, z13[1] +// CHECK-ENCODING: [0xb6,0xc1,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08ac1b6 + +luti4 {z30.b - z31.b}, zt0, z31[3] // 11000000-10001011-11000011-11111110 +// CHECK-INST: luti4 { z30.b, z31.b }, zt0, z31[3] +// CHECK-ENCODING: [0xfe,0xc3,0x8b,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08bc3fe + + +luti4 {z0.h - z3.h}, zt0, z0[0] // 11000000-10001010-10010000-00000000 +// CHECK-INST: luti4 { z0.h - z3.h }, zt0, z0[0] +// CHECK-ENCODING: [0x00,0x90,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08a9000 + +luti4 {z20.h - z23.h}, zt0, z10[1] // 11000000-10001011-10010001-01010100 +// CHECK-INST: luti4 { z20.h - z23.h }, zt0, z10[1] +// CHECK-ENCODING: [0x54,0x91,0x8b,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08b9154 + +luti4 {z20.h - z23.h}, zt0, z13[0] // 11000000-10001010-10010001-10110100 +// CHECK-INST: luti4 { z20.h - z23.h }, zt0, z13[0] +// CHECK-ENCODING: [0xb4,0x91,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08a91b4 + +luti4 {z28.h - z31.h}, zt0, z31[1] // 11000000-10001011-10010011-11111100 +// CHECK-INST: luti4 { z28.h - z31.h }, zt0, z31[1] +// CHECK-ENCODING: [0xfc,0x93,0x8b,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08b93fc + + +luti4 {z0.s - z3.s}, zt0, z0[0] // 11000000-10001010-10100000-00000000 +// CHECK-INST: luti4 { z0.s - z3.s }, zt0, z0[0] +// CHECK-ENCODING: [0x00,0xa0,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08aa000 + +luti4 {z20.s - z23.s}, zt0, z10[1] // 11000000-10001011-10100001-01010100 +// CHECK-INST: luti4 { z20.s - z23.s }, zt0, z10[1] +// CHECK-ENCODING: [0x54,0xa1,0x8b,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08ba154 + +luti4 {z20.s - z23.s}, zt0, z13[0] // 11000000-10001010-10100001-10110100 +// CHECK-INST: luti4 { z20.s - z23.s }, zt0, z13[0] +// CHECK-ENCODING: [0xb4,0xa1,0x8a,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08aa1b4 + +luti4 {z28.s - z31.s}, zt0, z31[1] // 11000000-10001011-10100011-11111100 +// CHECK-INST: luti4 { z28.s - z31.s }, zt0, z31[1] +// CHECK-ENCODING: [0xfc,0xa3,0x8b,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c08ba3fc + diff --git a/llvm/test/MC/AArch64/SME2/movt-diagnostics.s b/llvm/test/MC/AArch64/SME2/movt-diagnostics.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2/movt-diagnostics.s @@ -0,0 +1,32 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 2>&1 < %s| FileCheck %s + +// index must be a multiple of 8 in range [0, 56]. +// --------------------------------------------------------------------------// + +movt x0, zt0[57] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 8 in range [0, 56]. +// CHECK-NEXT: movt x0, zt0[57] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movt x0, zt0[58] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 8 in range [0, 56]. +// CHECK-NEXT: movt x0, zt0[58] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movt x0, zt0[64] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 8 in range [0, 56]. +// CHECK-NEXT: movt x0, zt0[64] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +movt x0, zt0[72] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 8 in range [0, 56]. +// CHECK-NEXT: movt x0, zt0[72] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid zt0 register + +movt x0, zt1[0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: unexpected token in argument list +// CHECK-NEXT: movt x0, zt1[0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SME2/movt.s b/llvm/test/MC/AArch64/SME2/movt.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2/movt.s @@ -0,0 +1,63 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %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=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2 - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=-sme2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + + +movt x0, zt0[0] // 11000000-01001100-00000011-11100000 +// CHECK-INST: movt x0, zt0[0] +// CHECK-ENCODING: [0xe0,0x03,0x4c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c04c03e0 + +movt x21, zt0[40] // 11000000-01001100-01010011-11110101 +// CHECK-INST: movt x21, zt0[40] +// CHECK-ENCODING: [0xf5,0x53,0x4c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c04c53f5 + +movt x23, zt0[48] // 11000000-01001100-01100011-11110111 +// CHECK-INST: movt x23, zt0[48] +// CHECK-ENCODING: [0xf7,0x63,0x4c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c04c63f7 + +movt xzr, zt0[56] // 11000000-01001100-01110011-11111111 +// CHECK-INST: movt xzr, zt0[56] +// CHECK-ENCODING: [0xff,0x73,0x4c,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c04c73ff + + +movt zt0[0], x0 // 11000000-01001110-00000011-11100000 +// CHECK-INST: movt zt0[0], x0 +// CHECK-ENCODING: [0xe0,0x03,0x4e,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c04e03e0 + +movt zt0[40], x21 // 11000000-01001110-01010011-11110101 +// CHECK-INST: movt zt0[40], x21 +// CHECK-ENCODING: [0xf5,0x53,0x4e,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c04e53f5 + +movt zt0[48], x23 // 11000000-01001110-01100011-11110111 +// CHECK-INST: movt zt0[48], x23 +// CHECK-ENCODING: [0xf7,0x63,0x4e,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c04e63f7 + +movt zt0[56], xzr // 11000000-01001110-01110011-11111111 +// CHECK-INST: movt zt0[56], xzr +// CHECK-ENCODING: [0xff,0x73,0x4e,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c04e73ff + diff --git a/llvm/test/MC/AArch64/SME2/str-diagnostics.s b/llvm/test/MC/AArch64/SME2/str-diagnostics.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2/str-diagnostics.s @@ -0,0 +1,6 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 2>&1 < %s| FileCheck %s + +str zt, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid lookup table, expected zt0 +// CHECK-NEXT: str zt, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SME2/str.s b/llvm/test/MC/AArch64/SME2/str.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2/str.s @@ -0,0 +1,38 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %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=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2 - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=-sme2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + + +str zt0, [x0] // 11100001-00111111-10000000-00000000 +// CHECK-INST: str zt0, [x0] +// CHECK-ENCODING: [0x00,0x80,0x3f,0xe1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: e13f8000 + +str zt0, [x10] // 11100001-00111111-10000001-01000000 +// CHECK-INST: str zt0, [x10] +// CHECK-ENCODING: [0x40,0x81,0x3f,0xe1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: e13f8140 + +str zt0, [x13] // 11100001-00111111-10000001-10100000 +// CHECK-INST: str zt0, [x13] +// CHECK-ENCODING: [0xa0,0x81,0x3f,0xe1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: e13f81a0 + +str zt0, [sp] // 11100001-00111111-10000011-11100000 +// CHECK-INST: str zt0, [sp] +// CHECK-ENCODING: [0xe0,0x83,0x3f,0xe1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: e13f83e0 + diff --git a/llvm/test/MC/AArch64/SME2/zero.s b/llvm/test/MC/AArch64/SME2/zero.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2/zero.s @@ -0,0 +1,20 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %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=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2 - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=-sme2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + + +zero {zt0} // 11000000-01001000-00000000-00000001 +// CHECK-INST: zero { zt0 } +// CHECK-ENCODING: [0x01,0x00,0x48,0xc0] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c0480001 +