Skip to content

Commit d30f18d

Browse files
[AArch64][llvm] Armv9.7-A: Add support for Memory Partitioning and Management (FEAT_MPAMv2) (#163157)
Add new instructions and system registers for `FEAT_MPAMv2`: * MLBI ALLE1 * MLBI VMALLE1 * MLBI VPIDE1, <Xt> * MLBI VPMGE1, <Xt> as documented here: * https://developer.arm.com/documentation/ddi0602/2025-09/ * https://developer.arm.com/documentation/109697/2025_09/2025-Architecture-Extensions Co-authored-by: Caroline Concatto <[email protected]>
1 parent 66e8270 commit d30f18d

File tree

14 files changed

+276
-72
lines changed

14 files changed

+276
-72
lines changed

clang/test/Driver/aarch64-v97a.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,7 @@
2929
// RUN: %clang -target aarch64 -march=armv9.7a+tlbid -### -c %s 2>&1 | FileCheck -check-prefix=V97A-TLBID %s
3030
// RUN: %clang -target aarch64 -march=armv9.7-a+tlbid -### -c %s 2>&1 | FileCheck -check-prefix=V97A-TLBID %s
3131
// V97A-TLBID: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.7a"{{.*}} "-target-feature" "+tlbid"
32+
33+
// RUN: %clang -target aarch64 -march=armv9.7a+mpamv2 -### -c %s 2>&1 | FileCheck -check-prefix=V97A-MPAMv2 %s
34+
// RUN: %clang -target aarch64 -march=armv9.7-a+mpamv2 -### -c %s 2>&1 | FileCheck -check-prefix=V97A-MPAMv2 %s
35+
// V97A-MPAMv2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.7a"{{.*}} "-target-feature" "+mpamv2"

clang/test/Driver/print-supported-extensions-aarch64.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
// CHECK-NEXT: lsui FEAT_LSUI Enable Armv9.6-A unprivileged load/store instructions
4646
// CHECK-NEXT: lut FEAT_LUT Enable Lookup Table instructions
4747
// CHECK-NEXT: mops FEAT_MOPS Enable Armv8.8-A memcpy and memset acceleration instructions
48+
// CHECK-NEXT: mpamv2 FEAT_MPAMv2 Enable Armv9.7-A MPAMv2 Lookaside Buffer Invalidate instructions
4849
// CHECK-NEXT: memtag FEAT_MTE, FEAT_MTE2 Enable Memory Tagging Extension
4950
// CHECK-NEXT: simd FEAT_AdvSIMD Enable Advanced SIMD instructions
5051
// CHECK-NEXT: occmo FEAT_OCCMO Enable Armv9.6-A Outer cacheable cache maintenance operations

llvm/lib/Target/AArch64/AArch64Features.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,9 @@ def FeatureLSCP : ExtensionWithMArch<"lscp", "LSCP", "FEAT_LSCP",
598598
def FeatureTLBID: ExtensionWithMArch<"tlbid", "TLBID", "FEAT_TLBID",
599599
"Enable Armv9.7-A TLBI Domains extension">;
600600

601+
def FeatureMPAMv2: ExtensionWithMArch<"mpamv2", "MPAMv2", "FEAT_MPAMv2",
602+
"Enable Armv9.7-A MPAMv2 Lookaside Buffer Invalidate instructions">;
603+
601604
//===----------------------------------------------------------------------===//
602605
// Other Features
603606
//===----------------------------------------------------------------------===//

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,8 @@ def HasCPA : Predicate<"Subtarget->hasCPA()">,
402402
AssemblerPredicateWithAll<(all_of FeatureCPA), "cpa">;
403403
def HasTLBID : Predicate<"Subtarget->hasTLBID()">,
404404
AssemblerPredicateWithAll<(all_of FeatureTLBID), "tlbid">;
405+
def HasMPAMv2 : Predicate<"Subtarget->hasMPAMv2()">,
406+
AssemblerPredicateWithAll<(all_of FeatureMPAMv2), "mpamv2">;
405407
def IsLE : Predicate<"Subtarget->isLittleEndian()">;
406408
def IsBE : Predicate<"!Subtarget->isLittleEndian()">;
407409
def IsWindows : Predicate<"Subtarget->isTargetWindows()">;

llvm/lib/Target/AArch64/AArch64SystemOperands.td

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1880,12 +1880,6 @@ def : ROSysReg<"ERXPFGF_EL1", 0b11, 0b000, 0b0101, 0b0100, 0b100>;
18801880
// v8.4a MPAM registers
18811881
// Op0 Op1 CRn CRm Op2
18821882
let Requires = [{ {AArch64::FeatureMPAM} }] in {
1883-
def : RWSysReg<"MPAM0_EL1", 0b11, 0b000, 0b1010, 0b0101, 0b001>;
1884-
def : RWSysReg<"MPAM1_EL1", 0b11, 0b000, 0b1010, 0b0101, 0b000>;
1885-
def : RWSysReg<"MPAM2_EL2", 0b11, 0b100, 0b1010, 0b0101, 0b000>;
1886-
def : RWSysReg<"MPAM3_EL3", 0b11, 0b110, 0b1010, 0b0101, 0b000>;
1887-
def : RWSysReg<"MPAM1_EL12", 0b11, 0b101, 0b1010, 0b0101, 0b000>;
1888-
def : RWSysReg<"MPAMHCR_EL2", 0b11, 0b100, 0b1010, 0b0100, 0b000>;
18891883
def : RWSysReg<"MPAMVPMV_EL2", 0b11, 0b100, 0b1010, 0b0100, 0b001>;
18901884
def : RWSysReg<"MPAMVPM0_EL2", 0b11, 0b100, 0b1010, 0b0110, 0b000>;
18911885
def : RWSysReg<"MPAMVPM1_EL2", 0b11, 0b100, 0b1010, 0b0110, 0b001>;
@@ -1895,7 +1889,6 @@ def : RWSysReg<"MPAMVPM4_EL2", 0b11, 0b100, 0b1010, 0b0110, 0b100>;
18951889
def : RWSysReg<"MPAMVPM5_EL2", 0b11, 0b100, 0b1010, 0b0110, 0b101>;
18961890
def : RWSysReg<"MPAMVPM6_EL2", 0b11, 0b100, 0b1010, 0b0110, 0b110>;
18971891
def : RWSysReg<"MPAMVPM7_EL2", 0b11, 0b100, 0b1010, 0b0110, 0b111>;
1898-
def : ROSysReg<"MPAMIDR_EL1", 0b11, 0b000, 0b1010, 0b0100, 0b100>;
18991892
} //FeatureMPAM
19001893

19011894
// v8.4a Activity Monitor registers
@@ -2336,6 +2329,26 @@ def : RWSysReg<"MPAMBW0_EL1", 0b11, 0b000, 0b1010, 0b0101, 0b101>;
23362329
def : RWSysReg<"MPAMBWCAP_EL2", 0b11, 0b100, 0b1010, 0b0101, 0b110>;
23372330
def : RWSysReg<"MPAMBWSM_EL1", 0b11, 0b000, 0b1010, 0b0101, 0b111>;
23382331

2332+
// v9.7a Memory partitioning and monitoring version 2
2333+
// (FEAT_MPAMv2) registers
2334+
// Op0 Op1 CRn CRm Op2
2335+
// MPAM system registers that are also available for MPAMv2
2336+
def : RWSysReg<"MPAM0_EL1", 0b11, 0b000, 0b1010, 0b0101, 0b001>;
2337+
def : RWSysReg<"MPAM1_EL1", 0b11, 0b000, 0b1010, 0b0101, 0b000>;
2338+
def : RWSysReg<"MPAM1_EL12", 0b11, 0b101, 0b1010, 0b0101, 0b000>;
2339+
def : RWSysReg<"MPAM2_EL2", 0b11, 0b100, 0b1010, 0b0101, 0b000>;
2340+
def : RWSysReg<"MPAM3_EL3", 0b11, 0b110, 0b1010, 0b0101, 0b000>;
2341+
def : RWSysReg<"MPAMHCR_EL2", 0b11, 0b100, 0b1010, 0b0100, 0b000>;
2342+
def : ROSysReg<"MPAMIDR_EL1", 0b11, 0b000, 0b1010, 0b0100, 0b100>;
2343+
// Only MPAMv2 registers
2344+
def : RWSysReg<"MPAMCTL_EL1", 0b11, 0b000, 0b1010, 0b0101, 0b010>;
2345+
def : RWSysReg<"MPAMCTL_EL12", 0b11, 0b101, 0b1010, 0b0101, 0b010>;
2346+
def : RWSysReg<"MPAMCTL_EL2", 0b11, 0b100, 0b1010, 0b0101, 0b010>;
2347+
def : RWSysReg<"MPAMCTL_EL3", 0b11, 0b110, 0b1010, 0b0101, 0b010>;
2348+
def : RWSysReg<"MPAMVIDCR_EL2", 0b11, 0b100, 0b1010, 0b0111, 0b000>;
2349+
def : RWSysReg<"MPAMVIDSR_EL2", 0b11, 0b100, 0b1010, 0b0111, 0b001>;
2350+
def : RWSysReg<"MPAMVIDSR_EL3", 0b11, 0b110, 0b1010, 0b0111, 0b001>;
2351+
23392352
//===----------------------------------------------------------------------===//
23402353
// FEAT_SRMASK v9.6a registers
23412354
//===----------------------------------------------------------------------===//
@@ -2442,3 +2455,35 @@ foreach n = 0-3 in {
24422455
}
24432456

24442457
def : ROSysReg<"TLBIDIDR_EL1", 0b11, 0b000, 0b1010, 0b0100, 0b110>;
2458+
2459+
// MPAM Lookaside Buffer Invalidate (MLBI) instructions
2460+
class MLBI<string name, bits<3> op1, bits<4> crn, bits<4> crm, bits<3> op2, bit needsreg> {
2461+
string Name = name;
2462+
bits<14> Encoding;
2463+
let Encoding{13-11} = op1;
2464+
let Encoding{10-7} = crn;
2465+
let Encoding{6-3} = crm;
2466+
let Encoding{2-0} = op2;
2467+
bit NeedsReg = needsreg;
2468+
string RequiresStr = [{ {AArch64::FeatureMPAMv2} }];
2469+
}
2470+
2471+
def MLBITable : GenericTable {
2472+
let FilterClass = "MLBI";
2473+
let CppTypeName = "MLBI";
2474+
let Fields = ["Name", "Encoding", "NeedsReg", "RequiresStr"];
2475+
2476+
let PrimaryKey = ["Encoding"];
2477+
let PrimaryKeyName = "lookupMLBIByEncoding";
2478+
}
2479+
2480+
def lookupMLBIByName : SearchIndex {
2481+
let Table = MLBITable;
2482+
let Key = ["Name"];
2483+
}
2484+
2485+
// Op1 CRn CRm Op2 needsReg
2486+
def : MLBI<"ALLE1", 0b100, 0b0111, 0b0000, 0b100, 0>;
2487+
def : MLBI<"VMALLE1", 0b100, 0b0111, 0b0000, 0b101, 0>;
2488+
def : MLBI<"VPIDE1", 0b100, 0b0111, 0b0000, 0b110, 1>;
2489+
def : MLBI<"VPMGE1", 0b100, 0b0111, 0b0000, 0b111, 1>;

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3886,6 +3886,7 @@ static const struct Extension {
38863886
{"cmh", {AArch64::FeatureCMH}},
38873887
{"lscp", {AArch64::FeatureLSCP}},
38883888
{"tlbid", {AArch64::FeatureTLBID}},
3889+
{"mpamv2", {AArch64::FeatureMPAMv2}},
38893890
};
38903891

38913892
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) {
@@ -3958,8 +3959,9 @@ void AArch64AsmParser::createSysAlias(uint16_t Encoding, OperandVector &Operands
39583959
AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
39593960
}
39603961

3961-
/// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for
3962-
/// the SYS instruction. Parse them specially so that we create a SYS MCInst.
3962+
/// parseSysAlias - The IC, DC, AT, TLBI, and MLBI instructions
3963+
/// are simple aliases for the SYS instruction. Parse them specially so that
3964+
/// we create a SYS MCInst.
39633965
bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
39643966
OperandVector &Operands) {
39653967
if (Name.contains('.'))
@@ -4021,7 +4023,19 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
40214023
OptionalRegister = TLBI->OptionalReg;
40224024
}
40234025
createSysAlias(TLBI->Encoding, Operands, S);
4024-
} else if (Mnemonic == "cfp" || Mnemonic == "dvp" || Mnemonic == "cpp" || Mnemonic == "cosp") {
4026+
} else if (Mnemonic == "mlbi") {
4027+
const AArch64MLBI::MLBI *MLBI = AArch64MLBI::lookupMLBIByName(Op);
4028+
if (!MLBI)
4029+
return TokError("invalid operand for MLBI instruction");
4030+
else if (!MLBI->haveFeatures(getSTI().getFeatureBits())) {
4031+
std::string Str("MLBI " + std::string(MLBI->Name) + " requires: ");
4032+
setRequiredFeatureString(MLBI->getRequiredFeatures(), Str);
4033+
return TokError(Str);
4034+
}
4035+
ExpectRegister = MLBI->NeedsReg;
4036+
createSysAlias(MLBI->Encoding, Operands, S);
4037+
} else if (Mnemonic == "cfp" || Mnemonic == "dvp" || Mnemonic == "cpp" ||
4038+
Mnemonic == "cosp") {
40254039

40264040
if (Op.lower() != "rctx")
40274041
return TokError("invalid operand for prediction restriction instruction");
@@ -5338,10 +5352,11 @@ bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info,
53385352
size_t Start = 0, Next = Name.find('.');
53395353
StringRef Head = Name.slice(Start, Next);
53405354

5341-
// IC, DC, AT, TLBI and Prediction invalidation instructions are aliases for
5342-
// the SYS instruction.
5355+
// IC, DC, AT, TLBI, MLBI and Prediction invalidation instructions are aliases
5356+
// for the SYS instruction.
53435357
if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi" ||
5344-
Head == "cfp" || Head == "dvp" || Head == "cpp" || Head == "cosp")
5358+
Head == "cfp" || Head == "dvp" || Head == "cpp" || Head == "cosp" ||
5359+
Head == "mlbi")
53455360
return parseSysAlias(Head, NameLoc, Operands);
53465361

53475362
// TLBIP instructions are aliases for the SYSP instruction.

llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,17 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI,
917917
if (CnVal == 7) {
918918
switch (CmVal) {
919919
default: return false;
920+
// MLBI aliases
921+
case 0: {
922+
const AArch64MLBI::MLBI *MLBI =
923+
AArch64MLBI::lookupMLBIByEncoding(Encoding);
924+
if (!MLBI || !MLBI->haveFeatures(STI.getFeatureBits()))
925+
return false;
926+
927+
NeedsReg = MLBI->NeedsReg;
928+
Ins = "mlbi\t";
929+
Name = std::string(MLBI->Name);
930+
} break;
920931
// Maybe IC, maybe Prediction Restriction
921932
case 1:
922933
switch (Op1Val) {

llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ namespace AArch64TLBIP {
197197
#define GET_TLBIPTable_IMPL
198198
#include "AArch64GenSystemOperands.inc"
199199
} // namespace AArch64TLBIP
200+
201+
namespace AArch64MLBI {
202+
#define GET_MLBITable_IMPL
203+
#include "AArch64GenSystemOperands.inc"
204+
} // namespace AArch64MLBI
200205
} // namespace llvm
201206

202207
namespace llvm {

llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,14 @@ struct TLBIP : SysAliasOptionalReg {
821821
#include "AArch64GenSystemOperands.inc"
822822
} // namespace AArch64TLBIP
823823

824+
namespace AArch64MLBI {
825+
struct MLBI : SysAliasReg {
826+
using SysAliasReg::SysAliasReg;
827+
};
828+
#define GET_MLBITable_DECL
829+
#include "AArch64GenSystemOperands.inc"
830+
} // namespace AArch64MLBI
831+
824832
namespace AArch64II {
825833
/// Target Operand Flag enum.
826834
enum TOF {

llvm/test/MC/AArch64/armv8.4a-mpam.s

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.4a < %s 2> %t | FileCheck %s --check-prefix=CHECK
2-
// RUN: FileCheck --check-prefix=CHECK-RO < %t %s
32
// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=-v8.4a < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
43

54
//------------------------------------------------------------------------------
@@ -56,9 +55,6 @@ mrs x0, MPAMIDR_EL1
5655
//CHECK: msr MPAMVPM6_EL2, x0 // encoding: [0xc0,0xa6,0x1c,0xd5]
5756
//CHECK: msr MPAMVPM7_EL2, x0 // encoding: [0xe0,0xa6,0x1c,0xd5]
5857

59-
//CHECK-RO: error: expected writable system register or pstate
60-
//CHECK-RO: msr MPAMIDR_EL1, x0
61-
//CHECK-RO: ^
6258

6359
//CHECK: mrs x0, MPAM0_EL1 // encoding: [0x20,0xa5,0x38,0xd5]
6460
//CHECK: mrs x0, MPAM1_EL1 // encoding: [0x00,0xa5,0x38,0xd5]
@@ -77,24 +73,7 @@ mrs x0, MPAMIDR_EL1
7773
//CHECK: mrs x0, MPAMVPM7_EL2 // encoding: [0xe0,0xa6,0x3c,0xd5]
7874
//CHECK: mrs x0, MPAMIDR_EL1 // encoding: [0x80,0xa4,0x38,0xd5]
7975

80-
//CHECK-ERROR: error: expected writable system register or pstate
81-
//CHECK-ERROR: msr MPAM0_EL1, x0
82-
//CHECK-ERROR: ^
83-
//CHECK-ERROR: error: expected writable system register or pstate
84-
//CHECK-ERROR: msr MPAM1_EL1, x0
85-
//CHECK-ERROR: ^
86-
//CHECK-ERROR: error: expected writable system register or pstate
87-
//CHECK-ERROR: msr MPAM2_EL2, x0
88-
//CHECK-ERROR: ^
89-
//CHECK-ERROR: error: expected writable system register or pstate
90-
//CHECK-ERROR: msr MPAM3_EL3, x0
91-
//CHECK-ERROR: ^
92-
//CHECK-ERROR: error: expected writable system register or pstate
93-
//CHECK-ERROR: msr MPAM1_EL12, x0
94-
//CHECK-ERROR: ^
95-
//CHECK-ERROR: error: expected writable system register or pstate
96-
//CHECK-ERROR: msr MPAMHCR_EL2, x0
97-
//CHECK-ERROR: ^
76+
9877
//CHECK-ERROR: error: expected writable system register or pstate
9978
//CHECK-ERROR: msr MPAMVPMV_EL2, x0
10079
//CHECK-ERROR: ^
@@ -122,28 +101,8 @@ mrs x0, MPAMIDR_EL1
122101
//CHECK-ERROR: error: expected writable system register or pstate
123102
//CHECK-ERROR: msr MPAMVPM7_EL2, x0
124103
//CHECK-ERROR: ^
125-
//CHECK-ERROR: error: expected writable system register or pstate
126-
//CHECK-ERROR: msr MPAMIDR_EL1, x0
127-
//CHECK-ERROR: ^
128104

129-
//CHECK-ERROR: error: expected readable system register
130-
//CHECK-ERROR: mrs x0, MPAM0_EL1
131-
//CHECK-ERROR: ^
132-
//CHECK-ERROR: error: expected readable system register
133-
//CHECK-ERROR: mrs x0, MPAM1_EL1
134-
//CHECK-ERROR: ^
135-
//CHECK-ERROR: error: expected readable system register
136-
//CHECK-ERROR: mrs x0, MPAM2_EL2
137-
//CHECK-ERROR: ^
138-
//CHECK-ERROR: error: expected readable system register
139-
//CHECK-ERROR: mrs x0, MPAM3_EL3
140-
//CHECK-ERROR: ^
141-
//CHECK-ERROR: error: expected readable system register
142-
//CHECK-ERROR: mrs x0, MPAM1_EL12
143-
//CHECK-ERROR: ^
144-
//CHECK-ERROR: error: expected readable system register
145-
//CHECK-ERROR: mrs x0, MPAMHCR_EL2
146-
//CHECK-ERROR: ^
105+
147106
//CHECK-ERROR: error: expected readable system register
148107
//CHECK-ERROR: mrs x0, MPAMVPMV_EL2
149108
//CHECK-ERROR: ^
@@ -171,6 +130,3 @@ mrs x0, MPAMIDR_EL1
171130
//CHECK-ERROR: error: expected readable system register
172131
//CHECK-ERROR: mrs x0, MPAMVPM7_EL2
173132
//CHECK-ERROR: ^
174-
//CHECK-ERROR: error: expected readable system register
175-
//CHECK-ERROR: mrs x0, MPAMIDR_EL1
176-
//CHECK-ERROR: ^

0 commit comments

Comments
 (0)