Index: llvm/lib/Target/AArch64/AArch64RegisterInfo.td =================================================================== --- llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -1372,6 +1372,24 @@ def MatrixTileList32 : MatrixTileListOperand<"MPR32", 32, (ops MPR32)>; def MatrixTileList64 : MatrixTileListOperand<"MPR64", 64, (ops MPR64)>; + +def SVCROperand : AsmOperandClass { + let Name = "SVCR"; + let ParserMethod = "tryParseSVCR"; + let DiagnosticType = "Invalid" # Name; +} + +def svcr_op : Operand { + let ParserMatchClass = SVCROperand; + let PrintMethod = "printSVCROp"; + let DecoderMethod = "DecodeSVCROp"; + let MCOperandPredicate = [{ + if (!MCOp.isImm()) + return false; + return AArch64SVCR::lookupSVCRByEncoding(MCOp.getImm()) != nullptr; + }]; +} + def MatrixIndexGPR32_12_15 : RegisterClass<"AArch64", [i32], 32, (sequence "W%u", 12, 15)>; def MatrixIndexGPR32Op12_15 : RegisterOperand { let EncoderMethod = "EncodeMatrixIndexGPR32"; Index: llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td =================================================================== --- llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td +++ llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td @@ -94,4 +94,39 @@ defm ZERO_M : sme_zero<"zero">; +//===----------------------------------------------------------------------===// +// Mode selection and state access instructions +//===----------------------------------------------------------------------===// + +// SME defines three pstate fields to set or clear PSTATE.SM, PSTATE.ZA, or +// both fields: +// +// MSR SVCRSM, # +// MSR SVCRZA, # +// MSR SVCRSMZA, # +// +// It's tricky to using the existing pstate operand defined in +// AArch64SystemOperands.td since it only encodes 5 bits including op1;op2, +// when these fields are also encoded in CRm[3:1]. +class MSRpstatesvcrImm0_1 + : PstateWriteSimple<(ins svcr_op:$pstatefield, imm0_1:$imm), "msr", + "\t$pstatefield, $imm">, + Sched<[WriteSys]> { + bits<3> pstatefield; + bit imm; + let Inst{18-16} = 0b011; // op1 + let Inst{11-9} = pstatefield; + let Inst{8} = imm; + let Inst{7-5} = 0b011; // op2 +} + +def MSRpstatesvcrImm1 : MSRpstatesvcrImm0_1; +def : InstAlias<"smstart", (MSRpstatesvcrImm1 0b011, 0b1)>; +def : InstAlias<"smstart sm", (MSRpstatesvcrImm1 0b001, 0b1)>; +def : InstAlias<"smstart za", (MSRpstatesvcrImm1 0b010, 0b1)>; + +def : InstAlias<"smstop", (MSRpstatesvcrImm1 0b011, 0b0)>; +def : InstAlias<"smstop sm", (MSRpstatesvcrImm1 0b001, 0b0)>; +def : InstAlias<"smstop za", (MSRpstatesvcrImm1 0b010, 0b0)>; + } // End let Predicates = [HasSME] Index: llvm/lib/Target/AArch64/AArch64SystemOperands.td =================================================================== --- llvm/lib/Target/AArch64/AArch64SystemOperands.td +++ llvm/lib/Target/AArch64/AArch64SystemOperands.td @@ -368,6 +368,26 @@ let Requires = [{ {AArch64::FeatureMTE} }] in def : PState<"TCO", 0b11100>; +//===----------------------------------------------------------------------===// +// SVCR instruction options. +//===----------------------------------------------------------------------===// + +class SVCR encoding> : SearchableTable { + let SearchableFields = ["Name", "Encoding"]; + let EnumValueField = "Encoding"; + + string Name = name; + bits<3> Encoding; + let Encoding = encoding; + code Requires = [{ {} }]; +} + +let Requires = [{ {AArch64::FeatureSME} }] in { +def : SVCR<"SVCRSM", 0b001>; +def : SVCR<"SVCRZA", 0b010>; +def : SVCR<"SVCRSMZA", 0b011>; +} + //===----------------------------------------------------------------------===// // PSB instruction options. //===----------------------------------------------------------------------===// @@ -758,6 +778,12 @@ def : RWSysReg<"GPTBR_EL3", 0b11, 0b110, 0b0010, 0b0001, 0b100>; } +// v9-a Scalable Matrix Extension (SME) registers +// Op0 Op1 CRn CRm Op2 +let Requires = [{ {AArch64::FeatureSME} }] in { +def : ROSysReg<"ID_AA64SMFR0_EL1", 0b11, 0b000, 0b0000, 0b0100, 0b101>; +} + //===---------------------- // Write-only regs //===---------------------- @@ -1616,3 +1642,23 @@ // Op0 Op1 CRn CRm Op2 let Requires = [{ {AArch64::ProcAppleA7} }] in def : RWSysReg<"CPM_IOACC_CTL_EL3", 0b11, 0b111, 0b1111, 0b0010, 0b000>; + +// Scalable Matrix Extension (SME) +// Op0 Op1 CRn CRm Op2 +let Requires = [{ {AArch64::FeatureSME} }] in { +def : RWSysReg<"SMCR_EL1", 0b11, 0b000, 0b0001, 0b0010, 0b110>; +def : RWSysReg<"SMCR_EL2", 0b11, 0b100, 0b0001, 0b0010, 0b110>; +def : RWSysReg<"SMCR_EL3", 0b11, 0b110, 0b0001, 0b0010, 0b110>; +def : RWSysReg<"SMCR_EL12", 0b11, 0b101, 0b0001, 0b0010, 0b110>; +def : RWSysReg<"SVCR", 0b11, 0b011, 0b0100, 0b0010, 0b010>; +def : RWSysReg<"SMPRI_EL1", 0b11, 0b000, 0b0001, 0b0010, 0b100>; +def : RWSysReg<"SMPRIMAP_EL2", 0b11, 0b100, 0b0001, 0b0010, 0b101>; +def : ROSysReg<"SMIDR_EL1", 0b11, 0b001, 0b0000, 0b0000, 0b110>; +def : RWSysReg<"TPIDR2_EL0", 0b11, 0b011, 0b1101, 0b0000, 0b101>; +} // HasSME + +// v8.4a MPAM and SME registers +// Op0 Op1 CRn CRm Op2 +let Requires = [{ {AArch64::FeatureMPAM, AArch64::FeatureSME} }] in { +def : RWSysReg<"MPAMSM_EL1", 0b11, 0b000, 0b1010, 0b0101, 0b011>; +} // HasMPAM, HasSME Index: llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -234,6 +234,7 @@ OperandMatchResultTy tryParseVectorRegister(unsigned &Reg, StringRef &Kind, RegKind MatchKind); OperandMatchResultTy tryParseMatrixRegister(OperandVector &Operands); + OperandMatchResultTy tryParseSVCR(OperandVector &Operands); OperandMatchResultTy tryParseOptionalShiftExtend(OperandVector &Operands); OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands); OperandMatchResultTy tryParseBarriernXSOperand(OperandVector &Operands); @@ -324,6 +325,7 @@ k_Register, k_MatrixRegister, k_MatrixTileList, + k_SVCR, k_VectorList, k_VectorIndex, k_Token, @@ -389,6 +391,12 @@ unsigned ElementWidth; }; + struct SVCROp { + const char *Data; + unsigned Length; + unsigned PStateField; + }; + struct VectorListOp { unsigned RegNum; unsigned Count; @@ -461,6 +469,7 @@ struct RegOp Reg; struct MatrixRegOp MatrixReg; struct MatrixTileListOp MatrixTileList; + struct SVCROp SVCR; struct VectorListOp VectorList; struct VectorIndexOp VectorIndex; struct ImmOp Imm; @@ -515,6 +524,9 @@ case k_MatrixTileList: MatrixTileList = o.MatrixTileList; break; + case k_SVCR: + SVCR = o.SVCR; + break; case k_VectorList: VectorList = o.VectorList; break; @@ -632,6 +644,11 @@ return MatrixTileList.ElementWidth; } + StringRef getSVCR() const { + assert(Kind == k_SVCR && "Invalid access!"); + return StringRef(SVCR.Data, SVCR.Length); + } + RegConstraintEqualityTy getRegEqualityTy() const { assert(Kind == k_Register && "Invalid access!"); return Reg.EqualityTy; @@ -1121,6 +1138,12 @@ return SysReg.PStateField != -1U; } + bool isSVCR() const { + if (Kind != k_SVCR) + return false; + return SVCR.PStateField != -1U; + } + bool isReg() const override { return Kind == k_Register; } @@ -1847,6 +1870,12 @@ Inst.addOperand(MCOperand::createImm(SysReg.PStateField)); } + void addSVCROperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + + Inst.addOperand(MCOperand::createImm(SVCR.PStateField)); + } + void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); @@ -2195,6 +2224,17 @@ return Op; } + static std::unique_ptr + CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) { + auto Op = std::make_unique(k_SVCR, Ctx); + Op->SVCR.PStateField = PStateField; + Op->SVCR.Data = Str.data(); + Op->SVCR.Length = Str.size(); + Op->StartLoc = S; + Op->EndLoc = S; + return Op; + } + static std::unique_ptr CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val, bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) { @@ -2284,6 +2324,10 @@ OS << ((RegMask & (1 << (I - 1))) >> (I - 1)); break; } + case k_SVCR: { + OS << getSVCR(); + break; + } case k_Register: OS << ""; if (!getShiftExtendAmount() && !hasShiftExtendAmount()) @@ -3072,6 +3116,28 @@ return false; } +OperandMatchResultTy +AArch64AsmParser::tryParseSVCR(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); + const AsmToken &Tok = Parser.getTok(); + SMLoc S = getLoc(); + + if (Tok.isNot(AsmToken::Identifier)) { + TokError("invalid operand for instruction"); + return MatchOperand_ParseFail; + } + + unsigned PStateImm = -1; + const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.getString()); + if (SVCR && SVCR->haveFeatures(getSTI().getFeatureBits())) + PStateImm = SVCR->Encoding; + + Operands.push_back( + AArch64Operand::CreateSVCR(PStateImm, Tok.getString(), S, getContext())); + Parser.Lex(); // Eat identifier token. + return MatchOperand_Success; +} + OperandMatchResultTy AArch64AsmParser::tryParseMatrixRegister(OperandVector &Operands) { MCAsmParser &Parser = getParser(); @@ -3528,6 +3594,9 @@ if (Tok.isNot(AsmToken::Identifier)) return MatchOperand_NoMatch; + if (AArch64SVCR::lookupSVCRByName(Tok.getString())) + return MatchOperand_NoMatch; + int MRSReg, MSRReg; auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.getString()); if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) { @@ -4144,8 +4213,15 @@ auto Tok = Parser.getTok(); if (Tok.isNot(AsmToken::Identifier)) return true; - Operands.push_back(AArch64Operand::CreateToken(Tok.getString(), false, - Tok.getLoc(), getContext())); + + auto Keyword = Tok.getString(); + Keyword = StringSwitch(Keyword.lower()) + .Case("sm", "sm") + .Case("za", "za") + .Default(Keyword); + Operands.push_back( + AArch64Operand::CreateToken(Keyword, false, Tok.getLoc(), getContext())); + Parser.Lex(); return false; } @@ -4219,6 +4295,11 @@ if (!parseOptionalMulOperand(Operands)) return false; + // If this is an "smstart" or "smstop" instruction, parse its special + // keyword operand as an identifier. + if (Mnemonic == "smstart" || Mnemonic == "smstop") + return parseKeywordOperand(Operands); + // This could be an optional "shift" or "extend" operand. OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands); // We can only continue if no tokens were eaten. @@ -5074,6 +5155,7 @@ case Match_MRS: return Error(Loc, "expected readable system register"); case Match_MSR: + case Match_InvalidSVCR: return Error(Loc, "expected writable system register or pstate"); case Match_InvalidComplexRotationEven: return Error(Loc, "complex rotation must be 0, 90, 180 or 270."); @@ -5744,6 +5826,7 @@ case Match_InvalidMatrixTileVectorV32: case Match_InvalidMatrixTileVectorV64: case Match_InvalidMatrixTileVectorV128: + case Match_InvalidSVCR: case Match_MSR: case Match_MRS: { if (ErrorInfo >= Operands.size()) @@ -6628,6 +6711,14 @@ case MCK__HASH_8: ExpectedVal = 8; break; + case MCK_MPR: + // If the Kind is a token for the MPR register class which has the "za" + // register (SME accumulator array), check if the asm is a literal "za" + // token. This is for the "smstart za" alias that defines the register + // as a literal token. + if (Op.isTokenEqual("za")) + return Match_Success; + break; } if (!Op.isImm()) return Match_InvalidOperand; Index: llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp =================================================================== --- llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -237,6 +237,8 @@ uint64_t Addr, const void *Decoder); static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm, uint64_t Addr, const void *Decoder); +static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address, + const void *Decoder); static bool Check(DecodeStatus &Out, DecodeStatus In) { switch (In) { @@ -2023,3 +2025,12 @@ Inst.addOperand(MCOperand::createImm(Imm + 1)); return Success; } + +static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address, + const void *Decoder) { + if (AArch64SVCR::lookupSVCRByEncoding(Imm)) { + Inst.addOperand(MCOperand::createImm(Imm)); + return Success; + } + return Fail; +} Index: llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h =================================================================== --- llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h +++ llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h @@ -200,6 +200,8 @@ template void printMatrix(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); + void printSVCROp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, + raw_ostream &O); template void printSVERegOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); Index: llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp =================================================================== --- llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp +++ llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp @@ -933,6 +933,17 @@ O << getRegisterName(RegOp.getReg()); } +void AArch64InstPrinter::printSVCROp(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNum); + assert(MO.isImm() && "Unexpected operand type!"); + unsigned svcrop = MO.getImm(); + const auto *SVCR = AArch64SVCR::lookupSVCRByEncoding(svcrop); + assert(SVCR && "Unexpected SVCR operand!"); + O << SVCR->Name; +} + void AArch64InstPrinter::printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { Index: llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h =================================================================== --- llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -346,6 +346,14 @@ : SysAlias(N, E, F), ImmValue(I) {} }; +namespace AArch64SVCR { + struct SVCR : SysAlias{ + using SysAlias::SysAlias; + }; + #define GET_SVCR_DECL + #include "AArch64GenSystemOperands.inc" +} + namespace AArch64AT{ struct AT : SysAlias { using SysAlias::SysAlias; Index: llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp =================================================================== --- llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp +++ llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp @@ -169,3 +169,10 @@ #include "AArch64GenSystemOperands.inc" } } + +namespace llvm { + namespace AArch64SVCR { +#define GET_SVCR_IMPL +#include "AArch64GenSystemOperands.inc" + } +} Index: llvm/test/MC/AArch64/SME/smstart.s =================================================================== --- /dev/null +++ llvm/test/MC/AArch64/SME/smstart.s @@ -0,0 +1,38 @@ +// 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 + +smstart +// CHECK-INST: smstart +// CHECK-ENCODING: [0x7f,0x47,0x03,0xd5] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 7f 47 03 d5 msr S0_3_C4_C7_3, xzr + +smstart sm +// CHECK-INST: smstart sm +// CHECK-ENCODING: [0x7f,0x43,0x03,0xd5] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 7f 43 03 d5 msr S0_3_C4_C3_3, xzr + +smstart za +// CHECK-INST: smstart za +// CHECK-ENCODING: [0x7f,0x45,0x03,0xd5] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 7f 45 03 d5 msr S0_3_C4_C5_3, xzr + +smstart SM +// CHECK-INST: smstart sm +// CHECK-ENCODING: [0x7f,0x43,0x03,0xd5] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 7f 43 03 d5 msr S0_3_C4_C3_3, xzr + +smstart ZA +// CHECK-INST: smstart za +// CHECK-ENCODING: [0x7f,0x45,0x03,0xd5] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 7f 45 03 d5 msr S0_3_C4_C5_3, xzr Index: llvm/test/MC/AArch64/SME/smstop.s =================================================================== --- /dev/null +++ llvm/test/MC/AArch64/SME/smstop.s @@ -0,0 +1,38 @@ +// 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 + +smstop +// CHECK-INST: smstop +// CHECK-ENCODING: [0x7f,0x46,0x03,0xd5] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 7f 46 03 d5 msr S0_3_C4_C6_3, xzr + +smstop sm +// CHECK-INST: smstop sm +// CHECK-ENCODING: [0x7f,0x42,0x03,0xd5] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 7f 42 03 d5 msr S0_3_C4_C2_3, xzr + +smstop za +// CHECK-INST: smstop za +// CHECK-ENCODING: [0x7f,0x44,0x03,0xd5] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 7f 44 03 d5 msr S0_3_C4_C4_3, xzr + +smstop SM +// CHECK-INST: smstop sm +// CHECK-ENCODING: [0x7f,0x42,0x03,0xd5] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 7f 42 03 d5 msr S0_3_C4_C2_3, xzr + +smstop ZA +// CHECK-INST: smstop za +// CHECK-ENCODING: [0x7f,0x44,0x03,0xd5] +// CHECK-ERROR: instruction requires: sme +// CHECK-UNKNOWN: 7f 44 03 d5 msr S0_3_C4_C4_3, xzr Index: llvm/test/MC/AArch64/SME/system-regs-diagnostics.s =================================================================== --- /dev/null +++ llvm/test/MC/AArch64/SME/system-regs-diagnostics.s @@ -0,0 +1,28 @@ +// RUN: not llvm-mc -triple aarch64 -mattr=+sme -show-encoding < %s 2>&1 | FileCheck %s + + +// --------------------------------------------------------------------------// +// Check read-only + +msr ID_AA64SMFR0_EL1, x3 +// CHECK: error: expected writable system register or pstate +// CHECK-NEXT: msr ID_AA64SMFR0_EL1, x3 + +msr SMIDR_EL1, x3 +// CHECK: error: expected writable system register or pstate +// CHECK-NEXT: msr SMIDR_EL1, x3 + +// --------------------------------------------------------------------------// +// Check MSR SVCR immediate is in range [0, 1] + +msr SVCRSM, #-1 +// CHECK: error: immediate must be an integer in range [0, 1]. +// CHECK-NEXT: msr SVCRSM, #-1 + +msr SVCRZA, #2 +// CHECK: error: immediate must be an integer in range [0, 1]. +// CHECK-NEXT: msr SVCRZA, #2 + +msr SVCRSMZA, #4 +// CHECK: error: immediate must be an integer in range [0, 1]. +// CHECK-NEXT: msr SVCRSMZA, #4 Index: llvm/test/MC/AArch64/SME/system-regs-mpam.s =================================================================== --- /dev/null +++ llvm/test/MC/AArch64/SME/system-regs-mpam.s @@ -0,0 +1,34 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme,+mpam < %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: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+mpam < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme,+mpam < %s \ +// RUN: | llvm-objdump -d --mattr=+sme,+mpam - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme,+mpam < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme,+mpam < %s \ +// RUN: | llvm-objdump -d --mattr=+sme - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme,+mpam < %s \ +// RUN: | llvm-objdump -d --mattr=+mpam - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +// --------------------------------------------------------------------------// +// read + +mrs x3, MPAMSM_EL1 +// CHECK-INST: mrs x3, MPAMSM_EL1 +// CHECK-ENCODING: [0x63,0xa5,0x38,0xd5] +// CHECK-ERROR: expected readable system register +// CHECK-UNKNOWN: 63 a5 38 d5 mrs x3, S3_0_C10_C5_3 + +// --------------------------------------------------------------------------// +// write + +msr MPAMSM_EL1, x3 +// CHECK-INST: msr MPAMSM_EL1, x3 +// CHECK-ENCODING: [0x63,0xa5,0x18,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: 63 a5 18 d5 msr S3_0_C10_C5_3, x3 Index: llvm/test/MC/AArch64/SME/system-regs.s =================================================================== --- /dev/null +++ llvm/test/MC/AArch64/SME/system-regs.s @@ -0,0 +1,158 @@ +// 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 + +// --------------------------------------------------------------------------// +// read + +mrs x3, ID_AA64SMFR0_EL1 +// CHECK-INST: mrs x3, ID_AA64SMFR0_EL1 +// CHECK-ENCODING: [0xa3,0x04,0x38,0xd5] +// CHECK-ERROR: expected readable system register +// CHECK-UNKNOWN: a3 04 38 d5 mrs x3, S3_0_C0_C4_5 + +mrs x3, SMCR_EL1 +// CHECK-INST: mrs x3, SMCR_EL1 +// CHECK-ENCODING: [0xc3,0x12,0x38,0xd5] +// CHECK-ERROR: expected readable system register +// CHECK-UNKNOWN: c3 12 38 d5 mrs x3, S3_0_C1_C2_6 + +mrs x3, SMCR_EL2 +// CHECK-INST: mrs x3, SMCR_EL2 +// CHECK-ENCODING: [0xc3,0x12,0x3c,0xd5] +// CHECK-ERROR: expected readable system register +// CHECK-UNKNOWN: c3 12 3c d5 mrs x3, S3_4_C1_C2_6 + +mrs x3, SMCR_EL3 +// CHECK-INST: mrs x3, SMCR_EL3 +// CHECK-ENCODING: [0xc3,0x12,0x3e,0xd5] +// CHECK-ERROR: expected readable system register +// CHECK-UNKNOWN: c3 12 3e d5 mrs x3, S3_6_C1_C2_6 + +mrs x3, SMCR_EL12 +// CHECK-INST: mrs x3, SMCR_EL12 +// CHECK-ENCODING: [0xc3,0x12,0x3d,0xd5] +// CHECK-ERROR: expected readable system register +// CHECK-UNKNOWN: c3 12 3d d5 mrs x3, S3_5_C1_C2_6 + +mrs x3, SVCR +// CHECK-INST: mrs x3, SVCR +// CHECK-ENCODING: [0x43,0x42,0x3b,0xd5] +// CHECK-ERROR: expected readable system register +// CHECK-UNKNOWN: 43 42 3b d5 mrs x3, S3_3_C4_C2_2 + +mrs x3, SMPRI_EL1 +// CHECK-INST: mrs x3, SMPRI_EL1 +// CHECK-ENCODING: [0x83,0x12,0x38,0xd5] +// CHECK-ERROR: expected readable system register +// CHECK-UNKNOWN: 83 12 38 d5 mrs x3, S3_0_C1_C2_4 + +mrs x3, SMPRIMAP_EL2 +// CHECK-INST: mrs x3, SMPRIMAP_EL2 +// CHECK-ENCODING: [0xa3,0x12,0x3c,0xd5] +// CHECK-ERROR: expected readable system register +// CHECK-UNKNOWN: a3 12 3c d5 mrs x3, S3_4_C1_C2_5 + +mrs x3, SMIDR_EL1 +// CHECK-INST: mrs x3, SMIDR_EL1 +// CHECK-ENCODING: [0xc3,0x00,0x39,0xd5] +// CHECK-ERROR: expected readable system register +// CHECK-UNKNOWN: c3 00 39 d5 mrs x3, S3_1_C0_C0_6 + +mrs x3, TPIDR2_EL0 +// CHECK-INST: mrs x3, TPIDR2_EL0 +// CHECK-ENCODING: [0xa3,0xd0,0x3b,0xd5] +// CHECK-ERROR: expected readable system register +// CHECK-UNKNOWN: a3 d0 3b d5 mrs x3, S3_3_C13_C0_5 + +// --------------------------------------------------------------------------// +// write + +msr SMCR_EL1, x3 +// CHECK-INST: msr SMCR_EL1, x3 +// CHECK-ENCODING: [0xc3,0x12,0x18,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: c3 12 18 d5 msr S3_0_C1_C2_6, x3 + +msr SMCR_EL2, x3 +// CHECK-INST: msr SMCR_EL2, x3 +// CHECK-ENCODING: [0xc3,0x12,0x1c,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: c3 12 1c d5 msr S3_4_C1_C2_6, x3 + +msr SMCR_EL3, x3 +// CHECK-INST: msr SMCR_EL3, x3 +// CHECK-ENCODING: [0xc3,0x12,0x1e,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: c3 12 1e d5 msr S3_6_C1_C2_6, x3 + +msr SMCR_EL12, x3 +// CHECK-INST: msr SMCR_EL12, x3 +// CHECK-ENCODING: [0xc3,0x12,0x1d,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: c3 12 1d d5 msr S3_5_C1_C2_6, x3 + +msr SVCR, x3 +// CHECK-INST: msr SVCR, x3 +// CHECK-ENCODING: [0x43,0x42,0x1b,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: 43 42 1b d5 msr S3_3_C4_C2_2, x3 + +msr SMPRI_EL1, x3 +// CHECK-INST: msr SMPRI_EL1, x3 +// CHECK-ENCODING: [0x83,0x12,0x18,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: 83 12 18 d5 msr S3_0_C1_C2_4, x3 + +msr SMPRIMAP_EL2, x3 +// CHECK-INST: msr SMPRIMAP_EL2, x3 +// CHECK-ENCODING: [0xa3,0x12,0x1c,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: a3 12 1c d5 msr S3_4_C1_C2_5, x3 + +msr SVCRSM, #0 +// CHECK-INST: smstop sm +// CHECK-ENCODING: [0x7f,0x42,0x03,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: 7f 42 03 d5 msr S0_3_C4_C2_3, xzr + +msr SVCRSM, #1 +// CHECK-INST: smstart +// CHECK-ENCODING: [0x7f,0x43,0x03,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: 7f 43 03 d5 msr S0_3_C4_C3_3, xzr + +msr SVCRZA, #0 +// CHECK-INST: smstop za +// CHECK-ENCODING: [0x7f,0x44,0x03,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: 7f 44 03 d5 msr S0_3_C4_C4_3, xzr + +msr SVCRZA, #1 +// CHECK-INST: smstart za +// CHECK-ENCODING: [0x7f,0x45,0x03,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: 7f 45 03 d5 msr S0_3_C4_C5_3, xzr + +msr SVCRSMZA, #0 +// CHECK-INST: smstop +// CHECK-ENCODING: [0x7f,0x46,0x03,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: 7f 46 03 d5 msr S0_3_C4_C6_3, xzr + +msr SVCRSMZA, #1 +// CHECK-INST: smstart +// CHECK-ENCODING: [0x7f,0x47,0x03,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: 7f 47 03 d5 msr S0_3_C4_C7_3, xzr + +msr TPIDR2_EL0, x3 +// CHECK-INST: msr TPIDR2_EL0, x3 +// CHECK-ENCODING: [0xa3,0xd0,0x1b,0xd5] +// CHECK-ERROR: expected writable system register or pstate +// CHECK-UNKNOWN: a3 d0 1b d5 msr S3_3_C13_C0_5, x3