[llvm] [AArch64][llvm] Implement HINT instructions as aliases (NFCI) (PR #206383)

Jonathan Thackray via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 28 18:01:24 PDT 2026


https://github.com/jthackray created https://github.com/llvm/llvm-project/pull/206383

Implement some `HINT`-space encodings as aliases of `HINT`
instead of dedicated instructions. Re-implement these isns:
  * bti
  * psb
  * stshh
  * stcph
  * shuh
  * tsb

Parse aliases explicitly in `AArch64AsmParser::parseHintAlias()` as they
have custom operands. Remove the (now unused) `PSB`, `BTI`, `CMH`, `PHint`
and `TSB` tablegen defs, operand classes, parser hooks and printer helpers.

Also, tighten the BTI check in the parser. The old bitmask matched non-BTI
`HINT` immediates such as `shuh/stcph`; use an exact BTI HINT encoding
check instead (`isHintSpaceBTI()`)

Add additional MC coverage for HINT aliases. The only intended functional
change is a diagnostic tweak for invalid `tsb csync` operands, which now
uses the common `HINT` alias error message codepath:
```
-//CHECK-ERROR: error: 'csync' operand expected
+//CHECK-ERROR: error: invalid operand for instruction
```

Apart from this, no other test code was modified; only new tests added.

>From 0f0ae39d34669efcdab03af6d987afc20fc5fcb4 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Mon, 29 Jun 2026 01:57:57 +0100
Subject: [PATCH] [AArch64][llvm] Implement HINT instructions as aliases (NFCI)

Implement some `HINT`-space encodings as aliases of `HINT`
instead of dedicated instructions. Re-implement these isns:
  * bti
  * psb
  * stshh
  * stcph
  * shuh
  * tsb

Parse aliases explicitly in `AArch64AsmParser::parseHintAlias()` as they
have custom operands. Remove the (now unused) `PSB`, `BTI`, `CMH`, `PHint`
and `TSB` tablegen defs, operand classes, parser hooks and printer helpers.

Also, tighten the BTI check in the parser. The old bitmask matched non-BTI
`HINT` immediates such as `shuh/stcph`; use an exact BTI HINT encoding
check instead (`isHintSpaceBTI()`)

Add additional MC coverage for HINT aliases. The only intended functional
change is a diagnostic tweak for invalid `tsb csync` operands, which now
uses the common `HINT` alias error message codepath:
```
-//CHECK-ERROR: error: 'csync' operand expected
+//CHECK-ERROR: error: invalid operand for instruction
```

Apart from this, no other test code was modified; only new tests added.
---
 llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp |   3 +-
 .../lib/Target/AArch64/AArch64InstrFormats.td | 103 ----
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |  45 +-
 .../Target/AArch64/AArch64SystemOperands.td   | 152 ------
 .../AArch64/AsmParser/AArch64AsmParser.cpp    | 465 +++++++-----------
 .../MCTargetDesc/AArch64InstPrinter.cpp       |  55 +--
 .../AArch64/MCTargetDesc/AArch64InstPrinter.h |  11 -
 .../Target/AArch64/Utils/AArch64BaseInfo.cpp  |  35 --
 .../Target/AArch64/Utils/AArch64BaseInfo.h    |  57 +--
 .../AArch64/armv8.2a-statistical-profiling.s  |   3 +
 llvm/test/MC/AArch64/armv8.4a-trace-error.s   |   6 +-
 llvm/test/MC/AArch64/armv8.4a-trace.s         |   2 +
 llvm/test/MC/AArch64/armv8.5a-bti.s           |   3 +
 .../AArch64/armv9.6a-pcdphint-diagnostics.s   |  19 +
 llvm/test/MC/AArch64/armv9.6a-pcdphint.s      |  10 +-
 llvm/test/MC/AArch64/armv9.7a-memsys.s        |  14 +-
 llvm/test/MC/AArch64/basic-a64-instructions.s |  14 +-
 llvm/test/MC/AArch64/ras-extension.s          |   3 +
 llvm/test/MC/AArch64/speculation-barriers.s   |   2 +
 19 files changed, 285 insertions(+), 717 deletions(-)
 create mode 100644 llvm/test/MC/AArch64/armv9.6a-pcdphint-diagnostics.s

diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 156c12c5ab8dd..6468f047532a5 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -3202,8 +3202,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
     if (CurrentPatchableFunctionEntrySym &&
         CurrentPatchableFunctionEntrySym == CurrentFnBegin &&
         MI == &MF->front().front()) {
-      int64_t Imm = MI->getOperand(0).getImm();
-      if ((Imm & 32) && (Imm & 6)) {
+      if (AArch64BTIHint::isHintSpaceBTI(MI->getOperand(0).getImm())) {
         MCInst Inst;
         MCInstLowering.Lower(MI, Inst);
         EmitToStreamer(*OutStreamer, Inst);
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index daf53c99988b0..c84f1c4a66ac3 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -1861,29 +1861,6 @@ let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
     let Inst{11-5} = imm;
   }
 
-def PHintInstOperand : AsmOperandClass {
-    let Name = "PHint";
-    let ParserMethod = "tryParsePHintInstOperand";
-}
-
-def phint_op : Operand<i32> {
-    let ParserMatchClass = PHintInstOperand;
-    let PrintMethod = "printPHintOp";
-    let OperandType = "OPERAND_IMMEDIATE";
-    let MIOperandInfo = (ops i32imm: $policy);
-    let DecoderMethod = "DecodeUImm<3>";
-}
-
-class STSHHI
-    : SimpleSystemI<0, (ins phint_op:$policy), "stshh", "\t$policy", []>,
-      Sched<[WriteHint]> {
-  bits<1> policy;
-  let Inst{20-12} = 0b000110010;
-  let Inst{11-8} = 0b0110;
-  let Inst{7-6} = 0b00;
-  let Inst{5} = policy;
-}
-
 // System instructions taking a single literal operand which encodes into
 // CRm. op2 differentiates the opcodes.
 def BarrierAsmOperand : AsmOperandClass {
@@ -1952,55 +1929,6 @@ def msr_sysreg_op : Operand<i32> {
   let OperandType = "OPERAND_IMMEDIATE";
 }
 
-def PSBHintOperand : AsmOperandClass {
-  let Name = "PSBHint";
-  let ParserMethod = "tryParsePSBHint";
-}
-def psbhint_op : Operand<i32> {
-  let ParserMatchClass = PSBHintOperand;
-  let PrintMethod = "printPSBHintOp";
-  let MCOperandPredicate = [{
-    // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
-    // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
-    if (!MCOp.isImm())
-      return false;
-    return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
-  }];
-  let OperandType = "OPERAND_IMMEDIATE";
-}
-
-def BTIHintOperand : AsmOperandClass {
-  let Name = "BTIHint";
-  let ParserMethod = "tryParseBTIHint";
-}
-def btihint_op : Operand<i32> {
-  let ParserMatchClass = BTIHintOperand;
-  let PrintMethod = "printBTIHintOp";
-  let MCOperandPredicate = [{
-    // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields.
-    if (!MCOp.isImm())
-      return false;
-    return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr;
-  }];
-  let OperandType = "OPERAND_IMMEDIATE";
-}
-
-def CMHPriorityHintOperand : AsmOperandClass {
-  let Name = "CMHPriorityHint";
-  let ParserMethod = "tryParseCMHPriorityHint";
-}
-
-def CMHPriorityHint_op : Operand<i32> {
-  let ParserMatchClass = CMHPriorityHintOperand;
-  let PrintMethod = "printCMHPriorityHintOp";
-  let MCOperandPredicate = [{
-    if (!MCOp.isImm())
-      return false;
-    return AArch64CMHPriorityHint::lookupCMHPriorityHintByEncoding(MCOp.getImm()) != nullptr;
-  }];
-  let OperandType = "OPERAND_IMMEDIATE";
-}
-
 def TIndexHintOperand : AsmOperandClass {
   let Name = "TIndexHint";
   let ParserMethod = "tryParseTIndexHint";
@@ -13600,37 +13528,6 @@ multiclass SIMDThreeSameVectorFP8MatrixMul<string asm, SDPatternOperator OpNode>
     }
 }
 
-//----------------------------------------------------------------------------
-// Contention Management Hints - FEAT_CMH
-//----------------------------------------------------------------------------
-
-class SHUHInst<string asm> : I<
-    (outs),
-    (ins CMHPriorityHint_op:$priority),
-    asm, "\t$priority", "", []>, Sched<[]> {
-  bits<1> priority;
-  let Inst{31-12} = 0b11010101000000110010;
-  let Inst{11-8}  = 0b0110;
-  let Inst{7-6}   = 0b01;
-  let Inst{5}     = priority;
-  let Inst{4-0}   = 0b11111;
-}
-
-multiclass SHUH<string asm> {
-  def NAME : SHUHInst<asm>;
-  def      : InstAlias<asm, (!cast<Instruction>(NAME) 0), 1>;
-}
-
-class STCPHInst<string asm> : I<
-    (outs),
-    (ins),
-    asm, "", "", []>, Sched<[]> {
-    let Inst{31-12} = 0b11010101000000110010;
-    let Inst{11-8}  = 0b0110;
-    let Inst{7-5}   = 0b100;
-    let Inst{4-0}   = 0b11111;
-}
-
 //---
 // Permission Overlays Extension 2 (FEAT_S1POE2)
 //---
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index fc7aea5a4d5f5..e3bc8da02f153 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -1552,13 +1552,13 @@ let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in {
 //===----------------------------------------------------------------------===//
 
 def HINT : HintI<"hint">;
-def : InstAlias<"yield",(HINT 0b001)>;
-def : InstAlias<"wfe",  (HINT 0b010)>;
-def : InstAlias<"wfi",  (HINT 0b011)>;
-def : InstAlias<"sev",  (HINT 0b100)>;
-def : InstAlias<"sevl", (HINT 0b101)>;
-def : InstAlias<"dgh",  (HINT 0b110)>;
-def : InstAlias<"esb",  (HINT 0b10000)>, Requires<[HasRAS]>;
+def : InstAlias<"yield",(HINT 1)>;
+def : InstAlias<"wfe",  (HINT 2)>;
+def : InstAlias<"wfi",  (HINT 3)>;
+def : InstAlias<"sev",  (HINT 4)>;
+def : InstAlias<"sevl", (HINT 5)>;
+def : InstAlias<"dgh",  (HINT 6)>;
+def : InstAlias<"esb",  (HINT 16)>, Requires<[HasRAS]>;
 def : InstAlias<"csdb", (HINT 20)>;
 
 let CRm = 0b0000, hasSideEffects = 0 in
@@ -1566,20 +1566,30 @@ def NOP : SystemNoOperands<0b000, "hint\t#0">;
 
 def : InstAlias<"nop", (NOP)>;
 
-def STSHH: STSHHI;
+def : InstAlias<"stshh keep", (HINT 48), 1>;
+def : InstAlias<"stshh strm", (HINT 49), 1>;
+def : InstAlias<"shuh", (HINT 50), 1>;
+def : InstAlias<"shuh ph", (HINT 51), 1>;
+def : InstAlias<"stcph", (HINT 52), 1>;
 
 // In order to be able to write readable assembly, LLVM should accept assembly
 // inputs that use Branch Target Identification mnemonics, even with BTI disabled.
 // However, in order to be compatible with other assemblers (e.g. GAS), LLVM
 // should not emit these mnemonics unless BTI is enabled.
 def : InstAlias<"bti",  (HINT 32), 0>;
-def : InstAlias<"bti $op", (HINT btihint_op:$op), 0>;
+def : InstAlias<"bti r",  (HINT 32), 0>;
+def : InstAlias<"bti c",  (HINT 34), 0>;
+def : InstAlias<"bti j",  (HINT 36), 0>;
+def : InstAlias<"bti jc", (HINT 38), 0>;
 def : InstAlias<"bti r", (HINT 32)>, Requires<[HasBTIE]>;
 def : InstAlias<"bti",  (HINT 32)>, Requires<[HasBTI]>;
-def : InstAlias<"bti $op", (HINT btihint_op:$op)>, Requires<[HasBTI]>;
+def : InstAlias<"bti c",  (HINT 34)>, Requires<[HasBTI]>;
+def : InstAlias<"bti j",  (HINT 36)>, Requires<[HasBTI]>;
+def : InstAlias<"bti jc", (HINT 38)>, Requires<[HasBTI]>;
 
 // v8.2a Statistical Profiling extension
-def : InstAlias<"psb $op",  (HINT psbhint_op:$op)>, Requires<[HasSPE]>;
+def : InstAlias<"psb csync", (HINT 17), 1>, Requires<[HasSPE]>;
+def : InstAlias<"tsb csync", (HINT 18), 1>, Requires<[HasTRACEV8_4]>;
 
 // As far as LLVM is concerned this writes to the system's exclusive monitors.
 let mayLoad = 1, mayStore = 1 in
@@ -1597,12 +1607,6 @@ def DSB   : CRmSystemI<barrier_op, 0b100, "dsb",
 def ISB   : CRmSystemI<barrier_op, 0b110, "isb",
                        [(int_aarch64_isb (i32 imm32_0_15:$CRm))]>;
 
-def TSB   : CRmSystemI<barrier_op, 0b010, "tsb", []> {
-  let CRm        = 0b0010;
-  let Inst{12}   = 0;
-  let Predicates = [HasTRACEV8_4];
-}
-
 def DSBnXS  : CRmSystemI<barrier_nxs_op, 0b001, "dsb"> {
   let CRm{1-0}   = 0b11;
   let Inst{9-8}  = 0b10;
@@ -11931,13 +11935,6 @@ let Predicates = [HasF16F32MM] in
 let Uses = [FPMR, FPCR] in
   defm FMMLA : SIMDThreeSameVectorFP8MatrixMul<"fmmla", int_aarch64_neon_fmmla>;
 
-//===----------------------------------------------------------------------===//
-// Contention Management Hints (FEAT_CMH)
-//===----------------------------------------------------------------------===//
-
-defm SHUH  : SHUH<"shuh">;       // Shared Update Hint instruction
-def STCPH  : STCPHInst<"stcph">; // Store Concurrent Priority Hint instruction
-
 //===----------------------------------------------------------------------===//
 // Permission Overlays Extension 2 (FEAT_S1POE2)
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index bcd1786a0e9ea..971b57fb490f7 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -337,39 +337,6 @@ def lookupISBByName : SearchIndex {
 
 def : ISB<"sy", 0xf>;
 
-//===----------------------------------------------------------------------===//
-// TSB (Trace synchronization barrier) instruction options.
-//===----------------------------------------------------------------------===//
-
-class TSB<string name, bits<4> encoding> {
-  string Name = name;
-  bits<4> Encoding;
-  let Encoding = encoding;
-
-  code Requires = [{ {AArch64::FeatureTRACEV8_4} }];
-}
-
-def TSBValues : GenericEnum {
-  let FilterClass = "TSB";
-  let NameField = "Name";
-  let ValueField = "Encoding";
-}
-
-def TSBsList : GenericTable {
-  let FilterClass = "TSB";
-  let Fields = ["Name", "Encoding", "Requires"];
-
-  let PrimaryKey = ["Encoding"];
-  let PrimaryKeyName = "lookupTSBByEncoding";
-}
-
-def lookupTSBByName : SearchIndex {
-  let Table = TSBsList;
-  let Key = ["Name"];
-}
-
-def : TSB<"csync", 2>;
-
 //===----------------------------------------------------------------------===//
 // PRFM (prefetch) instruction options.
 //===----------------------------------------------------------------------===//
@@ -749,87 +716,6 @@ def : SVCR<"SVCRZA",   0b010>;
 def : SVCR<"SVCRSMZA", 0b011>;
 }
 
-//===----------------------------------------------------------------------===//
-// PSB instruction options.
-//===----------------------------------------------------------------------===//
-
-class PSB<string name, bits<5> encoding> {
-  string Name = name;
-  bits<5> Encoding;
-  let Encoding = encoding;
-}
-
-def PSBValues : GenericEnum {
-  let FilterClass = "PSB";
-  let NameField = "Name";
-  let ValueField = "Encoding";
-}
-
-def PSBsList : GenericTable {
-  let FilterClass = "PSB";
-  let Fields = ["Name", "Encoding"];
-
-  let PrimaryKey = ["Encoding"];
-  let PrimaryKeyName = "lookupPSBByEncoding";
-}
-
-def lookupPSBByName : SearchIndex {
-  let Table = PSBsList;
-  let Key = ["Name"];
-}
-
-def : PSB<"csync", 0x11>;
-
-//===----------------------------------------------------------------------===//
-// BTI instruction options.
-//===----------------------------------------------------------------------===//
-
-class BTI<string name, bits<3> encoding> {
-  string Name = name;
-  bits<3> Encoding;
-  let Encoding = encoding;
-}
-
-def BTIValues : GenericEnum {
-  let FilterClass = "BTI";
-  let NameField = "Name";
-  let ValueField = "Encoding";
-}
-
-def BTIsList : GenericTable {
-  let FilterClass = "BTI";
-  let Fields = ["Name", "Encoding"];
-
-  let PrimaryKey = ["Encoding"];
-  let PrimaryKeyName = "lookupBTIByEncoding";
-}
-
-def lookupBTIByName : SearchIndex {
-  let Table = BTIsList;
-  let Key = ["Name"];
-}
-
-def : BTI<"r",  0b000>;
-def : BTI<"c",  0b010>;
-def : BTI<"j",  0b100>;
-def : BTI<"jc", 0b110>;
-
-//===----------------------------------------------------------------------===//
-// CMHPriority instruction options.
-//===----------------------------------------------------------------------===//
-
-class CMHPriorityHint<string name, bits<1> encoding> : SearchableTable {
-  let SearchableFields = ["Name", "Encoding"];
-  let EnumValueField = "Encoding";
-
-  string Name = name;
-  bits<1> Encoding;
-  let Encoding = encoding;
-}
-
-def : CMHPriorityHint<"ph", 0b1>;
-
-
 //===----------------------------------------------------------------------===//
 // TIndex instruction options.
 //===----------------------------------------------------------------------===//
@@ -2446,44 +2332,6 @@ def : RWSysReg<"ACTLRMASK_EL2",   0b11, 0b100, 0b0001, 0b0100, 0b001>;
 def : RWSysReg<"ACTLRMASK_EL12",  0b11, 0b101, 0b0001, 0b0100, 0b001>;
 def : RWSysReg<"ACTLRALIAS_EL1",  0b11, 0b000, 0b0001, 0b0100, 0b101>;
 
-//===----------------------------------------------------------------------===//
-// v9.6a PCDPHINT instruction options.
-//===----------------------------------------------------------------------===//
-
-class PHint<bits<2> op0, bits<3> op1, bits<4> crn, bits<4> crm,
-              bits<3> op2, string name> {
-  string Name = name;
-  bits<16> Encoding;
-  let Encoding{15-14} = op0;
-  let Encoding{13-11} = op1;
-  let Encoding{10-7} = crn;
-  let Encoding{6-3} = crm;
-  let Encoding{2-0} = op2;
-  code Requires = [{ {} }];
-}
-
-def PHintValues : GenericEnum {
-  let FilterClass = "PHint";
-  let NameField = "Name";
-  let ValueField = "Encoding";
-}
-
-def PHintsList : GenericTable {
-  let FilterClass = "PHint";
-  let Fields = ["Name", "Encoding", "Requires"];
-
-  let PrimaryKey = ["Encoding"];
-  let PrimaryKeyName = "lookupPHintByEncoding";
-}
-
-def lookupPHintByName : SearchIndex {
-  let Table = PHintsList;
-  let Key = ["Name"];
-}
-
-def KEEP : PHint<0b00, 0b000, 0b0000, 0b0000, 0b000, "keep">;
-def STRM : PHint<0b00, 0b000, 0b0000, 0b0000, 0b001, "strm">;
-
 // v9.6a Realm management extension enhancements
 def : RWSysReg<"GPCBW_EL3", 0b11, 0b110, 0b0010, 0b0001, 0b101>;
 
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index b3fda2fe849fa..d9107f031d52f 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -162,6 +162,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
   bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
   bool parseSyslAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
   bool parseSyspAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
+  bool parseHintAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
   void createSysAlias(uint16_t Encoding, OperandVector &Operands, SMLoc S);
   AArch64CC::CondCode parseCondCodeString(StringRef Cond,
                                           std::string &Suggestion);
@@ -267,9 +268,6 @@ class AArch64AsmParser : public MCTargetAsmParser {
   template <bool IsSVEPrefetch = false>
   ParseStatus tryParsePrefetch(OperandVector &Operands);
   ParseStatus tryParseRPRFMOperand(OperandVector &Operands);
-  ParseStatus tryParsePSBHint(OperandVector &Operands);
-  ParseStatus tryParseBTIHint(OperandVector &Operands);
-  ParseStatus tryParseCMHPriorityHint(OperandVector &Operands);
   ParseStatus tryParseTIndexHint(OperandVector &Operands);
   ParseStatus tryParseAdrpLabel(OperandVector &Operands);
   ParseStatus tryParseAdrLabel(OperandVector &Operands);
@@ -300,7 +298,24 @@ class AArch64AsmParser : public MCTargetAsmParser {
   ParseStatus tryParseGPR64x8(OperandVector &Operands);
   ParseStatus tryParseImmRange(OperandVector &Operands);
   template <int> ParseStatus tryParseAdjImm0_63(OperandVector &Operands);
-  ParseStatus tryParsePHintInstOperand(OperandVector &Operands);
+  template <typename LookupFn, typename CreateFn>
+  ParseStatus tryParseNamedHintOperand(OperandVector &Operands,
+                                       LookupFn LookupByName,
+                                       CreateFn CreateOperand) {
+    SMLoc S = getLoc();
+    const AsmToken &Tok = getTok();
+    if (Tok.isNot(AsmToken::Identifier))
+      return TokError("invalid operand for instruction");
+
+    auto Entry = LookupByName(Tok.getString());
+    if (!Entry)
+      return TokError("invalid operand for instruction");
+
+    Operands.push_back(
+        CreateOperand(Entry->Encoding, Tok.getString(), S, getContext()));
+    Lex(); // Eat identifier token.
+    return ParseStatus::Success;
+  }
 
 public:
   enum AArch64MatchResultTy {
@@ -372,10 +387,6 @@ class AArch64Operand : public MCParsedAsmOperand {
     k_ShiftExtend,
     k_FPImm,
     k_Barrier,
-    k_PSBHint,
-    k_PHint,
-    k_BTIHint,
-    k_CMHPriorityHint,
     k_TIndexHint,
   } Kind;
 
@@ -491,31 +502,12 @@ class AArch64Operand : public MCParsedAsmOperand {
     unsigned Val;
   };
 
-  struct PSBHintOp {
-    const char *Data;
-    unsigned Length;
-    unsigned Val;
-  };
-  struct PHintOp {
-    const char *Data;
-    unsigned Length;
-    unsigned Val;
-  };
-  struct BTIHintOp {
-    const char *Data;
-    unsigned Length;
-    unsigned Val;
-  };
-  struct CMHPriorityHintOp {
-    const char *Data;
-    unsigned Length;
-    unsigned Val;
-  };
-  struct TIndexHintOp {
+  struct NamedHintOp {
     const char *Data;
     unsigned Length;
     unsigned Val;
   };
+  using TIndexHintOp = NamedHintOp;
 
   struct SVCROp {
     const char *Data;
@@ -524,28 +516,24 @@ class AArch64Operand : public MCParsedAsmOperand {
   };
 
   union {
-    struct TokOp Tok;
-    struct RegOp Reg;
-    struct MatrixRegOp MatrixReg;
-    struct MatrixTileListOp MatrixTileList;
-    struct VectorListOp VectorList;
-    struct VectorIndexOp VectorIndex;
-    struct ImmOp Imm;
-    struct ShiftedImmOp ShiftedImm;
-    struct ImmRangeOp ImmRange;
-    struct CondCodeOp CondCode;
-    struct FPImmOp FPImm;
-    struct BarrierOp Barrier;
-    struct SysRegOp SysReg;
-    struct SysCRImmOp SysCRImm;
-    struct PrefetchOp Prefetch;
-    struct PSBHintOp PSBHint;
-    struct PHintOp PHint;
-    struct BTIHintOp BTIHint;
-    struct CMHPriorityHintOp CMHPriorityHint;
-    struct TIndexHintOp TIndexHint;
-    struct ShiftExtendOp ShiftExtend;
-    struct SVCROp SVCR;
+    TokOp Tok;
+    RegOp Reg;
+    MatrixRegOp MatrixReg;
+    MatrixTileListOp MatrixTileList;
+    VectorListOp VectorList;
+    VectorIndexOp VectorIndex;
+    ImmOp Imm;
+    ShiftedImmOp ShiftedImm;
+    ImmRangeOp ImmRange;
+    CondCodeOp CondCode;
+    FPImmOp FPImm;
+    BarrierOp Barrier;
+    SysRegOp SysReg;
+    SysCRImmOp SysCRImm;
+    PrefetchOp Prefetch;
+    TIndexHintOp TIndexHint;
+    ShiftExtendOp ShiftExtend;
+    SVCROp SVCR;
   };
 
   // Keep the MCContext around as the MCExprs may need manipulated during
@@ -605,18 +593,6 @@ class AArch64Operand : public MCParsedAsmOperand {
     case k_Prefetch:
       Prefetch = o.Prefetch;
       break;
-    case k_PSBHint:
-      PSBHint = o.PSBHint;
-      break;
-    case k_PHint:
-      PHint = o.PHint;
-      break;
-    case k_BTIHint:
-      BTIHint = o.BTIHint;
-      break;
-    case k_CMHPriorityHint:
-      CMHPriorityHint = o.CMHPriorityHint;
-      break;
     case k_TIndexHint:
       TIndexHint = o.TIndexHint;
       break;
@@ -764,46 +740,6 @@ class AArch64Operand : public MCParsedAsmOperand {
     return Prefetch.Val;
   }
 
-  unsigned getPSBHint() const {
-    assert(Kind == k_PSBHint && "Invalid access!");
-    return PSBHint.Val;
-  }
-
-  unsigned getPHint() const {
-    assert(Kind == k_PHint && "Invalid access!");
-    return PHint.Val;
-  }
-
-  StringRef getPSBHintName() const {
-    assert(Kind == k_PSBHint && "Invalid access!");
-    return StringRef(PSBHint.Data, PSBHint.Length);
-  }
-
-  StringRef getPHintName() const {
-    assert(Kind == k_PHint && "Invalid access!");
-    return StringRef(PHint.Data, PHint.Length);
-  }
-
-  unsigned getBTIHint() const {
-    assert(Kind == k_BTIHint && "Invalid access!");
-    return BTIHint.Val;
-  }
-
-  StringRef getBTIHintName() const {
-    assert(Kind == k_BTIHint && "Invalid access!");
-    return StringRef(BTIHint.Data, BTIHint.Length);
-  }
-
-  unsigned getCMHPriorityHint() const {
-    assert(Kind == k_CMHPriorityHint && "Invalid access!");
-    return CMHPriorityHint.Val;
-  }
-
-  StringRef getCMHPriorityHintName() const {
-    assert(Kind == k_CMHPriorityHint && "Invalid access!");
-    return StringRef(CMHPriorityHint.Data, CMHPriorityHint.Length);
-  }
-
   unsigned getTIndexHint() const {
     assert(Kind == k_TIndexHint && "Invalid access!");
     return TIndexHint.Val;
@@ -1553,10 +1489,6 @@ class AArch64Operand : public MCParsedAsmOperand {
   }
   bool isSysCR() const { return Kind == k_SysCR; }
   bool isPrefetch() const { return Kind == k_Prefetch; }
-  bool isPSBHint() const { return Kind == k_PSBHint; }
-  bool isPHint() const { return Kind == k_PHint; }
-  bool isBTIHint() const { return Kind == k_BTIHint; }
-  bool isCMHPriorityHint() const { return Kind == k_CMHPriorityHint; }
   bool isTIndexHint() const { return Kind == k_TIndexHint; }
   bool isShiftExtend() const { return Kind == k_ShiftExtend; }
   bool isShifter() const {
@@ -2229,26 +2161,6 @@ class AArch64Operand : public MCParsedAsmOperand {
     Inst.addOperand(MCOperand::createImm(getPrefetch()));
   }
 
-  void addPSBHintOperands(MCInst &Inst, unsigned N) const {
-    assert(N == 1 && "Invalid number of operands!");
-    Inst.addOperand(MCOperand::createImm(getPSBHint()));
-  }
-
-  void addPHintOperands(MCInst &Inst, unsigned N) const {
-    assert(N == 1 && "Invalid number of operands!");
-    Inst.addOperand(MCOperand::createImm(getPHint()));
-  }
-
-  void addBTIHintOperands(MCInst &Inst, unsigned N) const {
-    assert(N == 1 && "Invalid number of operands!");
-    Inst.addOperand(MCOperand::createImm(getBTIHint()));
-  }
-
-  void addCMHPriorityHintOperands(MCInst &Inst, unsigned N) const {
-    assert(N == 1 && "Invalid number of operands!");
-    Inst.addOperand(MCOperand::createImm(getCMHPriorityHint()));
-  }
-
   void addTIndexHintOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     Inst.addOperand(MCOperand::createImm(getTIndexHint()));
@@ -2542,12 +2454,20 @@ class AArch64Operand : public MCParsedAsmOperand {
     return Op;
   }
 
+  struct IdentityHintEncoding {
+    unsigned operator()(unsigned Val) const { return Val; }
+  };
+
+  template <KindTy Kind, NamedHintOp AArch64Operand::*Member,
+            typename Encode = IdentityHintEncoding>
   static std::unique_ptr<AArch64Operand>
-  CreatePHintInst(unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
-    auto Op = std::make_unique<AArch64Operand>(k_PHint, Ctx);
-    Op->PHint.Val = Val;
-    Op->PHint.Data = Str.data();
-    Op->PHint.Length = Str.size();
+  CreateNamedHintOperand(unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx,
+                         Encode EncodeVal = {}) {
+    auto Op = std::make_unique<AArch64Operand>(Kind, Ctx);
+    auto &Hint = Op.get()->*Member;
+    Hint.Val = EncodeVal(Val);
+    Hint.Data = Str.data();
+    Hint.Length = Str.size();
     Op->StartLoc = S;
     Op->EndLoc = S;
     return Op;
@@ -2568,45 +2488,8 @@ class AArch64Operand : public MCParsedAsmOperand {
                                                         MCContext &Ctx) {
     auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
     Op->Prefetch.Val = Val;
-    Op->Barrier.Data = Str.data();
-    Op->Barrier.Length = Str.size();
-    Op->StartLoc = S;
-    Op->EndLoc = S;
-    return Op;
-  }
-
-  static std::unique_ptr<AArch64Operand> CreatePSBHint(unsigned Val,
-                                                       StringRef Str,
-                                                       SMLoc S,
-                                                       MCContext &Ctx) {
-    auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx);
-    Op->PSBHint.Val = Val;
-    Op->PSBHint.Data = Str.data();
-    Op->PSBHint.Length = Str.size();
-    Op->StartLoc = S;
-    Op->EndLoc = S;
-    return Op;
-  }
-
-  static std::unique_ptr<AArch64Operand> CreateBTIHint(unsigned Val,
-                                                       StringRef Str,
-                                                       SMLoc S,
-                                                       MCContext &Ctx) {
-    auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx);
-    Op->BTIHint.Val = Val | 32;
-    Op->BTIHint.Data = Str.data();
-    Op->BTIHint.Length = Str.size();
-    Op->StartLoc = S;
-    Op->EndLoc = S;
-    return Op;
-  }
-
-  static std::unique_ptr<AArch64Operand>
-  CreateCMHPriorityHint(unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
-    auto Op = std::make_unique<AArch64Operand>(k_CMHPriorityHint, Ctx);
-    Op->CMHPriorityHint.Val = Val;
-    Op->CMHPriorityHint.Data = Str.data();
-    Op->CMHPriorityHint.Length = Str.size();
+    Op->Prefetch.Data = Str.data();
+    Op->Prefetch.Length = Str.size();
     Op->StartLoc = S;
     Op->EndLoc = S;
     return Op;
@@ -2614,13 +2497,8 @@ class AArch64Operand : public MCParsedAsmOperand {
 
   static std::unique_ptr<AArch64Operand>
   CreateTIndexHint(unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
-    auto Op = std::make_unique<AArch64Operand>(k_TIndexHint, Ctx);
-    Op->TIndexHint.Val = Val;
-    Op->TIndexHint.Data = Str.data();
-    Op->TIndexHint.Length = Str.size();
-    Op->StartLoc = S;
-    Op->EndLoc = S;
-    return Op;
+    return CreateNamedHintOperand<k_TIndexHint, &AArch64Operand::TIndexHint>(
+        Val, Str, S, Ctx);
   }
 
   static std::unique_ptr<AArch64Operand>
@@ -2724,18 +2602,6 @@ void AArch64Operand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {
       OS << "<prfop invalid #" << getPrefetch() << ">";
     break;
   }
-  case k_PSBHint:
-    OS << getPSBHintName();
-    break;
-  case k_PHint:
-    OS << getPHintName();
-    break;
-  case k_BTIHint:
-    OS << getBTIHintName();
-    break;
-  case k_CMHPriorityHint:
-    OS << getCMHPriorityHintName();
-    break;
   case k_TIndexHint:
     OS << getTIndexHintName();
     break;
@@ -3297,23 +3163,6 @@ ParseStatus AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
   return ParseStatus::Success;
 }
 
-/// tryParsePSBHint - Try to parse a PSB operand, mapped to Hint command
-ParseStatus AArch64AsmParser::tryParsePSBHint(OperandVector &Operands) {
-  SMLoc S = getLoc();
-  const AsmToken &Tok = getTok();
-  if (Tok.isNot(AsmToken::Identifier))
-    return TokError("invalid operand for instruction");
-
-  auto PSB = AArch64PSBHint::lookupPSBByName(Tok.getString());
-  if (!PSB)
-    return TokError("invalid operand for instruction");
-
-  Operands.push_back(AArch64Operand::CreatePSBHint(
-      PSB->Encoding, Tok.getString(), S, getContext()));
-  Lex(); // Eat identifier token.
-  return ParseStatus::Success;
-}
-
 ParseStatus AArch64AsmParser::tryParseSyspXzrPair(OperandVector &Operands) {
   SMLoc StartLoc = getLoc();
 
@@ -3347,56 +3196,11 @@ ParseStatus AArch64AsmParser::tryParseSyspXzrPair(OperandVector &Operands) {
   return ParseStatus::Success;
 }
 
-/// tryParseBTIHint - Try to parse a BTI operand, mapped to Hint command
-ParseStatus AArch64AsmParser::tryParseBTIHint(OperandVector &Operands) {
-  SMLoc S = getLoc();
-  const AsmToken &Tok = getTok();
-  if (Tok.isNot(AsmToken::Identifier))
-    return TokError("invalid operand for instruction");
-
-  auto BTI = AArch64BTIHint::lookupBTIByName(Tok.getString());
-  if (!BTI)
-    return TokError("invalid operand for instruction");
-
-  Operands.push_back(AArch64Operand::CreateBTIHint(
-      BTI->Encoding, Tok.getString(), S, getContext()));
-  Lex(); // Eat identifier token.
-  return ParseStatus::Success;
-}
-
-/// tryParseCMHPriorityHint - Try to parse a CMHPriority operand
-ParseStatus AArch64AsmParser::tryParseCMHPriorityHint(OperandVector &Operands) {
-  SMLoc S = getLoc();
-  const AsmToken &Tok = getTok();
-  if (Tok.isNot(AsmToken::Identifier))
-    return TokError("invalid operand for instruction");
-
-  auto CMHPriority =
-      AArch64CMHPriorityHint::lookupCMHPriorityHintByName(Tok.getString());
-  if (!CMHPriority)
-    return TokError("invalid operand for instruction");
-
-  Operands.push_back(AArch64Operand::CreateCMHPriorityHint(
-      CMHPriority->Encoding, Tok.getString(), S, getContext()));
-  Lex(); // Eat identifier token.
-  return ParseStatus::Success;
-}
-
 /// tryParseTIndexHint - Try to parse a TIndex operand
 ParseStatus AArch64AsmParser::tryParseTIndexHint(OperandVector &Operands) {
-  SMLoc S = getLoc();
-  const AsmToken &Tok = getTok();
-  if (Tok.isNot(AsmToken::Identifier))
-    return TokError("invalid operand for instruction");
-
-  auto TIndex = AArch64TIndexHint::lookupTIndexByName(Tok.getString());
-  if (!TIndex)
-    return TokError("invalid operand for instruction");
-
-  Operands.push_back(AArch64Operand::CreateTIndexHint(
-      TIndex->Encoding, Tok.getString(), S, getContext()));
-  Lex(); // Eat identifier token.
-  return ParseStatus::Success;
+  return tryParseNamedHintOperand(Operands,
+                                  AArch64TIndexHint::lookupTIndexByName,
+                                  AArch64Operand::CreateTIndexHint);
 }
 
 /// tryParseAdrpLabel - Parse and validate a source label for the ADRP
@@ -4291,12 +4095,127 @@ bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
   return false;
 }
 
+/// parseHintAlias - Some named HINT encodings have aliases. Parse them
+/// specially so that we create a HINT MCInst.
+bool AArch64AsmParser::parseHintAlias(StringRef Name, SMLoc NameLoc,
+                                      OperandVector &Operands) {
+  if (Name.contains('.'))
+    return TokError("invalid operand");
+
+  enum class HintAliasKind { Invalid, BTI, PSB, SHUH, STCPH, STSHH, TSB };
+  HintAliasKind Kind = StringSwitch<HintAliasKind>(Name)
+                           .Case("bti", HintAliasKind::BTI)
+                           .Case("psb", HintAliasKind::PSB)
+                           .Case("shuh", HintAliasKind::SHUH)
+                           .Case("stcph", HintAliasKind::STCPH)
+                           .Case("stshh", HintAliasKind::STSHH)
+                           .Case("tsb", HintAliasKind::TSB)
+                           .Default(HintAliasKind::Invalid);
+  if (Kind == HintAliasKind::Invalid)
+    llvm_unreachable("unknown HINT alias");
+
+  Mnemonic = Name;
+  Operands.push_back(
+      AArch64Operand::CreateToken("hint", NameLoc, getContext()));
+
+  const AsmToken &Tok = getTok();
+  SMLoc S = Tok.getLoc();
+  unsigned Imm;
+
+  switch (Kind) {
+  case HintAliasKind::Invalid:
+    llvm_unreachable("unknown HINT alias");
+  case HintAliasKind::STCPH:
+    Imm = 52;
+    break;
+  case HintAliasKind::BTI:
+    if (Tok.is(AsmToken::EndOfStatement)) {
+      Imm = 32;
+    } else if (Tok.is(AsmToken::Identifier)) {
+      StringRef Op = Tok.getString();
+      if (Op == "r")
+        Imm = 32;
+      else if (Op == "c")
+        Imm = 34;
+      else if (Op == "j")
+        Imm = 36;
+      else if (Op == "jc")
+        Imm = 38;
+      else
+        return TokError("invalid operand for instruction");
+      Lex(); // Eat operand.
+    } else {
+      return TokError("invalid operand for instruction");
+    }
+    break;
+  case HintAliasKind::SHUH:
+    if (Tok.is(AsmToken::EndOfStatement)) {
+      Imm = 50;
+    } else if (Tok.is(AsmToken::Identifier) && Tok.getString() == "ph") {
+      Imm = 51;
+      Lex(); // Eat operand.
+    } else {
+      return TokError("invalid operand for instruction");
+    }
+    break;
+  case HintAliasKind::PSB:
+  case HintAliasKind::STSHH:
+  case HintAliasKind::TSB: {
+    if ((Kind == HintAliasKind::PSB || Kind == HintAliasKind::TSB) &&
+        Tok.is(AsmToken::EndOfStatement))
+      return Error(NameLoc, "too few operands for instruction");
+
+    if (Tok.isNot(AsmToken::Identifier)) {
+      return TokError("invalid operand for instruction");
+    }
+
+    StringRef Op = Tok.getString();
+    switch (Kind) {
+    case HintAliasKind::STSHH:
+      if (Op == "keep")
+        Imm = 48;
+      else if (Op == "strm")
+        Imm = 49;
+      else
+        return TokError("invalid operand for instruction");
+      break;
+    case HintAliasKind::PSB:
+      if (Op != "csync")
+        return TokError("invalid operand for instruction");
+      if (!getSTI().hasFeature(AArch64::FeatureAll) &&
+          !getSTI().hasFeature(AArch64::FeatureSPE))
+        return TokError("instruction requires: spe");
+      Imm = 17;
+      break;
+    case HintAliasKind::TSB:
+      if (Op != "csync")
+        return TokError("invalid operand for instruction");
+      if (!getSTI().hasFeature(AArch64::FeatureAll) &&
+          !getSTI().hasFeature(AArch64::FeatureTRACEV8_4))
+        return TokError("instruction requires: tracev8.4");
+      Imm = 18;
+      break;
+    default:
+      llvm_unreachable("unexpected HINT alias kind");
+    }
+    Lex(); // Eat operand.
+    break;
+  }
+  }
+
+  Operands.push_back(AArch64Operand::CreateImm(
+      MCConstantExpr::create(Imm, getContext()), S, getLoc(), getContext()));
+
+  if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
+    return true;
+
+  return false;
+}
+
 ParseStatus AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
   MCAsmParser &Parser = getParser();
   const AsmToken &Tok = getTok();
 
-  if (Mnemonic == "tsb" && Tok.isNot(AsmToken::Identifier))
-    return TokError("'csync' operand expected");
   if (parseOptionalToken(AsmToken::Hash) || Tok.is(AsmToken::Integer)) {
     // Immediate operand.
     const MCExpr *ImmVal;
@@ -4328,15 +4247,11 @@ ParseStatus AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
     return TokError("invalid operand for instruction");
 
   StringRef Operand = Tok.getString();
-  auto TSB = AArch64TSB::lookupTSBByName(Operand);
   auto DB = AArch64DB::lookupDBByName(Operand);
   // The only valid named option for ISB is 'sy'
   if (Mnemonic == "isb" && (!DB || DB->Encoding != AArch64DB::sy))
     return TokError("'sy' or #imm operand expected");
-  // The only valid named option for TSB is 'csync'
-  if (Mnemonic == "tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync))
-    return TokError("'csync' operand expected");
-  if (!DB && !TSB) {
+  if (!DB) {
     if (Mnemonic == "dsb") {
       // This case is a no match here, but it might be matched by the nXS
       // variant.
@@ -4346,8 +4261,8 @@ ParseStatus AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
   }
 
   Operands.push_back(AArch64Operand::CreateBarrier(
-      DB ? DB->Encoding : TSB->Encoding, Tok.getString(), getLoc(),
-      getContext(), false /*hasnXSModifier*/));
+      DB->Encoding, Tok.getString(), getLoc(), getContext(),
+      false /*hasnXSModifier*/));
   Lex(); // Consume the option
 
   return ParseStatus::Success;
@@ -4434,23 +4349,6 @@ ParseStatus AArch64AsmParser::tryParseSysReg(OperandVector &Operands) {
   return ParseStatus::Success;
 }
 
-ParseStatus
-AArch64AsmParser::tryParsePHintInstOperand(OperandVector &Operands) {
-  SMLoc S = getLoc();
-  const AsmToken &Tok = getTok();
-  if (Tok.isNot(AsmToken::Identifier))
-    return TokError("invalid operand for instruction");
-
-  auto PH = AArch64PHint::lookupPHintByName(Tok.getString());
-  if (!PH)
-    return TokError("invalid operand for instruction");
-
-  Operands.push_back(AArch64Operand::CreatePHintInst(
-      PH->Encoding, Tok.getString(), S, getContext()));
-  Lex(); // Eat identifier token.
-  return ParseStatus::Success;
-}
-
 /// tryParseNeonVectorRegister - Parse a vector register operand.
 bool AArch64AsmParser::tryParseNeonVectorRegister(OperandVector &Operands) {
   if (getTok().isNot(AsmToken::Identifier))
@@ -5522,6 +5420,11 @@ bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info,
   if (Head == "tlbip")
     return parseSyspAlias(Head, NameLoc, Operands);
 
+  // These mnemonics are aliases for HINT instructions.
+  if (Head == "bti" || Head == "stshh" || Head == "psb" || Head == "tsb" ||
+      Head == "shuh" || Head == "stcph")
+    return parseHintAlias(Name, NameLoc, Operands);
+
   Operands.push_back(AArch64Operand::CreateToken(Head, NameLoc, getContext()));
   Mnemonic = Head;
 
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
index 2783b559c8f5c..b6cb621685ba0 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
@@ -1571,50 +1571,15 @@ void AArch64InstPrinter::printPrefetchOp(const MCInst *MI, unsigned OpNum,
   markup(O, Markup::Immediate) << '#' << formatImm(prfop);
 }
 
-void AArch64InstPrinter::printPSBHintOp(const MCInst *MI, unsigned OpNum,
-                                        const MCSubtargetInfo &STI,
-                                        raw_ostream &O) {
-  unsigned psbhintop = MI->getOperand(OpNum).getImm();
-  auto PSB = AArch64PSBHint::lookupPSBByEncoding(psbhintop);
-  if (PSB)
-    O << AArch64PSBHint::getPSBStr(PSB->Name);
-  else
-    markup(O, Markup::Immediate) << '#' << formatImm(psbhintop);
-}
-
-void AArch64InstPrinter::printBTIHintOp(const MCInst *MI, unsigned OpNum,
-                                        const MCSubtargetInfo &STI,
-                                        raw_ostream &O) {
-  unsigned btihintop = MI->getOperand(OpNum).getImm() ^ 32;
-  auto BTI = AArch64BTIHint::lookupBTIByEncoding(btihintop);
-  if (BTI)
-    O << AArch64BTIHint::getBTIStr(BTI->Name);
-  else
-    markup(O, Markup::Immediate) << '#' << formatImm(btihintop);
-}
-
-void AArch64InstPrinter::printCMHPriorityHintOp(const MCInst *MI,
-                                                unsigned OpNum,
-                                                const MCSubtargetInfo &STI,
-                                                raw_ostream &O) {
-  unsigned priorityhint_op = MI->getOperand(OpNum).getImm();
-  auto PHint =
-      AArch64CMHPriorityHint::lookupCMHPriorityHintByEncoding(priorityhint_op);
-  if (PHint)
-    O << AArch64CMHPriorityHint::getCMHPriorityHintStr(PHint->Name);
-  else
-    markup(O, Markup::Immediate) << '#' << formatImm(priorityhint_op);
-}
-
 void AArch64InstPrinter::printTIndexHintOp(const MCInst *MI, unsigned OpNum,
                                            const MCSubtargetInfo &STI,
                                            raw_ostream &O) {
-  unsigned tindexhintop = MI->getOperand(OpNum).getImm();
-  auto TIndex = AArch64TIndexHint::lookupTIndexByEncoding(tindexhintop);
+  unsigned TIndexHintOp = MI->getOperand(OpNum).getImm();
+  auto TIndex = AArch64TIndexHint::lookupTIndexByEncoding(TIndexHintOp);
   if (TIndex)
     O << AArch64TIndexHint::getTIndexStr(TIndex->Name);
   else
-    markup(O, Markup::Immediate) << '#' << formatImm(tindexhintop);
+    markup(O, Markup::Immediate) << '#' << formatImm(TIndexHintOp);
 }
 
 void AArch64InstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
@@ -1966,9 +1931,6 @@ void AArch64InstPrinter::printBarrierOption(const MCInst *MI, unsigned OpNo,
   if (Opcode == AArch64::ISB) {
     auto ISB = AArch64ISB::lookupISBByEncoding(Val);
     Name = ISB ? AArch64ISB::getISBStr(ISB->Name) : "";
-  } else if (Opcode == AArch64::TSB) {
-    auto TSB = AArch64TSB::lookupTSBByEncoding(Val);
-    Name = TSB ? AArch64TSB::getTSBStr(TSB->Name) : "";
   } else {
     auto DB = AArch64DB::lookupDBByEncoding(Val);
     Name = DB ? AArch64DB::getDBStr(DB->Name) : "";
@@ -2261,14 +2223,3 @@ void AArch64InstPrinter::printSyspXzrPair(const MCInst *MI, unsigned OpNum,
          "MC representation of SyspXzrPair should be XZR");
   O << getRegisterName(Reg) << ", " << getRegisterName(Reg);
 }
-
-void AArch64InstPrinter::printPHintOp(const MCInst *MI, unsigned OpNum,
-                                      const MCSubtargetInfo &STI,
-                                      raw_ostream &O) {
-  unsigned Op = MI->getOperand(OpNum).getImm();
-  auto PH = AArch64PHint::lookupPHintByEncoding(Op);
-  if (PH)
-    O << AArch64PHint::getPHintStr(PH->Name);
-  else
-    markup(O, Markup::Immediate) << '#' << formatImm(Op);
-}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
index 3f7a3b4b0667b..bea14c14ae1f6 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
@@ -147,15 +147,6 @@ class AArch64InstPrinter : public MCInstPrinter {
   void printRPRFMOperand(const MCInst *MI, unsigned OpNum,
                          const MCSubtargetInfo &STI, raw_ostream &O);
 
-  void printPSBHintOp(const MCInst *MI, unsigned OpNum,
-                      const MCSubtargetInfo &STI, raw_ostream &O);
-
-  void printBTIHintOp(const MCInst *MI, unsigned OpNum,
-                      const MCSubtargetInfo &STI, raw_ostream &O);
-
-  void printCMHPriorityHintOp(const MCInst *MI, unsigned OpNum,
-                              const MCSubtargetInfo &STI, raw_ostream &O);
-
   void printTIndexHintOp(const MCInst *MI, unsigned OpNum,
                          const MCSubtargetInfo &STI, raw_ostream &O);
 
@@ -245,8 +236,6 @@ class AArch64InstPrinter : public MCInstPrinter {
   template <unsigned ImmIs0, unsigned ImmIs1>
   void printExactFPImm(const MCInst *MI, unsigned OpNum,
                        const MCSubtargetInfo &STI, raw_ostream &O);
-  void printPHintOp(const MCInst *MI, unsigned OpNum,
-                    const MCSubtargetInfo &STI, raw_ostream &O);
 };
 
 class AArch64AppleInstPrinter : public AArch64InstPrinter {
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
index c2fccc91cfec9..9d94703ef2c8f 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
@@ -59,13 +59,6 @@ namespace llvm {
   }
 }
 
-namespace llvm {
-  namespace AArch64TSB {
-#define GET_TSBsList_IMPL
-#include "AArch64GenSystemOperands.inc"
-  }
-}
-
 namespace llvm {
   namespace AArch64PRFM {
 #define GET_PRFMsList_IMPL
@@ -117,34 +110,6 @@ namespace llvm {
   }
 }
 
-namespace llvm {
-  namespace AArch64PSBHint {
-#define GET_PSBsList_IMPL
-#include "AArch64GenSystemOperands.inc"
-  }
-}
-
-namespace llvm {
-namespace AArch64PHint {
-#define GET_PHintsList_IMPL
-#include "AArch64GenSystemOperands.inc"
-} // namespace AArch64PHint
-} // namespace llvm
-
-namespace llvm {
-  namespace AArch64BTIHint {
-#define GET_BTIsList_IMPL
-#include "AArch64GenSystemOperands.inc"
-  }
-}
-
-namespace llvm {
-namespace AArch64CMHPriorityHint {
-#define GET_CMHPRIORITYHINT_IMPL
-#include "AArch64GenSystemOperands.inc"
-} // namespace AArch64CMHPriorityHint
-} // namespace llvm
-
 namespace llvm {
 namespace AArch64TIndexHint {
 #define GET_TINDEX_IMPL
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index bd7faa42449b7..562ed6a901e4a 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -546,15 +546,6 @@ namespace  AArch64ISB {
 #include "AArch64GenSystemOperands.inc"
 }
 
-namespace  AArch64TSB {
-  struct TSB : SysAlias {
-    using SysAlias::SysAlias;
-  };
-#define GET_TSBValues_DECL
-#define GET_TSBsList_DECL
-#include "AArch64GenSystemOperands.inc"
-}
-
 namespace AArch64PRFM {
   struct PRFM : SysAlias {
     using SysAlias::SysAlias;
@@ -705,51 +696,15 @@ namespace AArch64PState {
 #include "AArch64GenSystemOperands.inc"
 }
 
-namespace AArch64PSBHint {
-  struct PSB : SysAlias {
-    using SysAlias::SysAlias;
-  };
-#define GET_PSBValues_DECL
-#define GET_PSBsList_DECL
-#include "AArch64GenSystemOperands.inc"
-}
-
-namespace AArch64PHint {
-struct PHint {
-  StringTable::Offset Name;
-  unsigned Encoding;
-  FeatureBitset FeaturesRequired;
-
-  bool haveFeatures(FeatureBitset ActiveFeatures) const {
-    return ActiveFeatures[llvm::AArch64::FeatureAll] ||
-           (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
-  }
-};
-
-#define GET_PHintValues_DECL
-#define GET_PHintsList_DECL
-#include "AArch64GenSystemOperands.inc"
-
-const PHint *lookupPHintByName(StringRef);
-const PHint *lookupPHintByEncoding(uint16_t);
-} // namespace AArch64PHint
-
 namespace AArch64BTIHint {
-  struct BTI : SysAlias {
-    using SysAlias::SysAlias;
-  };
-#define GET_BTIValues_DECL
-#define GET_BTIsList_DECL
-#include "AArch64GenSystemOperands.inc"
+inline static bool isBTIEncoding(int64_t Enc) {
+  return Enc == 0 || Enc == 2 || Enc == 4 || Enc == 6;
 }
 
-namespace AArch64CMHPriorityHint {
-struct CMHPriorityHint : SysAlias {
-  using SysAlias::SysAlias;
-};
-#define GET_CMHPRIORITYHINT_DECL
-#include "AArch64GenSystemOperands.inc"
-} // namespace AArch64CMHPriorityHint
+inline static bool isHintSpaceBTI(int64_t Imm) {
+  return Imm >= 32 && Imm < 64 && isBTIEncoding(Imm - 32);
+}
+} // namespace AArch64BTIHint
 
 namespace AArch64TIndexHint {
 struct TIndex : SysAlias {
diff --git a/llvm/test/MC/AArch64/armv8.2a-statistical-profiling.s b/llvm/test/MC/AArch64/armv8.2a-statistical-profiling.s
index 25fff6ac56ae9..006e24d4f8255 100644
--- a/llvm/test/MC/AArch64/armv8.2a-statistical-profiling.s
+++ b/llvm/test/MC/AArch64/armv8.2a-statistical-profiling.s
@@ -9,6 +9,9 @@
 // NO_SPE_OUT-NOT: mrs
 // NO_SPE_OUT-NOT: psb
 
+  hint #17
+// CHECK: psb csync              // encoding: [0x3f,0x22,0x03,0xd5]
+
   psb csync
 // CHECK: psb csync              // encoding: [0x3f,0x22,0x03,0xd5]
 // NO_SPE:  instruction requires: spe
diff --git a/llvm/test/MC/AArch64/armv8.4a-trace-error.s b/llvm/test/MC/AArch64/armv8.4a-trace-error.s
index 99b61280a3180..ec166c715b0ea 100644
--- a/llvm/test/MC/AArch64/armv8.4a-trace-error.s
+++ b/llvm/test/MC/AArch64/armv8.4a-trace-error.s
@@ -12,12 +12,12 @@ tsb 0
 //CHECK-ERROR: error: too few operands for instruction
 //CHECK-ERROR: tsb
 //CHECK-ERROR: ^
-//CHECK-ERROR: error: 'csync' operand expected
+//CHECK-ERROR: error: invalid operand for instruction
 //CHECK-ERROR: tsb foo
 //CHECK-ERROR:     ^
-//CHECK-ERROR: error: 'csync' operand expected
+//CHECK-ERROR: error: invalid operand for instruction
 //CHECK-ERROR: tsb #0
 //CHECK-ERROR:     ^
-//CHECK-ERROR: error: 'csync' operand expected
+//CHECK-ERROR: error: invalid operand for instruction
 //CHECK-ERROR: tsb 0
 //CHECK-ERROR:     ^
diff --git a/llvm/test/MC/AArch64/armv8.4a-trace.s b/llvm/test/MC/AArch64/armv8.4a-trace.s
index a7ce371a0a0b6..0351e20f3fd66 100644
--- a/llvm/test/MC/AArch64/armv8.4a-trace.s
+++ b/llvm/test/MC/AArch64/armv8.4a-trace.s
@@ -22,6 +22,7 @@ mrs x0, TRFCR_EL1
 mrs x0, TRFCR_EL2
 mrs x0, TRFCR_EL12
 
+hint #18
 tsb csync
 
 //CHECK:  msr TRFCR_EL1, x0           // encoding: [0x20,0x12,0x18,0xd5]
@@ -33,6 +34,7 @@ tsb csync
 //CHECK:  mrs x0, TRFCR_EL12          // encoding: [0x20,0x12,0x3d,0xd5]
 
 //CHECK:  tsb csync                   // encoding: [0x5f,0x22,0x03,0xd5]
+//CHECK-NEXT:  tsb csync              // encoding: [0x5f,0x22,0x03,0xd5]
 
 //CHECK-ERROR: error: expected writable system register or pstate
 //CHECK-ERROR: msr TRFCR_EL1, x0
diff --git a/llvm/test/MC/AArch64/armv8.5a-bti.s b/llvm/test/MC/AArch64/armv8.5a-bti.s
index e0585f7613fcc..e806d5ad03ca8 100644
--- a/llvm/test/MC/AArch64/armv8.5a-bti.s
+++ b/llvm/test/MC/AArch64/armv8.5a-bti.s
@@ -3,15 +3,18 @@
 // RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=-bti   < %s | FileCheck %s --check-prefix=NOBTI
 
 bti
+bti r
 bti c
 bti j
 bti jc
 
+// CHECK: bti      // encoding: [0x1f,0x24,0x03,0xd5]
 // CHECK: bti      // encoding: [0x1f,0x24,0x03,0xd5]
 // CHECK: bti c    // encoding: [0x5f,0x24,0x03,0xd5]
 // CHECK: bti j    // encoding: [0x9f,0x24,0x03,0xd5]
 // CHECK: bti jc   // encoding: [0xdf,0x24,0x03,0xd5]
 
+// NOBTI: hint #32 // encoding: [0x1f,0x24,0x03,0xd5]
 // NOBTI: hint #32 // encoding: [0x1f,0x24,0x03,0xd5]
 // NOBTI: hint #34 // encoding: [0x5f,0x24,0x03,0xd5]
 // NOBTI: hint #36 // encoding: [0x9f,0x24,0x03,0xd5]
diff --git a/llvm/test/MC/AArch64/armv9.6a-pcdphint-diagnostics.s b/llvm/test/MC/AArch64/armv9.6a-pcdphint-diagnostics.s
new file mode 100644
index 0000000000000..9e2b67a81459e
--- /dev/null
+++ b/llvm/test/MC/AArch64/armv9.6a-pcdphint-diagnostics.s
@@ -0,0 +1,19 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 | FileCheck %s
+
+stshh
+stshh foo
+stshh #0
+stshh 0
+
+// CHECK:      error: invalid operand for instruction
+// CHECK-NEXT: stshh
+// CHECK-NEXT:      ^
+// CHECK:      error: invalid operand for instruction
+// CHECK-NEXT: stshh foo
+// CHECK-NEXT:       ^
+// CHECK:      error: invalid operand for instruction
+// CHECK-NEXT: stshh #0
+// CHECK-NEXT:       ^
+// CHECK:      error: invalid operand for instruction
+// CHECK-NEXT: stshh 0
+// CHECK-NEXT:       ^
diff --git a/llvm/test/MC/AArch64/armv9.6a-pcdphint.s b/llvm/test/MC/AArch64/armv9.6a-pcdphint.s
index 46fe8981d1ebf..e6bf5cf680cf7 100644
--- a/llvm/test/MC/AArch64/armv9.6a-pcdphint.s
+++ b/llvm/test/MC/AArch64/armv9.6a-pcdphint.s
@@ -6,7 +6,15 @@
 // RUN: llvm-mc -triple=aarch64 -show-encoding < %s \
 // RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
 // RUN:        | llvm-mc -triple=aarch64 -disassemble -show-encoding \
-// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST,CHECK-HINT-ALIAS
+
+hint #48
+// CHECK-HINT-ALIAS: stshh keep
+// CHECK-ENCODING: encoding: [0x1f,0x26,0x03,0xd5]
+
+hint #49
+// CHECK-HINT-ALIAS-NEXT: stshh strm
+// CHECK-ENCODING: encoding: [0x3f,0x26,0x03,0xd5]
 
 stshh keep
 // CHECK-INST: stshh keep
diff --git a/llvm/test/MC/AArch64/armv9.7a-memsys.s b/llvm/test/MC/AArch64/armv9.7a-memsys.s
index ce3ac9bc7e8ee..11a75c2007b4d 100644
--- a/llvm/test/MC/AArch64/armv9.7a-memsys.s
+++ b/llvm/test/MC/AArch64/armv9.7a-memsys.s
@@ -10,10 +10,22 @@
 // RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+lscp < %s \
 // RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
 // RUN:        | llvm-mc -triple=aarch64 -mattr=+lscp -disassemble -show-encoding \
-// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST,CHECK-HINT-ALIAS
 
 // Armv9.7-A Contention Management Hints (FEAT_CMH).
 
+hint #50
+// CHECK-HINT-ALIAS: shuh
+// CHECK-ENCODING: encoding: [0x5f,0x26,0x03,0xd5]
+
+hint #51
+// CHECK-HINT-ALIAS-NEXT: shuh  ph
+// CHECK-ENCODING: encoding: [0x7f,0x26,0x03,0xd5]
+
+hint #52
+// CHECK-HINT-ALIAS-NEXT: stcph
+// CHECK-ENCODING: encoding: [0x9f,0x26,0x03,0xd5]
+
 shuh
 // CHECK-INST: shuh
 // CHECK-ENCODING: encoding: [0x5f,0x26,0x03,0xd5]
diff --git a/llvm/test/MC/AArch64/basic-a64-instructions.s b/llvm/test/MC/AArch64/basic-a64-instructions.s
index 093c09c67bacb..fad6dc796cc2a 100644
--- a/llvm/test/MC/AArch64/basic-a64-instructions.s
+++ b/llvm/test/MC/AArch64/basic-a64-instructions.s
@@ -3460,9 +3460,21 @@ _func:
 //------------------------------------------------------------------------------
 
         hint #0
+        hint #1
+        hint #2
+        hint #3
+        hint #4
+        hint #5
+        hint #6
         hint #127
 // CHECK: nop                             // encoding: [0x1f,0x20,0x03,0xd5]
-// CHECK: hint    #{{127|0x7f}}           // encoding: [0xff,0x2f,0x03,0xd5]
+// CHECK-NEXT: yield                           // encoding: [0x3f,0x20,0x03,0xd5]
+// CHECK-NEXT: wfe                             // encoding: [0x5f,0x20,0x03,0xd5]
+// CHECK-NEXT: wfi                             // encoding: [0x7f,0x20,0x03,0xd5]
+// CHECK-NEXT: sev                             // encoding: [0x9f,0x20,0x03,0xd5]
+// CHECK-NEXT: sevl                            // encoding: [0xbf,0x20,0x03,0xd5]
+// CHECK-NEXT: dgh                             // encoding: [0xdf,0x20,0x03,0xd5]
+// CHECK-NEXT: hint    #{{127|0x7f}}           // encoding: [0xff,0x2f,0x03,0xd5]
 
         nop
         yield
diff --git a/llvm/test/MC/AArch64/ras-extension.s b/llvm/test/MC/AArch64/ras-extension.s
index 2400add87cdde..53cc26ee1ea31 100644
--- a/llvm/test/MC/AArch64/ras-extension.s
+++ b/llvm/test/MC/AArch64/ras-extension.s
@@ -5,6 +5,9 @@
 // RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mcpu=cortex-r82 < %s | FileCheck %s
 // RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8r < %s | FileCheck %s
 
+  hint #16
+// CHECK: esb                             // encoding: [0x1f,0x22,0x03,0xd5]
+
   esb
 // CHECK: esb                             // encoding: [0x1f,0x22,0x03,0xd5]
 
diff --git a/llvm/test/MC/AArch64/speculation-barriers.s b/llvm/test/MC/AArch64/speculation-barriers.s
index 0ab3fe7923efa..7c80d96227166 100644
--- a/llvm/test/MC/AArch64/speculation-barriers.s
+++ b/llvm/test/MC/AArch64/speculation-barriers.s
@@ -1,9 +1,11 @@
 // RUN: llvm-mc -triple aarch64-none-linux-gnu -show-encoding < %s | FileCheck %s
 
+hint #20
 csdb
 ssbb
 pssbb
 
+// CHECK: csdb   // encoding: [0x9f,0x22,0x03,0xd5]
 // CHECK: csdb   // encoding: [0x9f,0x22,0x03,0xd5]
 // CHECK: ssbb   // encoding: [0x9f,0x30,0x03,0xd5]
 // CHECK: pssbb  // encoding: [0x9f,0x34,0x03,0xd5]



More information about the llvm-commits mailing list