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 <[email protected]> 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 <[email protected]> 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 0aea0561464a308fe004c1170361c57b477f50c5 Mon Sep 17 00:00:00 2001 From: Jonathan Thackray <[email protected]> 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, 108 insertions(+), 135 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..1feb25e5d5824 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,7 +4360,7 @@ ParseStatus AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) { } Operands.push_back(AArch64Operand::CreateBarrier( - DB ? DB->Encoding : TSB->Encoding, Tok.getString(), getLoc(), + DB ? DB->Encoding : 2, Tok.getString(), getLoc(), getContext(), false /*hasnXSModifier*/)); Lex(); // Consume the option @@ -4451,25 +4455,15 @@ 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..ecd075a1463f7 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 7a1ab765e13aca26636ef9f7f28634c33c6f58e7 Mon Sep 17 00:00:00 2001 From: Jonathan Thackray <[email protected]> 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 1feb25e5d5824..27e79f53c9243 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 ecd075a1463f7..3f68affb20814 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 { _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
