[AArch64] Add target feature "all"

This is used by disassemblers: `llvm-mc -disassemble -mattr=` and `llvm-objdump --mattr=`.
The main use case is for llvm-objdump to disassemble all known instructions
(D128030).

In user-facing tools, "all" is intentionally not supported in producers:
integrated assembler (`.arch_extension all`), clang -march (`-march=armv9.3a+all`).
Due to the code structure, `llvm-mc -mattr=+all` `llc -mattr=+all` are not
rejected (they are internal tool). Add `llvm/test/CodeGen/AArch64/mattr-all.ll`
to catch behavior changes.

AArch64SysReg::SysReg::haveFeatures: check `FeatureAll` to print
`AArch64SysReg::SysReg::AltName` for some system registers (e.g. `ERRIDR_EL1, RNDR`).

AArch64.td: add `AssemblerPredicateWithAll` to additionally test `FeatureAll`.
Change all `AssemblerPredicate` (except `UseNegativeImmediates`) to `AssemblerPredicateWithAll`.

utils/TableGen/{DecoderEmitter,SubtargetFeatureInfo}.cpp: support arbitrarily
nested all_of, any_of, and not.

Note: A predicate supports all_of, any_of, and not. For a target (though
currently not for AArch64) an encoding may be disassembled differently with
different target features.
Note: AArch64MCCodeEmitter::computeAvailableFeatures is not available to
the disassembler.

Reviewed By: peter.smith, lenary

Differential Revision: https://reviews.llvm.org/D128029
This commit is contained in:
Fangrui Song 2022-06-30 10:37:58 -07:00
parent 3a743a5892
commit 45f3a5aae7
12 changed files with 251 additions and 152 deletions

View File

@ -556,6 +556,13 @@ def HasV8_0rOps : SubtargetFeature<
FeatureSpecRestrict FeatureSpecRestrict
]>; ]>;
// Only intended to be used by disassemblers.
def FeatureAll
: SubtargetFeature<"all", "IsAll", "true", "Enable all instructions", []>;
class AssemblerPredicateWithAll<dag cond, string name="">
: AssemblerPredicate<(any_of FeatureAll, cond), name>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Register File Description // Register File Description
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -14,196 +14,196 @@
// ARM Instruction Predicate Definitions. // ARM Instruction Predicate Definitions.
// //
def HasV8_1a : Predicate<"Subtarget->hasV8_1aOps()">, def HasV8_1a : Predicate<"Subtarget->hasV8_1aOps()">,
AssemblerPredicate<(all_of HasV8_1aOps), "armv8.1a">; AssemblerPredicateWithAll<(all_of HasV8_1aOps), "armv8.1a">;
def HasV8_2a : Predicate<"Subtarget->hasV8_2aOps()">, def HasV8_2a : Predicate<"Subtarget->hasV8_2aOps()">,
AssemblerPredicate<(all_of HasV8_2aOps), "armv8.2a">; AssemblerPredicateWithAll<(all_of HasV8_2aOps), "armv8.2a">;
def HasV8_3a : Predicate<"Subtarget->hasV8_3aOps()">, def HasV8_3a : Predicate<"Subtarget->hasV8_3aOps()">,
AssemblerPredicate<(all_of HasV8_3aOps), "armv8.3a">; AssemblerPredicateWithAll<(all_of HasV8_3aOps), "armv8.3a">;
def HasV8_4a : Predicate<"Subtarget->hasV8_4aOps()">, def HasV8_4a : Predicate<"Subtarget->hasV8_4aOps()">,
AssemblerPredicate<(all_of HasV8_4aOps), "armv8.4a">; AssemblerPredicateWithAll<(all_of HasV8_4aOps), "armv8.4a">;
def HasV8_5a : Predicate<"Subtarget->hasV8_5aOps()">, def HasV8_5a : Predicate<"Subtarget->hasV8_5aOps()">,
AssemblerPredicate<(all_of HasV8_5aOps), "armv8.5a">; AssemblerPredicateWithAll<(all_of HasV8_5aOps), "armv8.5a">;
def HasV8_6a : Predicate<"Subtarget->hasV8_6aOps()">, def HasV8_6a : Predicate<"Subtarget->hasV8_6aOps()">,
AssemblerPredicate<(all_of HasV8_6aOps), "armv8.6a">; AssemblerPredicateWithAll<(all_of HasV8_6aOps), "armv8.6a">;
def HasV8_7a : Predicate<"Subtarget->hasV8_7aOps()">, def HasV8_7a : Predicate<"Subtarget->hasV8_7aOps()">,
AssemblerPredicate<(all_of HasV8_7aOps), "armv8.7a">; AssemblerPredicateWithAll<(all_of HasV8_7aOps), "armv8.7a">;
def HasV9_0a : Predicate<"Subtarget->hasV9_0aOps()">, def HasV9_0a : Predicate<"Subtarget->hasV9_0aOps()">,
AssemblerPredicate<(all_of HasV9_0aOps), "armv9-a">; AssemblerPredicateWithAll<(all_of HasV9_0aOps), "armv9-a">;
def HasV9_1a : Predicate<"Subtarget->hasV9_1aOps()">, def HasV9_1a : Predicate<"Subtarget->hasV9_1aOps()">,
AssemblerPredicate<(all_of HasV9_1aOps), "armv9.1a">; AssemblerPredicateWithAll<(all_of HasV9_1aOps), "armv9.1a">;
def HasV9_2a : Predicate<"Subtarget->hasV9_2aOps()">, def HasV9_2a : Predicate<"Subtarget->hasV9_2aOps()">,
AssemblerPredicate<(all_of HasV9_2aOps), "armv9.2a">; AssemblerPredicateWithAll<(all_of HasV9_2aOps), "armv9.2a">;
def HasV9_3a : Predicate<"Subtarget->hasV9_3aOps()">, def HasV9_3a : Predicate<"Subtarget->hasV9_3aOps()">,
AssemblerPredicate<(all_of HasV9_3aOps), "armv9.3a">; AssemblerPredicateWithAll<(all_of HasV9_3aOps), "armv9.3a">;
def HasV8_0r : Predicate<"Subtarget->hasV8_0rOps()">, def HasV8_0r : Predicate<"Subtarget->hasV8_0rOps()">,
AssemblerPredicate<(all_of HasV8_0rOps), "armv8-r">; AssemblerPredicateWithAll<(all_of HasV8_0rOps), "armv8-r">;
def HasEL2VMSA : Predicate<"Subtarget->hasEL2VMSA()">, def HasEL2VMSA : Predicate<"Subtarget->hasEL2VMSA()">,
AssemblerPredicate<(all_of FeatureEL2VMSA), "el2vmsa">; AssemblerPredicateWithAll<(all_of FeatureEL2VMSA), "el2vmsa">;
def HasEL3 : Predicate<"Subtarget->hasEL3()">, def HasEL3 : Predicate<"Subtarget->hasEL3()">,
AssemblerPredicate<(all_of FeatureEL3), "el3">; AssemblerPredicateWithAll<(all_of FeatureEL3), "el3">;
def HasVH : Predicate<"Subtarget->hasVH()">, def HasVH : Predicate<"Subtarget->hasVH()">,
AssemblerPredicate<(all_of FeatureVH), "vh">; AssemblerPredicateWithAll<(all_of FeatureVH), "vh">;
def HasLOR : Predicate<"Subtarget->hasLOR()">, def HasLOR : Predicate<"Subtarget->hasLOR()">,
AssemblerPredicate<(all_of FeatureLOR), "lor">; AssemblerPredicateWithAll<(all_of FeatureLOR), "lor">;
def HasPAuth : Predicate<"Subtarget->hasPAuth()">, def HasPAuth : Predicate<"Subtarget->hasPAuth()">,
AssemblerPredicate<(all_of FeaturePAuth), "pauth">; AssemblerPredicateWithAll<(all_of FeaturePAuth), "pauth">;
def HasJS : Predicate<"Subtarget->hasJS()">, def HasJS : Predicate<"Subtarget->hasJS()">,
AssemblerPredicate<(all_of FeatureJS), "jsconv">; AssemblerPredicateWithAll<(all_of FeatureJS), "jsconv">;
def HasCCIDX : Predicate<"Subtarget->hasCCIDX()">, def HasCCIDX : Predicate<"Subtarget->hasCCIDX()">,
AssemblerPredicate<(all_of FeatureCCIDX), "ccidx">; AssemblerPredicateWithAll<(all_of FeatureCCIDX), "ccidx">;
def HasComplxNum : Predicate<"Subtarget->hasComplxNum()">, def HasComplxNum : Predicate<"Subtarget->hasComplxNum()">,
AssemblerPredicate<(all_of FeatureComplxNum), "complxnum">; AssemblerPredicateWithAll<(all_of FeatureComplxNum), "complxnum">;
def HasNV : Predicate<"Subtarget->hasNV()">, def HasNV : Predicate<"Subtarget->hasNV()">,
AssemblerPredicate<(all_of FeatureNV), "nv">; AssemblerPredicateWithAll<(all_of FeatureNV), "nv">;
def HasMPAM : Predicate<"Subtarget->hasMPAM()">, def HasMPAM : Predicate<"Subtarget->hasMPAM()">,
AssemblerPredicate<(all_of FeatureMPAM), "mpam">; AssemblerPredicateWithAll<(all_of FeatureMPAM), "mpam">;
def HasDIT : Predicate<"Subtarget->hasDIT()">, def HasDIT : Predicate<"Subtarget->hasDIT()">,
AssemblerPredicate<(all_of FeatureDIT), "dit">; AssemblerPredicateWithAll<(all_of FeatureDIT), "dit">;
def HasTRACEV8_4 : Predicate<"Subtarget->hasTRACEV8_4()">, def HasTRACEV8_4 : Predicate<"Subtarget->hasTRACEV8_4()">,
AssemblerPredicate<(all_of FeatureTRACEV8_4), "tracev8.4">; AssemblerPredicateWithAll<(all_of FeatureTRACEV8_4), "tracev8.4">;
def HasAM : Predicate<"Subtarget->hasAM()">, def HasAM : Predicate<"Subtarget->hasAM()">,
AssemblerPredicate<(all_of FeatureAM), "am">; AssemblerPredicateWithAll<(all_of FeatureAM), "am">;
def HasSEL2 : Predicate<"Subtarget->hasSEL2()">, def HasSEL2 : Predicate<"Subtarget->hasSEL2()">,
AssemblerPredicate<(all_of FeatureSEL2), "sel2">; AssemblerPredicateWithAll<(all_of FeatureSEL2), "sel2">;
def HasTLB_RMI : Predicate<"Subtarget->hasTLB_RMI()">, def HasTLB_RMI : Predicate<"Subtarget->hasTLB_RMI()">,
AssemblerPredicate<(all_of FeatureTLB_RMI), "tlb-rmi">; AssemblerPredicateWithAll<(all_of FeatureTLB_RMI), "tlb-rmi">;
def HasFlagM : Predicate<"Subtarget->hasFlagM()">, def HasFlagM : Predicate<"Subtarget->hasFlagM()">,
AssemblerPredicate<(all_of FeatureFlagM), "flagm">; AssemblerPredicateWithAll<(all_of FeatureFlagM), "flagm">;
def HasRCPC_IMMO : Predicate<"Subtarget->hasRCPCImm()">, def HasRCPC_IMMO : Predicate<"Subtarget->hasRCPCImm()">,
AssemblerPredicate<(all_of FeatureRCPC_IMMO), "rcpc-immo">; AssemblerPredicateWithAll<(all_of FeatureRCPC_IMMO), "rcpc-immo">;
def HasFPARMv8 : Predicate<"Subtarget->hasFPARMv8()">, def HasFPARMv8 : Predicate<"Subtarget->hasFPARMv8()">,
AssemblerPredicate<(all_of FeatureFPARMv8), "fp-armv8">; AssemblerPredicateWithAll<(all_of FeatureFPARMv8), "fp-armv8">;
def HasNEON : Predicate<"Subtarget->hasNEON()">, def HasNEON : Predicate<"Subtarget->hasNEON()">,
AssemblerPredicate<(all_of FeatureNEON), "neon">; AssemblerPredicateWithAll<(all_of FeatureNEON), "neon">;
def HasCrypto : Predicate<"Subtarget->hasCrypto()">, def HasCrypto : Predicate<"Subtarget->hasCrypto()">,
AssemblerPredicate<(all_of FeatureCrypto), "crypto">; AssemblerPredicateWithAll<(all_of FeatureCrypto), "crypto">;
def HasSM4 : Predicate<"Subtarget->hasSM4()">, def HasSM4 : Predicate<"Subtarget->hasSM4()">,
AssemblerPredicate<(all_of FeatureSM4), "sm4">; AssemblerPredicateWithAll<(all_of FeatureSM4), "sm4">;
def HasSHA3 : Predicate<"Subtarget->hasSHA3()">, def HasSHA3 : Predicate<"Subtarget->hasSHA3()">,
AssemblerPredicate<(all_of FeatureSHA3), "sha3">; AssemblerPredicateWithAll<(all_of FeatureSHA3), "sha3">;
def HasSHA2 : Predicate<"Subtarget->hasSHA2()">, def HasSHA2 : Predicate<"Subtarget->hasSHA2()">,
AssemblerPredicate<(all_of FeatureSHA2), "sha2">; AssemblerPredicateWithAll<(all_of FeatureSHA2), "sha2">;
def HasAES : Predicate<"Subtarget->hasAES()">, def HasAES : Predicate<"Subtarget->hasAES()">,
AssemblerPredicate<(all_of FeatureAES), "aes">; AssemblerPredicateWithAll<(all_of FeatureAES), "aes">;
def HasDotProd : Predicate<"Subtarget->hasDotProd()">, def HasDotProd : Predicate<"Subtarget->hasDotProd()">,
AssemblerPredicate<(all_of FeatureDotProd), "dotprod">; AssemblerPredicateWithAll<(all_of FeatureDotProd), "dotprod">;
def HasCRC : Predicate<"Subtarget->hasCRC()">, def HasCRC : Predicate<"Subtarget->hasCRC()">,
AssemblerPredicate<(all_of FeatureCRC), "crc">; AssemblerPredicateWithAll<(all_of FeatureCRC), "crc">;
def HasLSE : Predicate<"Subtarget->hasLSE()">, def HasLSE : Predicate<"Subtarget->hasLSE()">,
AssemblerPredicate<(all_of FeatureLSE), "lse">; AssemblerPredicateWithAll<(all_of FeatureLSE), "lse">;
def HasNoLSE : Predicate<"!Subtarget->hasLSE()">; def HasNoLSE : Predicate<"!Subtarget->hasLSE()">;
def HasRAS : Predicate<"Subtarget->hasRAS()">, def HasRAS : Predicate<"Subtarget->hasRAS()">,
AssemblerPredicate<(all_of FeatureRAS), "ras">; AssemblerPredicateWithAll<(all_of FeatureRAS), "ras">;
def HasRDM : Predicate<"Subtarget->hasRDM()">, def HasRDM : Predicate<"Subtarget->hasRDM()">,
AssemblerPredicate<(all_of FeatureRDM), "rdm">; AssemblerPredicateWithAll<(all_of FeatureRDM), "rdm">;
def HasPerfMon : Predicate<"Subtarget->hasPerfMon()">; def HasPerfMon : Predicate<"Subtarget->hasPerfMon()">;
def HasFullFP16 : Predicate<"Subtarget->hasFullFP16()">, def HasFullFP16 : Predicate<"Subtarget->hasFullFP16()">,
AssemblerPredicate<(all_of FeatureFullFP16), "fullfp16">; AssemblerPredicateWithAll<(all_of FeatureFullFP16), "fullfp16">;
def HasFP16FML : Predicate<"Subtarget->hasFP16FML()">, def HasFP16FML : Predicate<"Subtarget->hasFP16FML()">,
AssemblerPredicate<(all_of FeatureFP16FML), "fp16fml">; AssemblerPredicateWithAll<(all_of FeatureFP16FML), "fp16fml">;
def HasSPE : Predicate<"Subtarget->hasSPE()">, def HasSPE : Predicate<"Subtarget->hasSPE()">,
AssemblerPredicate<(all_of FeatureSPE), "spe">; AssemblerPredicateWithAll<(all_of FeatureSPE), "spe">;
def HasFuseAES : Predicate<"Subtarget->hasFuseAES()">, def HasFuseAES : Predicate<"Subtarget->hasFuseAES()">,
AssemblerPredicate<(all_of FeatureFuseAES), AssemblerPredicateWithAll<(all_of FeatureFuseAES),
"fuse-aes">; "fuse-aes">;
def HasSVE : Predicate<"Subtarget->hasSVE()">, def HasSVE : Predicate<"Subtarget->hasSVE()">,
AssemblerPredicate<(all_of FeatureSVE), "sve">; AssemblerPredicateWithAll<(all_of FeatureSVE), "sve">;
def HasSVE2 : Predicate<"Subtarget->hasSVE2()">, def HasSVE2 : Predicate<"Subtarget->hasSVE2()">,
AssemblerPredicate<(all_of FeatureSVE2), "sve2">; AssemblerPredicateWithAll<(all_of FeatureSVE2), "sve2">;
def HasSVE2AES : Predicate<"Subtarget->hasSVE2AES()">, def HasSVE2AES : Predicate<"Subtarget->hasSVE2AES()">,
AssemblerPredicate<(all_of FeatureSVE2AES), "sve2-aes">; AssemblerPredicateWithAll<(all_of FeatureSVE2AES), "sve2-aes">;
def HasSVE2SM4 : Predicate<"Subtarget->hasSVE2SM4()">, def HasSVE2SM4 : Predicate<"Subtarget->hasSVE2SM4()">,
AssemblerPredicate<(all_of FeatureSVE2SM4), "sve2-sm4">; AssemblerPredicateWithAll<(all_of FeatureSVE2SM4), "sve2-sm4">;
def HasSVE2SHA3 : Predicate<"Subtarget->hasSVE2SHA3()">, def HasSVE2SHA3 : Predicate<"Subtarget->hasSVE2SHA3()">,
AssemblerPredicate<(all_of FeatureSVE2SHA3), "sve2-sha3">; AssemblerPredicateWithAll<(all_of FeatureSVE2SHA3), "sve2-sha3">;
def HasSVE2BitPerm : Predicate<"Subtarget->hasSVE2BitPerm()">, def HasSVE2BitPerm : Predicate<"Subtarget->hasSVE2BitPerm()">,
AssemblerPredicate<(all_of FeatureSVE2BitPerm), "sve2-bitperm">; AssemblerPredicateWithAll<(all_of FeatureSVE2BitPerm), "sve2-bitperm">;
def HasSME : Predicate<"Subtarget->hasSME()">, def HasSME : Predicate<"Subtarget->hasSME()">,
AssemblerPredicate<(all_of FeatureSME), "sme">; AssemblerPredicateWithAll<(all_of FeatureSME), "sme">;
def HasSMEF64 : Predicate<"Subtarget->hasSMEF64()">, def HasSMEF64 : Predicate<"Subtarget->hasSMEF64()">,
AssemblerPredicate<(all_of FeatureSMEF64), "sme-f64">; AssemblerPredicateWithAll<(all_of FeatureSMEF64), "sme-f64">;
def HasSMEI64 : Predicate<"Subtarget->hasSMEI64()">, def HasSMEI64 : Predicate<"Subtarget->hasSMEI64()">,
AssemblerPredicate<(all_of FeatureSMEI64), "sme-i64">; AssemblerPredicateWithAll<(all_of FeatureSMEI64), "sme-i64">;
// A subset of SVE(2) instructions are legal in Streaming SVE execution mode, // A subset of SVE(2) instructions are legal in Streaming SVE execution mode,
// they should be enabled if either has been specified. // they should be enabled if either has been specified.
def HasSVEorSME def HasSVEorSME
: Predicate<"Subtarget->hasSVE() || Subtarget->hasSME()">, : Predicate<"Subtarget->hasSVE() || Subtarget->hasSME()">,
AssemblerPredicate<(any_of FeatureSVE, FeatureSME), AssemblerPredicateWithAll<(any_of FeatureSVE, FeatureSME),
"sve or sme">; "sve or sme">;
def HasSVE2orSME def HasSVE2orSME
: Predicate<"Subtarget->hasSVE2() || Subtarget->hasSME()">, : Predicate<"Subtarget->hasSVE2() || Subtarget->hasSME()">,
AssemblerPredicate<(any_of FeatureSVE2, FeatureSME), AssemblerPredicateWithAll<(any_of FeatureSVE2, FeatureSME),
"sve2 or sme">; "sve2 or sme">;
// A subset of NEON instructions are legal in Streaming SVE execution mode, // A subset of NEON instructions are legal in Streaming SVE execution mode,
// they should be enabled if either has been specified. // they should be enabled if either has been specified.
def HasNEONorSME def HasNEONorSME
: Predicate<"Subtarget->hasNEON() || Subtarget->hasSME()">, : Predicate<"Subtarget->hasNEON() || Subtarget->hasSME()">,
AssemblerPredicate<(any_of FeatureNEON, FeatureSME), AssemblerPredicateWithAll<(any_of FeatureNEON, FeatureSME),
"neon or sme">; "neon or sme">;
def HasRCPC : Predicate<"Subtarget->hasRCPC()">, def HasRCPC : Predicate<"Subtarget->hasRCPC()">,
AssemblerPredicate<(all_of FeatureRCPC), "rcpc">; AssemblerPredicateWithAll<(all_of FeatureRCPC), "rcpc">;
def HasLDAPR : Predicate<"Subtarget->hasLDAPR()">, def HasLDAPR : Predicate<"Subtarget->hasLDAPR()">,
AssemblerPredicate<(all_of FeatureLDAPR), "ldapr">; AssemblerPredicateWithAll<(all_of FeatureLDAPR), "ldapr">;
def HasAltNZCV : Predicate<"Subtarget->hasAlternativeNZCV()">, def HasAltNZCV : Predicate<"Subtarget->hasAlternativeNZCV()">,
AssemblerPredicate<(all_of FeatureAltFPCmp), "altnzcv">; AssemblerPredicateWithAll<(all_of FeatureAltFPCmp), "altnzcv">;
def HasFRInt3264 : Predicate<"Subtarget->hasFRInt3264()">, def HasFRInt3264 : Predicate<"Subtarget->hasFRInt3264()">,
AssemblerPredicate<(all_of FeatureFRInt3264), "frint3264">; AssemblerPredicateWithAll<(all_of FeatureFRInt3264), "frint3264">;
def HasSB : Predicate<"Subtarget->hasSB()">, def HasSB : Predicate<"Subtarget->hasSB()">,
AssemblerPredicate<(all_of FeatureSB), "sb">; AssemblerPredicateWithAll<(all_of FeatureSB), "sb">;
def HasPredRes : Predicate<"Subtarget->hasPredRes()">, def HasPredRes : Predicate<"Subtarget->hasPredRes()">,
AssemblerPredicate<(all_of FeaturePredRes), "predres">; AssemblerPredicateWithAll<(all_of FeaturePredRes), "predres">;
def HasCCDP : Predicate<"Subtarget->hasCCDP()">, def HasCCDP : Predicate<"Subtarget->hasCCDP()">,
AssemblerPredicate<(all_of FeatureCacheDeepPersist), "ccdp">; AssemblerPredicateWithAll<(all_of FeatureCacheDeepPersist), "ccdp">;
def HasBTI : Predicate<"Subtarget->hasBTI()">, def HasBTI : Predicate<"Subtarget->hasBTI()">,
AssemblerPredicate<(all_of FeatureBranchTargetId), "bti">; AssemblerPredicateWithAll<(all_of FeatureBranchTargetId), "bti">;
def HasMTE : Predicate<"Subtarget->hasMTE()">, def HasMTE : Predicate<"Subtarget->hasMTE()">,
AssemblerPredicate<(all_of FeatureMTE), "mte">; AssemblerPredicateWithAll<(all_of FeatureMTE), "mte">;
def HasTME : Predicate<"Subtarget->hasTME()">, def HasTME : Predicate<"Subtarget->hasTME()">,
AssemblerPredicate<(all_of FeatureTME), "tme">; AssemblerPredicateWithAll<(all_of FeatureTME), "tme">;
def HasETE : Predicate<"Subtarget->hasETE()">, def HasETE : Predicate<"Subtarget->hasETE()">,
AssemblerPredicate<(all_of FeatureETE), "ete">; AssemblerPredicateWithAll<(all_of FeatureETE), "ete">;
def HasTRBE : Predicate<"Subtarget->hasTRBE()">, def HasTRBE : Predicate<"Subtarget->hasTRBE()">,
AssemblerPredicate<(all_of FeatureTRBE), "trbe">; AssemblerPredicateWithAll<(all_of FeatureTRBE), "trbe">;
def HasBF16 : Predicate<"Subtarget->hasBF16()">, def HasBF16 : Predicate<"Subtarget->hasBF16()">,
AssemblerPredicate<(all_of FeatureBF16), "bf16">; AssemblerPredicateWithAll<(all_of FeatureBF16), "bf16">;
def HasMatMulInt8 : Predicate<"Subtarget->hasMatMulInt8()">, def HasMatMulInt8 : Predicate<"Subtarget->hasMatMulInt8()">,
AssemblerPredicate<(all_of FeatureMatMulInt8), "i8mm">; AssemblerPredicateWithAll<(all_of FeatureMatMulInt8), "i8mm">;
def HasMatMulFP32 : Predicate<"Subtarget->hasMatMulFP32()">, def HasMatMulFP32 : Predicate<"Subtarget->hasMatMulFP32()">,
AssemblerPredicate<(all_of FeatureMatMulFP32), "f32mm">; AssemblerPredicateWithAll<(all_of FeatureMatMulFP32), "f32mm">;
def HasMatMulFP64 : Predicate<"Subtarget->hasMatMulFP64()">, def HasMatMulFP64 : Predicate<"Subtarget->hasMatMulFP64()">,
AssemblerPredicate<(all_of FeatureMatMulFP64), "f64mm">; AssemblerPredicateWithAll<(all_of FeatureMatMulFP64), "f64mm">;
def HasXS : Predicate<"Subtarget->hasXS()">, def HasXS : Predicate<"Subtarget->hasXS()">,
AssemblerPredicate<(all_of FeatureXS), "xs">; AssemblerPredicateWithAll<(all_of FeatureXS), "xs">;
def HasWFxT : Predicate<"Subtarget->hasWFxT()">, def HasWFxT : Predicate<"Subtarget->hasWFxT()">,
AssemblerPredicate<(all_of FeatureWFxT), "wfxt">; AssemblerPredicateWithAll<(all_of FeatureWFxT), "wfxt">;
def HasLS64 : Predicate<"Subtarget->hasLS64()">, def HasLS64 : Predicate<"Subtarget->hasLS64()">,
AssemblerPredicate<(all_of FeatureLS64), "ls64">; AssemblerPredicateWithAll<(all_of FeatureLS64), "ls64">;
def HasBRBE : Predicate<"Subtarget->hasBRBE()">, def HasBRBE : Predicate<"Subtarget->hasBRBE()">,
AssemblerPredicate<(all_of FeatureBRBE), "brbe">; AssemblerPredicateWithAll<(all_of FeatureBRBE), "brbe">;
def HasSPE_EEF : Predicate<"Subtarget->hasSPE_EEF()">, def HasSPE_EEF : Predicate<"Subtarget->hasSPE_EEF()">,
AssemblerPredicate<(all_of FeatureSPE_EEF), "spe-eef">; AssemblerPredicateWithAll<(all_of FeatureSPE_EEF), "spe-eef">;
def HasHBC : Predicate<"Subtarget->hasHBC()">, def HasHBC : Predicate<"Subtarget->hasHBC()">,
AssemblerPredicate<(all_of FeatureHBC), "hbc">; AssemblerPredicateWithAll<(all_of FeatureHBC), "hbc">;
def HasMOPS : Predicate<"Subtarget->hasMOPS()">, def HasMOPS : Predicate<"Subtarget->hasMOPS()">,
AssemblerPredicate<(all_of FeatureMOPS), "mops">; AssemblerPredicateWithAll<(all_of FeatureMOPS), "mops">;
def IsLE : Predicate<"Subtarget->isLittleEndian()">; def IsLE : Predicate<"Subtarget->isLittleEndian()">;
def IsBE : Predicate<"!Subtarget->isLittleEndian()">; def IsBE : Predicate<"!Subtarget->isLittleEndian()">;
def IsWindows : Predicate<"Subtarget->isTargetWindows()">; def IsWindows : Predicate<"Subtarget->isTargetWindows()">;

View File

@ -18,23 +18,23 @@ include "llvm/TableGen/SearchableTable.td"
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
def HasCCPP : Predicate<"Subtarget->hasCCPP()">, def HasCCPP : Predicate<"Subtarget->hasCCPP()">,
AssemblerPredicate<(all_of FeatureCCPP), "ccpp">; AssemblerPredicateWithAll<(all_of FeatureCCPP), "ccpp">;
def HasPAN : Predicate<"Subtarget->hasPAN()">, def HasPAN : Predicate<"Subtarget->hasPAN()">,
AssemblerPredicate<(all_of FeaturePAN), AssemblerPredicateWithAll<(all_of FeaturePAN),
"ARM v8.1 Privileged Access-Never extension">; "ARM v8.1 Privileged Access-Never extension">;
def HasPsUAO : Predicate<"Subtarget->hasPsUAO()">, def HasPsUAO : Predicate<"Subtarget->hasPsUAO()">,
AssemblerPredicate<(all_of FeaturePsUAO), AssemblerPredicateWithAll<(all_of FeaturePsUAO),
"ARM v8.2 UAO PState extension (psuao)">; "ARM v8.2 UAO PState extension (psuao)">;
def HasPAN_RWV : Predicate<"Subtarget->hasPAN_RWV()">, def HasPAN_RWV : Predicate<"Subtarget->hasPAN_RWV()">,
AssemblerPredicate<(all_of FeaturePAN_RWV), AssemblerPredicateWithAll<(all_of FeaturePAN_RWV),
"ARM v8.2 PAN AT S1E1R and AT S1E1W Variation">; "ARM v8.2 PAN AT S1E1R and AT S1E1W Variation">;
def HasCONTEXTIDREL2 def HasCONTEXTIDREL2
: Predicate<"Subtarget->hasCONTEXTIDREL2()">, : Predicate<"Subtarget->hasCONTEXTIDREL2()">,
AssemblerPredicate<(all_of FeatureCONTEXTIDREL2), AssemblerPredicateWithAll<(all_of FeatureCONTEXTIDREL2),
"Target contains CONTEXTIDR_EL2 RW operand">; "Target contains CONTEXTIDR_EL2 RW operand">;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -634,7 +634,8 @@ namespace AArch64SysReg {
FeatureBitset FeaturesRequired; FeatureBitset FeaturesRequired;
bool haveFeatures(FeatureBitset ActiveFeatures) const { bool haveFeatures(FeatureBitset ActiveFeatures) const {
return (FeaturesRequired & ActiveFeatures) == FeaturesRequired; return ActiveFeatures[llvm::AArch64::FeatureAll] ||
(FeaturesRequired & ActiveFeatures) == FeaturesRequired;
} }
}; };

View File

@ -0,0 +1,24 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
;; -mattr=+all is not intended to be used for code emitters. Nevertheless,
;; llc does not reject it. This test intends to catch behavior changes.
; RUN: llc -mtriple=aarch64 -mattr=+all < %s | FileCheck %s
define half @bf16() nounwind {
; CHECK-LABEL: bf16:
; CHECK: // %bb.0:
; CHECK-NEXT: adrp x8, .LCPI0_0
; CHECK-NEXT: ldr h0, [x8, :lo12:.LCPI0_0]
; CHECK-NEXT: ret
ret half 0xH0000
}
define i64 @perfmon() nounwind {
; CHECK-LABEL: perfmon:
; CHECK: // %bb.0:
; CHECK-NEXT: mov x0, xzr
; CHECK-NEXT: ret
%tmp0 = call i64 @llvm.readcyclecounter()
ret i64 %tmp0
}
declare i64 @llvm.readcyclecounter()

View File

@ -2,6 +2,9 @@
// RUN: llvm-mc -triple=aarch64 -M no-aliases < %s | FileCheck %s --check-prefixes=CHECK,NOALIAS // RUN: llvm-mc -triple=aarch64 -M no-aliases < %s | FileCheck %s --check-prefixes=CHECK,NOALIAS
// RUN: not llvm-mc -mattr=+no-neg-immediates -triple=aarch64-none-linux-gnu < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-NEG-IMM // RUN: not llvm-mc -mattr=+no-neg-immediates -triple=aarch64-none-linux-gnu < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-NEG-IMM
/// +all does not imply +no-neg-immediates.
// RUN: llvm-mc -triple=aarch64 -mattr=+all -M no-aliases %s | FileCheck %s --check-prefixes=CHECK,NOALIAS
add w0, w2, #4096 add w0, w2, #4096
sub w0, w2, #4096 sub w0, w2, #4096
// CHECK: add w0, w2, #1, lsl #12 // CHECK: add w0, w2, #1, lsl #12

View File

@ -1,5 +1,6 @@
// RUN: llvm-mc -triple aarch64 -show-encoding -mattr=+bf16 < %s | FileCheck %s // RUN: llvm-mc -triple aarch64 -show-encoding -mattr=+bf16 < %s | FileCheck %s
// RUN: llvm-mc -triple aarch64 -show-encoding -mattr=+v8.6a < %s | FileCheck %s // RUN: llvm-mc -triple aarch64 -show-encoding -mattr=+v8.6a < %s | FileCheck %s
// RUN: llvm-mc -triple aarch64 -show-encoding -mattr=+all %s | FileCheck %s
// RUN: not llvm-mc -triple aarch64 -show-encoding -mattr=-bf16 < %s 2>&1 | FileCheck %s --check-prefix=NOBF16 // RUN: not llvm-mc -triple aarch64 -show-encoding -mattr=-bf16 < %s 2>&1 | FileCheck %s --check-prefix=NOBF16
// RUN: not llvm-mc -triple aarch64 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=NOBF16 // RUN: not llvm-mc -triple aarch64 -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=NOBF16

View File

@ -0,0 +1,37 @@
# RUN: llvm-mc -triple=aarch64 -mattr=+all -disassemble %s 2>&1 | FileCheck %s
## aes
# CHECK: aese v0.16b, v1.16b
[0x20,0x48,0x28,0x4e]
## ete
# CHECK: mrs x0, TRCRSR
[0x00,0x0a,0x31,0xd5]
## fp16fml
# CHECK: fmlal v0.2s, v1.2h, v2.2h
[0x20,0xec,0x22,0x0e]
## armv8.2a ras
# CHECK: mrs x0, ERRIDR_EL1
[0x00,0x53,0x38,0xd5]
## armv8.5a mte
# CHECK: irg x0, x1
[0x20,0x10,0xdf,0x9a]
## armv8.5a rand
# CHECK: mrs x0, RNDR
[0x00,0x24,0x3b,0xd5]
## armv8.6a matmul
# CHECK: smmla v1.4s, v16.16b, v31.16b
[0x01,0xa6,0x9f,0x4e]
## armv8.8a-hbc
# CHECK: bc.eq #4
[0x30,0x00,0x00,0x54]
## armv9a rme
# CHECK: mrs x0, MFAR_EL3
[0xa0,0x60,0x3e,0xd5]

View File

@ -47,16 +47,20 @@ def AsmCond2a: SubtargetFeature<"cond2a", "cond2a", "true", "">;
def AsmCond2b: SubtargetFeature<"cond2b", "cond2b", "true", "">; def AsmCond2b: SubtargetFeature<"cond2b", "cond2b", "true", "">;
def AsmCond3a: SubtargetFeature<"cond3a", "cond3a", "true", "">; def AsmCond3a: SubtargetFeature<"cond3a", "cond3a", "true", "">;
def AsmCond3b: SubtargetFeature<"cond3b", "cond3b", "true", "">; def AsmCond3b: SubtargetFeature<"cond3b", "cond3b", "true", "">;
def AsmCond4 : SubtargetFeature<"cond4", "cond4", "true", "">;
def AsmPred1 : Predicate<"Pred1">, AssemblerPredicate<(all_of AsmCond1)>; def AsmPred1 : Predicate<"Pred1">, AssemblerPredicate<(all_of AsmCond1)>;
def AsmPred2 : Predicate<"Pred2">, AssemblerPredicate<(all_of AsmCond2a, AsmCond2b)>; def AsmPred2 : Predicate<"Pred2">, AssemblerPredicate<(all_of AsmCond2a, AsmCond2b)>;
def AsmPred3 : Predicate<"Pred3">, AssemblerPredicate<(any_of AsmCond3a, AsmCond3b)>; def AsmPred3 : Predicate<"Pred3">, AssemblerPredicate<(any_of AsmCond3a, AsmCond3b)>;
def AsmPred4 : Predicate<"Pred4">, AssemblerPredicate<(all_of AsmCond4, (not (any_of AsmCond3a, AsmCond3b)))>;
// MATCHER: if (FB[arch::AsmCond1]) // MATCHER: if (FB[arch::AsmCond1])
// MATCHER-NEXT: Features.set(Feature_AsmPred1Bit); // MATCHER-NEXT: Features.set(Feature_AsmPred1Bit);
// MATCHER-NEXT: if (FB[arch::AsmCond2a] && FB[arch::AsmCond2b]) // MATCHER-NEXT: if (FB[arch::AsmCond2a] && FB[arch::AsmCond2b])
// MATCHER-NEXT: Features.set(Feature_AsmPred2Bit); // MATCHER-NEXT: Features.set(Feature_AsmPred2Bit);
// MATCHER-NEXT: if ((FB[arch::AsmCond3a] || FB[arch::AsmCond3b])) // MATCHER-NEXT: if (FB[arch::AsmCond3a] || FB[arch::AsmCond3b])
// MATCHER-NEXT: Features.set(Feature_AsmPred3Bit); // MATCHER-NEXT: Features.set(Feature_AsmPred3Bit);
// MATCHER-NEXT: if (FB[arch::AsmCond4] && !(FB[arch::AsmCond3a] || FB[arch::AsmCond3b]))
// MATCHER-NEXT: Features.set(Feature_AsmPred4Bit);
def insn1 : TestInsn<1, [AsmPred1]>; def insn1 : TestInsn<1, [AsmPred1]>;
// DISASS: return (Bits[arch::AsmCond1]); // DISASS: return (Bits[arch::AsmCond1]);
@ -65,10 +69,10 @@ def insn2 : TestInsn<2, [AsmPred2]>;
// DISASS: return (Bits[arch::AsmCond2a] && Bits[arch::AsmCond2b]) // DISASS: return (Bits[arch::AsmCond2a] && Bits[arch::AsmCond2b])
def insn3 : TestInsn<3, [AsmPred3]>; def insn3 : TestInsn<3, [AsmPred3]>;
// DISASS: return ((Bits[arch::AsmCond3a] || Bits[arch::AsmCond3b])) // DISASS: return (Bits[arch::AsmCond3a] || Bits[arch::AsmCond3b])
def insn4 : TestInsn<4, [AsmPred1, AsmPred2]>; def insn4 : TestInsn<4, [AsmPred1, AsmPred2]>;
// DISASS: return (Bits[arch::AsmCond1] && Bits[arch::AsmCond2a] && Bits[arch::AsmCond2b]) // DISASS: return (Bits[arch::AsmCond1] && (Bits[arch::AsmCond2a] && Bits[arch::AsmCond2b]))
def insn5 : TestInsn<5, [AsmPred1, AsmPred3]>; def insn5 : TestInsn<5, [AsmPred1, AsmPred3]>;
// DISASS: return (Bits[arch::AsmCond1] && (Bits[arch::AsmCond3a] || Bits[arch::AsmCond3b])) // DISASS: return (Bits[arch::AsmCond1] && (Bits[arch::AsmCond3a] || Bits[arch::AsmCond3b]))

View File

@ -999,6 +999,17 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (D->getNumArgs() == 0) if (D->getNumArgs() == 0)
PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!"); PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
bool IsOr = CombineType == "any_of"; bool IsOr = CombineType == "any_of";
// Change (any_of FeatureAll, (any_of ...)) to (any_of FeatureAll, ...).
if (IsOr && D->getNumArgs() == 2 && isa<DagInit>(D->getArg(1))) {
DagInit *RHS = dyn_cast<DagInit>(D->getArg(1));
SmallVector<Init *> Args{D->getArg(0)};
SmallVector<StringInit *> ArgNames{D->getArgName(0)};
for (unsigned i = 0, e = RHS->getNumArgs(); i != e; ++i) {
Args.push_back(RHS->getArg(i));
ArgNames.push_back(RHS->getArgName(i));
}
D = DagInit::get(D->getOperator(), nullptr, Args, ArgNames);
}
for (auto *Arg : D->getArgs()) { for (auto *Arg : D->getArgs()) {
bool IsNeg = false; bool IsNeg = false;

View File

@ -509,6 +509,8 @@ protected:
// Returns true if predicate matches were emitted, false otherwise. // Returns true if predicate matches were emitted, false otherwise.
bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation, bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
unsigned Opc) const; unsigned Opc) const;
bool emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
raw_ostream &OS) const;
bool doesOpcodeNeedPredicate(unsigned Opc) const; bool doesOpcodeNeedPredicate(unsigned Opc) const;
unsigned getPredicateIndex(DecoderTableInfo &TableInfo, StringRef P) const; unsigned getPredicateIndex(DecoderTableInfo &TableInfo, StringRef P) const;
@ -1226,6 +1228,40 @@ unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders,
return (unsigned)(P - Decoders.begin()); return (unsigned)(P - Decoders.begin());
} }
// If ParenIfBinOp is true, print a surrounding () if Val uses && or ||.
bool FilterChooser::emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
raw_ostream &OS) const {
if (auto *D = dyn_cast<DefInit>(&Val)) {
if (!D->getDef()->isSubClassOf("SubtargetFeature"))
return true;
OS << "Bits[" << Emitter->PredicateNamespace << "::" << D->getAsString()
<< "]";
return false;
}
if (auto *D = dyn_cast<DagInit>(&Val)) {
std::string Op = D->getOperator()->getAsString();
if (Op == "not" && D->getNumArgs() == 1) {
OS << '!';
return emitPredicateMatchAux(*D->getArg(0), true, OS);
}
if ((Op == "any_of" || Op == "all_of") && D->getNumArgs() > 0) {
bool Paren = D->getNumArgs() > 1 && std::exchange(ParenIfBinOp, true);
if (Paren)
OS << '(';
ListSeparator LS(Op == "any_of" ? " || " : " && ");
for (auto *Arg : D->getArgs()) {
OS << LS;
if (emitPredicateMatchAux(*Arg, ParenIfBinOp, OS))
return true;
}
if (Paren)
OS << ')';
return false;
}
}
return true;
}
bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
unsigned Opc) const { unsigned Opc) const {
ListInit *Predicates = ListInit *Predicates =
@ -1239,40 +1275,11 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue())) if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
continue; continue;
const DagInit *D = Pred->getValueAsDag("AssemblerCondDag");
std::string CombineType = D->getOperator()->getAsString();
if (CombineType != "any_of" && CombineType != "all_of")
PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
if (D->getNumArgs() == 0)
PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
bool IsOr = CombineType == "any_of";
if (!IsFirstEmission) if (!IsFirstEmission)
o << " && "; o << " && ";
if (emitPredicateMatchAux(*Pred->getValueAsDag("AssemblerCondDag"),
if (IsOr) Predicates->size() > 1, o))
o << "("; PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
ListSeparator LS(IsOr ? " || " : " && ");
for (auto *Arg : D->getArgs()) {
o << LS;
if (auto *NotArg = dyn_cast<DagInit>(Arg)) {
if (NotArg->getOperator()->getAsString() != "not" ||
NotArg->getNumArgs() != 1)
PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
Arg = NotArg->getArg(0);
o << "!";
}
if (!isa<DefInit>(Arg) ||
!cast<DefInit>(Arg)->getDef()->isSubClassOf("SubtargetFeature"))
PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
o << "Bits[" << Emitter->PredicateNamespace << "::" << Arg->getAsString()
<< "]";
}
if (IsOr)
o << ")";
IsFirstEmission = false; IsFirstEmission = false;
} }
return !Predicates->empty(); return !Predicates->empty();

View File

@ -108,6 +108,39 @@ void SubtargetFeatureInfo::emitComputeAvailableFeatures(
OS << "}\n\n"; OS << "}\n\n";
} }
// If ParenIfBinOp is true, print a surrounding () if Val uses && or ||.
static bool emitFeaturesAux(StringRef TargetName, const Init &Val,
bool ParenIfBinOp, raw_ostream &OS) {
if (auto *D = dyn_cast<DefInit>(&Val)) {
if (!D->getDef()->isSubClassOf("SubtargetFeature"))
return true;
OS << "FB[" << TargetName << "::" << D->getAsString() << "]";
return false;
}
if (auto *D = dyn_cast<DagInit>(&Val)) {
std::string Op = D->getOperator()->getAsString();
if (Op == "not" && D->getNumArgs() == 1) {
OS << '!';
return emitFeaturesAux(TargetName, *D->getArg(0), true, OS);
}
if ((Op == "any_of" || Op == "all_of") && D->getNumArgs() > 0) {
bool Paren = D->getNumArgs() > 1 && std::exchange(ParenIfBinOp, true);
if (Paren)
OS << '(';
ListSeparator LS(Op == "any_of" ? " || " : " && ");
for (auto *Arg : D->getArgs()) {
OS << LS;
if (emitFeaturesAux(TargetName, *Arg, ParenIfBinOp, OS))
return true;
}
if (Paren)
OS << ')';
return false;
}
}
return true;
}
void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures( void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
StringRef TargetName, StringRef ClassName, StringRef FuncName, StringRef TargetName, StringRef ClassName, StringRef FuncName,
SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) { SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
@ -118,37 +151,8 @@ void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
const SubtargetFeatureInfo &SFI = SF.second; const SubtargetFeatureInfo &SFI = SF.second;
OS << " if ("; OS << " if (";
emitFeaturesAux(TargetName, *SFI.TheDef->getValueAsDag("AssemblerCondDag"),
const DagInit *D = SFI.TheDef->getValueAsDag("AssemblerCondDag"); /*ParenIfBinOp=*/false, OS);
std::string CombineType = D->getOperator()->getAsString();
if (CombineType != "any_of" && CombineType != "all_of")
PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!");
if (D->getNumArgs() == 0)
PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!");
bool IsOr = CombineType == "any_of";
if (IsOr)
OS << "(";
ListSeparator LS(IsOr ? " || " : " && ");
for (auto *Arg : D->getArgs()) {
OS << LS;
if (auto *NotArg = dyn_cast<DagInit>(Arg)) {
if (NotArg->getOperator()->getAsString() != "not" ||
NotArg->getNumArgs() != 1)
PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!");
Arg = NotArg->getArg(0);
OS << "!";
}
if (!isa<DefInit>(Arg) ||
!cast<DefInit>(Arg)->getDef()->isSubClassOf("SubtargetFeature"))
PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!");
OS << "FB[" << TargetName << "::" << Arg->getAsString() << "]";
}
if (IsOr)
OS << ")";
OS << ")\n"; OS << ")\n";
OS << " Features.set(" << SFI.getEnumBitName() << ");\n"; OS << " Features.set(" << SFI.getEnumBitName() << ");\n";
} }