Skip to content

Commit 6836261

Browse files
jthackrayStylie777
andauthored
[AArch64][llvm] Armv9.7-A: Add support for GICv5 (FEAT_GCIE) (#163159)
Add new instruction and system registers that are specified in the Generic Interrupt Controller Architecture v5 (GICv5) standard, announced here: * https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/introducing-gicv5 and documented here: * https://developer.arm.com/documentation/109697/2025_09/2025-Architecture-Extensions * https://developer.arm.com/documentation/ddi0602/2025-09/ Co-authored-by: Jack Styles <[email protected]>
1 parent ca10dac commit 6836261

File tree

13 files changed

+1424
-6
lines changed

13 files changed

+1424
-6
lines changed

clang/test/Driver/aarch64-v97a.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,7 @@
3737
// RUN: %clang -target aarch64 -march=armv9.7a+mtetc -### -c %s 2>&1 | FileCheck -check-prefix=V97A-MTETC %s
3838
// RUN: %clang -target aarch64 -march=armv9.7-a+mtetc -### -c %s 2>&1 | FileCheck -check-prefix=V97A-MTETC %s
3939
// V97A-MTETC: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.7a"{{.*}} "-target-feature" "+mtetc"
40+
41+
// RUN: %clang -target aarch64 -march=armv9.7a+gcie -### -c %s 2>&1 | FileCheck -check-prefix=V97A-GCIE %s
42+
// RUN: %clang -target aarch64 -march=armv9.7-a+gcie -### -c %s 2>&1 | FileCheck -check-prefix=V97A-GCIE %s
43+
// V97A-GCIE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.7a"{{.*}} "-target-feature" "+gcie"

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
// CHECK-NEXT: fp8fma FEAT_FP8FMA Enable Armv9.5-A FP8 multiply-add instructions
3333
// CHECK-NEXT: fprcvt FEAT_FPRCVT Enable Armv9.6-A base convert instructions for SIMD&FP scalar register operands of different input and output sizes
3434
// CHECK-NEXT: fp16 FEAT_FP16 Enable half-precision floating-point data processing
35+
// CHECK-NEXT: gcie FEAT_GCIE Enable GICv5 (Generic Interrupt Controller) CPU Interface Extension
3536
// CHECK-NEXT: gcs FEAT_GCS Enable Armv9.4-A Guarded Call Stack Extension
3637
// CHECK-NEXT: hbc FEAT_HBC Enable Armv8.8-A Hinted Conditional Branches Extension
3738
// CHECK-NEXT: i8mm FEAT_I8MM Enable Matrix Multiply Int8 Extension

llvm/lib/Target/AArch64/AArch64Features.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,9 @@ def FeatureMPAMv2: ExtensionWithMArch<"mpamv2", "MPAMv2", "FEAT_MPAMv2",
604604
def FeatureMTETC: ExtensionWithMArch<"mtetc", "MTETC", "FEAT_MTETC",
605605
"Enable Virtual Memory Tagging Extension">;
606606

607+
def FeatureGCIE: ExtensionWithMArch<"gcie", "GCIE", "FEAT_GCIE",
608+
"Enable GICv5 (Generic Interrupt Controller) CPU Interface Extension">;
609+
607610
//===----------------------------------------------------------------------===//
608611
// Other Features
609612
//===----------------------------------------------------------------------===//

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,8 @@ def HasMPAMv2 : Predicate<"Subtarget->hasMPAMv2()">,
406406
AssemblerPredicateWithAll<(all_of FeatureMPAMv2), "mpamv2">;
407407
def HasMTETC : Predicate<"Subtarget->hasMTETC()">,
408408
AssemblerPredicateWithAll<(all_of FeatureMTETC), "mtetc">;
409+
def HasGCIE : Predicate<"Subtarget->hasGCIE()">,
410+
AssemblerPredicateWithAll<(all_of FeatureGCIE), "gcie">;
409411
def IsLE : Predicate<"Subtarget->isLittleEndian()">;
410412
def IsBE : Predicate<"!Subtarget->isLittleEndian()">;
411413
def IsWindows : Predicate<"Subtarget->isTargetWindows()">;

llvm/lib/Target/AArch64/AArch64SystemOperands.td

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2493,3 +2493,206 @@ def : MLBI<"ALLE1", 0b100, 0b0111, 0b0000, 0b100, 0>;
24932493
def : MLBI<"VMALLE1", 0b100, 0b0111, 0b0000, 0b101, 0>;
24942494
def : MLBI<"VPIDE1", 0b100, 0b0111, 0b0000, 0b110, 1>;
24952495
def : MLBI<"VPMGE1", 0b100, 0b0111, 0b0000, 0b111, 1>;
2496+
2497+
2498+
// v9.7-A GICv5 (FEAT_GCIE)
2499+
// CPU Interface Registers
2500+
// Op0 Op1 CRn CRm Op2
2501+
def : RWSysReg<"ICC_APR_EL1", 0b11, 0b001, 0b1100, 0b0000, 0b000>;
2502+
def : RWSysReg<"ICC_APR_EL3", 0b11, 0b110, 0b1100, 0b1000, 0b000>;
2503+
def : RWSysReg<"ICC_CR0_EL1", 0b11, 0b001, 0b1100, 0b0000, 0b001>;
2504+
def : RWSysReg<"ICC_CR0_EL3", 0b11, 0b110, 0b1100, 0b1001, 0b000>;
2505+
def : ROSysReg<"ICC_DOMHPPIR_EL3", 0b11, 0b110, 0b1100, 0b1000, 0b010>;
2506+
def : ROSysReg<"ICC_HAPR_EL1", 0b11, 0b001, 0b1100, 0b0000, 0b011>;
2507+
def : ROSysReg<"ICC_HPPIR_EL1", 0b11, 0b000, 0b1100, 0b1010, 0b011>;
2508+
def : ROSysReg<"ICC_HPPIR_EL3", 0b11, 0b110, 0b1100, 0b1001, 0b001>;
2509+
def : ROSysReg<"ICC_IAFFIDR_EL1", 0b11, 0b000, 0b1100, 0b1010, 0b101>;
2510+
def : RWSysReg<"ICC_ICSR_EL1", 0b11, 0b000, 0b1100, 0b1010, 0b100>;
2511+
def : ROSysReg<"ICC_IDR0_EL1", 0b11, 0b000, 0b1100, 0b1010, 0b010>;
2512+
def : RWSysReg<"ICC_PCR_EL1", 0b11, 0b001, 0b1100, 0b0000, 0b010>;
2513+
def : RWSysReg<"ICC_PCR_EL3", 0b11, 0b110, 0b1100, 0b1000, 0b001>;
2514+
2515+
// Virtual CPU Interface Registers
2516+
// Op0 Op1 CRn CRm Op2
2517+
def : RWSysReg<"ICV_APR_EL1", 0b11, 0b001, 0b1100, 0b0000, 0b000>;
2518+
def : RWSysReg<"ICV_CR0_EL1", 0b11, 0b001, 0b1100, 0b0000, 0b001>;
2519+
def : RWSysReg<"ICV_HAPR_EL1", 0b11, 0b001, 0b1100, 0b0000, 0b011>;
2520+
def : RWSysReg<"ICV_HPPIR_EL1", 0b11, 0b000, 0b1100, 0b1010, 0b011>;
2521+
def : RWSysReg<"ICV_PCR_EL1", 0b11, 0b001, 0b1100, 0b0000, 0b010>;
2522+
2523+
foreach n=0-3 in {
2524+
defvar nb = !cast<bits<2>>(n);
2525+
// Op0 Op1 CRn CRm Op2
2526+
def : RWSysReg<"ICC_PPI_DOMAINR"#n#"_EL3", 0b11, 0b110, 0b1100, 0b1000, {0b1,nb{1-0}}>;
2527+
2528+
}
2529+
2530+
foreach n=0-15 in{
2531+
defvar nb = !cast<bits<4>>(n);
2532+
// Op0 Op1 CRn CRm Op2
2533+
def : RWSysReg<"ICC_PPI_PRIORITYR"#n#"_EL1", 0b11, 0b000, 0b1100, {0b111,nb{3}}, nb{2-0}>;
2534+
}
2535+
2536+
// PPI and Virtual PPI Registers
2537+
multiclass PPIRegisters<string prefix> {
2538+
foreach n=0-1 in {
2539+
defvar nb = !cast<bit>(n);
2540+
// Op0 Op1 CRn CRm Op2
2541+
def : RWSysReg<prefix#"_PPI_CACTIVER"#n#"_EL1", 0b11, 0b000, 0b1100, 0b1101, {0b00,nb}>;
2542+
def : RWSysReg<prefix#"_PPI_CPENDR"#n#"_EL1", 0b11, 0b000, 0b1100, 0b1101, {0b10,nb}>;
2543+
def : RWSysReg<prefix#"_PPI_ENABLER"#n#"_EL1", 0b11, 0b000, 0b1100, 0b1010, {0b11,nb}>;
2544+
def : RWSysReg<prefix#"_PPI_SACTIVER"#n#"_EL1", 0b11, 0b000, 0b1100, 0b1101, {0b01,nb}>;
2545+
def : RWSysReg<prefix#"_PPI_SPENDR"#n#"_EL1", 0b11, 0b000, 0b1100, 0b1101, {0b11,nb}>;
2546+
def : RWSysReg<prefix#"_PPI_HMR"#n#"_EL1", 0b11, 0b000, 0b1100, 0b1010, {0b00,nb}>;
2547+
}
2548+
}
2549+
2550+
defm : PPIRegisters<"ICC">; // PPI Registers
2551+
defm : PPIRegisters<"ICV">; // Virtual PPI Registers
2552+
2553+
foreach n=0-15 in {
2554+
defvar nb = !cast<bits<4>>(n);
2555+
// Op0 Op1 CRn CRm Op2
2556+
def : RWSysReg<"ICV_PPI_PRIORITYR"#n#"_EL1", 0b11, 0b000, 0b1100, {0b111,nb{3}}, nb{2-0}>;
2557+
}
2558+
2559+
// Hypervisor Control Registers
2560+
// Op0 Op1 CRn CRm Op2
2561+
def : RWSysReg<"ICH_APR_EL2", 0b11, 0b100, 0b1100, 0b1000, 0b100>;
2562+
def : RWSysReg<"ICH_CONTEXTR_EL2", 0b11, 0b100, 0b1100, 0b1011, 0b110>;
2563+
def : RWSysReg<"ICH_HFGITR_EL2", 0b11, 0b100, 0b1100, 0b1001, 0b111>;
2564+
def : RWSysReg<"ICH_HFGRTR_EL2", 0b11, 0b100, 0b1100, 0b1001, 0b100>;
2565+
def : RWSysReg<"ICH_HFGWTR_EL2", 0b11, 0b100, 0b1100, 0b1001, 0b110>;
2566+
def : ROSysReg<"ICH_HPPIR_EL2", 0b11, 0b100, 0b1100, 0b1000, 0b101>;
2567+
def : RWSysReg<"ICH_VCTLR_EL2", 0b11, 0b100, 0b1100, 0b1011, 0b100>;
2568+
2569+
foreach n=0-1 in {
2570+
defvar nb = !cast<bit>(n);
2571+
// Op0 Op1 CRn CRm Op2
2572+
def : RWSysReg<"ICH_PPI_ACTIVER"#n#"_EL2", 0b11, 0b100, 0b1100, 0b1010, {0b11,nb}>;
2573+
def : RWSysReg<"ICH_PPI_DVIR"#n#"_EL2", 0b11, 0b100, 0b1100, 0b1010, {0b00,nb}>;
2574+
def : RWSysReg<"ICH_PPI_ENABLER"#n#"_EL2", 0b11, 0b100, 0b1100, 0b1010, {0b01,nb}>;
2575+
def : RWSysReg<"ICH_PPI_PENDR"#n#"_EL2", 0b11, 0b100, 0b1100, 0b1010, {0b10,nb}>;
2576+
}
2577+
2578+
foreach n=0-15 in {
2579+
defvar nb = !cast<bits<4>>(n);
2580+
// Op0 Op1 CRn CRm Op2
2581+
def : RWSysReg<"ICH_PPI_PRIORITYR"#n#"_EL2", 0b11, 0b100, 0b1100, {0b111,nb{3}}, nb{2-0}>;
2582+
}
2583+
2584+
//===----------------------------------------------------------------------===//
2585+
// GICv5 instruction options.
2586+
//===----------------------------------------------------------------------===//
2587+
2588+
// GIC
2589+
class GIC<string name, bits<3> op1, bits<4> crn, bits<4> crm, bits<3> op2> {
2590+
string Name = name;
2591+
bits<14> Encoding;
2592+
let Encoding{13-11} = op1;
2593+
let Encoding{10-7} = crn;
2594+
let Encoding{6-3} = crm;
2595+
let Encoding{2-0} = op2;
2596+
bit NeedsReg = 1;
2597+
string RequiresStr = [{ {AArch64::FeatureGCIE} }];
2598+
}
2599+
2600+
// GSB
2601+
class GSB<string name, bits<3> op1, bits<4> crn, bits<4> crm, bits<3> op2> {
2602+
string Name = name;
2603+
bits<14> Encoding;
2604+
let Encoding{13-11} = op1;
2605+
let Encoding{10-7} = crn;
2606+
let Encoding{6-3} = crm;
2607+
let Encoding{2-0} = op2;
2608+
string RequiresStr = [{ {AArch64::FeatureGCIE} }];
2609+
}
2610+
2611+
// GICR
2612+
class GICR<string name, bits<3> op1, bits<4> crn, bits<4> crm, bits<3> op2> {
2613+
string Name = name;
2614+
bits<14> Encoding;
2615+
let Encoding{13-11} = op1;
2616+
let Encoding{10-7} = crn;
2617+
let Encoding{6-3} = crm;
2618+
let Encoding{2-0} = op2;
2619+
bit NeedsReg = 1;
2620+
string RequiresStr = [{ {AArch64::FeatureGCIE} }];
2621+
}
2622+
2623+
def GICTable : GenericTable {
2624+
let FilterClass = "GIC";
2625+
let CppTypeName = "GIC";
2626+
let Fields = ["Name", "Encoding", "NeedsReg", "RequiresStr"];
2627+
2628+
let PrimaryKey = ["Encoding"];
2629+
let PrimaryKeyName = "lookupGICByEncoding";
2630+
}
2631+
2632+
def GSBTable : GenericTable {
2633+
let FilterClass = "GSB";
2634+
let CppTypeName = "GSB";
2635+
let Fields = ["Name", "Encoding", "RequiresStr"];
2636+
2637+
let PrimaryKey = ["Encoding"];
2638+
let PrimaryKeyName = "lookupGSBByEncoding";
2639+
}
2640+
2641+
def GICRTable : GenericTable {
2642+
let FilterClass = "GICR";
2643+
let CppTypeName = "GICR";
2644+
let Fields = ["Name", "Encoding", "NeedsReg", "RequiresStr"];
2645+
2646+
let PrimaryKey = ["Encoding"];
2647+
let PrimaryKeyName = "lookupGICRByEncoding";
2648+
}
2649+
2650+
def lookupGICByName : SearchIndex {
2651+
let Table = GICTable;
2652+
let Key = ["Name"];
2653+
}
2654+
2655+
def lookupGSBByName : SearchIndex {
2656+
let Table = GSBTable;
2657+
let Key = ["Name"];
2658+
}
2659+
2660+
def lookupGICRByName : SearchIndex {
2661+
let Table = GICRTable;
2662+
let Key = ["Name"];
2663+
}
2664+
2665+
// Op1 CRn CRm Op2
2666+
def : GSB<"sys", 0b000, 0b1100, 0b0000, 0b000>;
2667+
def : GSB<"ack", 0b000, 0b1100, 0b0000, 0b001>;
2668+
2669+
// Op1 CRn CRm Op2
2670+
def : GICR<"cdia", 0b000, 0b1100, 0b0011, 0b000>;
2671+
def : GICR<"cdnmia", 0b000, 0b1100, 0b0011, 0b001>;
2672+
2673+
// Op1 CRn CRm Op2
2674+
def : GIC<"cdaff", 0b000, 0b1100, 0b0001, 0b011>;
2675+
def : GIC<"cddi", 0b000, 0b1100, 0b0010, 0b000>;
2676+
def : GIC<"cddis", 0b000, 0b1100, 0b0001, 0b000>;
2677+
def : GIC<"cden", 0b000, 0b1100, 0b0001, 0b001>;
2678+
def : GIC<"cdeoi", 0b000, 0b1100, 0b0001, 0b111>;
2679+
def : GIC<"cdhm", 0b000, 0b1100, 0b0010, 0b001>;
2680+
def : GIC<"cdpend", 0b000, 0b1100, 0b0001, 0b100>;
2681+
def : GIC<"cdpri", 0b000, 0b1100, 0b0001, 0b010>;
2682+
def : GIC<"cdrcfg", 0b000, 0b1100, 0b0001, 0b101>;
2683+
def : GIC<"vdaff", 0b100, 0b1100, 0b0001, 0b011>;
2684+
def : GIC<"vddi", 0b100, 0b1100, 0b0010, 0b000>;
2685+
def : GIC<"vddis", 0b100, 0b1100, 0b0001, 0b000>;
2686+
def : GIC<"vden", 0b100, 0b1100, 0b0001, 0b001>;
2687+
def : GIC<"vdhm", 0b100, 0b1100, 0b0010, 0b001>;
2688+
def : GIC<"vdpend", 0b100, 0b1100, 0b0001, 0b100>;
2689+
def : GIC<"vdpri", 0b100, 0b1100, 0b0001, 0b010>;
2690+
def : GIC<"vdrcfg", 0b100, 0b1100, 0b0001, 0b101>;
2691+
def : GIC<"ldaff", 0b110, 0b1100, 0b0001, 0b011>;
2692+
def : GIC<"lddi", 0b110, 0b1100, 0b0010, 0b000>;
2693+
def : GIC<"lddis", 0b110, 0b1100, 0b0001, 0b000>;
2694+
def : GIC<"lden", 0b110, 0b1100, 0b0001, 0b001>;
2695+
def : GIC<"ldhm", 0b110, 0b1100, 0b0010, 0b001>;
2696+
def : GIC<"ldpend", 0b110, 0b1100, 0b0001, 0b100>;
2697+
def : GIC<"ldpri", 0b110, 0b1100, 0b0001, 0b010>;
2698+
def : GIC<"ldrcfg", 0b110, 0b1100, 0b0001, 0b101>;

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

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
159159
SMLoc getLoc() const { return getParser().getTok().getLoc(); }
160160

161161
bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
162+
bool parseSyslAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
162163
bool parseSyspAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
163164
void createSysAlias(uint16_t Encoding, OperandVector &Operands, SMLoc S);
164165
AArch64CC::CondCode parseCondCodeString(StringRef Cond,
@@ -3888,6 +3889,7 @@ static const struct Extension {
38883889
{"tlbid", {AArch64::FeatureTLBID}},
38893890
{"mpamv2", {AArch64::FeatureMPAMv2}},
38903891
{"mtetc", {AArch64::FeatureMTETC}},
3892+
{"gcie", {AArch64::FeatureGCIE}},
38913893
};
38923894

38933895
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) {
@@ -3960,7 +3962,7 @@ void AArch64AsmParser::createSysAlias(uint16_t Encoding, OperandVector &Operands
39603962
AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
39613963
}
39623964

3963-
/// parseSysAlias - The IC, DC, AT, TLBI, and MLBI instructions
3965+
/// parseSysAlias - The IC, DC, AT, TLBI, MLBI and GIC{R} and GSB instructions
39643966
/// are simple aliases for the SYS instruction. Parse them specially so that
39653967
/// we create a SYS MCInst.
39663968
bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
@@ -4035,6 +4037,28 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
40354037
}
40364038
ExpectRegister = MLBI->NeedsReg;
40374039
createSysAlias(MLBI->Encoding, Operands, S);
4040+
} else if (Mnemonic == "gic") {
4041+
const AArch64GIC::GIC *GIC = AArch64GIC::lookupGICByName(Op);
4042+
if (!GIC)
4043+
return TokError("invalid operand for GIC instruction");
4044+
else if (!GIC->haveFeatures(getSTI().getFeatureBits())) {
4045+
std::string Str("GIC " + std::string(GIC->Name) + " requires: ");
4046+
setRequiredFeatureString(GIC->getRequiredFeatures(), Str);
4047+
return TokError(Str);
4048+
}
4049+
ExpectRegister = true;
4050+
createSysAlias(GIC->Encoding, Operands, S);
4051+
} else if (Mnemonic == "gsb") {
4052+
const AArch64GSB::GSB *GSB = AArch64GSB::lookupGSBByName(Op);
4053+
if (!GSB)
4054+
return TokError("invalid operand for GSB instruction");
4055+
else if (!GSB->haveFeatures(getSTI().getFeatureBits())) {
4056+
std::string Str("GSB " + std::string(GSB->Name) + " requires: ");
4057+
setRequiredFeatureString(GSB->getRequiredFeatures(), Str);
4058+
return TokError(Str);
4059+
}
4060+
ExpectRegister = false;
4061+
createSysAlias(GSB->Encoding, Operands, S);
40384062
} else if (Mnemonic == "cfp" || Mnemonic == "dvp" || Mnemonic == "cpp" ||
40394063
Mnemonic == "cosp") {
40404064

@@ -4086,6 +4110,55 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
40864110
return false;
40874111
}
40884112

4113+
/// parseSyslAlias - The GICR instructions are simple aliases for
4114+
/// the SYSL instruction. Parse them specially so that we create a
4115+
/// SYS MCInst.
4116+
bool AArch64AsmParser::parseSyslAlias(StringRef Name, SMLoc NameLoc,
4117+
OperandVector &Operands) {
4118+
4119+
Mnemonic = Name;
4120+
Operands.push_back(
4121+
AArch64Operand::CreateToken("sysl", NameLoc, getContext()));
4122+
4123+
// Now expect two operands (identifier + register)
4124+
SMLoc startLoc = getLoc();
4125+
const AsmToken &regTok = getTok();
4126+
StringRef reg = regTok.getString();
4127+
unsigned RegNum = matchRegisterNameAlias(reg.lower(), RegKind::Scalar);
4128+
if (!RegNum)
4129+
return TokError("expected register operand");
4130+
4131+
Operands.push_back(AArch64Operand::CreateReg(
4132+
RegNum, RegKind::Scalar, startLoc, getLoc(), getContext(), EqualsReg));
4133+
4134+
Lex(); // Eat token
4135+
if (parseToken(AsmToken::Comma))
4136+
return true;
4137+
4138+
// Check for identifier
4139+
const AsmToken &operandTok = getTok();
4140+
StringRef Op = operandTok.getString();
4141+
SMLoc S2 = operandTok.getLoc();
4142+
Lex(); // Eat token
4143+
4144+
if (Mnemonic == "gicr") {
4145+
const AArch64GICR::GICR *GICR = AArch64GICR::lookupGICRByName(Op);
4146+
if (!GICR)
4147+
return Error(S2, "invalid operand for GICR instruction");
4148+
else if (!GICR->haveFeatures(getSTI().getFeatureBits())) {
4149+
std::string Str("GICR " + std::string(GICR->Name) + " requires: ");
4150+
setRequiredFeatureString(GICR->getRequiredFeatures(), Str);
4151+
return Error(S2, Str);
4152+
}
4153+
createSysAlias(GICR->Encoding, Operands, S2);
4154+
}
4155+
4156+
if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
4157+
return true;
4158+
4159+
return false;
4160+
}
4161+
40894162
/// parseSyspAlias - The TLBIP instructions are simple aliases for
40904163
/// the SYSP instruction. Parse them specially so that we create a SYSP MCInst.
40914164
bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
@@ -5353,13 +5426,17 @@ bool AArch64AsmParser::parseInstruction(ParseInstructionInfo &Info,
53535426
size_t Start = 0, Next = Name.find('.');
53545427
StringRef Head = Name.slice(Start, Next);
53555428

5356-
// IC, DC, AT, TLBI, MLBI and Prediction invalidation instructions are aliases
5357-
// for the SYS instruction.
5429+
// IC, DC, AT, TLBI, MLBI, GIC{R}, GSB and Prediction invalidation
5430+
// instructions are aliases for the SYS instruction.
53585431
if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi" ||
53595432
Head == "cfp" || Head == "dvp" || Head == "cpp" || Head == "cosp" ||
5360-
Head == "mlbi")
5433+
Head == "mlbi" || Head == "gic" || Head == "gsb")
53615434
return parseSysAlias(Head, NameLoc, Operands);
53625435

5436+
// GICR instructions are aliases for the SYSL instruction.
5437+
if (Head == "gicr")
5438+
return parseSyslAlias(Head, NameLoc, Operands);
5439+
53635440
// TLBIP instructions are aliases for the SYSP instruction.
53645441
if (Head == "tlbip")
53655442
return parseSyspAlias(Head, NameLoc, Operands);

0 commit comments

Comments
 (0)