Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/test/Driver/aarch64-v97a.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@
// 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"

// RUN: %clang -target aarch64 -march=armv9.7a+tlbid -### -c %s 2>&1 | FileCheck -check-prefix=V97A-TLBID %s
// RUN: %clang -target aarch64 -march=armv9.7-a+tlbid -### -c %s 2>&1 | FileCheck -check-prefix=V97A-TLBID %s
// V97A-TLBID: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" "-target-feature" "+v9.7a"{{.*}} "-target-feature" "+tlbid"
1 change: 1 addition & 0 deletions clang/test/Driver/print-supported-extensions-aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
// CHECK-NEXT: sve2p1 FEAT_SVE2p1 Enable Scalable Vector Extension 2.1 instructions
// CHECK-NEXT: sve2p2 FEAT_SVE2p2 Enable Armv9.6-A Scalable Vector Extension 2.2 instructions
// CHECK-NEXT: the FEAT_THE Enable Armv8.9-A Translation Hardening Extension
// CHECK-NEXT: tlbid FEAT_TLBID Enable Armv9.7-A TLBI Domains extension
// CHECK-NEXT: tlbiw FEAT_TLBIW Enable Armv9.5-A TLBI VMALL for Dirty State
// CHECK-NEXT: tme FEAT_TME Enable Transactional Memory Extension
// CHECK-NEXT: wfxt FEAT_WFxT Enable Armv8.7-A WFET and WFIT instruction
3 changes: 3 additions & 0 deletions llvm/lib/Target/AArch64/AArch64Features.td
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,9 @@ def FeatureCMH : ExtensionWithMArch<"cmh", "CMH", "FEAT_CMH",
def FeatureLSCP : ExtensionWithMArch<"lscp", "LSCP", "FEAT_LSCP",
"Enable Armv9.7-A Load-acquire and store-release pair extension">;

def FeatureTLBID: ExtensionWithMArch<"tlbid", "TLBID", "FEAT_TLBID",
"Enable Armv9.7-A TLBI Domains extension">;

//===----------------------------------------------------------------------===//
// Other Features
//===----------------------------------------------------------------------===//
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,8 @@ def HasGCS : Predicate<"Subtarget->hasGCS()">,
AssemblerPredicateWithAll<(all_of FeatureGCS), "gcs">;
def HasCPA : Predicate<"Subtarget->hasCPA()">,
AssemblerPredicateWithAll<(all_of FeatureCPA), "cpa">;
def HasTLBID : Predicate<"Subtarget->hasTLBID()">,
AssemblerPredicateWithAll<(all_of FeatureTLBID), "tlbid">;
def IsLE : Predicate<"Subtarget->isLittleEndian()">;
def IsBE : Predicate<"!Subtarget->isLittleEndian()">;
def IsWindows : Predicate<"Subtarget->isTargetWindows()">;
Expand Down
72 changes: 37 additions & 35 deletions llvm/lib/Target/AArch64/AArch64SystemOperands.td
Original file line number Diff line number Diff line change
Expand Up @@ -832,32 +832,33 @@ def : CMHPriorityHint<"ph", 0b1>;
//===----------------------------------------------------------------------===//

class TLBICommon<string name, bits<3> op1, bits<4> crn, bits<4> crm,
bits<3> op2, bit needsreg> {
bits<3> op2, bit needsreg, bit optionalreg> {
string Name = name;
bits<14> Encoding;
let Encoding{13-11} = op1;
let Encoding{10-7} = crn;
let Encoding{6-3} = crm;
let Encoding{2-0} = op2;
bit NeedsReg = needsreg;
bit OptionalReg = optionalreg;
list<string> Requires = [];
list<string> ExtraRequires = [];
code RequiresStr = [{ { }] # !interleave(Requires # ExtraRequires, [{, }]) # [{ } }];
}

class TLBIEntry<string name, bits<3> op1, bits<4> crn, bits<4> crm,
bits<3> op2, bit needsreg>
: TLBICommon<name, op1, crn, crm, op2, needsreg>;
bits<3> op2, bit needsreg, bit optionalreg>
: TLBICommon<name, op1, crn, crm, op2, needsreg, optionalreg>;

class TLBIPEntry<string name, bits<3> op1, bits<4> crn, bits<4> crm,
bits<3> op2, bit needsreg>
: TLBICommon<name, op1, crn, crm, op2, needsreg>;
bits<3> op2, bit needsreg, bit optionalreg>
: TLBICommon<name, op1, crn, crm, op2, needsreg, optionalreg>;

multiclass TLBITableBase {
def NAME # Table : GenericTable {
let FilterClass = NAME # "Entry";
let CppTypeName = NAME;
let Fields = ["Name", "Encoding", "NeedsReg", "RequiresStr"];
let Fields = ["Name", "Encoding", "NeedsReg", "OptionalReg", "RequiresStr"];
let PrimaryKey = ["Encoding"];
let PrimaryKeyName = "lookup" # NAME # "ByEncoding";
}
Expand All @@ -871,60 +872,60 @@ defm TLBI : TLBITableBase;
defm TLBIP : TLBITableBase;

multiclass TLBI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn, bits<4> crm,
bits<3> op2, bit needsreg = 1> {
def : TLBIEntry<name, op1, crn, crm, op2, needsreg>;
def : TLBIEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, needsreg> {
bits<3> op2, bit needsreg = 1, bit optionalreg = 0> {
def : TLBIEntry<name, op1, crn, crm, op2, needsreg, optionalreg>;
def : TLBIEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, needsreg, optionalreg> {
let Encoding{7} = 1;
let ExtraRequires = ["AArch64::FeatureXS"];
}
if !eq(hasTLBIP, true) then {
def : TLBIPEntry<name, op1, crn, crm, op2, needsreg>;
def : TLBIPEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, needsreg> {
def : TLBIPEntry<name, op1, crn, crm, op2, needsreg, optionalreg>;
def : TLBIPEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, needsreg, optionalreg> {
let Encoding{7} = 1;
let ExtraRequires = ["AArch64::FeatureXS"];
}
}
}

// hasTLBIP op1 CRn CRm op2 needsreg
// hasTLBIP op1 CRn CRm op2 needsreg, optreg
defm : TLBI<"IPAS2E1IS", 1, 0b100, 0b1000, 0b0000, 0b001>;
defm : TLBI<"IPAS2LE1IS", 1, 0b100, 0b1000, 0b0000, 0b101>;
defm : TLBI<"VMALLE1IS", 0, 0b000, 0b1000, 0b0011, 0b000, 0>;
defm : TLBI<"ALLE2IS", 0, 0b100, 0b1000, 0b0011, 0b000, 0>;
defm : TLBI<"ALLE3IS", 0, 0b110, 0b1000, 0b0011, 0b000, 0>;
defm : TLBI<"VMALLE1IS", 0, 0b000, 0b1000, 0b0011, 0b000, 0, 1>;
defm : TLBI<"ALLE2IS", 0, 0b100, 0b1000, 0b0011, 0b000, 0, 1>;
defm : TLBI<"ALLE3IS", 0, 0b110, 0b1000, 0b0011, 0b000, 0, 1>;
defm : TLBI<"VAE1IS", 1, 0b000, 0b1000, 0b0011, 0b001>;
defm : TLBI<"VAE2IS", 1, 0b100, 0b1000, 0b0011, 0b001>;
defm : TLBI<"VAE3IS", 1, 0b110, 0b1000, 0b0011, 0b001>;
defm : TLBI<"ASIDE1IS", 0, 0b000, 0b1000, 0b0011, 0b010>;
defm : TLBI<"VAAE1IS", 1, 0b000, 0b1000, 0b0011, 0b011>;
defm : TLBI<"ALLE1IS", 0, 0b100, 0b1000, 0b0011, 0b100, 0>;
defm : TLBI<"ALLE1IS", 0, 0b100, 0b1000, 0b0011, 0b100, 0, 1>;
defm : TLBI<"VALE1IS", 1, 0b000, 0b1000, 0b0011, 0b101>;
defm : TLBI<"VALE2IS", 1, 0b100, 0b1000, 0b0011, 0b101>;
defm : TLBI<"VALE3IS", 1, 0b110, 0b1000, 0b0011, 0b101>;
defm : TLBI<"VMALLS12E1IS", 0, 0b100, 0b1000, 0b0011, 0b110, 0>;
defm : TLBI<"VMALLS12E1IS", 0, 0b100, 0b1000, 0b0011, 0b110, 0, 1>;
defm : TLBI<"VAALE1IS", 1, 0b000, 0b1000, 0b0011, 0b111>;
defm : TLBI<"IPAS2E1", 1, 0b100, 0b1000, 0b0100, 0b001>;
defm : TLBI<"IPAS2LE1", 1, 0b100, 0b1000, 0b0100, 0b101>;
defm : TLBI<"VMALLE1", 0, 0b000, 0b1000, 0b0111, 0b000, 0>;
defm : TLBI<"ALLE2", 0, 0b100, 0b1000, 0b0111, 0b000, 0>;
defm : TLBI<"ALLE3", 0, 0b110, 0b1000, 0b0111, 0b000, 0>;
defm : TLBI<"VMALLE1", 0, 0b000, 0b1000, 0b0111, 0b000, 0, 0>;
defm : TLBI<"ALLE2", 0, 0b100, 0b1000, 0b0111, 0b000, 0, 0>;
defm : TLBI<"ALLE3", 0, 0b110, 0b1000, 0b0111, 0b000, 0, 0>;
defm : TLBI<"VAE1", 1, 0b000, 0b1000, 0b0111, 0b001>;
defm : TLBI<"VAE2", 1, 0b100, 0b1000, 0b0111, 0b001>;
defm : TLBI<"VAE3", 1, 0b110, 0b1000, 0b0111, 0b001>;
defm : TLBI<"ASIDE1", 0, 0b000, 0b1000, 0b0111, 0b010>;
defm : TLBI<"VAAE1", 1, 0b000, 0b1000, 0b0111, 0b011>;
defm : TLBI<"ALLE1", 0, 0b100, 0b1000, 0b0111, 0b100, 0>;
defm : TLBI<"ALLE1", 0, 0b100, 0b1000, 0b0111, 0b100, 0, 0>;
defm : TLBI<"VALE1", 1, 0b000, 0b1000, 0b0111, 0b101>;
defm : TLBI<"VALE2", 1, 0b100, 0b1000, 0b0111, 0b101>;
defm : TLBI<"VALE3", 1, 0b110, 0b1000, 0b0111, 0b101>;
defm : TLBI<"VMALLS12E1", 0, 0b100, 0b1000, 0b0111, 0b110, 0>;
defm : TLBI<"VMALLS12E1", 0, 0b100, 0b1000, 0b0111, 0b110, 0, 0>;
defm : TLBI<"VAALE1", 1, 0b000, 0b1000, 0b0111, 0b111>;

// Armv8.4-A Translation Lookaside Buffer Instructions (TLBI)
let Requires = ["AArch64::FeatureTLB_RMI"] in {
// Armv8.4-A Outer Sharable TLB Maintenance instructions:
// hasTLBIP op1 CRn CRm op2 needsreg
defm : TLBI<"VMALLE1OS", 0, 0b000, 0b1000, 0b0001, 0b000, 0>;
// hasTLBIP op1 CRn CRm op2 needsreg, optreg
defm : TLBI<"VMALLE1OS", 0, 0b000, 0b1000, 0b0001, 0b000, 0, 1>;
defm : TLBI<"VAE1OS", 1, 0b000, 0b1000, 0b0001, 0b001>;
defm : TLBI<"ASIDE1OS", 0, 0b000, 0b1000, 0b0001, 0b010>;
defm : TLBI<"VAAE1OS", 1, 0b000, 0b1000, 0b0001, 0b011>;
Expand All @@ -934,15 +935,15 @@ defm : TLBI<"IPAS2E1OS", 1, 0b100, 0b1000, 0b0100, 0b000>;
defm : TLBI<"IPAS2LE1OS", 1, 0b100, 0b1000, 0b0100, 0b100>;
defm : TLBI<"VAE2OS", 1, 0b100, 0b1000, 0b0001, 0b001>;
defm : TLBI<"VALE2OS", 1, 0b100, 0b1000, 0b0001, 0b101>;
defm : TLBI<"VMALLS12E1OS", 0, 0b100, 0b1000, 0b0001, 0b110, 0>;
defm : TLBI<"VMALLS12E1OS", 0, 0b100, 0b1000, 0b0001, 0b110, 0, 1>;
defm : TLBI<"VAE3OS", 1, 0b110, 0b1000, 0b0001, 0b001>;
defm : TLBI<"VALE3OS", 1, 0b110, 0b1000, 0b0001, 0b101>;
defm : TLBI<"ALLE2OS", 0, 0b100, 0b1000, 0b0001, 0b000, 0>;
defm : TLBI<"ALLE1OS", 0, 0b100, 0b1000, 0b0001, 0b100, 0>;
defm : TLBI<"ALLE3OS", 0, 0b110, 0b1000, 0b0001, 0b000, 0>;
defm : TLBI<"ALLE2OS", 0, 0b100, 0b1000, 0b0001, 0b000, 0, 1>;
defm : TLBI<"ALLE1OS", 0, 0b100, 0b1000, 0b0001, 0b100, 0, 1>;
defm : TLBI<"ALLE3OS", 0, 0b110, 0b1000, 0b0001, 0b000, 0, 1>;

// Armv8.4-A TLB Range Maintenance instructions:
// hasTLBIP op1 CRn CRm op2 needsreg
// hasTLBIP op1 CRn CRm op2
defm : TLBI<"RVAE1", 1, 0b000, 0b1000, 0b0110, 0b001>;
defm : TLBI<"RVAAE1", 1, 0b000, 0b1000, 0b0110, 0b011>;
defm : TLBI<"RVALE1", 1, 0b000, 0b1000, 0b0110, 0b101>;
Expand Down Expand Up @@ -977,18 +978,19 @@ defm : TLBI<"RVALE3OS", 1, 0b110, 0b1000, 0b0101, 0b101>;

// Armv9-A Realm Management Extension TLBI Instructions
let Requires = ["AArch64::FeatureRME"] in {
// hasTLBIP op1 CRn CRm op2 needsreg
defm : TLBI<"RPAOS", 0, 0b110, 0b1000, 0b0100, 0b011>;
defm : TLBI<"RPALOS", 0, 0b110, 0b1000, 0b0100, 0b111>;
defm : TLBI<"PAALLOS", 0, 0b110, 0b1000, 0b0001, 0b100, 0>;
defm : TLBI<"PAALL", 0, 0b110, 0b1000, 0b0111, 0b100, 0>;
defm : TLBI<"PAALLOS", 0, 0b110, 0b1000, 0b0001, 0b100, 0, 0>;
defm : TLBI<"PAALL", 0, 0b110, 0b1000, 0b0111, 0b100, 0, 0>;
}

// Armv9.5-A TLBI VMALL for Dirty State
let Requires = ["AArch64::FeatureTLBIW"] in {
// op1, CRn, CRm, op2, needsreg
defm : TLBI<"VMALLWS2E1", 0, 0b100, 0b1000, 0b0110, 0b010, 0>;
defm : TLBI<"VMALLWS2E1IS", 0, 0b100, 0b1000, 0b0010, 0b010, 0>;
defm : TLBI<"VMALLWS2E1OS", 0, 0b100, 0b1000, 0b0101, 0b010, 0>;
// hasTLBIP op1 CRn CRm op2 needsreg, optreg
defm : TLBI<"VMALLWS2E1", 0, 0b100, 0b1000, 0b0110, 0b010, 0, 0>;
defm : TLBI<"VMALLWS2E1IS", 0, 0b100, 0b1000, 0b0010, 0b010, 0, 1>;
defm : TLBI<"VMALLWS2E1OS", 0, 0b100, 0b1000, 0b0101, 0b010, 0, 1>;
}

//===----------------------------------------------------------------------===//
Expand Down
20 changes: 14 additions & 6 deletions llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3885,6 +3885,7 @@ static const struct Extension {
{"sme-tmop", {AArch64::FeatureSME_TMOP}},
{"cmh", {AArch64::FeatureCMH}},
{"lscp", {AArch64::FeatureLSCP}},
{"tlbid", {AArch64::FeatureTLBID}},
};

static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) {
Expand Down Expand Up @@ -3971,6 +3972,8 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
StringRef Op = Tok.getString();
SMLoc S = Tok.getLoc();
bool ExpectRegister = true;
bool OptionalRegister = false;
bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);

if (Mnemonic == "ic") {
const AArch64IC::IC *IC = AArch64IC::lookupICByName(Op);
Expand Down Expand Up @@ -4013,13 +4016,16 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
return TokError(Str);
}
ExpectRegister = TLBI->NeedsReg;
bool hasTLBID = getSTI().hasFeature(AArch64::FeatureTLBID);
if (hasAll || hasTLBID) {
OptionalRegister = TLBI->OptionalReg;
}
createSysAlias(TLBI->Encoding, Operands, S);
} else if (Mnemonic == "cfp" || Mnemonic == "dvp" || Mnemonic == "cpp" || Mnemonic == "cosp") {

if (Op.lower() != "rctx")
return TokError("invalid operand for prediction restriction instruction");

bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);

Expand Down Expand Up @@ -4052,10 +4058,12 @@ bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
HasRegister = true;
}

if (ExpectRegister && !HasRegister)
return TokError("specified " + Mnemonic + " op requires a register");
else if (!ExpectRegister && HasRegister)
return TokError("specified " + Mnemonic + " op does not use a register");
if (!OptionalRegister) {
if (ExpectRegister && !HasRegister)
return TokError("specified " + Mnemonic + " op requires a register");
else if (!ExpectRegister && HasRegister)
return TokError("specified " + Mnemonic + " op does not use a register");
}

if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
return true;
Expand Down Expand Up @@ -4088,7 +4096,7 @@ bool AArch64AsmParser::parseSyspAlias(StringRef Name, SMLoc NameLoc,
return TokError("invalid operand for TLBIP instruction");
const AArch64TLBIP::TLBIP TLBIP(
TLBIPorig->Name, TLBIPorig->Encoding | (HasnXSQualifier ? (1 << 7) : 0),
TLBIPorig->NeedsReg,
TLBIPorig->NeedsReg, TLBIPorig->OptionalReg,
HasnXSQualifier
? TLBIPorig->FeaturesRequired | FeatureBitset({AArch64::FeatureXS})
: TLBIPorig->FeaturesRequired);
Expand Down
14 changes: 10 additions & 4 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,8 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI,
Encoding |= CnVal << 7;
Encoding |= Op1Val << 11;

bool NeedsReg;
bool NeedsReg = false;
bool OptionalReg = false;
std::string Ins;
std::string Name;

Expand Down Expand Up @@ -1004,6 +1005,9 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI,
return false;

NeedsReg = TLBI->NeedsReg;
if (STI.hasFeature(AArch64::FeatureAll) ||
STI.hasFeature(AArch64::FeatureTLBID))
OptionalReg = TLBI->OptionalReg;
Ins = "tlbi\t";
Name = std::string(TLBI->Name);
}
Expand All @@ -1013,18 +1017,20 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI,
StringRef Reg = getRegisterName(MI->getOperand(4).getReg());
bool NotXZR = Reg != "xzr";

// If a mandatory is not specified in the TableGen
// If a mandatory or optional register is not specified in the TableGen
// (i.e. no register operand should be present), and the register value
// is not xzr/x31, then disassemble to a SYS alias instead.
if (NotXZR && !NeedsReg)
if (NotXZR && !NeedsReg && !OptionalReg)
return false;

std::string Str = Ins + Name;
llvm::transform(Str, Str.begin(), ::tolower);

O << '\t' << Str;

if (NeedsReg)
// For optional registers, don't print the value if it's xzr/x31
// since this defaults to xzr/x31 if register is not specified.
if (NeedsReg || (OptionalReg && NotXZR))
O << ", " << Reg;

return true;
Expand Down
24 changes: 17 additions & 7 deletions llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,16 @@ struct SysAliasReg : SysAlias {
: SysAlias(N, E, F), NeedsReg(R) {}
};

struct SysAliasOptionalReg : SysAlias {
bool NeedsReg;
bool OptionalReg;
constexpr SysAliasOptionalReg(const char *N, uint16_t E, bool R, bool O)
: SysAlias(N, E), NeedsReg(R), OptionalReg(O) {}
constexpr SysAliasOptionalReg(const char *N, uint16_t E, bool R, bool O,
FeatureBitset F)
: SysAlias(N, E, F), NeedsReg(R), OptionalReg(O) {}
};

struct SysAliasImm : SysAlias {
uint16_t ImmValue;
constexpr SysAliasImm(const char *N, uint16_t E, uint16_t I)
Expand Down Expand Up @@ -796,16 +806,16 @@ namespace AArch64SysReg {
}

namespace AArch64TLBI {
struct TLBI : SysAliasReg {
using SysAliasReg::SysAliasReg;
};
#define GET_TLBITable_DECL
#include "AArch64GenSystemOperands.inc"
struct TLBI : SysAliasOptionalReg {
using SysAliasOptionalReg::SysAliasOptionalReg;
};
#define GET_TLBITable_DECL
#include "AArch64GenSystemOperands.inc"
}

namespace AArch64TLBIP {
struct TLBIP : SysAliasReg {
using SysAliasReg::SysAliasReg;
struct TLBIP : SysAliasOptionalReg {
using SysAliasOptionalReg::SysAliasOptionalReg;
};
#define GET_TLBIPTable_DECL
#include "AArch64GenSystemOperands.inc"
Expand Down
Loading