diff --git a/clang/test/Driver/aarch64-v97a.c b/clang/test/Driver/aarch64-v97a.c index 4a55d44466cc0..ec0e4245b81aa 100644 --- a/clang/test/Driver/aarch64-v97a.c +++ b/clang/test/Driver/aarch64-v97a.c @@ -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" diff --git a/clang/test/Driver/print-supported-extensions-aarch64.c b/clang/test/Driver/print-supported-extensions-aarch64.c index 9928f395866d8..3e4ceae5bd5c1 100644 --- a/clang/test/Driver/print-supported-extensions-aarch64.c +++ b/clang/test/Driver/print-supported-extensions-aarch64.c @@ -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 diff --git a/llvm/lib/Target/AArch64/AArch64Features.td b/llvm/lib/Target/AArch64/AArch64Features.td index 7fe83537b7a36..eea06968f438a 100644 --- a/llvm/lib/Target/AArch64/AArch64Features.td +++ b/llvm/lib/Target/AArch64/AArch64Features.td @@ -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 //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 218cd4911a25a..36d50b8f8918d 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -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()">; diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td index d538d071c7d37..81610c11ade2f 100644 --- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td +++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td @@ -832,7 +832,7 @@ def : CMHPriorityHint<"ph", 0b1>; //===----------------------------------------------------------------------===// class TLBICommon 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; @@ -840,24 +840,25 @@ class TLBICommon op1, bits<4> crn, bits<4> crm, let Encoding{6-3} = crm; let Encoding{2-0} = op2; bit NeedsReg = needsreg; + bit OptionalReg = optionalreg; list Requires = []; list ExtraRequires = []; code RequiresStr = [{ { }] # !interleave(Requires # ExtraRequires, [{, }]) # [{ } }]; } class TLBIEntry op1, bits<4> crn, bits<4> crm, - bits<3> op2, bit needsreg> - : TLBICommon; + bits<3> op2, bit needsreg, bit optionalreg> + : TLBICommon; class TLBIPEntry op1, bits<4> crn, bits<4> crm, - bits<3> op2, bit needsreg> - : TLBICommon; + bits<3> op2, bit needsreg, bit optionalreg> + : TLBICommon; 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"; } @@ -871,60 +872,60 @@ defm TLBI : TLBITableBase; defm TLBIP : TLBITableBase; multiclass TLBI op1, bits<4> crn, bits<4> crm, - bits<3> op2, bit needsreg = 1> { - def : TLBIEntry; - def : TLBIEntry { + bits<3> op2, bit needsreg = 1, bit optionalreg = 0> { + def : TLBIEntry; + def : TLBIEntry { let Encoding{7} = 1; let ExtraRequires = ["AArch64::FeatureXS"]; } if !eq(hasTLBIP, true) then { - def : TLBIPEntry; - def : TLBIPEntry { + def : TLBIPEntry; + def : TLBIPEntry { 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>; @@ -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>; @@ -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>; } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 11047a2b008bf..bb6ae27cbdb20 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -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) { @@ -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); @@ -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); @@ -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; @@ -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); diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp index 6bd53f61884c2..936c36b29c12c 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp @@ -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; @@ -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); } @@ -1013,10 +1017,10 @@ 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; @@ -1024,7 +1028,9 @@ bool AArch64InstPrinter::printSysAlias(const MCInst *MI, 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; diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h index e09a0ee0518db..fb5db0dfadddf 100644 --- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -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) @@ -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" diff --git a/llvm/test/MC/AArch64/armv9.7a-tlbid-diagnostics.s b/llvm/test/MC/AArch64/armv9.7a-tlbid-diagnostics.s new file mode 100644 index 0000000000000..2440fd30fae03 --- /dev/null +++ b/llvm/test/MC/AArch64/armv9.7a-tlbid-diagnostics.s @@ -0,0 +1,64 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+tlb-rmi,+tlbiw,+rme < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+tlb-rmi,+tlbiw,+tlbid,+rme < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-NO-REGISTER + +// Test without using +tlbid - no optional register operand allowed + +tlbi vmalle1is, x1 +// CHECK-ERROR: error: specified tlbi op does not use a register + +tlbi vmalle1is, x5 +// CHECK-ERROR: error: specified tlbi op does not use a register + +tlbi vmalle1os, x5 +// CHECK-ERROR: error: specified tlbi op does not use a register + +tlbi vmalls12e1os, x5 +// CHECK-ERROR: error: specified tlbi op does not use a register + +tlbi alle1is, x5 +// CHECK-ERROR: error: specified tlbi op does not use a register + +tlbi alle2is, x5 +// CHECK-ERROR: error: specified tlbi op does not use a register + +tlbi alle3is, x5 +// CHECK-ERROR: error: specified tlbi op does not use a register + +tlbi vmallws2e1os, x1 +// CHECK-ERROR: error: specified tlbi op does not use a register + +tlbi vmalls12e1is, x1 +// CHECK-ERROR: error: specified tlbi op does not use a register + +tlbi vmallws2e1is, x1 +// CHECK-ERROR: error: specified tlbi op does not use a register + +tlbi vmalle1, x1 +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-NO-REGISTER: error: specified tlbi op does not use a register + +tlbi alle1, x1 +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-NO-REGISTER: error: specified tlbi op does not use a register + +tlbi alle2, x1 +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-NO-REGISTER: error: specified tlbi op does not use a register + +tlbi alle3, x1 +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-NO-REGISTER: error: specified tlbi op does not use a register + +tlbi vmalls12e1, x1 +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-NO-REGISTER: error: specified tlbi op does not use a register + +tlbi paallos, x1 +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-NO-REGISTER: error: specified tlbi op does not use a register + +tlbi paall, x1 +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-NO-REGISTER: error: specified tlbi op does not use a register diff --git a/llvm/test/MC/AArch64/armv9.7a-tlbid.s b/llvm/test/MC/AArch64/armv9.7a-tlbid.s new file mode 100644 index 0000000000000..74a9bac4768b1 --- /dev/null +++ b/llvm/test/MC/AArch64/armv9.7a-tlbid.s @@ -0,0 +1,84 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+tlbid,+tlb-rmi,+tlbiw < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+tlb-rmi,+tlbiw < %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=+tlbid,+tlb-rmi,+tlbiw --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=-tlbid,-tlb-rmi,-tlbiw --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=+tlbid,+tlb-rmi,+tlbiw < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+tlbid,+tlb-rmi,+tlbiw -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// Armv9.7-A TLBI Domains (FEAT_TLBID) + +tlbi vmalle1is +// CHECK-INST: tlbi vmalle1is +// CHECK-ENCODING: encoding: [0x1f,0x83,0x08,0xd5] +// CHECK-UNKNOWN: d508831f tlbi vmalle1is + +tlbi vmalle1is, xzr +// CHECK-INST: tlbi vmalle1is +// CHECK-ENCODING: encoding: [0x1f,0x83,0x08,0xd5] +// CHECK-UNKNOWN: d508831f tlbi vmalle1is + +tlbi vmalle1is, x31 +// CHECK-INST: tlbi vmalle1is +// CHECK-ENCODING: encoding: [0x1f,0x83,0x08,0xd5] +// CHECK-UNKNOWN: d508831f tlbi vmalle1is + +tlbi vmalle1is, x5 +// CHECK-INST: tlbi vmalle1is, x5 +// CHECK-ENCODING: encoding: [0x05,0x83,0x08,0xd5] +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-UNKNOWN: d5088305 sys #0, c8, c3, #0, x5 + +tlbi vmalle1os, x5 +// CHECK-INST: tlbi vmalle1os, x5 +// CHECK-ENCODING: encoding: [0x05,0x81,0x08,0xd5] +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-UNKNOWN: d5088105 sys #0, c8, c1, #0, x5 + +tlbi alle1is, x5 +// CHECK-INST: tlbi alle1is, x5 +// CHECK-ENCODING: encoding: [0x85,0x83,0x0c,0xd5] +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-UNKNOWN: d50c8385 sys #4, c8, c3, #4, x5 + +tlbi alle2is, x5 +// CHECK-INST: tlbi alle2is, x5 +// CHECK-ENCODING: encoding: [0x05,0x83,0x0c,0xd5] +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-UNKNOWN: d50c8305 sys #4, c8, c3, #0, x5 + +tlbi alle3is, x5 +// CHECK-INST: tlbi alle3is, x5 +// CHECK-ENCODING: encoding: [0x05,0x83,0x0e,0xd5] +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-UNKNOWN: d50e8305 sys #6, c8, c3, #0, x5 + +tlbi vmalls12e1is, x1 +// CHECK-INST: tlbi vmalls12e1is, x1 +// CHECK-ENCODING: encoding: [0xc1,0x83,0x0c,0xd5] +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-UNKNOWN: d50c83c1 sys #4, c8, c3, #6, x1 + +tlbi vmalls12e1os, x5 +// CHECK-INST: tlbi vmalls12e1os, x5 +// CHECK-ENCODING: encoding: [0xc5,0x81,0x0c,0xd5] +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-UNKNOWN: d50c81c5 sys #4, c8, c1, #6, x5 + +tlbi vmallws2e1is, x1 +// CHECK-INST: tlbi vmallws2e1is, x1 +// CHECK-ENCODING: encoding: [0x41,0x82,0x0c,0xd5] +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-UNKNOWN: d50c8241 sys #4, c8, c2, #2, x1 + +tlbi vmallws2e1os, x1 +// CHECK-INST: tlbi vmallws2e1os, x1 +// CHECK-ENCODING: encoding: [0x41,0x85,0x0c,0xd5] +// CHECK-ERROR: error: specified tlbi op does not use a register +// CHECK-UNKNOWN: d50c8541 sys #4, c8, c5, #2, x1 diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp index e9f7f2ceeb070..0801c2a6edd26 100644 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -1444,7 +1444,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { AArch64::AEK_SME_TMOP, AArch64::AEK_SVEBITPERM, AArch64::AEK_SSVE_BITPERM, AArch64::AEK_SVESHA3, AArch64::AEK_SVESM4, AArch64::AEK_CMH, - AArch64::AEK_LSCP, + AArch64::AEK_LSCP, AArch64::AEK_TLBID, }; std::vector Features; @@ -1558,6 +1558,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { EXPECT_TRUE(llvm::is_contained(Features, "+sme-tmop")); EXPECT_TRUE(llvm::is_contained(Features, "+cmh")); EXPECT_TRUE(llvm::is_contained(Features, "+lscp")); + EXPECT_TRUE(llvm::is_contained(Features, "+tlbid")); // Assuming we listed every extension above, this should produce the same // result. @@ -1726,6 +1727,7 @@ TEST(TargetParserTest, AArch64ArchExtFeature) { {"sme-tmop", "nosme-tmop", "+sme-tmop", "-sme-tmop"}, {"cmh", "nocmh", "+cmh", "-cmh"}, {"lscp", "nolscp", "+lscp", "-lscp"}, + {"tlbid", "notlbid", "+tlbid", "-tlbid"}, }; for (unsigned i = 0; i < std::size(ArchExt); i++) {