[llvm] f516e91 - [AArch64] Add new v9.4-A PM pstate system register

Lucas Prates via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 19 07:07:58 PST 2022


Author: Lucas Prates
Date: 2022-12-19T15:07:52Z
New Revision: f516e91715642f270d075e097f09a1442f6100f3

URL: https://github.com/llvm/llvm-project/commit/f516e91715642f270d075e097f09a1442f6100f3
DIFF: https://github.com/llvm/llvm-project/commit/f516e91715642f270d075e097f09a1442f6100f3.diff

LOG: [AArch64] Add new v9.4-A PM pstate system register

This adds support for the new PM pstate system register introduced by
the v9.4-A Exception-based Event Profiling extension (FEAT_EBEP).

The new PM pstate register takes a 1-bit immediate and requires
different values to be specified for the higher bits of the Crm field.
To enable that, this patch creates an explicit separation between the
pstate system registers that take 4-bit and 1-bit immediate operands,
allowing each entry to specify the value for the 3 high bits of Crm.

This also updates other pstate registers to correctly accept 4-bit
immediates, matching their decoding specification from the Arm ARM.
These include: `PAN`,  `UAO`, `DIT` and `SSBS`.

More information about this extension and the new register can be found
at:
* https://developer.arm.com/documentation/ddi0601/2022-09/AArch64-Registers/PM--PMU-Exception-Mask

Contributors:
* Lucas Prates
* Sam Elliott

Reviewed By: lenary

Differential Revision: https://reviews.llvm.org/D139925

Added: 
    llvm/test/MC/AArch64/armv9.4a-ebep-error.s
    llvm/test/MC/AArch64/armv9.4a-ebep.s
    llvm/test/MC/Disassembler/AArch64/armv9.4a-ebep.txt

Modified: 
    llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
    llvm/lib/Target/AArch64/AArch64InstrFormats.td
    llvm/lib/Target/AArch64/AArch64SystemOperands.td
    llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
    llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
    llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
    llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
    llvm/test/MC/AArch64/armv8.1a-pan.s
    llvm/test/MC/AArch64/armv8.2a-uao.s
    llvm/test/MC/AArch64/armv8.4a-dit.s
    llvm/test/MC/AArch64/armv8.5a-ssbs-error.s
    llvm/test/MC/Disassembler/AArch64/armv8.1a-pan.txt
    llvm/test/MC/Disassembler/AArch64/armv8.2a-uao.txt

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index 0d563b706018..ed89527da97f 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -3568,26 +3568,28 @@ bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *N) {
     // pstatefield for the MSR (immediate) instruction, we also require that an
     // immediate value has been provided as an argument, we know that this is
     // the case as it has been ensured by semantic checking.
-    auto PMapper = AArch64PState::lookupPStateByName(RegString->getString());
-    if (PMapper) {
-      assert(isa<ConstantSDNode>(N->getOperand(2)) &&
-             "Expected a constant integer expression.");
-      unsigned Reg = PMapper->Encoding;
-      uint64_t Immed = cast<ConstantSDNode>(N->getOperand(2))->getZExtValue();
-      unsigned State;
-      if (Reg == AArch64PState::PAN || Reg == AArch64PState::UAO ||
-          Reg == AArch64PState::SSBS) {
-        assert(Immed < 2 && "Bad imm");
-        State = AArch64::MSRpstateImm1;
-      } else {
-        assert(Immed < 16 && "Bad imm");
-        State = AArch64::MSRpstateImm4;
+    auto trySelectPState = [&](auto PMapper, unsigned State) {
+      if (PMapper) {
+        assert(isa<ConstantSDNode>(N->getOperand(2)) &&
+               "Expected a constant integer expression.");
+        unsigned Reg = PMapper->Encoding;
+        uint64_t Immed = cast<ConstantSDNode>(N->getOperand(2))->getZExtValue();
+        CurDAG->SelectNodeTo(
+            N, State, MVT::Other, CurDAG->getTargetConstant(Reg, DL, MVT::i32),
+            CurDAG->getTargetConstant(Immed, DL, MVT::i16), N->getOperand(0));
+        return true;
       }
-      CurDAG->SelectNodeTo(
-          N, State, MVT::Other, CurDAG->getTargetConstant(Reg, DL, MVT::i32),
-          CurDAG->getTargetConstant(Immed, DL, MVT::i16), N->getOperand(0));
+      return false;
+    };
+
+    if (trySelectPState(
+            AArch64PState::lookupPStateImm0_15ByName(RegString->getString()),
+            AArch64::MSRpstateImm4))
+      return true;
+    if (trySelectPState(
+            AArch64PState::lookupPStateImm0_1ByName(RegString->getString()),
+            AArch64::MSRpstateImm1))
       return true;
-    }
   }
 
   int Imm = getIntOperandFromRegisterString(RegString->getString());

diff  --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 016563cca9f5..9e64b2121c61 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -1730,6 +1730,11 @@ def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
 def pstatefield4_op : Operand<i32> {
   let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
   let PrintMethod = "printSystemPStateField";
+  let MCOperandPredicate = [{
+    if (!MCOp.isImm())
+      return false;
+    return AArch64SVCR::lookupPStateImm0_15ByEncoding(MCOp.getImm()) != nullptr;
+  }];
 }
 
 // Instructions to modify PSTATE, no input reg
@@ -1752,10 +1757,10 @@ class MSRpstateImm0_15
   let Inst{11-8} = imm;
   let Inst{7-5} = pstatefield{2-0};
 
-  let DecoderMethod = "DecodeSystemPStateInstruction";
+  let DecoderMethod = "DecodeSystemPStateImm0_15Instruction";
   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
   // Fail the decoder should attempt to decode the instruction as MSRI.
-  let hasCompleteDecoder = 0;
+  let hasCompleteDecoder = false;
 }
 
 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
@@ -1765,6 +1770,11 @@ def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
 def pstatefield1_op : Operand<i32> {
   let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
   let PrintMethod = "printSystemPStateField";
+  let MCOperandPredicate = [{
+    if (!MCOp.isImm())
+      return false;
+    return AArch64SVCR::lookupPStateImm0_1ByEncoding(MCOp.getImm()) != nullptr;
+  }];
 }
 
 class MSRpstateImm0_1
@@ -1772,17 +1782,18 @@ class MSRpstateImm0_1
                  "\t$pstatefield, $imm">,
     Sched<[WriteSys]> {
 
-  bits<6> pstatefield;
+  bits<9> pstatefield;
   bit imm;
   let Inst{18-16} = pstatefield{5-3};
-  let Inst{11-9} = 0b000;
+  let Inst{11-9} = pstatefield{8-6};
   let Inst{8} = imm;
   let Inst{7-5} = pstatefield{2-0};
 
-  let DecoderMethod = "DecodeSystemPStateInstruction";
+  let DecoderMethod = "DecodeSystemPStateImm0_1Instruction";
   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
   // Fail the decoder should attempt to decode the instruction as MSRI.
-  let hasCompleteDecoder = 0;
+  let hasCompleteDecoder = false;
+  let DecoderNamespace = "Fallback";
 }
 
 // SYS and SYSL generic system instructions.

diff  --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index 275ea72e9daf..bed826db4cd5 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -397,35 +397,52 @@ def : ExactFPImm<"two",  "2.0", 0x3>;
 // PState instruction options.
 //===----------------------------------------------------------------------===//
 
-class PState<string name, bits<5> encoding> : SearchableTable {
+class PStateImm0_15<string name, bits<3> op1, bits<3> op2> : SearchableTable {
   let SearchableFields = ["Name", "Encoding"];
   let EnumValueField = "Encoding";
 
   string Name = name;
-  bits<5> Encoding;
-  let Encoding = encoding;
+  bits<6> Encoding;
+  let Encoding{5-3} = op1;
+  let Encoding{2-0} = op2;
+  code Requires = [{ {} }];
+}
+
+class PStateImm0_1<string name, bits<3> op1, bits<3> op2, bits<3> crm_high> : SearchableTable {
+  let SearchableFields = ["Name", "Encoding"];
+  let EnumValueField = "Encoding";
+
+  string Name = name;
+  bits<9> Encoding;
+  let Encoding{8-6} = crm_high;
+  let Encoding{5-3} = op1;
+  let Encoding{2-0} = op2;
   code Requires = [{ {} }];
 }
 
-def : PState<"SPSel",   0b00101>;
-def : PState<"DAIFSet", 0b11110>;
-def : PState<"DAIFClr", 0b11111>;
+//                   Name,     Op1,   Op2
+def : PStateImm0_15<"SPSel",   0b000, 0b101>;
+def : PStateImm0_15<"DAIFSet", 0b011, 0b110>;
+def : PStateImm0_15<"DAIFClr", 0b011, 0b111>;
 // v8.1a "Privileged Access Never" extension-specific PStates
 let Requires = [{ {AArch64::FeaturePAN} }] in
-def : PState<"PAN",     0b00100>;
+def : PStateImm0_15<"PAN",     0b000, 0b100>;
 
 // v8.2a "User Access Override" extension-specific PStates
 let Requires = [{ {AArch64::FeaturePsUAO} }] in
-def : PState<"UAO",     0b00011>;
+def : PStateImm0_15<"UAO",     0b000, 0b011>;
 // v8.4a timing insensitivity of data processing instructions
 let Requires = [{ {AArch64::FeatureDIT} }] in
-def : PState<"DIT",     0b11010>;
+def : PStateImm0_15<"DIT",     0b011, 0b010>;
 // v8.5a Spectre Mitigation
 let Requires = [{ {AArch64::FeatureSSBS} }] in
-def : PState<"SSBS",    0b11001>;
+def : PStateImm0_15<"SSBS",    0b011, 0b001>;
 // v8.5a Memory Tagging Extension
 let Requires = [{ {AArch64::FeatureMTE} }] in
-def : PState<"TCO",     0b11100>;
+def : PStateImm0_15<"TCO",     0b011, 0b100>;
+// v9.4a Exception-based event profiling
+//                  Name,      Op1,   Op2,   Crm_high
+def : PStateImm0_1<"PM",       0b001, 0b000, 0b001>;
 
 //===----------------------------------------------------------------------===//
 // SVCR instruction options.
@@ -1877,3 +1894,7 @@ def : ROSysReg<"ERXGSR_EL1",        0b11, 0b000, 0b0101, 0b0011, 0b010>;
 def : RWSysReg<"PFAR_EL1",          0b11, 0b000, 0b0110, 0b0000, 0b101>;
 def : RWSysReg<"PFAR_EL12",         0b11, 0b101, 0b0110, 0b0000, 0b101>;
 def : RWSysReg<"PFAR_EL2",          0b11, 0b100, 0b0110, 0b0000, 0b101>;
+
+// v9.4a Exception-based event profiling (FEAT_EBEP)
+//                                  Op0   Op1    CRn     CRm     Op2
+def : RWSysReg<"PM",                0b11, 0b000, 0b0100, 0b0011, 0b001>;

diff  --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 9c7cd2debb89..7d52185ba075 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -1185,15 +1185,13 @@ class AArch64Operand : public MCParsedAsmOperand {
 
   bool isSystemPStateFieldWithImm0_1() const {
     if (!isSysReg()) return false;
-    return (SysReg.PStateField == AArch64PState::PAN ||
-            SysReg.PStateField == AArch64PState::DIT ||
-            SysReg.PStateField == AArch64PState::UAO ||
-            SysReg.PStateField == AArch64PState::SSBS);
+    return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
   }
 
   bool isSystemPStateFieldWithImm0_15() const {
-    if (!isSysReg() || isSystemPStateFieldWithImm0_1()) return false;
-    return SysReg.PStateField != -1U;
+    if (!isSysReg())
+      return false;
+    return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
   }
 
   bool isSVCR() const {
@@ -3472,7 +3470,9 @@ AArch64AsmParser::tryParseSVCR(OperandVector &Operands) {
 
   unsigned PStateImm = -1;
   const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.getString());
-  if (SVCR && SVCR->haveFeatures(getSTI().getFeatureBits()))
+  if (!SVCR)
+    return MatchOperand_NoMatch;
+  if (SVCR->haveFeatures(getSTI().getFeatureBits()))
     PStateImm = SVCR->Encoding;
 
   Operands.push_back(
@@ -4054,10 +4054,15 @@ AArch64AsmParser::tryParseSysReg(OperandVector &Operands) {
   } else
     MRSReg = MSRReg = AArch64SysReg::parseGenericRegister(Tok.getString());
 
-  auto PState = AArch64PState::lookupPStateByName(Tok.getString());
   unsigned PStateImm = -1;
-  if (PState && PState->haveFeatures(getSTI().getFeatureBits()))
-    PStateImm = PState->Encoding;
+  auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.getString());
+  if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
+    PStateImm = PState15->Encoding;
+  if (!PState15) {
+    auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.getString());
+    if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
+      PStateImm = PState1->Encoding;
+  }
 
   Operands.push_back(
       AArch64Operand::CreateSysReg(Tok.getString(), getLoc(), MRSReg, MSRReg,

diff  --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
index 511e37eea25a..dd84fa473f80 100644
--- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
+++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
@@ -214,8 +214,13 @@ static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn,
                                               uint64_t Address,
                                               const MCDisassembler *Decoder);
 static DecodeStatus
-DecodeSystemPStateInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
-                              const MCDisassembler *Decoder);
+DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn,
+                                     uint64_t Address,
+                                     const MCDisassembler *Decoder);
+static DecodeStatus
+DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn,
+                                    uint64_t Address,
+                                    const MCDisassembler *Decoder);
 static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn,
                                         uint64_t Address,
                                         const MCDisassembler *Decoder);
@@ -1814,29 +1819,49 @@ static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn,
   return Success;
 }
 
+static bool isInvalidPState(uint64_t Op1, uint64_t Op2) {
+  return Op1 == 0b000 && (Op2 == 0b000 || // CFINV
+                          Op2 == 0b001 || // XAFlag
+                          Op2 == 0b010);  // AXFlag
+}
+
 static DecodeStatus
-DecodeSystemPStateInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
-                              const MCDisassembler *Decoder) {
+DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
+                                     const MCDisassembler *Decoder) {
   uint64_t op1 = fieldFromInstruction(insn, 16, 3);
   uint64_t op2 = fieldFromInstruction(insn, 5, 3);
-  uint64_t crm = fieldFromInstruction(insn, 8, 4);
+  uint64_t imm = fieldFromInstruction(insn, 8, 4);
   uint64_t pstate_field = (op1 << 3) | op2;
 
-  switch (pstate_field) {
-  case 0x01: // XAFlag
-  case 0x02: // AXFlag
+  if (isInvalidPState(op1, op2))
     return Fail;
-  }
 
-  if ((pstate_field == AArch64PState::PAN  ||
-       pstate_field == AArch64PState::UAO  ||
-       pstate_field == AArch64PState::SSBS) && crm > 1)
+  Inst.addOperand(MCOperand::createImm(pstate_field));
+  Inst.addOperand(MCOperand::createImm(imm));
+
+  auto PState = AArch64PState::lookupPStateImm0_15ByEncoding(pstate_field);
+  if (PState &&
+      PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
+    return Success;
+  return Fail;
+}
+
+static DecodeStatus
+DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
+                                    const MCDisassembler *Decoder) {
+  uint64_t op1 = fieldFromInstruction(insn, 16, 3);
+  uint64_t op2 = fieldFromInstruction(insn, 5, 3);
+  uint64_t crm_high = fieldFromInstruction(insn, 9, 3);
+  uint64_t imm = fieldFromInstruction(insn, 8, 1);
+  uint64_t pstate_field = (crm_high << 6) | (op1 << 3) | op2;
+
+  if (isInvalidPState(op1, op2))
     return Fail;
 
   Inst.addOperand(MCOperand::createImm(pstate_field));
-  Inst.addOperand(MCOperand::createImm(crm));
+  Inst.addOperand(MCOperand::createImm(imm));
 
-  auto PState = AArch64PState::lookupPStateByEncoding(pstate_field);
+  auto PState = AArch64PState::lookupPStateImm0_1ByEncoding(pstate_field);
   if (PState &&
       PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
     return Success;

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
index 8c3fdb1ff44b..8c2345b9da64 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
@@ -1914,9 +1914,12 @@ void AArch64InstPrinter::printSystemPStateField(const MCInst *MI, unsigned OpNo,
                                                 raw_ostream &O) {
   unsigned Val = MI->getOperand(OpNo).getImm();
 
-  auto PState = AArch64PState::lookupPStateByEncoding(Val);
-  if (PState && PState->haveFeatures(STI.getFeatureBits()))
-    O << PState->Name;
+  auto PStateImm15 = AArch64PState::lookupPStateImm0_15ByEncoding(Val);
+  auto PStateImm1 = AArch64PState::lookupPStateImm0_1ByEncoding(Val);
+  if (PStateImm15 && PStateImm15->haveFeatures(STI.getFeatureBits()))
+    O << PStateImm15->Name;
+  else if (PStateImm1 && PStateImm1->haveFeatures(STI.getFeatureBits()))
+    O << PStateImm1->Name;
   else
     O << "#" << formatImm(Val);
 }

diff  --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
index de76f44b2fcf..a742c406537b 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
@@ -118,7 +118,9 @@ namespace llvm {
 
 namespace llvm {
   namespace AArch64PState {
-#define GET_PSTATE_IMPL
+#define GET_PSTATEIMM0_15_IMPL
+#include "AArch64GenSystemOperands.inc"
+#define GET_PSTATEIMM0_1_IMPL
 #include "AArch64GenSystemOperands.inc"
   }
 }

diff  --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index 18717b0c0aa8..313ba3df4930 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -574,10 +574,16 @@ namespace AArch64ExactFPImm {
 }
 
 namespace AArch64PState {
-  struct PState : SysAlias{
+  struct PStateImm0_15 : SysAlias{
     using SysAlias::SysAlias;
   };
-  #define GET_PSTATE_DECL
+  #define GET_PSTATEIMM0_15_DECL
+  #include "AArch64GenSystemOperands.inc"
+
+  struct PStateImm0_1 : SysAlias{
+    using SysAlias::SysAlias;
+  };
+  #define GET_PSTATEIMM0_1_DECL
   #include "AArch64GenSystemOperands.inc"
 }
 

diff  --git a/llvm/test/MC/AArch64/armv8.1a-pan.s b/llvm/test/MC/AArch64/armv8.1a-pan.s
index ab11e45115d5..d39542c30abe 100644
--- a/llvm/test/MC/AArch64/armv8.1a-pan.s
+++ b/llvm/test/MC/AArch64/armv8.1a-pan.s
@@ -15,16 +15,16 @@
 // CHECK:  mrs x13, PAN          // encoding: [0x6d,0x42,0x38,0xd5]
 
   msr pan, #-1
-  msr pan, #2
+  msr pan, #16
   msr pan, w0
   mrs w0, pan
-// CHECK-ERROR: error: immediate must be an integer in range [0, 1].
+// CHECK-ERROR: error: immediate must be an integer in range [0, 15].
 // CHECK-ERROR:   msr pan, #-1
 // CHECK-ERROR:            ^
-// CHECK-ERROR: error: immediate must be an integer in range [0, 1].
-// CHECK-ERROR:   msr pan, #2
+// CHECK-ERROR: error: immediate must be an integer in range [0, 15].
+// CHECK-ERROR:   msr pan, #16
 // CHECK-ERROR:            ^
-// CHECK-ERROR: error: immediate must be an integer in range [0, 1].
+// CHECK-ERROR: error: immediate must be an integer in range [0, 15].
 // CHECK-ERROR:   msr pan, w0
 // CHECK-ERROR:            ^
 // CHECK-ERROR: error: invalid operand for instruction

diff  --git a/llvm/test/MC/AArch64/armv8.2a-uao.s b/llvm/test/MC/AArch64/armv8.2a-uao.s
index 499b876f5c32..630dfe6c4675 100644
--- a/llvm/test/MC/AArch64/armv8.2a-uao.s
+++ b/llvm/test/MC/AArch64/armv8.2a-uao.s
@@ -8,9 +8,9 @@
 // CHECK: msr     UAO, #0                 // encoding: [0x7f,0x40,0x00,0xd5]
 // CHECK: msr     UAO, #1                 // encoding: [0x7f,0x41,0x00,0xd5]
 
-  msr uao, #2
-// CHECK-ERROR: error: immediate must be an integer in range [0, 1].
-// CHECK-ERROR:   msr uao, #2
+  msr uao, #16
+// CHECK-ERROR: error: immediate must be an integer in range [0, 15].
+// CHECK-ERROR:   msr uao, #16
 // CHECK-ERROR:            ^
 
   msr uao, x1

diff  --git a/llvm/test/MC/AArch64/armv8.4a-dit.s b/llvm/test/MC/AArch64/armv8.4a-dit.s
index d90819770696..7d0b62ee4233 100644
--- a/llvm/test/MC/AArch64/armv8.4a-dit.s
+++ b/llvm/test/MC/AArch64/armv8.4a-dit.s
@@ -14,13 +14,13 @@ mrs x0, DIT
 //CHECK-NEXT: msr DIT, x0                 // encoding: [0xa0,0x42,0x1b,0xd5]
 //CHECK-NEXT: mrs x0, DIT                 // encoding: [0xa0,0x42,0x3b,0xd5]
 
-msr DIT, #2
+msr DIT, #16
 msr DIT, #-1
 
-//CHECK-ERROR:      error: immediate must be an integer in range [0, 1].
-//CHECK-ERROR-NEXT: msr DIT, #2
+//CHECK-ERROR:      error: immediate must be an integer in range [0, 15].
+//CHECK-ERROR-NEXT: msr DIT, #16
 //CHECK-ERROR-NEXT:          ^
-//CHECK-ERROR-NEXT: error: immediate must be an integer in range [0, 1].
+//CHECK-ERROR-NEXT: error: immediate must be an integer in range [0, 15].
 //CHECK-ERROR-NEXT: msr DIT, #-1
 //CHECK-ERROR-NEXT:          ^
 
@@ -34,7 +34,7 @@ msr DIT, #-1
 //CHECK-NO-V84-NEXT: mrs x0, DIT
 //CHECK-NO-V84-NEXT:         ^
 //CHECK-NO-V84-NEXT: error: expected writable system register or pstate
-//CHECK-NO-V84-NEXT: msr DIT, #2
+//CHECK-NO-V84-NEXT: msr DIT, #16
 //CHECK-NO-V84-NEXT:     ^
 //CHECK-NO-V84-NEXT: error: expected writable system register or pstate
 //CHECK-NO-V84-NEXT: msr DIT, #-1

diff  --git a/llvm/test/MC/AArch64/armv8.5a-ssbs-error.s b/llvm/test/MC/AArch64/armv8.5a-ssbs-error.s
index 59819705e46c..a7c9f4c4fbb5 100644
--- a/llvm/test/MC/AArch64/armv8.5a-ssbs-error.s
+++ b/llvm/test/MC/AArch64/armv8.5a-ssbs-error.s
@@ -2,9 +2,9 @@
 // RUN: not llvm-mc -triple aarch64 -show-encoding -mattr=+v8.5a < %s 2>&1 | FileCheck %s
 // RUN: not llvm-mc -triple aarch64 -show-encoding -mattr=-ssbs  < %s 2>&1 | FileCheck %s --check-prefix=NOSPECID
 
-msr SSBS, #2
+msr SSBS, #16
 
-// CHECK:         error: immediate must be an integer in range [0, 1].
-// CHECK-NEXT:    msr SSBS, #2
+// CHECK:         error: immediate must be an integer in range [0, 15].
+// CHECK-NEXT:    msr SSBS, #16
 // NOSPECID:      error: expected writable system register or pstate
-// NOSPECID-NEXT: msr {{ssbs|SSBS}}, #2
+// NOSPECID-NEXT: msr {{ssbs|SSBS}}, #16

diff  --git a/llvm/test/MC/AArch64/armv9.4a-ebep-error.s b/llvm/test/MC/AArch64/armv9.4a-ebep-error.s
new file mode 100644
index 000000000000..77dbe09d523f
--- /dev/null
+++ b/llvm/test/MC/AArch64/armv9.4a-ebep-error.s
@@ -0,0 +1,6 @@
+// RUN: not llvm-mc -triple aarch64 -show-encoding < %s 2>&1 | FileCheck %s
+
+msr PM, #2
+// CHECK:         error: immediate must be an integer in range [0, 1].
+// CHECK-NEXT:    msr PM, #2
+// CHECK-NEXT:    ^

diff  --git a/llvm/test/MC/AArch64/armv9.4a-ebep.s b/llvm/test/MC/AArch64/armv9.4a-ebep.s
new file mode 100644
index 000000000000..7e9f1115d975
--- /dev/null
+++ b/llvm/test/MC/AArch64/armv9.4a-ebep.s
@@ -0,0 +1,9 @@
+// RUN: llvm-mc -triple aarch64 -show-encoding < %s | FileCheck %s
+
+mrs x2, PM
+msr PM, x3
+msr PM, #1
+
+// CHECK:       mrs x2, {{pm|PM}} // encoding: [0x22,0x43,0x38,0xd5]
+// CHECK:       msr {{pm|PM}}, x3 // encoding: [0x23,0x43,0x18,0xd5]
+// CHECK:       msr {{pm|PM}}, #1 // encoding: [0x1f,0x43,0x01,0xd5]

diff  --git a/llvm/test/MC/Disassembler/AArch64/armv8.1a-pan.txt b/llvm/test/MC/Disassembler/AArch64/armv8.1a-pan.txt
index 22dc5fd58948..c47583ac17c8 100644
--- a/llvm/test/MC/Disassembler/AArch64/armv8.1a-pan.txt
+++ b/llvm/test/MC/Disassembler/AArch64/armv8.1a-pan.txt
@@ -2,11 +2,11 @@
 
 0x9f,0x40,0x00,0xd5
 0x9f,0x41,0x00,0xd5
-0x9f,0x42,0x00,0xd5
+0x9f,0x4f,0x00,0xd5
 0x65,0x42,0x18,0xd5
 0x6d,0x42,0x38,0xd5
 # CHECK:  msr PAN, #0
 # CHECK:  msr PAN, #1
-# CHECK-NOT: msr PAN, #2
+# CHECK:  msr PAN, #15
 # CHECK:  msr PAN, x5
 # CHECK:  mrs x13, PAN

diff  --git a/llvm/test/MC/Disassembler/AArch64/armv8.2a-uao.txt b/llvm/test/MC/Disassembler/AArch64/armv8.2a-uao.txt
index b8300f4c7264..6c6817d85e4c 100644
--- a/llvm/test/MC/Disassembler/AArch64/armv8.2a-uao.txt
+++ b/llvm/test/MC/Disassembler/AArch64/armv8.2a-uao.txt
@@ -3,13 +3,13 @@
 
 [0x7f,0x40,0x00,0xd5]
 [0x7f,0x41,0x00,0xd5]
-[0x7f,0x42,0x00,0xd5]
+[0x7f,0x4f,0x00,0xd5]
 # CHECK: msr UAO, #0
 # CHECK: msr UAO, #1
-# CHECK: msr S0_0_C4_C2_3, xzr
+# CHECK: msr UAO, #15
 # NO_V82A: msr S0_0_C4_C0_3, xzr
 # NO_V82A: msr S0_0_C4_C1_3, xzr
-# NO_V82A: msr S0_0_C4_C2_3, xzr
+# NO_V82A: msr S0_0_C4_C15_3, xzr
 
 [0x81,0x42,0x18,0xd5]
 [0x82,0x42,0x38,0xd5]

diff  --git a/llvm/test/MC/Disassembler/AArch64/armv9.4a-ebep.txt b/llvm/test/MC/Disassembler/AArch64/armv9.4a-ebep.txt
new file mode 100644
index 000000000000..aa9c95fb2082
--- /dev/null
+++ b/llvm/test/MC/Disassembler/AArch64/armv9.4a-ebep.txt
@@ -0,0 +1,13 @@
+# RUN: llvm-mc -triple=aarch64 -disassemble %s | FileCheck %s
+
+[0x23,0x43,0x38,0xd5]
+# CHECK:  mrs x3, PM
+
+[0x26,0x43,0x18,0xd5]
+# CHECK:  msr PM, x6
+
+[0x1f,0x42,0x01,0xd5]
+# CHECK:  msr PM, #0
+
+[0x1f,0x43,0x01,0xd5]
+# CHECK:  msr PM, #1


        


More information about the llvm-commits mailing list