[llvm-branch-commits] [llvm] [AArch64][llvm] Some instructions should be `HINT` aliases (NFC) (PR #189926)
Jonathan Thackray via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jun 18 00:01:14 PDT 2026
https://github.com/jthackray updated https://github.com/llvm/llvm-project/pull/189926
>From 484fc36422ebace3ac9f38d15464640a4c6b0195 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Tue, 31 Mar 2026 01:18:43 +0100
Subject: [PATCH 1/4] [AArch64][llvm] Some instructions should be `HINT`
aliases (NFC)
Implement the following instructions as a `HINT` alias instead of a
dedicated instruction in separate classes:
* `stshh`
* `stcph`
* `shuh`
* `tsb`
Updated all their helper methods too, and updated the `stshh` pseudo
expansion for the intrinsic to emit `HINT #0x30 | policy`.
Code in AArch64AsmPrinter::emitInstruction identified an initial BTI using a
broad bitmask on the HINT immediate, which also matched shuh/stcph (50..52)
This could move the patchable entry label after a non-BTI instruction.
Replaced it with an exact BTI check using the BTI HINT range (32..63) and
AArch64BTIHint::lookupBTIByEncoding(Imm ^ 32).
A following change will remove duplicated code and simplify.
No test changes.
---
llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 6 +-
.../lib/Target/AArch64/AArch64InstrFormats.td | 81 ++++++++---------
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 19 ++--
.../Target/AArch64/AArch64SystemOperands.td | 15 ++--
.../AArch64/AsmParser/AArch64AsmParser.cpp | 86 +++++++++++++++++++
.../MCTargetDesc/AArch64InstPrinter.cpp | 25 +++++-
.../AArch64/MCTargetDesc/AArch64InstPrinter.h | 6 ++
.../Target/AArch64/Utils/AArch64BaseInfo.h | 2 +-
8 files changed, 170 insertions(+), 70 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index b16c0460adf38..b93119393afe6 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -3202,8 +3202,10 @@ 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)) {
+ uint64_t Imm = MI->getOperand(0).getImm();
+ // Match only exact BTI encodings in HINT space.
+ if (Imm >= 32 && Imm < 64 &&
+ AArch64BTIHint::lookupBTIByEncoding(Imm ^ 32)) {
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 787a11401cb6e..09be57953386d 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -1869,19 +1869,51 @@ def PHintInstOperand : AsmOperandClass {
def phint_op : Operand<i32> {
let ParserMatchClass = PHintInstOperand;
let PrintMethod = "printPHintOp";
+ let MCOperandPredicate = [{
+ if (!MCOp.isImm())
+ return false;
+ return AArch64PHint::lookupPHintByEncoding(MCOp.getImm()) != nullptr;
+ }];
let OperandType = "OPERAND_IMMEDIATE";
let MIOperandInfo = (ops i32imm: $policy);
- let DecoderMethod = "DecodeUImm<3>";
+ let DecoderMethod = "DecodeUImm<7>";
}
-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;
+def TSBHintOperand : AsmOperandClass {
+ let Name = "TSBHint";
+ let ParserMethod = "tryParseTSBHintOperand";
+}
+
+def tsbhint_op : Operand<i32> {
+ let ParserMatchClass = TSBHintOperand;
+ let PrintMethod = "printTSBHintOp";
+ let MCOperandPredicate = [{
+ if (!MCOp.isImm() || MCOp.getImm() < 16)
+ return false;
+ return AArch64TSB::lookupTSBByEncoding(MCOp.getImm() - 16) != nullptr;
+ }];
+ let OperandType = "OPERAND_IMMEDIATE";
+ let MIOperandInfo = (ops i32imm: $policy);
+ let DecoderMethod = "DecodeUImm<7>";
+}
+
+def SHUHintOperand : AsmOperandClass {
+ let Name = "SHUHint";
+ let ParserMethod = "tryParseSHUHintOperand";
+}
+
+def shuhint_op : Operand<i32> {
+ let ParserMatchClass = SHUHintOperand;
+ let PrintMethod = "printSHUHintOp";
+ let MCOperandPredicate = [{
+ if (!MCOp.isImm() || MCOp.getImm() < 50)
+ return false;
+ return AArch64CMHPriorityHint::lookupCMHPriorityHintByEncoding(
+ MCOp.getImm() - 50) != nullptr;
+ }];
+ let OperandType = "OPERAND_IMMEDIATE";
+ let MIOperandInfo = (ops i32imm: $priority);
+ let DecoderMethod = "DecodeUImm<7>";
}
// System instructions taking a single literal operand which encodes into
@@ -13600,37 +13632,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 96c77c2f75196..e0da5119acdbe 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -1566,7 +1566,10 @@ def NOP : SystemNoOperands<0b000, "hint\t#0">;
def : InstAlias<"nop", (NOP)>;
-def STSHH: STSHHI;
+def : InstAlias<"stshh $policy", (HINT phint_op:$policy)>;
+def : InstAlias<"shuh", (HINT 50)>;
+def : InstAlias<"shuh $op", (HINT shuhint_op:$op)>;
+def : InstAlias<"stcph", (HINT 52)>;
// In order to be able to write readable assembly, LLVM should accept assembly
// inputs that use Branch Target Identification mnemonics, even with BTI disabled.
@@ -1597,12 +1600,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;
@@ -1672,6 +1669,7 @@ def GCSPOPM_NoOp : InstAlias<"gcspopm", (GCSPOPM XZR)>, Requires<[HasGCS]>; // R
def GCSB_DSYNC_disable : InstAlias<"gcsb\tdsync", (HINT 19), 0>;
def GCSB_DSYNC : InstAlias<"gcsb\tdsync", (HINT 19), 1>, Requires<[HasGCS]>;
+def : InstAlias<"tsb\t$op", (HINT tsbhint_op:$op)>, Requires<[HasTRACEV8_4]>;
def : TokenAlias<"DSYNC", "dsync">;
@@ -11932,13 +11930,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..d933a8f0029bb 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -2450,15 +2450,10 @@ 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> {
+class PHint<string name, bits<7> encoding> {
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;
+ bits<7> Encoding;
+ let Encoding = encoding;
code Requires = [{ {} }];
}
@@ -2481,8 +2476,8 @@ def lookupPHintByName : SearchIndex {
let Key = ["Name"];
}
-def KEEP : PHint<0b00, 0b000, 0b0000, 0b0000, 0b000, "keep">;
-def STRM : PHint<0b00, 0b000, 0b0000, 0b0000, 0b001, "strm">;
+def KEEP : PHint<"keep", 0b0110000>;
+def STRM : PHint<"strm", 0b0110001>;
// 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 1f0678c3c17c9..1e707656c388a 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -268,6 +268,8 @@ class AArch64AsmParser : public MCTargetAsmParser {
ParseStatus tryParseRPRFMOperand(OperandVector &Operands);
ParseStatus tryParsePSBHint(OperandVector &Operands);
ParseStatus tryParseBTIHint(OperandVector &Operands);
+ ParseStatus tryParseSHUHintOperand(OperandVector &Operands);
+ ParseStatus tryParseTSBHintOperand(OperandVector &Operands);
ParseStatus tryParseCMHPriorityHint(OperandVector &Operands);
ParseStatus tryParseTIndexHint(OperandVector &Operands);
ParseStatus tryParseAdrpLabel(OperandVector &Operands);
@@ -392,6 +394,8 @@ class AArch64Operand : public MCParsedAsmOperand {
k_PSBHint,
k_PHint,
k_BTIHint,
+ k_SHUHint,
+ k_TSBHint,
k_CMHPriorityHint,
k_TIndexHint,
} Kind;
@@ -516,6 +520,8 @@ class AArch64Operand : public MCParsedAsmOperand {
using PSBHintOp = NamedHintOp;
using PHintOp = NamedHintOp;
using BTIHintOp = NamedHintOp;
+ using SHUHintOp = NamedHintOp;
+ using TSBHintOp = NamedHintOp;
using CMHPriorityHintOp = NamedHintOp;
using TIndexHintOp = NamedHintOp;
@@ -544,6 +550,8 @@ class AArch64Operand : public MCParsedAsmOperand {
PSBHintOp PSBHint;
PHintOp PHint;
BTIHintOp BTIHint;
+ SHUHintOp SHUHint;
+ TSBHintOp TSBHint;
CMHPriorityHintOp CMHPriorityHint;
TIndexHintOp TIndexHint;
ShiftExtendOp ShiftExtend;
@@ -616,6 +624,12 @@ class AArch64Operand : public MCParsedAsmOperand {
case k_BTIHint:
BTIHint = o.BTIHint;
break;
+ case k_SHUHint:
+ SHUHint = o.SHUHint;
+ break;
+ case k_TSBHint:
+ TSBHint = o.TSBHint;
+ break;
case k_CMHPriorityHint:
CMHPriorityHint = o.CMHPriorityHint;
break;
@@ -791,11 +805,31 @@ class AArch64Operand : public MCParsedAsmOperand {
return BTIHint.Val;
}
+ unsigned getSHUHint() const {
+ assert(Kind == k_SHUHint && "Invalid access!");
+ return SHUHint.Val;
+ }
+
+ unsigned getTSBHint() const {
+ assert(Kind == k_TSBHint && "Invalid access!");
+ return TSBHint.Val;
+ }
+
StringRef getBTIHintName() const {
assert(Kind == k_BTIHint && "Invalid access!");
return StringRef(BTIHint.Data, BTIHint.Length);
}
+ StringRef getSHUHintName() const {
+ assert(Kind == k_SHUHint && "Invalid access!");
+ return StringRef(SHUHint.Data, SHUHint.Length);
+ }
+
+ StringRef getTSBHintName() const {
+ assert(Kind == k_TSBHint && "Invalid access!");
+ return StringRef(TSBHint.Data, TSBHint.Length);
+ }
+
unsigned getCMHPriorityHint() const {
assert(Kind == k_CMHPriorityHint && "Invalid access!");
return CMHPriorityHint.Val;
@@ -1558,6 +1592,8 @@ class AArch64Operand : public MCParsedAsmOperand {
bool isPSBHint() const { return Kind == k_PSBHint; }
bool isPHint() const { return Kind == k_PHint; }
bool isBTIHint() const { return Kind == k_BTIHint; }
+ bool isSHUHint() const { return Kind == k_SHUHint; }
+ bool isTSBHint() const { return Kind == k_TSBHint; }
bool isCMHPriorityHint() const { return Kind == k_CMHPriorityHint; }
bool isTIndexHint() const { return Kind == k_TIndexHint; }
bool isShiftExtend() const { return Kind == k_ShiftExtend; }
@@ -2245,6 +2281,16 @@ class AArch64Operand : public MCParsedAsmOperand {
Inst.addOperand(MCOperand::createImm(getBTIHint()));
}
+ void addSHUHintOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::createImm(getSHUHint()));
+ }
+
+ void addTSBHintOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::createImm(getTSBHint()));
+ }
+
void addCMHPriorityHintOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::createImm(getCMHPriorityHint()));
@@ -2610,6 +2656,18 @@ class AArch64Operand : public MCParsedAsmOperand {
BTIHintEncoding>(Val, Str, S, Ctx);
}
+ static std::unique_ptr<AArch64Operand>
+ CreateSHUHint(unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
+ return CreateNamedHintOperand<k_SHUHint, &AArch64Operand::SHUHint>(
+ Val, Str, S, Ctx, [](unsigned EncodedVal) { return EncodedVal + 50; });
+ }
+
+ static std::unique_ptr<AArch64Operand>
+ CreateTSBHint(unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
+ return CreateNamedHintOperand<k_TSBHint, &AArch64Operand::TSBHint>(
+ Val, Str, S, Ctx, [](unsigned EncodedVal) { return EncodedVal | 16; });
+ }
+
static std::unique_ptr<AArch64Operand>
CreateCMHPriorityHint(unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
return CreateNamedHintOperand<k_CMHPriorityHint,
@@ -2733,6 +2791,12 @@ void AArch64Operand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {
case k_BTIHint:
OS << getBTIHintName();
break;
+ case k_SHUHint:
+ OS << getSHUHintName();
+ break;
+ case k_TSBHint:
+ OS << getTSBHintName();
+ break;
case k_CMHPriorityHint:
OS << getCMHPriorityHintName();
break;
@@ -4386,6 +4450,28 @@ AArch64AsmParser::tryParsePHintInstOperand(OperandVector &Operands) {
AArch64Operand::CreatePHintInst);
}
+ParseStatus AArch64AsmParser::tryParseSHUHintOperand(OperandVector &Operands) {
+ return tryParseNamedHintOperand(
+ Operands, AArch64CMHPriorityHint::lookupCMHPriorityHintByName,
+ AArch64Operand::CreateSHUHint);
+}
+
+ParseStatus AArch64AsmParser::tryParseTSBHintOperand(OperandVector &Operands) {
+ SMLoc S = getLoc();
+ const AsmToken &Tok = getTok();
+ if (Tok.isNot(AsmToken::Identifier))
+ return TokError("'csync' operand expected");
+
+ auto TSB = AArch64TSB::lookupTSBByName(Tok.getString());
+ if (!TSB || TSB->Encoding != AArch64TSB::csync)
+ return TokError("'csync' operand expected");
+
+ Operands.push_back(AArch64Operand::CreateTSBHint(
+ TSB->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))
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
index 8e5d57b66b049..b901d579533da 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
@@ -1596,6 +1596,28 @@ void AArch64InstPrinter::printBTIHintOp(const MCInst *MI, unsigned OpNum,
AArch64BTIHint::lookupBTIByEncoding, decodeBTIHint);
}
+void AArch64InstPrinter::printSHUHintOp(const MCInst *MI, unsigned OpNum,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ unsigned shuhintop = MI->getOperand(OpNum).getImm() - 50;
+ auto SHU = AArch64CMHPriorityHint::lookupCMHPriorityHintByEncoding(shuhintop);
+ if (SHU)
+ O << SHU->Name;
+ else
+ markup(O, Markup::Immediate) << '#' << formatImm(shuhintop);
+}
+
+void AArch64InstPrinter::printTSBHintOp(const MCInst *MI, unsigned OpNum,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ unsigned tsbhintop = MI->getOperand(OpNum).getImm() ^ 16;
+ auto TSB = AArch64TSB::lookupTSBByEncoding(tsbhintop);
+ if (TSB)
+ O << TSB->Name;
+ else
+ markup(O, Markup::Immediate) << '#' << formatImm(tsbhintop);
+}
+
void AArch64InstPrinter::printCMHPriorityHintOp(const MCInst *MI,
unsigned OpNum,
const MCSubtargetInfo &STI,
@@ -1962,9 +1984,6 @@ void AArch64InstPrinter::printBarrierOption(const MCInst *MI, unsigned OpNo,
if (Opcode == AArch64::ISB) {
auto ISB = AArch64ISB::lookupISBByEncoding(Val);
Name = ISB ? ISB->Name : "";
- } else if (Opcode == AArch64::TSB) {
- auto TSB = AArch64TSB::lookupTSBByEncoding(Val);
- Name = TSB ? TSB->Name : "";
} else {
auto DB = AArch64DB::lookupDBByEncoding(Val);
Name = DB ? DB->Name : "";
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
index 48e2e7e4eaa36..057f48d808456 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
@@ -153,6 +153,12 @@ class AArch64InstPrinter : public MCInstPrinter {
void printBTIHintOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
+ void printSHUHintOp(const MCInst *MI, unsigned OpNum,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+
+ void printTSBHintOp(const MCInst *MI, unsigned OpNum,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+
void printCMHPriorityHintOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index 1f18af709bd93..cda590782d512 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -726,7 +726,7 @@ struct PHint {
#include "AArch64GenSystemOperands.inc"
const PHint *lookupPHintByName(StringRef);
-const PHint *lookupPHintByEncoding(uint16_t);
+const PHint *lookupPHintByEncoding(uint8_t);
} // namespace AArch64PHint
namespace AArch64BTIHint {
>From cc60ab0de461f59bc0f9afa352da2df01d89e80d Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Tue, 28 Apr 2026 19:34:14 +0100
Subject: [PATCH 2/4] fixup! Add testcases for all missing HINTs
---
.../MC/AArch64/armv8.2a-statistical-profiling.s | 3 +++
llvm/test/MC/AArch64/armv8.4a-trace.s | 8 ++++++++
llvm/test/MC/AArch64/armv9.5a-pauthlr.s | 6 ++++++
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 | 12 ++++++++++++
llvm/test/MC/AArch64/ras-extension.s | 3 +++
llvm/test/MC/AArch64/speculation-barriers.s | 2 ++
8 files changed, 56 insertions(+), 2 deletions(-)
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.s b/llvm/test/MC/AArch64/armv8.4a-trace.s
index a7ce371a0a0b6..1fb0ef0deb167 100644
--- a/llvm/test/MC/AArch64/armv8.4a-trace.s
+++ b/llvm/test/MC/AArch64/armv8.4a-trace.s
@@ -10,6 +10,10 @@
// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.4a,-tracev8.4 -o - %s 2>&1 | \
// RUN: FileCheck %s --check-prefixes CHECK-ERROR
+// RUN: llvm-mc -triple aarch64-none-linux-gnu -filetype=obj -mattr=+tracev8.4 %s \
+// RUN: | llvm-objdump -d --mattr=+tracev8.4 --no-print-imm-hex - \
+// RUN: | FileCheck %s --check-prefix=CHECK-HINT-ALIAS
+
//------------------------------------------------------------------------------
// ARMV8.4-A Debug, Trace and PMU Extensions
//------------------------------------------------------------------------------
@@ -22,6 +26,9 @@ mrs x0, TRFCR_EL1
mrs x0, TRFCR_EL2
mrs x0, TRFCR_EL12
+hint #18
+//CHECK-HINT-ALIAS: tsb csync
+
tsb csync
//CHECK: msr TRFCR_EL1, x0 // encoding: [0x20,0x12,0x18,0xd5]
@@ -32,6 +39,7 @@ tsb csync
//CHECK: mrs x0, TRFCR_EL2 // encoding: [0x20,0x12,0x3c,0xd5]
//CHECK: mrs x0, TRFCR_EL12 // encoding: [0x20,0x12,0x3d,0xd5]
+//CHECK: tsb csync // encoding: [0x5f,0x22,0x03,0xd5]
//CHECK: tsb csync // encoding: [0x5f,0x22,0x03,0xd5]
//CHECK-ERROR: error: expected writable system register or pstate
diff --git a/llvm/test/MC/AArch64/armv9.5a-pauthlr.s b/llvm/test/MC/AArch64/armv9.5a-pauthlr.s
index 2655798852892..f554867705b9f 100644
--- a/llvm/test/MC/AArch64/armv9.5a-pauthlr.s
+++ b/llvm/test/MC/AArch64/armv9.5a-pauthlr.s
@@ -170,6 +170,12 @@ label1:
// CHECK-ERROR: instruction requires: pauth-lr
// CHECK-UNKNOWN: d65f0fe3 <unknown>
+ hint #39
+// CHECK-INST: hint #39
+// CHECK-DISASS: pacm
+// CHECK-ENCODING: [0xff,0x24,0x03,0xd5]
+// CHECK-UNKNOWN: d50324ff hint #39
+
pacm
// CHECK-INST: pacm
// CHECK-DISASS: pacm
diff --git a/llvm/test/MC/AArch64/armv9.6a-pcdphint.s b/llvm/test/MC/AArch64/armv9.6a-pcdphint.s
index 46fe8981d1ebf..bb45eb60c1119 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: 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..f93c1ee2c4c2b 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: shuh ph
+// CHECK-ENCODING: encoding: [0x7f,0x26,0x03,0xd5]
+
+hint #52
+// CHECK-HINT-ALIAS: 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..2855c9cf2e945 100644
--- a/llvm/test/MC/AArch64/basic-a64-instructions.s
+++ b/llvm/test/MC/AArch64/basic-a64-instructions.s
@@ -3460,8 +3460,20 @@ _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: yield // encoding: [0x3f,0x20,0x03,0xd5]
+// CHECK: wfe // encoding: [0x5f,0x20,0x03,0xd5]
+// CHECK: wfi // encoding: [0x7f,0x20,0x03,0xd5]
+// CHECK: sev // encoding: [0x9f,0x20,0x03,0xd5]
+// CHECK: sevl // encoding: [0xbf,0x20,0x03,0xd5]
+// CHECK: dgh // encoding: [0xdf,0x20,0x03,0xd5]
// CHECK: hint #{{127|0x7f}} // encoding: [0xff,0x2f,0x03,0xd5]
nop
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]
>From 38e2806d1566f4882ffd3822dd42d90edf8af1da Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Thu, 18 Jun 2026 01:20:39 +0100
Subject: [PATCH 3/4] fixup! Address PR comments
---
llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 5 +-
.../lib/Target/AArch64/AArch64InstrFormats.td | 13 ++--
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 17 ++---
.../Target/AArch64/AArch64SystemOperands.td | 72 +++++++------------
.../AArch64/AsmParser/AArch64AsmParser.cpp | 38 ++++------
.../MCTargetDesc/AArch64InstPrinter.cpp | 18 ++---
.../AArch64/MCTargetDesc/AArch64InstPrinter.h | 3 +
.../Target/AArch64/Utils/AArch64BaseInfo.cpp | 23 +++---
.../Target/AArch64/Utils/AArch64BaseInfo.h | 48 +++++++------
llvm/test/MC/AArch64/armv8.4a-trace-error.s | 6 +-
10 files changed, 107 insertions(+), 136 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index b93119393afe6..d77ebfdbab16b 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -3202,10 +3202,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
if (CurrentPatchableFunctionEntrySym &&
CurrentPatchableFunctionEntrySym == CurrentFnBegin &&
MI == &MF->front().front()) {
- uint64_t Imm = MI->getOperand(0).getImm();
- // Match only exact BTI encodings in HINT space.
- if (Imm >= 32 && Imm < 64 &&
- AArch64BTIHint::lookupBTIByEncoding(Imm ^ 32)) {
+ 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 09be57953386d..cd01835c492c4 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -1870,9 +1870,9 @@ def phint_op : Operand<i32> {
let ParserMatchClass = PHintInstOperand;
let PrintMethod = "printPHintOp";
let MCOperandPredicate = [{
- if (!MCOp.isImm())
+ if (!MCOp.isImm() || MCOp.getImm() < 48)
return false;
- return AArch64PHint::lookupPHintByEncoding(MCOp.getImm()) != nullptr;
+ return AArch64PHint::lookupPHintByEncoding(MCOp.getImm() - 48) != nullptr;
}];
let OperandType = "OPERAND_IMMEDIATE";
let MIOperandInfo = (ops i32imm: $policy);
@@ -1890,7 +1890,8 @@ def tsbhint_op : Operand<i32> {
let MCOperandPredicate = [{
if (!MCOp.isImm() || MCOp.getImm() < 16)
return false;
- return AArch64TSB::lookupTSBByEncoding(MCOp.getImm() - 16) != nullptr;
+ return AArch64TSBHint::lookupTSBHintByEncoding(MCOp.getImm() - 16) !=
+ nullptr;
}];
let OperandType = "OPERAND_IMMEDIATE";
let MIOperandInfo = (ops i32imm: $policy);
@@ -1908,8 +1909,8 @@ def shuhint_op : Operand<i32> {
let MCOperandPredicate = [{
if (!MCOp.isImm() || MCOp.getImm() < 50)
return false;
- return AArch64CMHPriorityHint::lookupCMHPriorityHintByEncoding(
- MCOp.getImm() - 50) != nullptr;
+ return AArch64SHUHint::lookupSHUHintByEncoding(MCOp.getImm() - 50) !=
+ nullptr;
}];
let OperandType = "OPERAND_IMMEDIATE";
let MIOperandInfo = (ops i32imm: $priority);
@@ -2012,7 +2013,7 @@ def btihint_op : Operand<i32> {
// "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;
+ return AArch64BTIHint::isHintSpaceBTI(MCOp.getImm());
}];
let OperandType = "OPERAND_IMMEDIATE";
}
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index e0da5119acdbe..0be7748aa0dc3 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
@@ -1584,6 +1584,8 @@ def : InstAlias<"bti $op", (HINT btihint_op:$op)>, Requires<[HasBTI]>;
// v8.2a Statistical Profiling extension
def : InstAlias<"psb $op", (HINT psbhint_op:$op)>, Requires<[HasSPE]>;
+def : InstAlias<"tsb $op", (HINT tsbhint_op:$op)>, Requires<[HasTRACEV8_4]>;
+
// As far as LLVM is concerned this writes to the system's exclusive monitors.
let mayLoad = 1, mayStore = 1 in
def CLREX : CRmSystemI<imm0_15, 0b010, "clrex">;
@@ -1669,7 +1671,6 @@ def GCSPOPM_NoOp : InstAlias<"gcspopm", (GCSPOPM XZR)>, Requires<[HasGCS]>; // R
def GCSB_DSYNC_disable : InstAlias<"gcsb\tdsync", (HINT 19), 0>;
def GCSB_DSYNC : InstAlias<"gcsb\tdsync", (HINT 19), 1>, Requires<[HasGCS]>;
-def : InstAlias<"tsb\t$op", (HINT tsbhint_op:$op)>, Requires<[HasTRACEV8_4]>;
def : TokenAlias<"DSYNC", "dsync">;
diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index d933a8f0029bb..b34e1232a11ad 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -338,37 +338,19 @@ def lookupISBByName : SearchIndex {
def : ISB<"sy", 0xf>;
//===----------------------------------------------------------------------===//
-// TSB (Trace synchronization barrier) instruction options.
+// TSB (Trace synchronization barrier) HINT instruction options.
//===----------------------------------------------------------------------===//
-class TSB<string name, bits<4> encoding> {
+class TSBHint<string name, bits<4> encoding> : SearchableTable {
+ let SearchableFields = ["Name", "Encoding"];
+ let EnumValueField = "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>;
+def : TSBHint<"csync", 2>;
//===----------------------------------------------------------------------===//
// PRFM (prefetch) instruction options.
@@ -829,6 +811,17 @@ class CMHPriorityHint<string name, bits<1> encoding> : SearchableTable {
def : CMHPriorityHint<"ph", 0b1>;
+class SHUHint<string name, bits<1> encoding> : SearchableTable {
+ let SearchableFields = ["Name", "Encoding"];
+ let EnumValueField = "Encoding";
+
+ string Name = name;
+ bits<1> Encoding;
+ let Encoding = encoding;
+}
+
+def : SHUHint<"ph", 0b1>;
+
//===----------------------------------------------------------------------===//
// TIndex instruction options.
@@ -2450,34 +2443,17 @@ def : RWSysReg<"ACTLRALIAS_EL1", 0b11, 0b000, 0b0001, 0b0100, 0b101>;
// v9.6a PCDPHINT instruction options.
//===----------------------------------------------------------------------===//
-class PHint<string name, bits<7> encoding> {
+class PHint<string name, bits<1> encoding> : SearchableTable {
+ let SearchableFields = ["Name", "Encoding"];
+ let EnumValueField = "Encoding";
+
string Name = name;
- bits<7> Encoding;
+ bits<1> Encoding;
let Encoding = encoding;
- 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<"keep", 0b0110000>;
-def STRM : PHint<"strm", 0b0110001>;
+def : PHint<"keep", 0b0>;
+def : PHint<"strm", 0b1>;
// 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 1e707656c388a..83457dcdbf73d 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -2597,6 +2597,10 @@ class AArch64Operand : public MCParsedAsmOperand {
unsigned operator()(unsigned Val) const { return Val | 32; }
};
+ struct PHintEncoding {
+ unsigned operator()(unsigned Val) const { return Val + 48; }
+ };
+
template <KindTy Kind, NamedHintOp AArch64Operand::*Member,
typename Encode = IdentityHintEncoding>
static std::unique_ptr<AArch64Operand>
@@ -2614,8 +2618,8 @@ class AArch64Operand : public MCParsedAsmOperand {
static std::unique_ptr<AArch64Operand>
CreatePHintInst(unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
- return CreateNamedHintOperand<k_PHint, &AArch64Operand::PHint>(Val, Str, S,
- Ctx);
+ return CreateNamedHintOperand<k_PHint, &AArch64Operand::PHint>(
+ Val, Str, S, Ctx, PHintEncoding{});
}
static std::unique_ptr<AArch64Operand> CreateSysCR(unsigned Val, SMLoc S,
@@ -4338,15 +4342,15 @@ ParseStatus AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
return TokError("invalid operand for instruction");
StringRef Operand = Tok.getString();
- auto TSB = AArch64TSB::lookupTSBByName(Operand);
+ bool IsTSB = Mnemonic == "tsb" && Operand == "csync";
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))
+ if (Mnemonic == "tsb" && !IsTSB)
return TokError("'csync' operand expected");
- if (!DB && !TSB) {
+ if (!DB && !IsTSB) {
if (Mnemonic == "dsb") {
// This case is a no match here, but it might be matched by the nXS
// variant.
@@ -4356,8 +4360,8 @@ ParseStatus AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
}
Operands.push_back(AArch64Operand::CreateBarrier(
- DB ? DB->Encoding : TSB->Encoding, Tok.getString(), getLoc(),
- getContext(), false /*hasnXSModifier*/));
+ DB ? DB->Encoding : 2, Tok.getString(), getLoc(), getContext(),
+ false /*hasnXSModifier*/));
Lex(); // Consume the option
return ParseStatus::Success;
@@ -4451,25 +4455,13 @@ AArch64AsmParser::tryParsePHintInstOperand(OperandVector &Operands) {
}
ParseStatus AArch64AsmParser::tryParseSHUHintOperand(OperandVector &Operands) {
- return tryParseNamedHintOperand(
- Operands, AArch64CMHPriorityHint::lookupCMHPriorityHintByName,
- AArch64Operand::CreateSHUHint);
+ return tryParseNamedHintOperand(Operands, AArch64SHUHint::lookupSHUHintByName,
+ AArch64Operand::CreateSHUHint);
}
ParseStatus AArch64AsmParser::tryParseTSBHintOperand(OperandVector &Operands) {
- SMLoc S = getLoc();
- const AsmToken &Tok = getTok();
- if (Tok.isNot(AsmToken::Identifier))
- return TokError("'csync' operand expected");
-
- auto TSB = AArch64TSB::lookupTSBByName(Tok.getString());
- if (!TSB || TSB->Encoding != AArch64TSB::csync)
- return TokError("'csync' operand expected");
-
- Operands.push_back(AArch64Operand::CreateTSBHint(
- TSB->Encoding, Tok.getString(), S, getContext()));
- Lex(); // Eat identifier token.
- return ParseStatus::Success;
+ return tryParseNamedHintOperand(Operands, AArch64TSBHint::lookupTSBHintByName,
+ AArch64Operand::CreateTSBHint);
}
/// tryParseNeonVectorRegister - Parse a vector register operand.
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
index b901d579533da..be0e206f7469a 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
@@ -1599,23 +1599,15 @@ void AArch64InstPrinter::printBTIHintOp(const MCInst *MI, unsigned OpNum,
void AArch64InstPrinter::printSHUHintOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
- unsigned shuhintop = MI->getOperand(OpNum).getImm() - 50;
- auto SHU = AArch64CMHPriorityHint::lookupCMHPriorityHintByEncoding(shuhintop);
- if (SHU)
- O << SHU->Name;
- else
- markup(O, Markup::Immediate) << '#' << formatImm(shuhintop);
+ printNamedHintOp(MI->getOperand(OpNum).getImm(), O,
+ AArch64SHUHint::lookupSHUHintByEncoding, decodeSHUHint);
}
void AArch64InstPrinter::printTSBHintOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
- unsigned tsbhintop = MI->getOperand(OpNum).getImm() ^ 16;
- auto TSB = AArch64TSB::lookupTSBByEncoding(tsbhintop);
- if (TSB)
- O << TSB->Name;
- else
- markup(O, Markup::Immediate) << '#' << formatImm(tsbhintop);
+ printNamedHintOp(MI->getOperand(OpNum).getImm(), O,
+ AArch64TSBHint::lookupTSBHintByEncoding, decodeTSBHint);
}
void AArch64InstPrinter::printCMHPriorityHintOp(const MCInst *MI,
@@ -2280,5 +2272,5 @@ void AArch64InstPrinter::printPHintOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
printNamedHintOp(MI->getOperand(OpNum).getImm(), O,
- AArch64PHint::lookupPHintByEncoding, decodeIdentityHint);
+ AArch64PHint::lookupPHintByEncoding, decodePHint);
}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
index 057f48d808456..e2f6ae876dbb3 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
@@ -174,6 +174,9 @@ class AArch64InstPrinter : public MCInstPrinter {
static unsigned decodeIdentityHint(unsigned Value) { return Value; }
static unsigned decodeBTIHint(unsigned Value) { return Value ^ 32; }
+ static unsigned decodePHint(unsigned Value) { return Value - 48; }
+ static unsigned decodeSHUHint(unsigned Value) { return Value - 50; }
+ static unsigned decodeTSBHint(unsigned Value) { return Value ^ 16; }
void printVectorList(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O,
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
index c2fccc91cfec9..cee6affd42950 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
@@ -126,11 +119,18 @@ namespace llvm {
namespace llvm {
namespace AArch64PHint {
-#define GET_PHintsList_IMPL
+#define GET_PHINT_IMPL
#include "AArch64GenSystemOperands.inc"
} // namespace AArch64PHint
} // namespace llvm
+namespace llvm {
+namespace AArch64TSBHint {
+#define GET_TSBHINT_IMPL
+#include "AArch64GenSystemOperands.inc"
+} // namespace AArch64TSBHint
+} // namespace llvm
+
namespace llvm {
namespace AArch64BTIHint {
#define GET_BTIsList_IMPL
@@ -145,6 +145,13 @@ namespace AArch64CMHPriorityHint {
} // namespace AArch64CMHPriorityHint
} // namespace llvm
+namespace llvm {
+namespace AArch64SHUHint {
+#define GET_SHUHINT_IMPL
+#include "AArch64GenSystemOperands.inc"
+} // namespace AArch64SHUHint
+} // 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 cda590782d512..88e07aa81fcfb 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -541,15 +541,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;
@@ -710,25 +701,23 @@ namespace AArch64PSBHint {
}
namespace AArch64PHint {
-struct PHint {
- const char *Name;
- unsigned Encoding;
- FeatureBitset FeaturesRequired;
-
- bool haveFeatures(FeatureBitset ActiveFeatures) const {
- return ActiveFeatures[llvm::AArch64::FeatureAll] ||
- (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
- }
+struct PHint : SysAlias {
+ using SysAlias::SysAlias;
};
-#define GET_PHintValues_DECL
-#define GET_PHintsList_DECL
+#define GET_PHINT_DECL
#include "AArch64GenSystemOperands.inc"
-
-const PHint *lookupPHintByName(StringRef);
-const PHint *lookupPHintByEncoding(uint8_t);
} // namespace AArch64PHint
+namespace AArch64TSBHint {
+struct TSBHint : SysAlias {
+ using SysAlias::SysAlias;
+};
+
+#define GET_TSBHINT_DECL
+#include "AArch64GenSystemOperands.inc"
+} // namespace AArch64TSBHint
+
namespace AArch64BTIHint {
struct BTI : SysAlias {
using SysAlias::SysAlias;
@@ -736,6 +725,10 @@ namespace AArch64BTIHint {
#define GET_BTIValues_DECL
#define GET_BTIsList_DECL
#include "AArch64GenSystemOperands.inc"
+
+ inline static bool isHintSpaceBTI(int64_t Imm) {
+ return Imm >= 32 && Imm < 64 && lookupBTIByEncoding(Imm ^ 32);
+ }
}
namespace AArch64CMHPriorityHint {
@@ -746,6 +739,15 @@ struct CMHPriorityHint : SysAlias {
#include "AArch64GenSystemOperands.inc"
} // namespace AArch64CMHPriorityHint
+namespace AArch64SHUHint {
+struct SHUHint : SysAlias {
+ using SysAlias::SysAlias;
+};
+
+#define GET_SHUHINT_DECL
+#include "AArch64GenSystemOperands.inc"
+} // namespace AArch64SHUHint
+
namespace AArch64TIndexHint {
struct TIndex : SysAlias {
using SysAlias::SysAlias;
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: ^
>From 3a9fdec4303ecfd631c9296b0a410d8803933a03 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Thu, 18 Jun 2026 07:56:56 +0100
Subject: [PATCH 4/4] fixup! Convert PSB to use PSBHint for consistency
---
.../lib/Target/AArch64/AArch64InstrFormats.td | 5 ++--
.../Target/AArch64/AArch64SystemOperands.td | 30 +++++--------------
.../AArch64/AsmParser/AArch64AsmParser.cpp | 22 ++++++++++----
.../MCTargetDesc/AArch64InstPrinter.cpp | 2 +-
.../AArch64/MCTargetDesc/AArch64InstPrinter.h | 1 +
.../Target/AArch64/Utils/AArch64BaseInfo.cpp | 8 ++---
.../Target/AArch64/Utils/AArch64BaseInfo.h | 11 ++++---
7 files changed, 38 insertions(+), 41 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index cd01835c492c4..822c3ee3da276 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -1995,9 +1995,10 @@ def psbhint_op : Operand<i32> {
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())
+ if (!MCOp.isImm() || MCOp.getImm() < 16)
return false;
- return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
+ return AArch64PSBHint::lookupPSBHintByEncoding(MCOp.getImm() - 16) !=
+ nullptr;
}];
let OperandType = "OPERAND_IMMEDIATE";
}
diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index b34e1232a11ad..91801c8041777 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -732,35 +732,19 @@ def : SVCR<"SVCRSMZA", 0b011>;
}
//===----------------------------------------------------------------------===//
-// PSB instruction options.
+// PSB (Profiling synchronization barrier) HINT instruction options.
//===----------------------------------------------------------------------===//
-class PSB<string name, bits<5> encoding> {
+class PSBHint<string name, bits<4> encoding> : SearchableTable {
+ let SearchableFields = ["Name", "Encoding"];
+ let EnumValueField = "Encoding";
+
string Name = name;
- bits<5> Encoding;
+ bits<4> 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>;
+def : PSBHint<"csync", 1>;
//===----------------------------------------------------------------------===//
// BTI instruction options.
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 83457dcdbf73d..60936f1e86151 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -2601,6 +2601,18 @@ class AArch64Operand : public MCParsedAsmOperand {
unsigned operator()(unsigned Val) const { return Val + 48; }
};
+ struct PSBHintEncoding {
+ unsigned operator()(unsigned Val) const { return Val + 16; }
+ };
+
+ struct SHUHintEncoding {
+ unsigned operator()(unsigned Val) const { return Val + 50; }
+ };
+
+ struct TSBHintEncoding {
+ unsigned operator()(unsigned Val) const { return Val | 16; }
+ };
+
template <KindTy Kind, NamedHintOp AArch64Operand::*Member,
typename Encode = IdentityHintEncoding>
static std::unique_ptr<AArch64Operand>
@@ -2648,8 +2660,8 @@ class AArch64Operand : public MCParsedAsmOperand {
StringRef Str,
SMLoc S,
MCContext &Ctx) {
- return CreateNamedHintOperand<k_PSBHint, &AArch64Operand::PSBHint>(Val, Str,
- S, Ctx);
+ return CreateNamedHintOperand<k_PSBHint, &AArch64Operand::PSBHint>(
+ Val, Str, S, Ctx, PSBHintEncoding{});
}
static std::unique_ptr<AArch64Operand> CreateBTIHint(unsigned Val,
@@ -2663,13 +2675,13 @@ class AArch64Operand : public MCParsedAsmOperand {
static std::unique_ptr<AArch64Operand>
CreateSHUHint(unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
return CreateNamedHintOperand<k_SHUHint, &AArch64Operand::SHUHint>(
- Val, Str, S, Ctx, [](unsigned EncodedVal) { return EncodedVal + 50; });
+ Val, Str, S, Ctx, SHUHintEncoding{});
}
static std::unique_ptr<AArch64Operand>
CreateTSBHint(unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
return CreateNamedHintOperand<k_TSBHint, &AArch64Operand::TSBHint>(
- Val, Str, S, Ctx, [](unsigned EncodedVal) { return EncodedVal | 16; });
+ Val, Str, S, Ctx, TSBHintEncoding{});
}
static std::unique_ptr<AArch64Operand>
@@ -3365,7 +3377,7 @@ ParseStatus AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
/// tryParsePSBHint - Try to parse a PSB operand, mapped to Hint command
ParseStatus AArch64AsmParser::tryParsePSBHint(OperandVector &Operands) {
- return tryParseNamedHintOperand(Operands, AArch64PSBHint::lookupPSBByName,
+ return tryParseNamedHintOperand(Operands, AArch64PSBHint::lookupPSBHintByName,
AArch64Operand::CreatePSBHint);
}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
index be0e206f7469a..4235f1724b0a1 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
@@ -1586,7 +1586,7 @@ void AArch64InstPrinter::printPSBHintOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
printNamedHintOp(MI->getOperand(OpNum).getImm(), O,
- AArch64PSBHint::lookupPSBByEncoding, decodeIdentityHint);
+ AArch64PSBHint::lookupPSBHintByEncoding, decodePSBHint);
}
void AArch64InstPrinter::printBTIHintOp(const MCInst *MI, unsigned OpNum,
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
index e2f6ae876dbb3..9877a6aba9684 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
@@ -174,6 +174,7 @@ class AArch64InstPrinter : public MCInstPrinter {
static unsigned decodeIdentityHint(unsigned Value) { return Value; }
static unsigned decodeBTIHint(unsigned Value) { return Value ^ 32; }
+ static unsigned decodePSBHint(unsigned Value) { return Value - 16; }
static unsigned decodePHint(unsigned Value) { return Value - 48; }
static unsigned decodeSHUHint(unsigned Value) { return Value - 50; }
static unsigned decodeTSBHint(unsigned Value) { return Value ^ 16; }
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
index cee6affd42950..37132b08a0782 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
@@ -111,11 +111,11 @@ namespace llvm {
}
namespace llvm {
- namespace AArch64PSBHint {
-#define GET_PSBsList_IMPL
+namespace AArch64PSBHint {
+#define GET_PSBHINT_IMPL
#include "AArch64GenSystemOperands.inc"
- }
-}
+} // namespace AArch64PSBHint
+} // namespace llvm
namespace llvm {
namespace AArch64PHint {
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index 88e07aa81fcfb..7b990182ead22 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -692,13 +692,12 @@ namespace AArch64PState {
}
namespace AArch64PSBHint {
- struct PSB : SysAlias {
- using SysAlias::SysAlias;
- };
-#define GET_PSBValues_DECL
-#define GET_PSBsList_DECL
+struct PSBHint : SysAlias {
+ using SysAlias::SysAlias;
+};
+#define GET_PSBHINT_DECL
#include "AArch64GenSystemOperands.inc"
-}
+} // namespace AArch64PSBHint
namespace AArch64PHint {
struct PHint : SysAlias {
More information about the llvm-branch-commits
mailing list