[llvm] 2050e7e - [Arm][AArch64] Add support for v8.9-A/v9.4-A base extensions

Lucas Prates via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 8 02:15:36 PST 2022


Author: Lucas Prates
Date: 2022-12-08T10:15:29Z
New Revision: 2050e7ebe18cc4cf906d9b54d17ee885cd868327

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

LOG: [Arm][AArch64] Add support for v8.9-A/v9.4-A base extensions

This implements the base extensions that are part of the v8.9-A and
v9.4-A architecture versions, including:

* The Clear BHB Instruction (FEAT_CLRBHB)
* The Speculation Restriction Instruction (FEAT_SPECRES2)
* The SLC target for the PRFM instruction
* New system registers:
  * ID_AA64PFR2_EL1
  * ID_AA64MMFR3_EL1
  * HFGITR2_EL2
  * SCTLR2_EL3

More information on the new extensions can be found on:

* https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/arm-a-profile-architecture-2022
* https://developer.arm.com/downloads/-/exploration-tools

Contributors: Sam Elliott, Tomas Matheson and Son Tuan Vu.

Reviewed By: lenary

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

Added: 
    llvm/test/MC/AArch64/armv8.9a-clrbhb.s
    llvm/test/MC/AArch64/armv8.9a-prfm-slc.s
    llvm/test/MC/AArch64/armv8.9a-specres2-error.s
    llvm/test/MC/AArch64/armv8.9a-specres2.s
    llvm/test/MC/ARM/armv8.9a-clrbhb.s
    llvm/test/MC/Disassembler/AArch64/armv8.9a-clrbhb.txt
    llvm/test/MC/Disassembler/AArch64/armv8.9a-prfm-slc.txt
    llvm/test/MC/Disassembler/AArch64/armv8.9a-specres2.txt
    llvm/test/MC/Disassembler/ARM/armv8.9a-clrbhb-arm.txt
    llvm/test/MC/Disassembler/ARM/armv8.9a-clrbhb-thumb.txt

Modified: 
    llvm/include/llvm/Support/AArch64TargetParser.def
    llvm/include/llvm/Support/AArch64TargetParser.h
    llvm/lib/Target/AArch64/AArch64.td
    llvm/lib/Target/AArch64/AArch64InstrInfo.td
    llvm/lib/Target/AArch64/AArch64SystemOperands.td
    llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
    llvm/lib/Target/ARM/ARM.td
    llvm/lib/Target/ARM/ARMInstrInfo.td
    llvm/lib/Target/ARM/ARMInstrThumb2.td
    llvm/lib/Target/ARM/ARMPredicates.td
    llvm/test/MC/AArch64/arm64-system-encoding.s
    llvm/test/MC/AArch64/armv8.6a-fgt.s
    llvm/test/MC/AArch64/basic-a64-diagnostics.s
    llvm/test/MC/AArch64/basic-a64-instructions.s
    llvm/test/MC/Disassembler/AArch64/armv8.6a-fgt.txt
    llvm/test/MC/Disassembler/AArch64/basic-a64-instructions.txt
    llvm/test/MC/Disassembler/AArch64/mattr-all.txt
    llvm/unittests/Support/TargetParserTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Support/AArch64TargetParser.def b/llvm/include/llvm/Support/AArch64TargetParser.def
index e09450d28737c..2c6b3f0bb5f0d 100644
--- a/llvm/include/llvm/Support/AArch64TargetParser.def
+++ b/llvm/include/llvm/Support/AArch64TargetParser.def
@@ -151,6 +151,7 @@ AARCH64_ARCH_EXT_NAME("sme2p1",       AArch64::AEK_SME2p1,      "+sme2p1",
 AARCH64_ARCH_EXT_NAME("hbc",          AArch64::AEK_HBC,         "+hbc",          "-hbc")
 AARCH64_ARCH_EXT_NAME("mops",         AArch64::AEK_MOPS,        "+mops",         "-mops")
 AARCH64_ARCH_EXT_NAME("pmuv3",        AArch64::AEK_PERFMON,     "+perfmon",      "-perfmon")
+AARCH64_ARCH_EXT_NAME("predres2",     AArch64::AEK_SPECRES2,    "+specres2",     "-specres2")
 AARCH64_ARCH_EXT_NAME("cssc",         AArch64::AEK_CSSC,        "+cssc",         "-cssc")
 AARCH64_ARCH_EXT_NAME("rcpc3",        AArch64::AEK_RCPC3,       "+rcpc3",        "-rcpc3")
 AARCH64_ARCH_EXT_NAME("the",          AArch64::AEK_THE,         "+the",          "-the")

diff  --git a/llvm/include/llvm/Support/AArch64TargetParser.h b/llvm/include/llvm/Support/AArch64TargetParser.h
index 78ff44b2021c7..2779788972eb1 100644
--- a/llvm/include/llvm/Support/AArch64TargetParser.h
+++ b/llvm/include/llvm/Support/AArch64TargetParser.h
@@ -82,6 +82,7 @@ enum ArchExtKind : uint64_t {
   AEK_THE =         1ULL << 50, // FEAT_THE
   AEK_D128 =        1ULL << 51, // FEAT_D128
   AEK_LSE128 =      1ULL << 52, // FEAT_LSE128
+  AEK_SPECRES2 =    1ULL << 53, // FEAT_SPECRES2
 };
 // clang-format on
 

diff  --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 2d47be23a21a4..78958e01c2a7d 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -508,6 +508,16 @@ def FeatureNoBTIAtReturnTwice : SubtargetFeature<"no-bti-at-return-twice",
                                                  "Don't place a BTI instruction "
                                                  "after a return-twice">;
 
+def FeatureCLRBHB : SubtargetFeature<"clrbhb", "HasCLRBHB",
+    "true", "Enable Clear BHB instruction (FEAT_CLRBHB)">;
+
+def FeaturePRFM_SLC : SubtargetFeature<"prfm-slc-target", "HasPRFM_SLC",
+    "true", "Enable SLC target for PRFM instruction">;
+
+def FeatureSPECRES2 : SubtargetFeature<"specres2", "HasSPECRES2",
+    "true", "Enable Speculation Restriction Instruction (FEAT_SPECRES2)",
+    [FeaturePredRes]>;
+
 def FeatureMEC : SubtargetFeature<"mec", "HasMEC",
     "true", "Enable Memory Encryption Contexts Extension", [FeatureRME]>;
 
@@ -578,7 +588,8 @@ def HasV8_8aOps : SubtargetFeature<
 
 def HasV8_9aOps : SubtargetFeature<
   "v8.9a", "HasV8_9aOps", "true", "Support ARM v8.9a instructions",
-  [HasV8_8aOps, FeatureCSSC]>;
+  [HasV8_8aOps, FeatureCLRBHB, FeaturePRFM_SLC, FeatureSPECRES2,
+   FeatureCSSC]>;
 
 def HasV9_0aOps : SubtargetFeature<
   "v9a", "HasV9_0aOps", "true", "Support ARM v9a instructions",

diff  --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 09405724bab6e..f3fbb94b0e878 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -233,6 +233,10 @@ def HasHBC           : Predicate<"Subtarget->hasHBC()">,
                        AssemblerPredicateWithAll<(all_of FeatureHBC), "hbc">;
 def HasMOPS          : Predicate<"Subtarget->hasMOPS()">,
                        AssemblerPredicateWithAll<(all_of FeatureMOPS), "mops">;
+def HasCLRBHB        : Predicate<"Subtarget->hasCLRBHB()">,
+                       AssemblerPredicateWithAll<(all_of FeatureCLRBHB), "clrbhb">;
+def HasSPECRES2      : Predicate<"Subtarget->hasSPECRES2()">,
+                       AssemblerPredicateWithAll<(all_of FeatureSPECRES2), "specres2">;
 def HasITE           : Predicate<"Subtarget->hasITE()">,
                        AssemblerPredicateWithAll<(all_of FeatureITE), "ite">;
 def HasTHE           : Predicate<"Subtarget->hasTHE()">,
@@ -8546,6 +8550,11 @@ def : Pat<(AArch64AssertZExtBool GPR32:$op),
 //===----------------------------===//
 // 2022 Architecture Extensions:
 //===----------------------------===//
+def : InstAlias<"clrbhb",  (HINT 22), 0>;
+let Predicates = [HasCLRBHB] in {
+  def : InstAlias<"clrbhb",  (HINT 22), 1>;
+}
+
 defm RCW     : ReadCheckWriteCompareAndSwap;
 
 defm RCWCLR  : ReadCheckWriteOperation<0b001, "clr">;

diff  --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index c49c6f3a41fe0..06dd215e71d3d 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -230,33 +230,51 @@ def : TSB<"csync", 0>;
 // PRFM (prefetch) instruction options.
 //===----------------------------------------------------------------------===//
 
-class PRFM<string name, bits<5> encoding> : SearchableTable {
+class PRFM<string type,   bits<2> type_encoding,
+           string target, bits<2> target_encoding,
+           string policy, bits<1> policy_encoding> : SearchableTable {
   let SearchableFields = ["Name", "Encoding"];
   let EnumValueField = "Encoding";
 
-  string Name = name;
+  string Name = type # target # policy;
   bits<5> Encoding;
-  let Encoding = encoding;
+  let Encoding{4-3} = type_encoding;
+  let Encoding{2-1} = target_encoding;
+  let Encoding{0} = policy_encoding;
+
+  code Requires = [{ {} }];
 }
 
-def : PRFM<"pldl1keep", 0x00>;
-def : PRFM<"pldl1strm", 0x01>;
-def : PRFM<"pldl2keep", 0x02>;
-def : PRFM<"pldl2strm", 0x03>;
-def : PRFM<"pldl3keep", 0x04>;
-def : PRFM<"pldl3strm", 0x05>;
-def : PRFM<"plil1keep", 0x08>;
-def : PRFM<"plil1strm", 0x09>;
-def : PRFM<"plil2keep", 0x0a>;
-def : PRFM<"plil2strm", 0x0b>;
-def : PRFM<"plil3keep", 0x0c>;
-def : PRFM<"plil3strm", 0x0d>;
-def : PRFM<"pstl1keep", 0x10>;
-def : PRFM<"pstl1strm", 0x11>;
-def : PRFM<"pstl2keep", 0x12>;
-def : PRFM<"pstl2strm", 0x13>;
-def : PRFM<"pstl3keep", 0x14>;
-def : PRFM<"pstl3strm", 0x15>;
+def : PRFM<"pld", 0b00, "l1",  0b00, "keep", 0b0>;
+def : PRFM<"pld", 0b00, "l1",  0b00, "strm", 0b1>;
+def : PRFM<"pld", 0b00, "l2",  0b01, "keep", 0b0>;
+def : PRFM<"pld", 0b00, "l2",  0b01, "strm", 0b1>;
+def : PRFM<"pld", 0b00, "l3",  0b10, "keep", 0b0>;
+def : PRFM<"pld", 0b00, "l3",  0b10, "strm", 0b1>;
+let Requires = [{ {AArch64::FeaturePRFM_SLC} }] in {
+def : PRFM<"pld", 0b00, "slc", 0b11, "keep", 0b0>;
+def : PRFM<"pld", 0b00, "slc", 0b11, "strm", 0b1>;
+}
+def : PRFM<"pli", 0b01, "l1",  0b00, "keep", 0b0>;
+def : PRFM<"pli", 0b01, "l1",  0b00, "strm", 0b1>;
+def : PRFM<"pli", 0b01, "l2",  0b01, "keep", 0b0>;
+def : PRFM<"pli", 0b01, "l2",  0b01, "strm", 0b1>;
+def : PRFM<"pli", 0b01, "l3",  0b10, "keep", 0b0>;
+def : PRFM<"pli", 0b01, "l3",  0b10, "strm", 0b1>;
+let Requires = [{ {AArch64::FeaturePRFM_SLC} }] in {
+def : PRFM<"pli", 0b01, "slc", 0b11, "keep", 0b0>;
+def : PRFM<"pli", 0b01, "slc", 0b11, "strm", 0b1>;
+}
+def : PRFM<"pst", 0b10, "l1",  0b00, "keep", 0b0>;
+def : PRFM<"pst", 0b10, "l1",  0b00, "strm", 0b1>;
+def : PRFM<"pst", 0b10, "l2",  0b01, "keep", 0b0>;
+def : PRFM<"pst", 0b10, "l2",  0b01, "strm", 0b1>;
+def : PRFM<"pst", 0b10, "l3",  0b10, "keep", 0b0>;
+def : PRFM<"pst", 0b10, "l3",  0b10, "strm", 0b1>;
+let Requires = [{ {AArch64::FeaturePRFM_SLC} }] in {
+def : PRFM<"pst", 0b10, "slc", 0b11, "keep", 0b0>;
+def : PRFM<"pst", 0b10, "slc", 0b11, "strm", 0b1>;
+}
 
 //===----------------------------------------------------------------------===//
 // SVE Prefetch instruction options.
@@ -600,23 +618,6 @@ defm : TLBI<"PAALLOS",      0b110, 0b1000, 0b0001, 0b100, 0>;
 defm : TLBI<"PAALL",        0b110, 0b1000, 0b0111, 0b100, 0>;
 }
 
-// Armv8.5-A Prediction Restriction by Context instruction options:
-class PRCTX<string name, bits<4> crm> : SearchableTable {
-  let SearchableFields = ["Name", "Encoding"];
-  let EnumValueField = "Encoding";
-
-  string Name = name;
-  bits<11> Encoding;
-  let Encoding{10-4} = 0b0110111;
-  let Encoding{3-0} = crm;
-  bit NeedsReg = 1;
-  code Requires = [{ {} }];
-}
-
-let Requires = [{ {AArch64::FeaturePredRes} }] in {
-def : PRCTX<"RCTX", 0b0011>;
-}
-
 //===----------------------------------------------------------------------===//
 // MRS/MSR (system register read/write) instruction options.
 //===----------------------------------------------------------------------===//
@@ -709,6 +710,7 @@ def : ROSysReg<"ID_ISAR6_EL1",       0b11, 0b000, 0b0000, 0b0010, 0b111> {
 }
 def : ROSysReg<"ID_AA64PFR0_EL1",     0b11, 0b000, 0b0000, 0b0100, 0b000>;
 def : ROSysReg<"ID_AA64PFR1_EL1",     0b11, 0b000, 0b0000, 0b0100, 0b001>;
+def : ROSysReg<"ID_AA64PFR2_EL1",     0b11, 0b000, 0b0000, 0b0100, 0b010>;
 def : ROSysReg<"ID_AA64DFR0_EL1",     0b11, 0b000, 0b0000, 0b0101, 0b000>;
 def : ROSysReg<"ID_AA64DFR1_EL1",     0b11, 0b000, 0b0000, 0b0101, 0b001>;
 def : ROSysReg<"ID_AA64AFR0_EL1",     0b11, 0b000, 0b0000, 0b0101, 0b100>;
@@ -719,20 +721,21 @@ def : ROSysReg<"ID_AA64ISAR2_EL1",    0b11, 0b000, 0b0000, 0b0110, 0b010>;
 def : ROSysReg<"ID_AA64MMFR0_EL1",    0b11, 0b000, 0b0000, 0b0111, 0b000>;
 def : ROSysReg<"ID_AA64MMFR1_EL1",    0b11, 0b000, 0b0000, 0b0111, 0b001>;
 def : ROSysReg<"ID_AA64MMFR2_EL1",    0b11, 0b000, 0b0000, 0b0111, 0b010>;
-def : ROSysReg<"MVFR0_EL1",          0b11, 0b000, 0b0000, 0b0011, 0b000>;
-def : ROSysReg<"MVFR1_EL1",          0b11, 0b000, 0b0000, 0b0011, 0b001>;
-def : ROSysReg<"MVFR2_EL1",          0b11, 0b000, 0b0000, 0b0011, 0b010>;
-def : ROSysReg<"RVBAR_EL1",          0b11, 0b000, 0b1100, 0b0000, 0b001>;
-def : ROSysReg<"RVBAR_EL2",          0b11, 0b100, 0b1100, 0b0000, 0b001>;
-def : ROSysReg<"RVBAR_EL3",          0b11, 0b110, 0b1100, 0b0000, 0b001>;
-def : ROSysReg<"ISR_EL1",            0b11, 0b000, 0b1100, 0b0001, 0b000>;
-def : ROSysReg<"CNTPCT_EL0",         0b11, 0b011, 0b1110, 0b0000, 0b001>;
-def : ROSysReg<"CNTVCT_EL0",         0b11, 0b011, 0b1110, 0b0000, 0b010>;
-def : ROSysReg<"ID_MMFR4_EL1",       0b11, 0b000, 0b0000, 0b0010, 0b110>;
-def : ROSysReg<"ID_MMFR5_EL1",       0b11, 0b000, 0b0000, 0b0011, 0b110>;
+def : ROSysReg<"ID_AA64MMFR3_EL1",    0b11, 0b000, 0b0000, 0b0111, 0b011>;
+def : ROSysReg<"MVFR0_EL1",           0b11, 0b000, 0b0000, 0b0011, 0b000>;
+def : ROSysReg<"MVFR1_EL1",           0b11, 0b000, 0b0000, 0b0011, 0b001>;
+def : ROSysReg<"MVFR2_EL1",           0b11, 0b000, 0b0000, 0b0011, 0b010>;
+def : ROSysReg<"RVBAR_EL1",           0b11, 0b000, 0b1100, 0b0000, 0b001>;
+def : ROSysReg<"RVBAR_EL2",           0b11, 0b100, 0b1100, 0b0000, 0b001>;
+def : ROSysReg<"RVBAR_EL3",           0b11, 0b110, 0b1100, 0b0000, 0b001>;
+def : ROSysReg<"ISR_EL1",             0b11, 0b000, 0b1100, 0b0001, 0b000>;
+def : ROSysReg<"CNTPCT_EL0",          0b11, 0b011, 0b1110, 0b0000, 0b001>;
+def : ROSysReg<"CNTVCT_EL0",          0b11, 0b011, 0b1110, 0b0000, 0b010>;
+def : ROSysReg<"ID_MMFR4_EL1",        0b11, 0b000, 0b0000, 0b0010, 0b110>;
+def : ROSysReg<"ID_MMFR5_EL1",        0b11, 0b000, 0b0000, 0b0011, 0b110>;
 
 // Trace registers
-//                                 Op0    Op1     CRn     CRm    Op2
+//                                   Op0    Op1     CRn     CRm    Op2
 def : ROSysReg<"TRCSTATR",           0b10, 0b001, 0b0000, 0b0011, 0b000>;
 def : ROSysReg<"TRCIDR8",            0b10, 0b001, 0b0000, 0b0000, 0b110>;
 def : ROSysReg<"TRCIDR9",            0b10, 0b001, 0b0000, 0b0001, 0b110>;
@@ -1662,6 +1665,7 @@ def : RWSysReg<"HDFGRTR2_EL2",     0b11, 0b100, 0b0011, 0b0001, 0b000>;
 def : RWSysReg<"HDFGWTR2_EL2",     0b11, 0b100, 0b0011, 0b0001, 0b001>;
 def : RWSysReg<"HFGRTR2_EL2",      0b11, 0b100, 0b0011, 0b0001, 0b010>;
 def : RWSysReg<"HFGWTR2_EL2",      0b11, 0b100, 0b0011, 0b0001, 0b011>;
+def : RWSysReg<"HFGITR2_EL2",      0b11, 0b100, 0b0011, 0b0001, 0b111>;
 }
 
 // v8.6a Enhanced Counter Virtualization
@@ -1768,6 +1772,7 @@ def : RWSysReg<"S2POR_EL1",   0b11, 0b000, 0b1010, 0b0010, 0b101>;
 def : RWSysReg<"SCTLR2_EL1",  0b11, 0b000, 0b0001, 0b0000, 0b011>;
 def : RWSysReg<"SCTLR2_EL12", 0b11, 0b101, 0b0001, 0b0000, 0b011>;
 def : RWSysReg<"SCTLR2_EL2",  0b11, 0b100, 0b0001, 0b0000, 0b011>;
+def : RWSysReg<"SCTLR2_EL3",  0b11, 0b110, 0b0001, 0b0000, 0b011>;
 
 // v8.9a/v9.4a Extension to Translation Control Registers (FEAT_TCR2)
 //                            Op0   Op1    CRn     CRm     Op2

diff  --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index d64cd5da92dfa..90cafd4a0a539 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -3639,6 +3639,7 @@ static const struct Extension {
     {"ras", {AArch64::FeatureRAS}},
     {"lse", {AArch64::FeatureLSE}},
     {"predres", {AArch64::FeaturePredRes}},
+    {"predres2", {AArch64::FeatureSPECRES2}},
     {"ccdp", {AArch64::FeatureCacheDeepPersist}},
     {"mte", {AArch64::FeatureMTE}},
     {"memtag", {AArch64::FeatureMTE}},
@@ -3797,23 +3798,31 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
       return TokError(Str);
     }
     createSysAlias(TLBI->Encoding, Operands, S);
-  } else if (Mnemonic == "cfp" || Mnemonic == "dvp" || Mnemonic == "cpp") {
-    const AArch64PRCTX::PRCTX *PRCTX = AArch64PRCTX::lookupPRCTXByName(Op);
-    if (!PRCTX)
+  } else if (Mnemonic == "cfp" || Mnemonic == "dvp" || Mnemonic == "cpp" || Mnemonic == "cosp") {
+
+    if (Op.lower() != "rctx")
       return TokError("invalid operand for prediction restriction instruction");
-    else if (!PRCTX->haveFeatures(getSTI().getFeatureBits())) {
-      std::string Str(
-          Mnemonic.upper() + std::string(PRCTX->Name) + " requires: ");
-      setRequiredFeatureString(PRCTX->getRequiredFeatures(), Str);
-      return TokError(Str);
-    }
-    uint16_t PRCTX_Op2 =
-      Mnemonic == "cfp" ? 4 :
-      Mnemonic == "dvp" ? 5 :
-      Mnemonic == "cpp" ? 7 :
-      0;
-    assert(PRCTX_Op2 && "Invalid mnemonic for prediction restriction instruction");
-    createSysAlias(PRCTX->Encoding << 3 | PRCTX_Op2 , Operands, S);
+
+    bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
+    bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
+    bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
+
+    if (Mnemonic == "cosp" && !hasSpecres2)
+      return TokError("COSP requires: predres2");
+    if (!hasPredres)
+      return TokError(Mnemonic.upper() + "RCTX requires: predres");
+
+    uint16_t PRCTX_Op2 = Mnemonic == "cfp"    ? 0b100
+                         : Mnemonic == "dvp"  ? 0b101
+                         : Mnemonic == "cosp" ? 0b110
+                         : Mnemonic == "cpp"  ? 0b111
+                                              : 0;
+    assert(PRCTX_Op2 &&
+           "Invalid mnemonic for prediction restriction instruction");
+    const auto SYS_3_7_3 = 0b01101110011; // op=3, CRn=7, CRm=3
+    const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
+
+    createSysAlias(Encoding, Operands, S);
   }
 
   Lex(); // Eat operand.
@@ -5080,7 +5089,7 @@ bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
   // IC, DC, AT, TLBI and Prediction invalidation instructions are aliases for
   // the SYS instruction.
   if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi" ||
-      Head == "cfp" || Head == "dvp" || Head == "cpp")
+      Head == "cfp" || Head == "dvp" || Head == "cpp" || Head == "cosp")
     return parseSysAlias(Head, NameLoc, Operands);
 
   // TLBIP instructions are aliases for the SYSP instruction.

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
index 8525308e6b2a7..b8fd616f4f782 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
@@ -910,18 +910,23 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI,
     // Prediction Restriction aliases
     case 3: {
       Search_PRCTX:
-      const AArch64PRCTX::PRCTX *PRCTX = AArch64PRCTX::lookupPRCTXByEncoding(Encoding >> 3);
-      if (!PRCTX || !PRCTX->haveFeatures(STI.getFeatureBits()))
+      if (Op1Val != 3 || CnVal != 7 || CmVal != 3)
         return false;
 
-      NeedsReg = PRCTX->NeedsReg;
+      const auto Requires =
+          Op2Val == 6 ? AArch64::FeatureSPECRES2 : AArch64::FeaturePredRes;
+      if (!(STI.hasFeature(AArch64::FeatureAll) || STI.hasFeature(Requires)))
+        return false;
+
+      NeedsReg = true;
       switch (Op2Val) {
       default: return false;
       case 4: Ins = "cfp\t"; break;
       case 5: Ins = "dvp\t"; break;
+      case 6: Ins = "cosp\t"; break;
       case 7: Ins = "cpp\t"; break;
       }
-      Name = std::string(PRCTX->Name);
+      Name = "RCTX";
     }
     break;
     // IC aliases
@@ -1433,9 +1438,12 @@ void AArch64InstPrinter::printPrefetchOp(const MCInst *MI, unsigned OpNum,
       O << PRFM->Name;
       return;
     }
-  } else if (auto PRFM = AArch64PRFM::lookupPRFMByEncoding(prfop)) {
-    O << PRFM->Name;
-    return;
+  } else {
+    auto PRFM = AArch64PRFM::lookupPRFMByEncoding(prfop);
+    if (PRFM && PRFM->haveFeatures(STI.getFeatureBits())) {
+      O << PRFM->Name;
+      return;
+    }
   }
 
   O << markup("<imm:") << '#' << formatImm(prfop) << markup(">");

diff  --git a/llvm/lib/Target/ARM/ARM.td b/llvm/lib/Target/ARM/ARM.td
index 9208c5949f106..ec631b73f973d 100644
--- a/llvm/lib/Target/ARM/ARM.td
+++ b/llvm/lib/Target/ARM/ARM.td
@@ -542,6 +542,11 @@ def FeatureNoBTIAtReturnTwice : SubtargetFeature<"no-bti-at-return-twice",
                                                  "Don't place a BTI instruction "
                                                  "after a return-twice">;
 
+// Armv8.9-A/Armv9.4-A 2022 Architecture Extensions
+def FeatureCLRBHB : SubtargetFeature<"clrbhb", "HasCLRBHB", "true",
+                                     "Enable Clear BHB instruction">;
+
+
 def FeatureFixCortexA57AES1742098 : SubtargetFeature<"fix-cortex-a57-aes-1742098",
   "FixCortexA57AES1742098", "true",
   "Work around Cortex-A57 Erratum 1742098 / Cortex-A72 Erratum 1655431 (AES)">;
@@ -674,7 +679,7 @@ def HasV8_8aOps   : SubtargetFeature<"v8.8a", "HasV8_8aOps", "true",
 
 def HasV8_9aOps   : SubtargetFeature<"v8.9a", "HasV8_9aOps", "true",
                                    "Support ARM v8.9a instructions",
-                                   [HasV8_8aOps]>;
+                                   [HasV8_8aOps, FeatureCLRBHB]>;
 
 def HasV9_0aOps   : SubtargetFeature<"v9a", "HasV9_0aOps", "true",
                                    "Support ARM v9a instructions",

diff  --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index 9f014482063fb..5c56e4714aff1 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -2189,6 +2189,10 @@ def : InstAlias<"sevl$p", (HINT 5, pred:$p)>, Requires<[IsARM, HasV8]>;
 def : InstAlias<"esb$p", (HINT 16, pred:$p)>, Requires<[IsARM, HasRAS]>;
 def : InstAlias<"csdb$p", (HINT 20, pred:$p)>, Requires<[IsARM, HasV6K]>;
 
+// Clear BHB instruction
+def : InstAlias<"clrbhb$p", (HINT 22, pred:$p), 0>, Requires<[IsARM, HasV8]>;
+def : InstAlias<"clrbhb$p", (HINT 22, pred:$p), 1>, Requires<[IsARM, HasV8, HasCLRBHB]>;
+
 def SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel",
              "\t$Rd, $Rn, $Rm",
              [(set GPR:$Rd, (int_arm_sel GPR:$Rn, GPR:$Rm))]>,

diff  --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index f102e5e1c9792..ebe4864032619 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -4089,6 +4089,10 @@ def : t2InstAlias<"bti$p", (t2HINT 15, pred:$p), 1>;
 def : t2InstAlias<"pac$p r12,lr,sp", (t2HINT 29, pred:$p), 1>;
 def : t2InstAlias<"aut$p r12,lr,sp", (t2HINT 45, pred:$p), 1>;
 
+// Clear BHB instruction
+def : InstAlias<"clrbhb$p", (t2HINT 22, pred:$p), 0>, Requires<[IsThumb2, HasV8]>;
+def : InstAlias<"clrbhb$p", (t2HINT 22, pred:$p), 1>, Requires<[IsThumb2, HasV8, HasCLRBHB]>;
+
 def t2DBG : T2I<(outs), (ins imm0_15:$opt), NoItinerary, "dbg", "\t$opt",
                 [(int_arm_dbg imm0_15:$opt)]> {
   bits<4> opt;

diff  --git a/llvm/lib/Target/ARM/ARMPredicates.td b/llvm/lib/Target/ARM/ARMPredicates.td
index c0dc6a3634715..59562efea6b96 100644
--- a/llvm/lib/Target/ARM/ARMPredicates.td
+++ b/llvm/lib/Target/ARM/ARMPredicates.td
@@ -226,3 +226,7 @@ def GenExecuteOnly : Predicate<"Subtarget->genExecuteOnly()">;
 // Armv8.5-A extensions
 def HasSB            : Predicate<"Subtarget->hasSB()">,
                        AssemblerPredicate<(all_of FeatureSB), "sb">;
+
+// Armv8.9-A/9.4-A 2022 Architecture extensions
+def HasCLRBHB        : Predicate<"Subtarget->hasCLRBHB()">,
+                       AssemblerPredicate<(all_of FeatureCLRBHB), "clrbhb">;

diff  --git a/llvm/test/MC/AArch64/arm64-system-encoding.s b/llvm/test/MC/AArch64/arm64-system-encoding.s
index 744d35f4edbfe..fc769e221cba4 100644
--- a/llvm/test/MC/AArch64/arm64-system-encoding.s
+++ b/llvm/test/MC/AArch64/arm64-system-encoding.s
@@ -158,6 +158,7 @@ foo:
   msr SCTLR2_EL1, x3
   msr SCTLR2_EL12, x3
   msr SCTLR2_EL2, x3
+  msr SCTLR2_EL3, x3
   msr TCR2_EL1, x3
   msr TCR2_EL12, x3
   msr TCR2_EL2, x3
@@ -264,6 +265,7 @@ foo:
 ; CHECK: msr SCTLR2_EL1, x3             ; encoding: [0x63,0x10,0x18,0xd5]
 ; CHECK: msr SCTLR2_EL12, x3            ; encoding: [0x63,0x10,0x1d,0xd5]
 ; CHECK: msr SCTLR2_EL2, x3             ; encoding: [0x63,0x10,0x1c,0xd5]
+; CHECK: msr SCTLR2_EL3, x3             ; encoding: [0x63,0x10,0x1e,0xd5]
 ; CHECK: msr TCR2_EL1, x3               ; encoding: [0x63,0x20,0x18,0xd5]
 ; CHECK: msr TCR2_EL12, x3              ; encoding: [0x63,0x20,0x1d,0xd5]
 ; CHECK: msr TCR2_EL2, x3               ; encoding: [0x63,0x20,0x1c,0xd5]
@@ -334,8 +336,11 @@ foo:
   mrs x3, ID_AA64ISAR2_EL1
   mrs x3, ID_AA64MMFR0_EL1
   mrs x3, ID_AA64MMFR1_EL1
+  mrs x3, ID_AA64MMFR2_EL1
+  mrs x3, ID_AA64MMFR3_EL1
   mrs x3, ID_AA64PFR0_EL1
   mrs x3, ID_AA64PFR1_EL1
+  mrs x3, ID_AA64PFR2_EL1
   mrs x3, IFSR32_EL2
   mrs x3, ISR_EL1
   mrs x3, MAIR_EL1
@@ -482,6 +487,7 @@ foo:
   mrs x3, SCTLR2_EL1
   mrs x3, SCTLR2_EL12
   mrs x3, SCTLR2_EL2
+  mrs x3, SCTLR2_EL3
   mrs x3, TCR2_EL1
   mrs x3, TCR2_EL12
   mrs x3, TCR2_EL2
@@ -548,8 +554,11 @@ foo:
 ; CHECK: mrs x3, ID_AA64ISAR2_EL1       ; encoding: [0x43,0x06,0x38,0xd5]
 ; CHECK: mrs x3, ID_AA64MMFR0_EL1       ; encoding: [0x03,0x07,0x38,0xd5]
 ; CHECK: mrs x3, ID_AA64MMFR1_EL1       ; encoding: [0x23,0x07,0x38,0xd5]
+; CHECK: mrs x3, ID_AA64MMFR2_EL1       ; encoding: [0x43,0x07,0x38,0xd5]
+; CHECK: mrs x3, ID_AA64MMFR3_EL1       ; encoding: [0x63,0x07,0x38,0xd5]
 ; CHECK: mrs x3, ID_AA64PFR0_EL1        ; encoding: [0x03,0x04,0x38,0xd5]
 ; CHECK: mrs x3, ID_AA64PFR1_EL1        ; encoding: [0x23,0x04,0x38,0xd5]
+; CHECK: mrs x3, ID_AA64PFR2_EL1        ; encoding: [0x43,0x04,0x38,0xd5]
 ; CHECK: mrs x3, IFSR32_EL2             ; encoding: [0x23,0x50,0x3c,0xd5]
 ; CHECK: mrs x3, ISR_EL1                ; encoding: [0x03,0xc1,0x38,0xd5]
 ; CHECK: mrs x3, MAIR_EL1               ; encoding: [0x03,0xa2,0x38,0xd5]
@@ -695,6 +704,7 @@ foo:
 ; CHECK: mrs x3, SCTLR2_EL1           ; encoding: [0x63,0x10,0x38,0xd5]
 ; CHECK: mrs x3, SCTLR2_EL12          ; encoding: [0x63,0x10,0x3d,0xd5]
 ; CHECK: mrs x3, SCTLR2_EL2           ; encoding: [0x63,0x10,0x3c,0xd5]
+; CHECK: mrs x3, SCTLR2_EL3           ; encoding: [0x63,0x10,0x3e,0xd5]
 ; CHECK: mrs x3, TCR2_EL1             ; encoding: [0x63,0x20,0x38,0xd5]
 ; CHECK: mrs x3, TCR2_EL12            ; encoding: [0x63,0x20,0x3d,0xd5]
 ; CHECK: mrs x3, TCR2_EL2             ; encoding: [0x63,0x20,0x3c,0xd5]

diff  --git a/llvm/test/MC/AArch64/armv8.6a-fgt.s b/llvm/test/MC/AArch64/armv8.6a-fgt.s
index c9be670a58434..11002aca5e1a0 100644
--- a/llvm/test/MC/AArch64/armv8.6a-fgt.s
+++ b/llvm/test/MC/AArch64/armv8.6a-fgt.s
@@ -45,10 +45,13 @@ mrs x3, HDFGRTR2_EL2
 mrs x3, HDFGWTR2_EL2
 mrs x3, HFGRTR2_EL2
 mrs x3, HFGWTR2_EL2
+mrs x3, HFGITR2_EL2
 // CHECK: mrs     x3, HDFGRTR2_EL2                // encoding: [0x03,0x31,0x3c,0xd5]
 // CHECK: mrs     x3, HDFGWTR2_EL2                // encoding: [0x23,0x31,0x3c,0xd5]
 // CHECK: mrs     x3, HFGRTR2_EL2                 // encoding: [0x43,0x31,0x3c,0xd5]
 // CHECK: mrs     x3, HFGWTR2_EL2                 // encoding: [0x63,0x31,0x3c,0xd5]
+// CHECK: mrs     x3, HFGITR2_EL2                 // encoding: [0xe3,0x31,0x3c,0xd5]
+// NOFGT: error: expected readable system register
 // NOFGT: error: expected readable system register
 // NOFGT: error: expected readable system register
 // NOFGT: error: expected readable system register
@@ -59,10 +62,13 @@ msr HDFGRTR2_EL2, x3
 msr HDFGWTR2_EL2, x3
 msr HFGRTR2_EL2, x3
 msr HFGWTR2_EL2, x3
+msr HFGITR2_EL2, x3
 // CHECK: msr     HDFGRTR2_EL2, x3                // encoding: [0x03,0x31,0x1c,0xd5]
 // CHECK: msr     HDFGWTR2_EL2, x3                // encoding: [0x23,0x31,0x1c,0xd5]
 // CHECK: msr     HFGRTR2_EL2, x3                 // encoding: [0x43,0x31,0x1c,0xd5]
 // CHECK: msr     HFGWTR2_EL2, x3                 // encoding: [0x63,0x31,0x1c,0xd5]
+// CHECK: msr     HFGITR2_EL2, x3                 // encoding: [0xe3,0x31,0x1c,0xd5]
+// NOFGT: error: expected writable system register
 // NOFGT: error: expected writable system register
 // NOFGT: error: expected writable system register
 // NOFGT: error: expected writable system register

diff  --git a/llvm/test/MC/AArch64/armv8.9a-clrbhb.s b/llvm/test/MC/AArch64/armv8.9a-clrbhb.s
new file mode 100644
index 0000000000000..e0bb0afb357a0
--- /dev/null
+++ b/llvm/test/MC/AArch64/armv8.9a-clrbhb.s
@@ -0,0 +1,43 @@
+// CLRBHB is optional for all v8a/v9a, mandatory for 8.9a/9.4a.
+// Assembly is always permitted for instructions in the hint space.
+
+// Optional, off by default
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi < %s | FileCheck %s --check-prefix=HINT_22
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v8a < %s | FileCheck %s --check-prefix=HINT_22
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v8.8a < %s | FileCheck %s --check-prefix=HINT_22
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v9a < %s | FileCheck %s --check-prefix=HINT_22
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v9.3a < %s | FileCheck %s --check-prefix=HINT_22
+
+// Optional, off by default, doubly disabled
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=-clrbhb < %s | FileCheck %s --check-prefix=HINT_22
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v8a,-clrbhb < %s | FileCheck %s --check-prefix=HINT_22
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v8.8a,-clrbhb < %s | FileCheck %s --check-prefix=HINT_22
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v9a,-clrbhb < %s | FileCheck %s --check-prefix=HINT_22
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v9.3a,-clrbhb < %s | FileCheck %s --check-prefix=HINT_22
+
+// Optional, off by default, manually enabled
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+clrbhb < %s | FileCheck %s --check-prefix=CLRBHB
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v8a,+clrbhb < %s | FileCheck %s --check-prefix=CLRBHB
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v8.8a,+clrbhb < %s | FileCheck %s --check-prefix=CLRBHB
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v9a,+clrbhb < %s | FileCheck %s --check-prefix=CLRBHB
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v9.3a,+clrbhb < %s | FileCheck %s --check-prefix=CLRBHB
+
+// Mandatory, enabled by default
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v8.9a < %s | FileCheck %s --check-prefix=CLRBHB
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v9.4a < %s | FileCheck %s --check-prefix=CLRBHB
+
+// Mandatory, on by default, doubly enabled
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v8.9a,+clrbhb < %s | FileCheck %s --check-prefix=CLRBHB
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v9.4a,+clrbhb < %s | FileCheck %s --check-prefix=CLRBHB
+
+// Mandatory, can't prevent disabling in LLVM
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v8.9a,-clrbhb < %s | FileCheck %s --check-prefix=HINT_22
+// RUN: llvm-mc -show-encoding -triple aarch64-none-none-eabi -mattr=+v9.4a,-clrbhb < %s | FileCheck %s --check-prefix=HINT_22
+
+        clrbhb
+        hint #22
+
+// CLRBHB: clrbhb    // encoding: [0xdf,0x22,0x03,0xd5]
+// CLRBHB: clrbhb    // encoding: [0xdf,0x22,0x03,0xd5]
+// HINT_22: hint #22 // encoding: [0xdf,0x22,0x03,0xd5]
+// HINT_22: hint #22 // encoding: [0xdf,0x22,0x03,0xd5]

diff  --git a/llvm/test/MC/AArch64/armv8.9a-prfm-slc.s b/llvm/test/MC/AArch64/armv8.9a-prfm-slc.s
new file mode 100644
index 0000000000000..b7af572e81445
--- /dev/null
+++ b/llvm/test/MC/AArch64/armv8.9a-prfm-slc.s
@@ -0,0 +1,32 @@
+
+// RUN: llvm-mc -triple aarch64 -show-encoding < %s | FileCheck %s --check-prefix=NO-SLC
+// RUN: llvm-mc -triple aarch64 -show-encoding -mattr=+v8.9a < %s | FileCheck %s
+// RUN: llvm-mc -triple aarch64 -show-encoding -mattr=+v9.4a < %s | FileCheck %s
+
+prfm pldslckeep, [x3]
+// CHECK: prfm pldslckeep, [x3]  // encoding: [0x66,0x00,0x80,0xf9]
+// NO-SLC: prfm #6, [x3]
+prfm pldslcstrm, [x3]
+// CHECK: prfm pldslcstrm, [x3]  // encoding: [0x67,0x00,0x80,0xf9]
+// NO-SLC: prfm #7, [x3]
+prfm plislckeep, [x3]
+// CHECK: prfm plislckeep, [x3]  // encoding: [0x6e,0x00,0x80,0xf9]
+// NO-SLC: prfm #14, [x3]
+prfm plislcstrm, [x3]
+// CHECK: prfm plislcstrm, [x3]  // encoding: [0x6f,0x00,0x80,0xf9]
+// NO-SLC: prfm #15, [x3]
+prfm pstslckeep, [x3]
+// CHECK: prfm pstslckeep, [x3]  // encoding: [0x76,0x00,0x80,0xf9]
+// NO-SLC: prfm #22, [x3]
+prfm pstslcstrm, [x3]
+// CHECK: prfm pstslcstrm, [x3]  // encoding: [0x77,0x00,0x80,0xf9]
+// NO-SLC: prfm #23, [x3]
+
+self:
+prfm pldslckeep, self
+// CHECK: prfm pldslckeep, self // encoding: [0bAAA00110,A,A,0xd8]
+// NO-SLC: prfm #6, self
+
+prfm pldslckeep, [x3, x5]
+// CHECK: prfm pldslckeep, [x3, x5] // encoding: [0x66,0x68,0xa5,0xf8]
+// NO-SLC: prfm #6, [x3, x5]

diff  --git a/llvm/test/MC/AArch64/armv8.9a-specres2-error.s b/llvm/test/MC/AArch64/armv8.9a-specres2-error.s
new file mode 100644
index 0000000000000..c2f32a20bc03e
--- /dev/null
+++ b/llvm/test/MC/AArch64/armv8.9a-specres2-error.s
@@ -0,0 +1,10 @@
+// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+specres2 < %s 2>&1| FileCheck %s
+
+cosp rctx
+
+// CHECK: specified cosp op requires a register
+
+cosp x0, x1
+
+// CHECK:      invalid operand for prediction restriction instruction
+// CHECK-NEXT: cosp

diff  --git a/llvm/test/MC/AArch64/armv8.9a-specres2.s b/llvm/test/MC/AArch64/armv8.9a-specres2.s
new file mode 100644
index 0000000000000..b411ec31580b9
--- /dev/null
+++ b/llvm/test/MC/AArch64/armv8.9a-specres2.s
@@ -0,0 +1,13 @@
+// RUN:     llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+specres2 < %s      | FileCheck %s
+// RUN:     llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.9a    < %s      | FileCheck %s
+// RUN:     llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v9.4a    < %s      | FileCheck %s
+// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=-specres2 < %s 2>&1 | FileCheck %s --check-prefix=NOSPECRES2
+
+cosp rctx, x0
+sys #3, c7, c3, #6, x0
+
+// CHECK: cosp rctx, x0          // encoding: [0xc0,0x73,0x0b,0xd5]
+// CHECK: cosp rctx, x0          // encoding: [0xc0,0x73,0x0b,0xd5]
+
+// NOSPECRES2: COSP requires: predres2
+// NOSPECRES2-NEXT: cosp

diff  --git a/llvm/test/MC/AArch64/basic-a64-diagnostics.s b/llvm/test/MC/AArch64/basic-a64-diagnostics.s
index 87d9531a5edd8..b4ebf991281b2 100644
--- a/llvm/test/MC/AArch64/basic-a64-diagnostics.s
+++ b/llvm/test/MC/AArch64/basic-a64-diagnostics.s
@@ -3596,6 +3596,7 @@
         msr MVFR2_EL1, x12
         msr ID_AA64PFR0_EL1, x12
         msr ID_AA64PFR1_EL1, x12
+        msr ID_AA64PFR2_EL1, x12
         msr ID_AA64DFR0_EL1, x12
         msr ID_AA64DFR1_EL1, x12
         msr ID_AA64AFR0_EL1, x12
@@ -3604,6 +3605,8 @@
         msr ID_AA64ISAR1_EL1, x12
         msr ID_AA64MMFR0_EL1, x12
         msr ID_AA64MMFR1_EL1, x12
+        msr ID_AA64MMFR2_EL1, x12
+        msr ID_AA64MMFR3_EL1, x12
         msr PMCEID0_EL0, x12
         msr PMCEID1_EL0, x12
         msr PMMIR_EL1, x12
@@ -3724,6 +3727,9 @@
 // CHECK-ERROR-NEXT:         msr ID_AA64PFR1_EL1, x12
 // CHECK-ERROR-NEXT:             ^
 // CHECK-ERROR-NEXT: error: expected writable system register or pstate
+// CHECK-ERROR-NEXT:         msr ID_AA64PFR2_EL1, x12
+// CHECK-ERROR-NEXT:             ^
+// CHECK-ERROR-NEXT: error: expected writable system register or pstate
 // CHECK-ERROR-NEXT:         msr ID_AA64DFR0_EL1, x12
 // CHECK-ERROR-NEXT:             ^
 // CHECK-ERROR-NEXT: error: expected writable system register or pstate
@@ -3748,6 +3754,12 @@
 // CHECK-ERROR-NEXT:         msr ID_AA64MMFR1_EL1, x12
 // CHECK-ERROR-NEXT:             ^
 // CHECK-ERROR-NEXT: error: expected writable system register or pstate
+// CHECK-ERROR-NEXT:         msr ID_AA64MMFR2_EL1, x12
+// CHECK-ERROR-NEXT:             ^
+// CHECK-ERROR-NEXT: error: expected writable system register or pstate
+// CHECK-ERROR-NEXT:         msr ID_AA64MMFR3_EL1, x12
+// CHECK-ERROR-NEXT:             ^
+// CHECK-ERROR-NEXT: error: expected writable system register or pstate
 // CHECK-ERROR-NEXT:         msr PMCEID0_EL0, x12
 // CHECK-ERROR-NEXT:             ^
 // CHECK-ERROR-NEXT: error: expected writable system register or pstate

diff  --git a/llvm/test/MC/AArch64/basic-a64-instructions.s b/llvm/test/MC/AArch64/basic-a64-instructions.s
index 06d5a358e95e0..207ba3c08b96b 100644
--- a/llvm/test/MC/AArch64/basic-a64-instructions.s
+++ b/llvm/test/MC/AArch64/basic-a64-instructions.s
@@ -3963,6 +3963,7 @@ _func:
         msr SCTLR2_EL1, x12
         msr SCTLR2_EL12, x12
         msr SCTLR2_EL2, x12
+        msr SCTLR2_EL3, x12
         msr TCR2_EL1, x12
         msr TCR2_EL12, x12
         msr TCR2_EL2, x12
@@ -4243,6 +4244,7 @@ _func:
 // CHECK: msr      {{sctlr2_el1|SCTLR2_EL1}}, x12       // encoding: [0x6c,0x10,0x18,0xd5]
 // CHECK: msr      {{sctlr2_el12|SCTLR2_EL12}}, x12       // encoding: [0x6c,0x10,0x1d,0xd5]
 // CHECK: msr      {{sctlr2_el2|SCTLR2_EL2}}, x12       // encoding: [0x6c,0x10,0x1c,0xd5]
+// CHECK: msr      {{sctlr2_el3|SCTLR2_EL3}}, x12       // encoding: [0x6c,0x10,0x1e,0xd5]
 // CHECK: msr      {{tcr2_el1|TCR2_EL1}}, x12       // encoding: [0x6c,0x20,0x18,0xd5]
 // CHECK: msr      {{tcr2_el12|TCR2_EL12}}, x12       // encoding: [0x6c,0x20,0x1d,0xd5]
 // CHECK: msr      {{tcr2_el2|TCR2_EL2}}, x12       // encoding: [0x6c,0x20,0x1c,0xd5]
@@ -4362,6 +4364,7 @@ _func:
 	mrs x9, MVFR2_EL1
 	mrs x9, ID_AA64PFR0_EL1
 	mrs x9, ID_AA64PFR1_EL1
+	mrs x9, ID_AA64PFR2_EL1
 	mrs x9, ID_AA64DFR0_EL1
 	mrs x9, ID_AA64DFR1_EL1
 	mrs x9, ID_AA64AFR0_EL1
@@ -4370,6 +4373,8 @@ _func:
 	mrs x9, ID_AA64ISAR1_EL1
 	mrs x9, ID_AA64MMFR0_EL1
 	mrs x9, ID_AA64MMFR1_EL1
+	mrs x9, ID_AA64MMFR2_EL1
+	mrs x9, ID_AA64MMFR3_EL1
 	mrs x9, SCTLR_EL1
 	mrs x9, SCTLR_EL2
 	mrs x9, SCTLR_EL3
@@ -4575,6 +4580,7 @@ _func:
         mrs x9, SCTLR2_EL1
         mrs x9, SCTLR2_EL12
         mrs x9, SCTLR2_EL2
+        mrs x9, SCTLR2_EL3
         mrs x9, TCR2_EL1
         mrs x9, TCR2_EL12
         mrs x9, TCR2_EL2
@@ -4693,6 +4699,7 @@ _func:
 // CHECK: mrs      x9, {{mvfr2_el1|MVFR2_EL1}}              // encoding: [0x49,0x03,0x38,0xd5]
 // CHECK: mrs      x9, {{id_aa64pfr0_el1|ID_AA64PFR0_EL1}}        // encoding: [0x09,0x04,0x38,0xd5]
 // CHECK: mrs      x9, {{id_aa64pfr1_el1|ID_AA64PFR1_EL1}}        // encoding: [0x29,0x04,0x38,0xd5]
+// CHECK: mrs      x9, {{id_aa64pfr2_el1|ID_AA64PFR2_EL1}}        // encoding: [0x49,0x04,0x38,0xd5]
 // CHECK: mrs      x9, {{id_aa64dfr0_el1|ID_AA64DFR0_EL1}}        // encoding: [0x09,0x05,0x38,0xd5]
 // CHECK: mrs      x9, {{id_aa64dfr1_el1|ID_AA64DFR1_EL1}}        // encoding: [0x29,0x05,0x38,0xd5]
 // CHECK: mrs      x9, {{id_aa64afr0_el1|ID_AA64AFR0_EL1}}        // encoding: [0x89,0x05,0x38,0xd5]
@@ -4701,6 +4708,8 @@ _func:
 // CHECK: mrs      x9, {{id_aa64isar1_el1|ID_AA64ISAR1_EL1}}       // encoding: [0x29,0x06,0x38,0xd5]
 // CHECK: mrs      x9, {{id_aa64mmfr0_el1|ID_AA64MMFR0_EL1}}       // encoding: [0x09,0x07,0x38,0xd5]
 // CHECK: mrs      x9, {{id_aa64mmfr1_el1|ID_AA64MMFR1_EL1}}       // encoding: [0x29,0x07,0x38,0xd5]
+// CHECK: mrs      x9, {{id_aa64mmfr2_el1|ID_AA64MMFR2_EL1}}       // encoding: [0x49,0x07,0x38,0xd5]
+// CHECK: mrs      x9, {{id_aa64mmfr3_el1|ID_AA64MMFR3_EL1}}       // encoding: [0x69,0x07,0x38,0xd5]
 // CHECK: mrs      x9, {{sctlr_el1|SCTLR_EL1}}              // encoding: [0x09,0x10,0x38,0xd5]
 // CHECK: mrs      x9, {{sctlr_el2|SCTLR_EL2}}              // encoding: [0x09,0x10,0x3c,0xd5]
 // CHECK: mrs      x9, {{sctlr_el3|SCTLR_EL3}}              // encoding: [0x09,0x10,0x3e,0xd5]
@@ -4906,6 +4915,7 @@ _func:
 // CHECK: mrs      x9, {{sctlr2_el1|SCTLR2_EL1}}        // encoding: [0x69,0x10,0x38,0xd5]
 // CHECK: mrs      x9, {{sctlr2_el12|SCTLR2_EL12}}        // encoding: [0x69,0x10,0x3d,0xd5]
 // CHECK: mrs      x9, {{sctlr2_el2|SCTLR2_EL2}}        // encoding: [0x69,0x10,0x3c,0xd5]
+// CHECK: mrs      x9, {{sctlr2_el3|SCTLR2_EL3}}        // encoding: [0x69,0x10,0x3e,0xd5]
 // CHECK: mrs      x9, {{tcr2_el1|TCR2_EL1}}        // encoding: [0x69,0x20,0x38,0xd5]
 // CHECK: mrs      x9, {{tcr2_el12|TCR2_EL12}}        // encoding: [0x69,0x20,0x3d,0xd5]
 // CHECK: mrs      x9, {{tcr2_el2|TCR2_EL2}}        // encoding: [0x69,0x20,0x3c,0xd5]

diff  --git a/llvm/test/MC/ARM/armv8.9a-clrbhb.s b/llvm/test/MC/ARM/armv8.9a-clrbhb.s
new file mode 100644
index 0000000000000..3f95633fb61de
--- /dev/null
+++ b/llvm/test/MC/ARM/armv8.9a-clrbhb.s
@@ -0,0 +1,53 @@
+// CLRBHB is optional for all v8a/v9a, mandatory for 8.9a/9.4a.
+// Assembly is always permitted for instructions in the hint space.
+
+// Invalid before v8
+// RUN: not llvm-mc -show-encoding -triple armv7-none-none-eabi < %s 2>&1 | FileCheck %s --check-prefix=INVALID
+// RUN: not llvm-mc -show-encoding -triple armv7-none-none-eabi -mattr=-clrbhb < %s 2>&1 | FileCheck %s --check-prefix=INVALID
+// RUN: not llvm-mc -show-encoding -triple armv7-none-none-eabi -mattr=+clrbhb < %s 2>&1 | FileCheck %s --check-prefix=REQUIRESV8
+
+// Optional, off by default
+// RUN: llvm-mc -show-encoding -triple armv8-none-none-eabi < %s | FileCheck %s --check-prefix=A32_HINT
+// RUN: llvm-mc -show-encoding -triple armv8.8a-none-none-eabi < %s | FileCheck %s --check-prefix=A32_HINT
+// RUN: llvm-mc -show-encoding -triple thumbv8-none-none-eabi < %s | FileCheck %s --check-prefix=T32_HINT
+// RUN: llvm-mc -show-encoding -triple thumbv8.8a-none-none-eabi < %s | FileCheck %s --check-prefix=T32_HINT
+
+// Optional, off by default, doubly disabled
+// RUN: llvm-mc -show-encoding -triple armv8-none-none-eabi -mattr=-clrbhb < %s | FileCheck %s --check-prefix=A32_HINT
+// RUN: llvm-mc -show-encoding -triple armv8.8a-none-none-eabi -mattr=-clrbhb < %s | FileCheck %s --check-prefix=A32_HINT
+// RUN: llvm-mc -show-encoding -triple thumbv8-none-none-eabi -mattr=-clrbhb < %s | FileCheck %s --check-prefix=T32_HINT
+// RUN: llvm-mc -show-encoding -triple thumbv8.8a-none-none-eabi -mattr=-clrbhb < %s | FileCheck %s --check-prefix=T32_HINT
+
+// Optional, off by default, manually enabled
+// RUN: llvm-mc -show-encoding -triple armv8-none-none-eabi -mattr=+clrbhb < %s | FileCheck %s --check-prefix=A32_CLRBHB
+// RUN: llvm-mc -show-encoding -triple armv8.8a-none-none-eabi -mattr=+clrbhb < %s | FileCheck %s --check-prefix=A32_CLRBHB
+// RUN: llvm-mc -show-encoding -triple thumbv8-none-none-eabi -mattr=+clrbhb < %s | FileCheck %s --check-prefix=T32_CLRBHB
+// RUN: llvm-mc -show-encoding -triple thumbv8.8a-none-none-eabi -mattr=+clrbhb < %s | FileCheck %s --check-prefix=T32_CLRBHB
+
+// Mandatory, enabled by default
+// RUN: llvm-mc -show-encoding -triple armv8.9a-none-none-eabi < %s | FileCheck %s --check-prefix=A32_CLRBHB
+// RUN: llvm-mc -show-encoding -triple thumbv8.9a-none-none-eabi < %s | FileCheck %s --check-prefix=T32_CLRBHB
+
+// Mandatory, on by default, doubly enabled
+// RUN: llvm-mc -show-encoding -triple armv8.9a-none-none-eabi -mattr=+clrbhb < %s | FileCheck %s --check-prefix=A32_CLRBHB
+// RUN: llvm-mc -show-encoding -triple thumbv8.9a-none-none-eabi -mattr=+clrbhb < %s | FileCheck %s --check-prefix=T32_CLRBHB
+
+// Mandatory, can't prevent disabling in LLVM
+// RUN: llvm-mc -show-encoding -triple armv8.9a-none-none-eabi -mattr=-clrbhb < %s | FileCheck %s --check-prefix=A32_HINT
+// RUN: llvm-mc -show-encoding -triple thumbv8.9a-none-none-eabi -mattr=-clrbhb < %s | FileCheck %s --check-prefix=T32_HINT
+
+        clrbhb
+        hint #22
+
+// INVALID: <stdin>:[[@LINE-3]]:9: error: invalid instruction
+// INVALID-NOT: <stdin>:[[@LINE-3]]:9: error: invalid instruction
+// REQUIRESV8: <stdin>:[[@LINE-5]]:9: error: instruction requires: armv8
+// REQUIRESV8-NOT: <stdin>:[[@LINE-5]]:9: error: instruction requires: armv8
+// A32_CLRBHB: clrbhb   @ encoding: [0x16,0xf0,0x20,0xe3]
+// A32_CLRBHB: clrbhb   @ encoding: [0x16,0xf0,0x20,0xe3]
+// A32_HINT: hint #22   @ encoding: [0x16,0xf0,0x20,0xe3]
+// A32_HINT: hint #22   @ encoding: [0x16,0xf0,0x20,0xe3]
+// T32_CLRBHB: clrbhb   @ encoding: [0xaf,0xf3,0x16,0x80]
+// T32_CLRBHB: clrbhb   @ encoding: [0xaf,0xf3,0x16,0x80]
+// T32_HINT: hint.w #22 @ encoding: [0xaf,0xf3,0x16,0x80]
+// T32_HINT: hint.w #22 @ encoding: [0xaf,0xf3,0x16,0x80]

diff  --git a/llvm/test/MC/Disassembler/AArch64/armv8.6a-fgt.txt b/llvm/test/MC/Disassembler/AArch64/armv8.6a-fgt.txt
index a4d3741d5817c..5b8d8170145fe 100644
--- a/llvm/test/MC/Disassembler/AArch64/armv8.6a-fgt.txt
+++ b/llvm/test/MC/Disassembler/AArch64/armv8.6a-fgt.txt
@@ -45,25 +45,31 @@
 [0x23,0x31,0x3c,0xd5]
 [0x43,0x31,0x3c,0xd5]
 [0x63,0x31,0x3c,0xd5]
+[0xe3,0x31,0x3c,0xd5]
 # CHECK: mrs x3, HDFGRTR2_EL2
 # CHECK: mrs x3, HDFGWTR2_EL2
 # CHECK: mrs x3, HFGRTR2_EL2
 # CHECK: mrs x3, HFGWTR2_EL2
+# CHECK: mrs x3, HFGITR2_EL2
 # NOFGT: mrs x3, S3_4_C3_C1_0
 # NOFGT: mrs x3, S3_4_C3_C1_1
 # NOFGT: mrs x3, S3_4_C3_C1_2
 # NOFGT: mrs x3, S3_4_C3_C1_3
+# NOFGT: mrs x3, S3_4_C3_C1_7
 
 
 [0x03,0x31,0x1c,0xd5]
 [0x23,0x31,0x1c,0xd5]
 [0x43,0x31,0x1c,0xd5]
 [0x63,0x31,0x1c,0xd5]
+[0xe3,0x31,0x1c,0xd5]
 # CHECK: msr HDFGRTR2_EL2, x3
 # CHECK: msr HDFGWTR2_EL2, x3
 # CHECK: msr HFGRTR2_EL2, x3
 # CHECK: msr HFGWTR2_EL2, x3
+# CHECK: msr HFGITR2_EL2, x3
 # NOFGT: msr S3_4_C3_C1_0, x3
 # NOFGT: msr S3_4_C3_C1_1, x3
 # NOFGT: msr S3_4_C3_C1_2, x3
 # NOFGT: msr S3_4_C3_C1_3, x3
+# NOFGT: msr S3_4_C3_C1_7, x3

diff  --git a/llvm/test/MC/Disassembler/AArch64/armv8.9a-clrbhb.txt b/llvm/test/MC/Disassembler/AArch64/armv8.9a-clrbhb.txt
new file mode 100644
index 0000000000000..f8c7e9fa1a15a
--- /dev/null
+++ b/llvm/test/MC/Disassembler/AArch64/armv8.9a-clrbhb.txt
@@ -0,0 +1,16 @@
+# CLRBHB is optional for all v8a/v9a, mandatory for 8.9a/9.4a.
+# Should disassemble to hint #22 if the feature is not present.
+# RUN: llvm-mc -triple=aarch64 -disassemble %s | FileCheck %s --check-prefix=HINT_22
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v8a %s | FileCheck %s --check-prefix=HINT_22
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v8.9a,-clrbhb %s | FileCheck %s --check-prefix=HINT_22
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v9.3a %s | FileCheck %s --check-prefix=HINT_22
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v9.4a,-clrbhb %s | FileCheck %s --check-prefix=HINT_22
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+clrbhb %s | FileCheck %s --check-prefix=CLRBHB
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v8a,+clrbhb %s | FileCheck %s --check-prefix=CLRBHB
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v8.9a %s | FileCheck %s --check-prefix=CLRBHB
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v9.3a,+clrbhb %s | FileCheck %s --check-prefix=CLRBHB
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v9.4a %s | FileCheck %s --check-prefix=CLRBHB
+
+[0xdf,0x22,0x03,0xd5]
+# CLRBHB: clrbhb
+# HINT_22: hint #22

diff  --git a/llvm/test/MC/Disassembler/AArch64/armv8.9a-prfm-slc.txt b/llvm/test/MC/Disassembler/AArch64/armv8.9a-prfm-slc.txt
new file mode 100644
index 0000000000000..06ea9628bcf53
--- /dev/null
+++ b/llvm/test/MC/Disassembler/AArch64/armv8.9a-prfm-slc.txt
@@ -0,0 +1,31 @@
+// RUN: llvm-mc -triple aarch64 -disassemble < %s | FileCheck %s --check-prefix=NO-SLC
+// RUN: llvm-mc -triple aarch64 -disassemble -mattr=+v8.9a < %s | FileCheck %s
+// RUN: llvm-mc -triple aarch64 -disassemble -mattr=+v9.4a < %s | FileCheck %s
+
+[0x66,0x00,0x80,0xf9]
+// CHECK: prfm pldslckeep, [x3]
+// NO-SLC: prfm #6, [x3]
+
+[0x67,0x00,0x80,0xf9]
+// CHECK: prfm pldslcstrm, [x3]
+// NO-SLC: prfm #7, [x3]
+
+[0x6e,0x00,0x80,0xf9]
+// CHECK: prfm plislckeep, [x3]
+// NO-SLC: prfm #14, [x3]
+
+[0x6f,0x00,0x80,0xf9]
+// CHECK: prfm plislcstrm, [x3]
+// NO-SLC: prfm #15, [x3]
+
+[0x76,0x00,0x80,0xf9]
+// CHECK: prfm pstslckeep, [x3]
+// NO-SLC: prfm #22, [x3]
+
+[0x06,0x00,0x00,0xd8]
+// CHECK: prfm pldslckeep, #0
+// NO-SLC: prfm #6, #0
+
+[0x66,0x68,0xa5,0xf8]
+// CHECK: prfm pldslckeep, [x3, x5]
+// NO-SLC: prfm #6, [x3, x5]

diff  --git a/llvm/test/MC/Disassembler/AArch64/armv8.9a-specres2.txt b/llvm/test/MC/Disassembler/AArch64/armv8.9a-specres2.txt
new file mode 100644
index 0000000000000..a114cd3493787
--- /dev/null
+++ b/llvm/test/MC/Disassembler/AArch64/armv8.9a-specres2.txt
@@ -0,0 +1,16 @@
+# FEAT_SPECRES2 is optional for all v8a/v9a, mandatory for 8.9a/9.4a.
+# Should disassemble to hint #22 if the feature is not present.
+# RUN: llvm-mc -triple=aarch64 -disassemble %s | FileCheck %s --check-prefix=HINT_22
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v8a %s | FileCheck %s --check-prefix=HINT_22
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v8.9a -mattr=-specres2 %s | FileCheck %s --check-prefix=HINT_22
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v9.3a %s | FileCheck %s --check-prefix=HINT_22
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v9.4a -mattr=-specres2 %s | FileCheck %s --check-prefix=HINT_22
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+specres2 %s | FileCheck %s --check-prefix=FEAT_SPECRES2
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v8a -mattr=+specres2 %s | FileCheck %s --check-prefix=FEAT_SPECRES2
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v8.9a %s | FileCheck %s --check-prefix=FEAT_SPECRES2
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v9.3a -mattr=+specres2 %s | FileCheck %s --check-prefix=FEAT_SPECRES2
+# RUN: llvm-mc -triple=aarch64 -disassemble -mattr=+v9.4a %s | FileCheck %s --check-prefix=FEAT_SPECRES2
+
+[0xc0,0x73,0x0b,0xd5]
+# FEAT_SPECRES2: cosp rctx, x0
+# HINT_22: sys #3, c7, c3, #6, x0

diff  --git a/llvm/test/MC/Disassembler/AArch64/basic-a64-instructions.txt b/llvm/test/MC/Disassembler/AArch64/basic-a64-instructions.txt
index 71ebaf4e4e547..429950928893a 100644
--- a/llvm/test/MC/Disassembler/AArch64/basic-a64-instructions.txt
+++ b/llvm/test/MC/Disassembler/AArch64/basic-a64-instructions.txt
@@ -3555,6 +3555,7 @@
 # CHECK: mrs      x9, {{mvfr2_el1|MVFR2_EL1}}
 # CHECK: mrs      x9, {{id_aa64pfr0_el1|ID_AA64PFR0_EL1}}
 # CHECK: mrs      x9, {{id_aa64pfr1_el1|ID_AA64PFR1_EL1}}
+# CHECK: mrs      x9, {{id_aa64pfr2_el1|ID_AA64PFR2_EL1}}
 # CHECK: mrs      x9, {{id_aa64dfr0_el1|ID_AA64DFR0_EL1}}
 # CHECK: mrs      x9, {{id_aa64dfr1_el1|ID_AA64DFR1_EL1}}
 # CHECK: mrs      x9, {{id_aa64afr0_el1|ID_AA64AFR0_EL1}}
@@ -3564,6 +3565,8 @@
 # CHECK: mrs      x9, {{id_aa64isar2_el1|ID_AA64ISAR2_EL1}}
 # CHECK: mrs      x9, {{id_aa64mmfr0_el1|ID_AA64MMFR0_EL1}}
 # CHECK: mrs      x9, {{id_aa64mmfr1_el1|ID_AA64MMFR1_EL1}}
+# CHECK: mrs      x9, {{id_aa64mmfr2_el1|ID_AA64MMFR2_EL1}}
+# CHECK: mrs      x9, {{id_aa64mmfr3_el1|ID_AA64MMFR3_EL1}}
 # CHECK: mrs      x9, {{sctlr_el1|SCTLR_EL1}}
 # CHECK: mrs      x9, {{sctlr_el2|SCTLR_EL2}}
 # CHECK: mrs      x9, {{sctlr_el3|SCTLR_EL3}}
@@ -3768,6 +3771,7 @@
 # CHECK: mrs      x9, {{sctlr2_el1|SCTLR2_EL1}}
 # CHECK: mrs      x9, {{sctlr2_el12|SCTLR2_EL12}}
 # CHECK: mrs      x9, {{sctlr2_el2|SCTLR2_EL2}}
+# CHECK: mrs      x9, {{sctlr2_el3|SCTLR2_EL3}}
 # CHECK: mrs      x9, {{tcr2_el1|TCR2_EL1}}
 # CHECK: mrs      x9, {{tcr2_el12|TCR2_EL12}}
 # CHECK: mrs      x9, {{tcr2_el2|TCR2_EL2}}
@@ -4050,6 +4054,7 @@
 0x6c 0x10 0x18 0xd5
 0x6c 0x10 0x1d 0xd5
 0x6c 0x10 0x1c 0xd5
+0x6c 0x10 0x1e 0xd5
 0x6c 0x20 0x18 0xd5
 0x6c 0x20 0x1d 0xd5
 0x6c 0x20 0x1c 0xd5
@@ -4169,6 +4174,7 @@
 0x49 0x3 0x38 0xd5
 0x9 0x4 0x38 0xd5
 0x29 0x4 0x38 0xd5
+0x49 0x4 0x38 0xd5
 0x9 0x5 0x38 0xd5
 0x29 0x5 0x38 0xd5
 0x89 0x5 0x38 0xd5
@@ -4178,6 +4184,8 @@
 0x49 0x06 0x38 0xd5
 0x9 0x7 0x38 0xd5
 0x29 0x7 0x38 0xd5
+0x49 0x7 0x38 0xd5
+0x69 0x7 0x38 0xd5
 0x9 0x10 0x38 0xd5
 0x9 0x10 0x3c 0xd5
 0x9 0x10 0x3e 0xd5
@@ -4383,6 +4391,7 @@
 0x69 0x10 0x38 0xd5
 0x69 0x10 0x3d 0xd5
 0x69 0x10 0x3c 0xd5
+0x69 0x10 0x3e 0xd5
 0x69 0x20 0x38 0xd5
 0x69 0x20 0x3d 0xd5
 0x69 0x20 0x3c 0xd5

diff  --git a/llvm/test/MC/Disassembler/AArch64/mattr-all.txt b/llvm/test/MC/Disassembler/AArch64/mattr-all.txt
index 02eeb89f31aba..1c7dfb361c6b8 100644
--- a/llvm/test/MC/Disassembler/AArch64/mattr-all.txt
+++ b/llvm/test/MC/Disassembler/AArch64/mattr-all.txt
@@ -40,6 +40,10 @@
 # CHECK: cfp rctx, x0
 [0x80,0x73,0x0b,0xd5]
 
+## predres2 (sysreg alias implementation is 
diff erent from predres)
+# CHECK: cosp rctx, x0
+[0xc0,0x73,0x0b,0xd5]
+
 ## sme
 # CHECK: addha za0.s, p0/m, p0/m, z0.s
 [0x00,0x00,0x90,0xc0]
@@ -55,4 +59,3 @@
 ## sme2
 # CHECK: add { z0.h, z1.h }, { z0.h, z1.h }, z0.h
 [0x00,0xa3,0x60,0xc1]
-

diff  --git a/llvm/test/MC/Disassembler/ARM/armv8.9a-clrbhb-arm.txt b/llvm/test/MC/Disassembler/ARM/armv8.9a-clrbhb-arm.txt
new file mode 100644
index 0000000000000..1d05daf0531ff
--- /dev/null
+++ b/llvm/test/MC/Disassembler/ARM/armv8.9a-clrbhb-arm.txt
@@ -0,0 +1,10 @@
+# CLRBHB is optional for all v8a/v9a, mandatory for 8.9a/9.4a.
+# Should disassemble to hint #22 if the feature is not present.
+# RUN: llvm-mc %s -disassemble -triple=armv8 2>&1 | FileCheck %s --check-prefix=HINT_22
+# RUN: llvm-mc %s -disassemble -triple=armv8 -mattr=+clrbhb | FileCheck %s --check-prefix=CLRBHB
+# RUN: llvm-mc %s -disassemble -triple=armv8.9a | FileCheck %s --check-prefix=CLRBHB
+# RUN: llvm-mc %s -disassemble -triple=armv8.9a -mattr=-clrbhb | FileCheck %s --check-prefix=HINT_22
+
+[0x16,0xf0,0x20,0xe3]
+# CLRBHB: clrbhb
+# HINT_22: hint #22

diff  --git a/llvm/test/MC/Disassembler/ARM/armv8.9a-clrbhb-thumb.txt b/llvm/test/MC/Disassembler/ARM/armv8.9a-clrbhb-thumb.txt
new file mode 100644
index 0000000000000..ddcde743eb7b7
--- /dev/null
+++ b/llvm/test/MC/Disassembler/ARM/armv8.9a-clrbhb-thumb.txt
@@ -0,0 +1,10 @@
+# CLRBHB is optional for all v8a/v9a, mandatory for 8.9a/9.4a.
+# Should disassemble to hint #22 if the feature is not present.
+# RUN: llvm-mc %s -disassemble -triple=thumbv8a | FileCheck %s --check-prefix=HINT_22
+# RUN: llvm-mc %s -disassemble -triple=thumbv8a -mattr=+clrbhb | FileCheck %s --check-prefix=CLRBHB
+# RUN: llvm-mc %s -disassemble -triple=thumbv8.9a | FileCheck %s --check-prefix=CLRBHB
+# RUN: llvm-mc %s -disassemble -triple=thumbv8.9a -mattr=-clrbhb | FileCheck %s --check-prefix=HINT_22
+
+[0xaf,0xf3,0x16,0x80]
+# CLRBHB: clrbhb
+# HINT_22: hint.w #22

diff  --git a/llvm/unittests/Support/TargetParserTest.cpp b/llvm/unittests/Support/TargetParserTest.cpp
index 5bcb131c13958..0161be254562e 100644
--- a/llvm/unittests/Support/TargetParserTest.cpp
+++ b/llvm/unittests/Support/TargetParserTest.cpp
@@ -1608,7 +1608,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
       AArch64::AEK_PERFMON, AArch64::AEK_SVE2p1,    AArch64::AEK_SME2p1,
       AArch64::AEK_B16B16,  AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC,
       AArch64::AEK_RCPC3,   AArch64::AEK_THE,       AArch64::AEK_D128,
-      AArch64::AEK_LSE128,
+      AArch64::AEK_LSE128,  AArch64::AEK_SPECRES2,
   };
 
   std::vector<StringRef> Features;
@@ -1679,6 +1679,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
   EXPECT_TRUE(llvm::is_contained(Features, "+the"));
   EXPECT_TRUE(llvm::is_contained(Features, "+d128"));
   EXPECT_TRUE(llvm::is_contained(Features, "+lse128"));
+  EXPECT_TRUE(llvm::is_contained(Features, "+specres2"));
 
   // Assuming we listed every extension above, this should produce the same
   // result. (note that AEK_NONE doesn't have a name so it won't be in the
@@ -1771,6 +1772,7 @@ TEST(TargetParserTest, AArch64ArchExtFeature) {
       {"hbc", "nohbc", "+hbc", "-hbc"},
       {"mops", "nomops", "+mops", "-mops"},
       {"pmuv3", "nopmuv3", "+perfmon", "-perfmon"},
+      {"predres2", "nopredres2", "+specres2", "-specres2"},
   };
 
   for (unsigned i = 0; i < std::size(ArchExt); i++) {


        


More information about the llvm-commits mailing list