[llvm-branch-commits] [clang] [llvm] [AArch64][llvm] Armv9.7-A: Add support for FEAT_CMH and FEAT_LSCP (PR #163155)
Jonathan Thackray via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Oct 23 05:47:32 PDT 2025
https://github.com/jthackray updated https://github.com/llvm/llvm-project/pull/163155
>From 09811c35b0e956fee4da8d0fe7be7417134deacd Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Mon, 8 Sep 2025 13:23:12 +0100
Subject: [PATCH 1/3] [AArch64][llvm] Armv9.7-A: Add support for FEAT_CMH and
FEAT_LSCP
Add the following instructions to support:
* `FEAT_CMH`: Contention Management Hints extension
* `SHUH` instruction
* `FEAT_LSCP`: Load-acquire and store-release pair extension
* `STLP` instruction
* `LDAP` instruction
* `LDAPP` instruction
as documented here:
* https://developer.arm.com/documentation/109697/2025_09/2025-Architecture-Extensions
* https://developer.arm.com/documentation/ddi0602/2025-09/
Co-authored-by: Martin Wehking <martin.wehking at arm.com>
---
clang/test/Driver/aarch64-v97a.c | 8 ++
.../print-supported-extensions-aarch64.c | 2 +
llvm/lib/Target/AArch64/AArch64Features.td | 5 ++
.../lib/Target/AArch64/AArch64InstrFormats.td | 78 +++++++++++++++++++
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 19 +++++
.../Target/AArch64/AArch64SystemOperands.td | 15 ++++
.../AArch64/AsmParser/AArch64AsmParser.cpp | 61 +++++++++++++++
.../MCTargetDesc/AArch64InstPrinter.cpp | 11 +++
.../AArch64/MCTargetDesc/AArch64InstPrinter.h | 3 +
.../Target/AArch64/Utils/AArch64BaseInfo.cpp | 7 ++
.../Target/AArch64/Utils/AArch64BaseInfo.h | 8 ++
.../TargetParser/TargetParserTest.cpp | 7 +-
12 files changed, 223 insertions(+), 1 deletion(-)
diff --git a/clang/test/Driver/aarch64-v97a.c b/clang/test/Driver/aarch64-v97a.c
index d34e48ed91954..4a55d44466cc0 100644
--- a/clang/test/Driver/aarch64-v97a.c
+++ b/clang/test/Driver/aarch64-v97a.c
@@ -17,3 +17,11 @@
// GENERICV97A-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.7a"{{.*}}
// ===== Features supported on aarch64 =====
+
+// RUN: %clang -target aarch64 -march=armv9.7a+cmh -### -c %s 2>&1 | FileCheck -check-prefix=V97A-CMH %s
+// RUN: %clang -target aarch64 -march=armv9.7-a+cmh -### -c %s 2>&1 | FileCheck -check-prefix=V97A-CMH %s
+// V97A-CMH: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.7a"{{.*}} "-target-feature" "+cmh"
+
+// RUN: %clang -target aarch64 -march=armv9.7a+lscp -### -c %s 2>&1 | FileCheck -check-prefix=V97A-LSCP %s
+// RUN: %clang -target aarch64 -march=armv9.7-a+lscp -### -c %s 2>&1 | FileCheck -check-prefix=V97A-LSCP %s
+// V97A-LSCP: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.7a"{{.*}} "-target-feature" "+lscp"
diff --git a/clang/test/Driver/print-supported-extensions-aarch64.c b/clang/test/Driver/print-supported-extensions-aarch64.c
index 5c840a60685c6..9928f395866d8 100644
--- a/clang/test/Driver/print-supported-extensions-aarch64.c
+++ b/clang/test/Driver/print-supported-extensions-aarch64.c
@@ -8,6 +8,7 @@
// CHECK-NEXT: bf16 FEAT_BF16 Enable BFloat16 Extension
// CHECK-NEXT: brbe FEAT_BRBE Enable Branch Record Buffer Extension
// CHECK-NEXT: bti FEAT_BTI Enable Branch Target Identification
+// CHECK-NEXT: cmh FEAT_CMH Enable Armv9.7-A Contention Management Hints
// CHECK-NEXT: cmpbr FEAT_CMPBR Enable Armv9.6-A base compare and branch instructions
// CHECK-NEXT: fcma FEAT_FCMA Enable Armv8.3-A Floating-point complex number support
// CHECK-NEXT: cpa FEAT_CPA Enable Armv9.5-A Checked Pointer Arithmetic
@@ -37,6 +38,7 @@
// CHECK-NEXT: ite FEAT_ITE Enable Armv9.4-A Instrumentation Extension
// CHECK-NEXT: jscvt FEAT_JSCVT Enable Armv8.3-A JavaScript FP conversion instructions
// CHECK-NEXT: ls64 FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA Enable Armv8.7-A LD64B/ST64B Accelerator Extension
+// CHECK-NEXT: lscp FEAT_LSCP Enable Armv9.7-A Load-acquire and store-release pair extension
// CHECK-NEXT: lse FEAT_LSE Enable Armv8.1-A Large System Extension (LSE) atomic instructions
// CHECK-NEXT: lse128 FEAT_LSE128 Enable Armv9.4-A 128-bit Atomic instructions
// CHECK-NEXT: lsfe FEAT_LSFE Enable Armv9.6-A base Atomic floating-point in-memory instructions
diff --git a/llvm/lib/Target/AArch64/AArch64Features.td b/llvm/lib/Target/AArch64/AArch64Features.td
index 1e71f81a402cf..7fe83537b7a36 100644
--- a/llvm/lib/Target/AArch64/AArch64Features.td
+++ b/llvm/lib/Target/AArch64/AArch64Features.td
@@ -589,6 +589,11 @@ def FeatureSSVE_FEXPA : ExtensionWithMArch<"ssve-fexpa", "SSVE_FEXPA", "FEAT_SSV
// Armv9.7 Architecture Extensions
//===----------------------------------------------------------------------===//
+def FeatureCMH : ExtensionWithMArch<"cmh", "CMH", "FEAT_CMH",
+ "Enable Armv9.7-A Contention Management Hints">;
+
+def FeatureLSCP : ExtensionWithMArch<"lscp", "LSCP", "FEAT_LSCP",
+ "Enable Armv9.7-A Load-acquire and store-release pair extension">;
//===----------------------------------------------------------------------===//
// Other Features
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 09ce713ea862c..d2f282eadd302 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -1894,6 +1894,21 @@ def btihint_op : Operand<i32> {
}];
}
+def CMHPriorityHintOperand : AsmOperandClass {
+ let Name = "CMHPriorityHint";
+ let ParserMethod = "tryParseCMHPriorityHint";
+}
+
+def CMHPriorityHint_op : Operand<i32> {
+ let ParserMatchClass = CMHPriorityHintOperand;
+ let PrintMethod = "printCMHPriorityHintOp";
+ let MCOperandPredicate = [{
+ if (!MCOp.isImm())
+ return false;
+ return AArch64CMHPriorityHint::lookupCMHPriorityHintByEncoding(MCOp.getImm()) != nullptr;
+ }];
+}
+
class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
"mrs", "\t$Rt, $systemreg"> {
bits<16> systemreg;
@@ -4636,6 +4651,48 @@ multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype,
GPR64sp:$Rn, 0)>;
}
+class BaseLoadStoreAcquirePairOffset<bits<4> opc, bit L, dag oops, dag iops,
+ string asm>
+ : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, #0]", "", []> {
+ bits<5> Rt;
+ bits<5> Rt2;
+ bits<5> Rn;
+ let Inst{31-23} = 0b110110010;
+ let Inst{22} = L;
+ let Inst{21} = 0b0;
+ let Inst{20-16} = Rt2;
+ let Inst{15-12} = opc;
+ let Inst{11-10} = 0b10;
+ let Inst{9-5} = Rn;
+ let Inst{4-0} = Rt;
+}
+
+multiclass LoadAcquirePairOffset<bits<4> opc, string asm> {
+ let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
+ def i : BaseLoadStoreAcquirePairOffset<opc, 0b1,
+ (outs GPR64:$Rt, GPR64:$Rt2),
+ (ins GPR64sp:$Rn), asm>,
+ Sched<[WriteAtomic, WriteLDHi]>;
+
+ def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
+ (!cast<Instruction>(NAME # "i") GPR64:$Rt, GPR64:$Rt2,
+ GPR64sp:$Rn)>;
+}
+
+
+multiclass StoreAcquirePairOffset<bits<4> opc, string asm> {
+ let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
+ def i : BaseLoadStoreAcquirePairOffset<opc, 0b0, (outs),
+ (ins GPR64:$Rt, GPR64:$Rt2,
+ GPR64sp:$Rn),
+ asm>,
+ Sched<[WriteSTP]>;
+
+ def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
+ (!cast<Instruction>(NAME # "i") GPR64:$Rt, GPR64:$Rt2,
+ GPR64sp:$Rn)>;
+}
+
// (pre-indexed)
class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
string asm>
@@ -13227,3 +13284,24 @@ multiclass SIMDThreeSameVectorFP8MatrixMul<string asm>{
let Predicates = [HasNEON, HasF8F32MM];
}
}
+
+//----------------------------------------------------------------------------
+// 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>;
+}
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index f788c7510f80c..218cd4911a25a 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -242,6 +242,11 @@ def HasLSUI : Predicate<"Subtarget->hasLSUI()">,
def HasOCCMO : Predicate<"Subtarget->hasOCCMO()">,
AssemblerPredicateWithAll<(all_of FeatureOCCMO), "occmo">;
+def HasCMH : Predicate<"Subtarget->hasCMH()">,
+ AssemblerPredicateWithAll<(all_of FeatureCMH), "cmh">;
+def HasLSCP : Predicate<"Subtarget->hasLSCP()">,
+ AssemblerPredicateWithAll<(all_of FeatureLSCP), "lscp">;
+
// A subset of SVE(2) instructions are legal in Streaming SVE execution mode,
// they should be enabled if either has been specified.
def HasSVE_or_SME
@@ -3692,6 +3697,12 @@ def UDF : UDFType<0, "udf">;
// Load instructions.
//===----------------------------------------------------------------------===//
+let Predicates = [HasLSCP] in {
+defm LDAP : LoadAcquirePairOffset<0b0101, "ldap">;
+defm LDAPP : LoadAcquirePairOffset<0b0111, "ldapp">;
+defm STLP : StoreAcquirePairOffset<0b0101, "stlp">;
+}
+
// Pair (indexed, offset)
defm LDPW : LoadPairOffset<0b00, 0, GPR32z, simm7s4, "ldp">;
defm LDPX : LoadPairOffset<0b10, 0, GPR64z, simm7s8, "ldp">;
@@ -11251,6 +11262,14 @@ let Predicates = [HasLSFE] in {
let Uses = [FPMR, FPCR] in
defm FMMLA : SIMDThreeSameVectorFP8MatrixMul<"fmmla">;
+//===----------------------------------------------------------------------===//
+// Contention Management Hints (FEAT_CMH)
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasCMH] in {
+ defm SHUH : SHUH<"shuh">; // Shared Update Hint instruction
+}
+
include "AArch64InstrAtomics.td"
include "AArch64SVEInstrInfo.td"
include "AArch64SMEInstrInfo.td"
diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index 943891746c45f..d538d071c7d37 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -812,6 +812,21 @@ def : BTI<"c", 0b010>;
def : BTI<"j", 0b100>;
def : BTI<"jc", 0b110>;
+//===----------------------------------------------------------------------===//
+// CMHPriority instruction options.
+//===----------------------------------------------------------------------===//
+
+class CMHPriorityHint<string name, bits<1> encoding> : SearchableTable {
+ let SearchableFields = ["Name", "Encoding"];
+ let EnumValueField = "Encoding";
+
+ string Name = name;
+ bits<1> Encoding;
+ let Encoding = encoding;
+}
+
+def : CMHPriorityHint<"ph", 0b1>;
+
//===----------------------------------------------------------------------===//
// TLBI (translation lookaside buffer invalidate) instruction options.
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index c2c9fa5d5e604..82de7aacfed45 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -266,6 +266,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
ParseStatus tryParseRPRFMOperand(OperandVector &Operands);
ParseStatus tryParsePSBHint(OperandVector &Operands);
ParseStatus tryParseBTIHint(OperandVector &Operands);
+ ParseStatus tryParseCMHPriorityHint(OperandVector &Operands);
ParseStatus tryParseAdrpLabel(OperandVector &Operands);
ParseStatus tryParseAdrLabel(OperandVector &Operands);
template <bool AddFPZeroAsLiteral>
@@ -370,6 +371,7 @@ class AArch64Operand : public MCParsedAsmOperand {
k_PSBHint,
k_PHint,
k_BTIHint,
+ k_CMHPriorityHint,
} Kind;
SMLoc StartLoc, EndLoc;
@@ -499,6 +501,11 @@ class AArch64Operand : public MCParsedAsmOperand {
unsigned Length;
unsigned Val;
};
+ struct CMHPriorityHintOp {
+ const char *Data;
+ unsigned Length;
+ unsigned Val;
+ };
struct SVCROp {
const char *Data;
@@ -525,6 +532,7 @@ class AArch64Operand : public MCParsedAsmOperand {
struct PSBHintOp PSBHint;
struct PHintOp PHint;
struct BTIHintOp BTIHint;
+ struct CMHPriorityHintOp CMHPriorityHint;
struct ShiftExtendOp ShiftExtend;
struct SVCROp SVCR;
};
@@ -595,6 +603,9 @@ class AArch64Operand : public MCParsedAsmOperand {
case k_BTIHint:
BTIHint = o.BTIHint;
break;
+ case k_CMHPriorityHint:
+ CMHPriorityHint = o.CMHPriorityHint;
+ break;
case k_ShiftExtend:
ShiftExtend = o.ShiftExtend;
break;
@@ -769,6 +780,16 @@ class AArch64Operand : public MCParsedAsmOperand {
return StringRef(BTIHint.Data, BTIHint.Length);
}
+ unsigned getCMHPriorityHint() const {
+ assert(Kind == k_CMHPriorityHint && "Invalid access!");
+ return CMHPriorityHint.Val;
+ }
+
+ StringRef getCMHPriorityHintName() const {
+ assert(Kind == k_CMHPriorityHint && "Invalid access!");
+ return StringRef(CMHPriorityHint.Data, CMHPriorityHint.Length);
+ }
+
StringRef getSVCR() const {
assert(Kind == k_SVCR && "Invalid access!");
return StringRef(SVCR.Data, SVCR.Length);
@@ -1511,6 +1532,7 @@ 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 isCMHPriorityHint() const { return Kind == k_CMHPriorityHint; }
bool isShiftExtend() const { return Kind == k_ShiftExtend; }
bool isShifter() const {
if (!isShiftExtend())
@@ -2196,6 +2218,11 @@ class AArch64Operand : public MCParsedAsmOperand {
Inst.addOperand(MCOperand::createImm(getBTIHint()));
}
+ void addCMHPriorityHintOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::createImm(getCMHPriorityHint()));
+ }
+
void addShifterOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
unsigned Imm =
@@ -2546,6 +2573,17 @@ class AArch64Operand : public MCParsedAsmOperand {
return Op;
}
+ static std::unique_ptr<AArch64Operand>
+ CreateCMHPriorityHint(unsigned Val, StringRef Str, SMLoc S, MCContext &Ctx) {
+ auto Op = std::make_unique<AArch64Operand>(k_CMHPriorityHint, Ctx);
+ Op->CMHPriorityHint.Val = Val;
+ Op->CMHPriorityHint.Data = Str.data();
+ Op->CMHPriorityHint.Length = Str.size();
+ Op->StartLoc = S;
+ Op->EndLoc = S;
+ return Op;
+ }
+
static std::unique_ptr<AArch64Operand>
CreateMatrixRegister(unsigned RegNum, unsigned ElementWidth, MatrixKind Kind,
SMLoc S, SMLoc E, MCContext &Ctx) {
@@ -2656,6 +2694,9 @@ void AArch64Operand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {
case k_BTIHint:
OS << getBTIHintName();
break;
+ case k_CMHPriorityHint:
+ OS << getCMHPriorityHintName();
+ break;
case k_MatrixRegister:
OS << "<matrix " << getMatrixReg() << ">";
break;
@@ -3279,6 +3320,24 @@ ParseStatus AArch64AsmParser::tryParseBTIHint(OperandVector &Operands) {
return ParseStatus::Success;
}
+/// tryParseCMHPriorityHint - Try to parse a CMHPriority operand
+ParseStatus AArch64AsmParser::tryParseCMHPriorityHint(OperandVector &Operands) {
+ SMLoc S = getLoc();
+ const AsmToken &Tok = getTok();
+ if (Tok.isNot(AsmToken::Identifier))
+ return TokError("invalid operand for instruction");
+
+ auto CMHPriority =
+ AArch64CMHPriorityHint::lookupCMHPriorityHintByName(Tok.getString());
+ if (!CMHPriority)
+ return TokError("invalid operand for instruction");
+
+ Operands.push_back(AArch64Operand::CreateCMHPriorityHint(
+ CMHPriority->Encoding, Tok.getString(), S, getContext()));
+ Lex(); // Eat identifier token.
+ return ParseStatus::Success;
+}
+
/// tryParseAdrpLabel - Parse and validate a source label for the ADRP
/// instruction.
ParseStatus AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
@@ -3824,6 +3883,8 @@ static const struct Extension {
{"ssve-bitperm", {AArch64::FeatureSSVE_BitPerm}},
{"sme-mop4", {AArch64::FeatureSME_MOP4}},
{"sme-tmop", {AArch64::FeatureSME_TMOP}},
+ {"cmh", {AArch64::FeatureCMH}},
+ {"lscp", {AArch64::FeatureLSCP}},
};
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) {
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
index 35bd24418f3e7..6bd53f61884c2 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
@@ -1508,6 +1508,17 @@ void AArch64InstPrinter::printBTIHintOp(const MCInst *MI, unsigned OpNum,
markup(O, Markup::Immediate) << '#' << formatImm(btihintop);
}
+void AArch64InstPrinter::printCMHPriorityHintOp(const MCInst *MI,
+ unsigned OpNum,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ unsigned priorityhint_op = MI->getOperand(OpNum).getImm();
+ auto PHint =
+ AArch64CMHPriorityHint::lookupCMHPriorityHintByEncoding(priorityhint_op);
+ if (PHint)
+ O << PHint->Name;
+}
+
void AArch64InstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
index 15ef2ddfc22fd..2bdf40a3cfc5e 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
@@ -151,6 +151,9 @@ class AArch64InstPrinter : public MCInstPrinter {
void printBTIHintOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
+ void printCMHPriorityHintOp(const MCInst *MI, unsigned OpNum,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+
void printFPImmOperand(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 d6cb0e857d57a..93348ca95c4e8 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp
@@ -138,6 +138,13 @@ namespace llvm {
}
}
+namespace llvm {
+namespace AArch64CMHPriorityHint {
+#define GET_CMHPRIORITYHINT_IMPL
+#include "AArch64GenSystemOperands.inc"
+} // namespace AArch64CMHPriorityHint
+} // namespace llvm
+
namespace llvm {
namespace AArch64SysReg {
#define GET_SysRegsList_IMPL
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index fea33ef10149d..e09a0ee0518db 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -677,6 +677,14 @@ namespace AArch64BTIHint {
#include "AArch64GenSystemOperands.inc"
}
+namespace AArch64CMHPriorityHint {
+struct CMHPriorityHint : SysAlias {
+ using SysAlias::SysAlias;
+};
+#define GET_CMHPRIORITYHINT_DECL
+#include "AArch64GenSystemOperands.inc"
+} // namespace AArch64CMHPriorityHint
+
namespace AArch64SME {
enum ToggleCondition : unsigned {
Always,
diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index b269bde4e2724..e9f7f2ceeb070 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -1443,7 +1443,8 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
AArch64::AEK_SVEAES, AArch64::AEK_SME_MOP4,
AArch64::AEK_SME_TMOP, AArch64::AEK_SVEBITPERM,
AArch64::AEK_SSVE_BITPERM, AArch64::AEK_SVESHA3,
- AArch64::AEK_SVESM4,
+ AArch64::AEK_SVESM4, AArch64::AEK_CMH,
+ AArch64::AEK_LSCP,
};
std::vector<StringRef> Features;
@@ -1555,6 +1556,8 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
EXPECT_TRUE(llvm::is_contained(Features, "+pops"));
EXPECT_TRUE(llvm::is_contained(Features, "+sme-mop4"));
EXPECT_TRUE(llvm::is_contained(Features, "+sme-tmop"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+cmh"));
+ EXPECT_TRUE(llvm::is_contained(Features, "+lscp"));
// Assuming we listed every extension above, this should produce the same
// result.
@@ -1721,6 +1724,8 @@ TEST(TargetParserTest, AArch64ArchExtFeature) {
{"pops", "nopops", "+pops", "-pops"},
{"sme-mop4", "nosme-mop4", "+sme-mop4", "-sme-mop4"},
{"sme-tmop", "nosme-tmop", "+sme-tmop", "-sme-tmop"},
+ {"cmh", "nocmh", "+cmh", "-cmh"},
+ {"lscp", "nolscp", "+lscp", "-lscp"},
};
for (unsigned i = 0; i < std::size(ArchExt); i++) {
>From 2e5ddf98b04cf5efaf40c6a26f24e8f689022c04 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Fri, 17 Oct 2025 01:14:12 +0100
Subject: [PATCH 2/3] fixup! [AArch64][llvm] Armv9.7-A: Add support for
FEAT_CMH and FEAT_LSCP
Oops, forgot to upstream the testcases, and so found I'd missed a bet0 patch
from Martin. D'oh!
---
.../lib/Target/AArch64/AArch64InstrFormats.td | 10 ++
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 3 +-
.../Target/AArch64/AArch64SystemOperands.td | 13 ++
llvm/test/MC/AArch64/armv9.7a-memsys.s | 140 ++++++++++++++++++
4 files changed, 165 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/MC/AArch64/armv9.7a-memsys.s
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index d2f282eadd302..6730c61552914 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -13305,3 +13305,13 @@ 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;
+}
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 218cd4911a25a..50646484f0cde 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -11267,7 +11267,8 @@ defm FMMLA : SIMDThreeSameVectorFP8MatrixMul<"fmmla">;
//===----------------------------------------------------------------------===//
let Predicates = [HasCMH] in {
- defm SHUH : SHUH<"shuh">; // Shared Update Hint instruction
+ defm SHUH : SHUH<"shuh">; // Shared Update Hint instruction
+ def STCPH : STCPHInst<"stcph">; // Store Concurrent Priority Hint instruction
}
include "AArch64InstrAtomics.td"
diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index d538d071c7d37..a358d4b7174f3 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -2427,3 +2427,16 @@ def : DC<"CIVAPS", 0b000, 0b0111, 0b1111, 0b001>;
let Requires = [{ {AArch64::FeaturePoPS, AArch64::FeatureMTE} }] in {
def : DC<"CIGDVAPS", 0b000, 0b0111, 0b1111, 0b101>;
}
+
+// v9.7a TLBI domains system registers (MemSys)
+foreach n = 0-3 in {
+ defvar nb = !cast<bits<3>>(n);
+ def : RWSysReg<"VTLBID"#n#"_EL2", 0b11, 0b100, 0b0010, 0b1000, nb>;
+}
+
+foreach n = 0-3 in {
+ defvar nb = !cast<bits<3>>(n);
+ def : RWSysReg<"VTLBIDOS"#n#"_EL2", 0b11, 0b100, 0b0010, 0b1001, nb>;
+}
+
+def : ROSysReg<"TLBIDIDR_EL1", 0b11, 0b000, 0b1010, 0b0100, 0b110>;
diff --git a/llvm/test/MC/AArch64/armv9.7a-memsys.s b/llvm/test/MC/AArch64/armv9.7a-memsys.s
new file mode 100644
index 0000000000000..cc6ff20cd5b54
--- /dev/null
+++ b/llvm/test/MC/AArch64/armv9.7a-memsys.s
@@ -0,0 +1,140 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+cmh,+lscp < %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+all < %s \
+// RUN: | llvm-objdump -d --mattr=+cmh,+lscp --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+all < %s \
+// RUN: | llvm-objdump -d --mattr=-cmh,-lscp --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+cmh,+lscp < %s \
+// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN: | llvm-mc -triple=aarch64 -mattr=+cmh,+lscp -disassemble -show-encoding \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+// Armv9.7-A Contention Management Hints (FEAT_CMH).
+
+shuh
+// CHECK-INST: shuh
+// CHECK-ENCODING: encoding: [0x5f,0x26,0x03,0xd5]
+// CHECK-ERROR: error: instruction requires: cmh
+// CHECK-UNKNOWN: d503265f hint #50
+
+shuh ph
+// CHECK-INST: shuh ph
+// CHECK-ENCODING: encoding: [0x7f,0x26,0x03,0xd5]
+// CHECK-ERROR: error: instruction requires: cmh
+// CHECK-UNKNOWN: d503267f hint #51
+
+stcph
+// CHECK-INST: stcph
+// CHECK-ENCODING: [0x9f,0x26,0x03,0xd5]
+// CHECK-ERROR: error: instruction requires: cmh
+// CHECK-UNKNOWN: d503269f hint #52
+
+ldap x0, x1, [x2]
+// CHECK-INST: ldap x0, x1, [x2]
+// CHECK-ENCODING: encoding: [0x40,0x58,0x41,0xd9]
+// CHECK-ERROR: error: instruction requires: lscp
+// CHECK-UNKNOWN: d9415840 <unknown>
+
+ldap x0, x1, [x2, #0]
+// CHECK-INST: ldap x0, x1, [x2]
+// CHECK-ENCODING: encoding: [0x40,0x58,0x41,0xd9]
+// CHECK-ERROR: error: instruction requires: lscp
+// CHECK-UNKNOWN: d9415840 <unknown>
+
+ldapp x0, x1, [x2]
+// CHECK-INST: ldapp x0, x1, [x2]
+// CHECK-ENCODING: encoding: [0x40,0x78,0x41,0xd9]
+// CHECK-ERROR: error: instruction requires: lscp
+// CHECK-UNKNOWN: d9417840 <unknown>
+
+ldapp x0, x1, [x2, #0]
+// CHECK-INST: ldapp x0, x1, [x2]
+// CHECK-ENCODING: encoding: [0x40,0x78,0x41,0xd9]
+// CHECK-ERROR: error: instruction requires: lscp
+// CHECK-UNKNOWN: d9417840 <unknown>
+
+stlp x0, x1, [x2, #0]
+// CHECK-INST: stlp x0, x1, [x2]
+// CHECK-ENCODING: encoding: [0x40,0x58,0x01,0xd9]
+// CHECK-ERROR: error: instruction requires: lscp
+// CHECK-UNKNOWN: d9015840 <unknown>
+
+stlp x0, x1, [x2]
+// CHECK-INST: stlp x0, x1, [x2]
+// CHECK-ENCODING: encoding: [0x40,0x58,0x01,0xd9]
+// CHECK-ERROR: error: instruction requires: lscp
+// CHECK-UNKNOWN: d9015840 <unknown>
+
+mrs x3, VTLBID0_EL2
+// CHECK-INST: mrs x3, VTLBID0_EL2
+// CHECK-ENCODING: encoding: [0x03,0x28,0x3c,0xd5]
+// CHECK-UNKNOWN: d53c2803
+mrs x3, VTLBID1_EL2
+// CHECK-INST: mrs x3, VTLBID1_EL2
+// CHECK-ENCODING: encoding: [0x23,0x28,0x3c,0xd5]
+// CHECK-UNKNOWN: d53c2823
+mrs x3, VTLBID2_EL2
+// CHECK-INST: mrs x3, VTLBID2_EL2
+// CHECK-ENCODING: encoding: [0x43,0x28,0x3c,0xd5]
+// CHECK-UNKNOWN: d53c2843
+mrs x3, VTLBID3_EL2
+// CHECK-INST: mrs x3, VTLBID3_EL2
+// CHECK-ENCODING: encoding: [0x63,0x28,0x3c,0xd5]
+// CHECK-UNKNOWN: d53c2863
+mrs x3, VTLBIDOS0_EL2
+// CHECK-INST: mrs x3, VTLBIDOS0_EL2
+// CHECK-ENCODING: encoding: [0x03,0x29,0x3c,0xd5]
+// CHECK-UNKNOWN: d53c2903
+mrs x3, VTLBIDOS1_EL2
+// CHECK-INST: mrs x3, VTLBIDOS1_EL2
+// CHECK-ENCODING: encoding: [0x23,0x29,0x3c,0xd5]
+// CHECK-UNKNOWN: d53c2923
+mrs x3, VTLBIDOS2_EL2
+// CHECK-INST: mrs x3, VTLBIDOS2_EL2
+// CHECK-ENCODING: encoding: [0x43,0x29,0x3c,0xd5]
+// CHECK-UNKNOWN: d53c2943
+mrs x3, VTLBIDOS3_EL2
+// CHECK-INST: mrs x3, VTLBIDOS3_EL2
+// CHECK-ENCODING: encoding: [0x63,0x29,0x3c,0xd5]
+// CHECK-UNKNOWN: d53c2963
+mrs x3, TLBIDIDR_EL1
+// CHECK-INST: mrs x3, TLBIDIDR_EL1
+// CHECK-ENCODING: encoding: [0xc3,0xa4,0x38,0xd5]
+// CHECK-UNKNOWN: d538a4c3
+
+msr VTLBID0_EL2, x3
+// CHECK-INST: msr VTLBID0_EL2, x3
+// CHECK-ENCODING: encoding: [0x03,0x28,0x1c,0xd5]
+// CHECK-UNKNOWN: d51c2803
+msr VTLBID1_EL2, x3
+// CHECK-INST: msr VTLBID1_EL2, x3
+// CHECK-ENCODING: encoding: [0x23,0x28,0x1c,0xd5]
+// CHECK-UNKNOWN: d51c2823
+msr VTLBID2_EL2, x3
+// CHECK-INST: msr VTLBID2_EL2, x3
+// CHECK-ENCODING: encoding: [0x43,0x28,0x1c,0xd5]
+// CHECK-UNKNOWN: d51c2843
+msr VTLBID3_EL2, x3
+// CHECK-INST: msr VTLBID3_EL2, x3
+// CHECK-ENCODING: encoding: [0x63,0x28,0x1c,0xd5]
+// CHECK-UNKNOWN: d51c2863
+msr VTLBIDOS0_EL2, x3
+// CHECK-INST: msr VTLBIDOS0_EL2, x3
+// CHECK-ENCODING: encoding: [0x03,0x29,0x1c,0xd5]
+// CHECK-UNKNOWN: d51c2903
+msr VTLBIDOS1_EL2, x3
+// CHECK-INST: msr VTLBIDOS1_EL2, x3
+// CHECK-ENCODING: encoding: [0x23,0x29,0x1c,0xd5]
+// CHECK-UNKNOWN: d51c2923
+msr VTLBIDOS2_EL2, x3
+// CHECK-INST: msr VTLBIDOS2_EL2, x3
+// CHECK-ENCODING: encoding: [0x43,0x29,0x1c,0xd5]
+// CHECK-UNKNOWN: d51c2943
+msr VTLBIDOS3_EL2, x3
+// CHECK-INST: msr VTLBIDOS3_EL2, x3
+// CHECK-ENCODING: encoding: [0x63,0x29,0x1c,0xd5]
+// CHECK-UNKNOWN: d51c2963
+
>From c0d7bf6a3d460fe3fe09c850c66d8cc3e4f40692 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Wed, 22 Oct 2025 13:54:26 +0100
Subject: [PATCH 3/3] fixup! [AArch64][llvm] Armv9.7-A: Add support for
FEAT_CMH and FEAT_LSCP
Small fix to test script
---
llvm/test/MC/AArch64/armv9.7a-memsys.s | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/test/MC/AArch64/armv9.7a-memsys.s b/llvm/test/MC/AArch64/armv9.7a-memsys.s
index cc6ff20cd5b54..228c71ef6e5c5 100644
--- a/llvm/test/MC/AArch64/armv9.7a-memsys.s
+++ b/llvm/test/MC/AArch64/armv9.7a-memsys.s
@@ -2,9 +2,9 @@
// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
-// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+all < %s \
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+cmh,+lscp < %s \
// RUN: | llvm-objdump -d --mattr=+cmh,+lscp --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST
-// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+all < %s \
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+cmh,+lscp < %s \
// RUN: | llvm-objdump -d --mattr=-cmh,-lscp --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN
// Disassemble encoding and check the re-encoding (-show-encoding) matches.
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+cmh,+lscp < %s \
More information about the llvm-branch-commits
mailing list