[AArch64][SME] Add system registers and related instructions

This patch adds the new system registers introduced in SME:

  - ID_AA64SMFR0_EL1 (ro) SME feature identifier.
  - SMCR_ELx (r/w) streaming mode control register for configuring
    effective SVE Streaming SVE Vector length when the PE is in
    Streaming SVE mode.
  - SVCR (r/w) streaming vector control register, visible at all
    exception levels. Provides access to PSTATE.SM and PSTATE.ZA
    using MSR and MRS instructions.
  - SMPRI_EL1 (r/w) streaming mode execution priority register.
  - SMPRIMAP_EL2 (r/w) streaming mode priority mapping register.
  - SMIDR_EL1 (ro) streaming mode identification register.
  - TPIDR2_EL0 (r/w) for use by SME software to manage per-thread
    SME context.
  - MPAMSM_EL1 (r/w) MPAM (v8.4) streaming mode register, for
    labelling memory accesses performed in streaming mode.

Also added in this patch are the SME mode change instructions.
Three MSR immediate instructions are implemented to set or clear
PSTATE.SM, PSTATE.ZA, or both respectively:

  - MSR SVCRSM, #<imm1>
  - MSR SVCRZA, #<imm1>
  - MSR SVCRSMZA, #<imm1>

The following smstart/smstop aliases are also implemented for
convenience:

  smstart    -> MSR SVCRSMZA, #1
  smstart sm -> MSR SVCRSM,   #1
  smstart za -> MSR SVCRZA,   #1

  smstop     -> MSR SVCRSMZA, #0
  smstop sm  -> MSR SVCRSM,   #0
  smstop za  -> MSR SVCRZA,   #0

The reference can be found here:
https://developer.arm.com/documentation/ddi0602/2021-06

Reviewed By: david-arm

Differential Revision: https://reviews.llvm.org/D105576
This commit is contained in:
Cullen Rhodes 2021-07-20 07:19:10 +00:00
parent b4001ae885
commit 15af3aaa2e
16 changed files with 544 additions and 2 deletions

View File

@ -1356,3 +1356,20 @@ def MatrixIndexGPR32_12_15 : RegisterClass<"AArch64", [i32], 32, (sequence "W%u"
def MatrixIndexGPR32Op12_15 : RegisterOperand<MatrixIndexGPR32_12_15> {
let EncoderMethod = "encodeMatrixIndexGPR32";
}
def SVCROperand : AsmOperandClass {
let Name = "SVCR";
let ParserMethod = "tryParseSVCR";
let DiagnosticType = "Invalid" # Name;
}
def svcr_op : Operand<i32> {
let ParserMatchClass = SVCROperand;
let PrintMethod = "printSVCROp";
let DecoderMethod = "DecodeSVCROp";
let MCOperandPredicate = [{
if (!MCOp.isImm())
return false;
return AArch64SVCR::lookupSVCRByEncoding(MCOp.getImm()) != nullptr;
}];
}

View File

@ -74,6 +74,41 @@ let Predicates = [HasSME] in {
defm LD1_MXIPXX : sme_mem_ld_ss<"ld1">;
defm ST1_MXIPXX : sme_mem_st_ss<"st1">;
//===----------------------------------------------------------------------===//
// Mode selection and state access instructions
//===----------------------------------------------------------------------===//
// SME defines three pstate fields to set or clear PSTATE.SM, PSTATE.ZA, or
// both fields:
//
// MSR SVCRSM, #<imm1>
// MSR SVCRZA, #<imm1>
// MSR SVCRSMZA, #<imm1>
//
// 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)>;
//===----------------------------------------------------------------------===//
// SVE2 instructions
//===----------------------------------------------------------------------===//

View File

@ -368,6 +368,26 @@ def : PState<"SSBS", 0b11001>;
let Requires = [{ {AArch64::FeatureMTE} }] in
def : PState<"TCO", 0b11100>;
//===----------------------------------------------------------------------===//
// SVCR instruction options.
//===----------------------------------------------------------------------===//
class SVCR<string name, bits<3> 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<"GPCCR_EL3", 0b11, 0b110, 0b0010, 0b0001, 0b110>;
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 @@ def : RWSysReg<"PMSNEVFR_EL1", 0b11, 0b000, 0b1001, 0b1001, 0b001>;
// 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

View File

@ -233,6 +233,7 @@ private:
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);
@ -321,6 +322,7 @@ private:
k_CondCode,
k_Register,
k_MatrixRegister,
k_SVCR,
k_VectorList,
k_VectorIndex,
k_Token,
@ -448,6 +450,12 @@ private:
unsigned Val;
};
struct SVCROp {
const char *Data;
unsigned Length;
unsigned PStateField;
};
union {
struct TokOp Tok;
struct RegOp Reg;
@ -465,6 +473,7 @@ private:
struct PSBHintOp PSBHint;
struct BTIHintOp BTIHint;
struct ShiftExtendOp ShiftExtend;
struct SVCROp SVCR;
};
// Keep the MCContext around as the MCExprs may need manipulated during
@ -527,6 +536,9 @@ public:
case k_ShiftExtend:
ShiftExtend = o.ShiftExtend;
break;
case k_SVCR:
SVCR = o.SVCR;
break;
}
}
@ -665,6 +677,11 @@ public:
return StringRef(BTIHint.Data, BTIHint.Length);
}
StringRef getSVCR() const {
assert(Kind == k_SVCR && "Invalid access!");
return StringRef(SVCR.Data, SVCR.Length);
}
StringRef getPrefetchName() const {
assert(Kind == k_Prefetch && "Invalid access!");
return StringRef(Prefetch.Data, Prefetch.Length);
@ -1099,6 +1116,12 @@ public:
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;
}
@ -1809,6 +1832,12 @@ public:
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!");
@ -2114,6 +2143,17 @@ public:
return Op;
}
static std::unique_ptr<AArch64Operand>
CreateSVCR(uint32_t PStateField, StringRef Str, SMLoc S, MCContext &Ctx) {
auto Op = std::make_unique<AArch64Operand>(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<AArch64Operand>
CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val,
bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) {
@ -2195,6 +2235,10 @@ void AArch64Operand::print(raw_ostream &OS) const {
case k_MatrixRegister:
OS << "<matrix " << getMatrixReg() << ">";
break;
case k_SVCR: {
OS << getSVCR();
break;
}
case k_Register:
OS << "<register " << getReg() << ">";
if (!getShiftExtendAmount() && !hasShiftExtendAmount())
@ -2975,6 +3019,28 @@ bool AArch64AsmParser::parseCondCode(OperandVector &Operands,
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();
@ -3431,6 +3497,9 @@ AArch64AsmParser::tryParseSysReg(OperandVector &Operands) {
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())) {
@ -3946,8 +4015,15 @@ bool AArch64AsmParser::parseKeywordOperand(OperandVector &Operands) {
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<StringRef>(Keyword.lower())
.Case("sm", "sm")
.Case("za", "za")
.Default(Keyword);
Operands.push_back(
AArch64Operand::CreateToken(Keyword, false, Tok.getLoc(), getContext()));
Parser.Lex();
return false;
}
@ -4021,6 +4097,11 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
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.
@ -4876,6 +4957,7 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
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.");
@ -5551,6 +5633,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidMatrixTileVectorV32:
case Match_InvalidMatrixTileVectorV64:
case Match_InvalidMatrixTileVectorV128:
case Match_InvalidSVCR:
case Match_MSR:
case Match_MRS: {
if (ErrorInfo >= Operands.size())
@ -6435,6 +6518,14 @@ unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
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;

View File

@ -233,6 +233,8 @@ static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm,
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) {
@ -1992,3 +1994,12 @@ static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
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;
}

View File

@ -933,6 +933,17 @@ void AArch64InstPrinter::printMatrixTile(const MCInst *MI, unsigned OpNum,
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) {

View File

@ -196,6 +196,8 @@ protected:
template <int EltSize>
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 <char = 0>
void printSVERegOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);

View File

@ -169,3 +169,10 @@ namespace llvm {
#include "AArch64GenSystemOperands.inc"
}
}
namespace llvm {
namespace AArch64SVCR {
#define GET_SVCR_IMPL
#include "AArch64GenSystemOperands.inc"
}
}

View File

@ -346,6 +346,14 @@ struct SysAliasImm : SysAlias {
: 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;

View File

@ -0,0 +1,9 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme 2>&1 < %s| FileCheck %s
// ------------------------------------------------------------------------- //
// Invalid keyword
smstart foo
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: smstart foo
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

View File

@ -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

View File

@ -0,0 +1,9 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme 2>&1 < %s| FileCheck %s
// ------------------------------------------------------------------------- //
// Invalid keyword
smstop foo
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: smstop foo
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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