[llvm] 45f3a5a - [AArch64] Add target feature "all"
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 30 10:38:25 PDT 2022
Author: Fangrui Song
Date: 2022-06-30T10:37:58-07:00
New Revision: 45f3a5aae7320a847bbcb24eca0a33e933ec8561
URL: https://github.com/llvm/llvm-project/commit/45f3a5aae7320a847bbcb24eca0a33e933ec8561
DIFF: https://github.com/llvm/llvm-project/commit/45f3a5aae7320a847bbcb24eca0a33e933ec8561.diff
LOG: [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
Added:
llvm/test/CodeGen/AArch64/mattr-all.ll
llvm/test/MC/Disassembler/AArch64/mattr-all.txt
Modified:
llvm/lib/Target/AArch64/AArch64.td
llvm/lib/Target/AArch64/AArch64InstrInfo.td
llvm/lib/Target/AArch64/AArch64SystemOperands.td
llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
llvm/test/MC/AArch64/alias-addsubimm.s
llvm/test/MC/AArch64/armv8.6a-bf16.s
llvm/test/TableGen/AsmPredicateCombining.td
llvm/utils/TableGen/AsmWriterEmitter.cpp
llvm/utils/TableGen/DecoderEmitter.cpp
llvm/utils/TableGen/SubtargetFeatureInfo.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index f053b4533b03..f092c039b58e 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -556,6 +556,13 @@ def HasV8_0rOps : SubtargetFeature<
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
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 374b2f13a1ac..10ff79fc3a24 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -14,196 +14,196 @@
// ARM Instruction Predicate Definitions.
//
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()">,
- AssemblerPredicate<(all_of HasV8_2aOps), "armv8.2a">;
+ AssemblerPredicateWithAll<(all_of HasV8_2aOps), "armv8.2a">;
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()">,
- AssemblerPredicate<(all_of HasV8_4aOps), "armv8.4a">;
+ AssemblerPredicateWithAll<(all_of HasV8_4aOps), "armv8.4a">;
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()">,
- AssemblerPredicate<(all_of HasV8_6aOps), "armv8.6a">;
+ AssemblerPredicateWithAll<(all_of HasV8_6aOps), "armv8.6a">;
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()">,
- AssemblerPredicate<(all_of HasV9_0aOps), "armv9-a">;
+ AssemblerPredicateWithAll<(all_of HasV9_0aOps), "armv9-a">;
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()">,
- AssemblerPredicate<(all_of HasV9_2aOps), "armv9.2a">;
+ AssemblerPredicateWithAll<(all_of HasV9_2aOps), "armv9.2a">;
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()">,
- AssemblerPredicate<(all_of HasV8_0rOps), "armv8-r">;
+ AssemblerPredicateWithAll<(all_of HasV8_0rOps), "armv8-r">;
def HasEL2VMSA : Predicate<"Subtarget->hasEL2VMSA()">,
- AssemblerPredicate<(all_of FeatureEL2VMSA), "el2vmsa">;
+ AssemblerPredicateWithAll<(all_of FeatureEL2VMSA), "el2vmsa">;
def HasEL3 : Predicate<"Subtarget->hasEL3()">,
- AssemblerPredicate<(all_of FeatureEL3), "el3">;
+ AssemblerPredicateWithAll<(all_of FeatureEL3), "el3">;
def HasVH : Predicate<"Subtarget->hasVH()">,
- AssemblerPredicate<(all_of FeatureVH), "vh">;
+ AssemblerPredicateWithAll<(all_of FeatureVH), "vh">;
def HasLOR : Predicate<"Subtarget->hasLOR()">,
- AssemblerPredicate<(all_of FeatureLOR), "lor">;
+ AssemblerPredicateWithAll<(all_of FeatureLOR), "lor">;
def HasPAuth : Predicate<"Subtarget->hasPAuth()">,
- AssemblerPredicate<(all_of FeaturePAuth), "pauth">;
+ AssemblerPredicateWithAll<(all_of FeaturePAuth), "pauth">;
def HasJS : Predicate<"Subtarget->hasJS()">,
- AssemblerPredicate<(all_of FeatureJS), "jsconv">;
+ AssemblerPredicateWithAll<(all_of FeatureJS), "jsconv">;
def HasCCIDX : Predicate<"Subtarget->hasCCIDX()">,
- AssemblerPredicate<(all_of FeatureCCIDX), "ccidx">;
+ AssemblerPredicateWithAll<(all_of FeatureCCIDX), "ccidx">;
def HasComplxNum : Predicate<"Subtarget->hasComplxNum()">,
- AssemblerPredicate<(all_of FeatureComplxNum), "complxnum">;
+ AssemblerPredicateWithAll<(all_of FeatureComplxNum), "complxnum">;
def HasNV : Predicate<"Subtarget->hasNV()">,
- AssemblerPredicate<(all_of FeatureNV), "nv">;
+ AssemblerPredicateWithAll<(all_of FeatureNV), "nv">;
def HasMPAM : Predicate<"Subtarget->hasMPAM()">,
- AssemblerPredicate<(all_of FeatureMPAM), "mpam">;
+ AssemblerPredicateWithAll<(all_of FeatureMPAM), "mpam">;
def HasDIT : Predicate<"Subtarget->hasDIT()">,
- AssemblerPredicate<(all_of FeatureDIT), "dit">;
+ AssemblerPredicateWithAll<(all_of FeatureDIT), "dit">;
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()">,
- AssemblerPredicate<(all_of FeatureAM), "am">;
+ AssemblerPredicateWithAll<(all_of FeatureAM), "am">;
def HasSEL2 : Predicate<"Subtarget->hasSEL2()">,
- AssemblerPredicate<(all_of FeatureSEL2), "sel2">;
+ AssemblerPredicateWithAll<(all_of FeatureSEL2), "sel2">;
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()">,
- AssemblerPredicate<(all_of FeatureFlagM), "flagm">;
+ AssemblerPredicateWithAll<(all_of FeatureFlagM), "flagm">;
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()">,
- AssemblerPredicate<(all_of FeatureFPARMv8), "fp-armv8">;
+ AssemblerPredicateWithAll<(all_of FeatureFPARMv8), "fp-armv8">;
def HasNEON : Predicate<"Subtarget->hasNEON()">,
- AssemblerPredicate<(all_of FeatureNEON), "neon">;
+ AssemblerPredicateWithAll<(all_of FeatureNEON), "neon">;
def HasCrypto : Predicate<"Subtarget->hasCrypto()">,
- AssemblerPredicate<(all_of FeatureCrypto), "crypto">;
+ AssemblerPredicateWithAll<(all_of FeatureCrypto), "crypto">;
def HasSM4 : Predicate<"Subtarget->hasSM4()">,
- AssemblerPredicate<(all_of FeatureSM4), "sm4">;
+ AssemblerPredicateWithAll<(all_of FeatureSM4), "sm4">;
def HasSHA3 : Predicate<"Subtarget->hasSHA3()">,
- AssemblerPredicate<(all_of FeatureSHA3), "sha3">;
+ AssemblerPredicateWithAll<(all_of FeatureSHA3), "sha3">;
def HasSHA2 : Predicate<"Subtarget->hasSHA2()">,
- AssemblerPredicate<(all_of FeatureSHA2), "sha2">;
+ AssemblerPredicateWithAll<(all_of FeatureSHA2), "sha2">;
def HasAES : Predicate<"Subtarget->hasAES()">,
- AssemblerPredicate<(all_of FeatureAES), "aes">;
+ AssemblerPredicateWithAll<(all_of FeatureAES), "aes">;
def HasDotProd : Predicate<"Subtarget->hasDotProd()">,
- AssemblerPredicate<(all_of FeatureDotProd), "dotprod">;
+ AssemblerPredicateWithAll<(all_of FeatureDotProd), "dotprod">;
def HasCRC : Predicate<"Subtarget->hasCRC()">,
- AssemblerPredicate<(all_of FeatureCRC), "crc">;
+ AssemblerPredicateWithAll<(all_of FeatureCRC), "crc">;
def HasLSE : Predicate<"Subtarget->hasLSE()">,
- AssemblerPredicate<(all_of FeatureLSE), "lse">;
+ AssemblerPredicateWithAll<(all_of FeatureLSE), "lse">;
def HasNoLSE : Predicate<"!Subtarget->hasLSE()">;
def HasRAS : Predicate<"Subtarget->hasRAS()">,
- AssemblerPredicate<(all_of FeatureRAS), "ras">;
+ AssemblerPredicateWithAll<(all_of FeatureRAS), "ras">;
def HasRDM : Predicate<"Subtarget->hasRDM()">,
- AssemblerPredicate<(all_of FeatureRDM), "rdm">;
+ AssemblerPredicateWithAll<(all_of FeatureRDM), "rdm">;
def HasPerfMon : Predicate<"Subtarget->hasPerfMon()">;
def HasFullFP16 : Predicate<"Subtarget->hasFullFP16()">,
- AssemblerPredicate<(all_of FeatureFullFP16), "fullfp16">;
+ AssemblerPredicateWithAll<(all_of FeatureFullFP16), "fullfp16">;
def HasFP16FML : Predicate<"Subtarget->hasFP16FML()">,
- AssemblerPredicate<(all_of FeatureFP16FML), "fp16fml">;
+ AssemblerPredicateWithAll<(all_of FeatureFP16FML), "fp16fml">;
def HasSPE : Predicate<"Subtarget->hasSPE()">,
- AssemblerPredicate<(all_of FeatureSPE), "spe">;
+ AssemblerPredicateWithAll<(all_of FeatureSPE), "spe">;
def HasFuseAES : Predicate<"Subtarget->hasFuseAES()">,
- AssemblerPredicate<(all_of FeatureFuseAES),
+ AssemblerPredicateWithAll<(all_of FeatureFuseAES),
"fuse-aes">;
def HasSVE : Predicate<"Subtarget->hasSVE()">,
- AssemblerPredicate<(all_of FeatureSVE), "sve">;
+ AssemblerPredicateWithAll<(all_of FeatureSVE), "sve">;
def HasSVE2 : Predicate<"Subtarget->hasSVE2()">,
- AssemblerPredicate<(all_of FeatureSVE2), "sve2">;
+ AssemblerPredicateWithAll<(all_of FeatureSVE2), "sve2">;
def HasSVE2AES : Predicate<"Subtarget->hasSVE2AES()">,
- AssemblerPredicate<(all_of FeatureSVE2AES), "sve2-aes">;
+ AssemblerPredicateWithAll<(all_of FeatureSVE2AES), "sve2-aes">;
def HasSVE2SM4 : Predicate<"Subtarget->hasSVE2SM4()">,
- AssemblerPredicate<(all_of FeatureSVE2SM4), "sve2-sm4">;
+ AssemblerPredicateWithAll<(all_of FeatureSVE2SM4), "sve2-sm4">;
def HasSVE2SHA3 : Predicate<"Subtarget->hasSVE2SHA3()">,
- AssemblerPredicate<(all_of FeatureSVE2SHA3), "sve2-sha3">;
+ AssemblerPredicateWithAll<(all_of FeatureSVE2SHA3), "sve2-sha3">;
def HasSVE2BitPerm : Predicate<"Subtarget->hasSVE2BitPerm()">,
- AssemblerPredicate<(all_of FeatureSVE2BitPerm), "sve2-bitperm">;
+ AssemblerPredicateWithAll<(all_of FeatureSVE2BitPerm), "sve2-bitperm">;
def HasSME : Predicate<"Subtarget->hasSME()">,
- AssemblerPredicate<(all_of FeatureSME), "sme">;
+ AssemblerPredicateWithAll<(all_of FeatureSME), "sme">;
def HasSMEF64 : Predicate<"Subtarget->hasSMEF64()">,
- AssemblerPredicate<(all_of FeatureSMEF64), "sme-f64">;
+ AssemblerPredicateWithAll<(all_of FeatureSMEF64), "sme-f64">;
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,
// they should be enabled if either has been specified.
def HasSVEorSME
: Predicate<"Subtarget->hasSVE() || Subtarget->hasSME()">,
- AssemblerPredicate<(any_of FeatureSVE, FeatureSME),
+ AssemblerPredicateWithAll<(any_of FeatureSVE, FeatureSME),
"sve or sme">;
def HasSVE2orSME
: Predicate<"Subtarget->hasSVE2() || Subtarget->hasSME()">,
- AssemblerPredicate<(any_of FeatureSVE2, FeatureSME),
+ AssemblerPredicateWithAll<(any_of FeatureSVE2, FeatureSME),
"sve2 or sme">;
// A subset of NEON instructions are legal in Streaming SVE execution mode,
// they should be enabled if either has been specified.
def HasNEONorSME
: Predicate<"Subtarget->hasNEON() || Subtarget->hasSME()">,
- AssemblerPredicate<(any_of FeatureNEON, FeatureSME),
+ AssemblerPredicateWithAll<(any_of FeatureNEON, FeatureSME),
"neon or sme">;
def HasRCPC : Predicate<"Subtarget->hasRCPC()">,
- AssemblerPredicate<(all_of FeatureRCPC), "rcpc">;
+ AssemblerPredicateWithAll<(all_of FeatureRCPC), "rcpc">;
def HasLDAPR : Predicate<"Subtarget->hasLDAPR()">,
- AssemblerPredicate<(all_of FeatureLDAPR), "ldapr">;
+ AssemblerPredicateWithAll<(all_of FeatureLDAPR), "ldapr">;
def HasAltNZCV : Predicate<"Subtarget->hasAlternativeNZCV()">,
- AssemblerPredicate<(all_of FeatureAltFPCmp), "altnzcv">;
+ AssemblerPredicateWithAll<(all_of FeatureAltFPCmp), "altnzcv">;
def HasFRInt3264 : Predicate<"Subtarget->hasFRInt3264()">,
- AssemblerPredicate<(all_of FeatureFRInt3264), "frint3264">;
+ AssemblerPredicateWithAll<(all_of FeatureFRInt3264), "frint3264">;
def HasSB : Predicate<"Subtarget->hasSB()">,
- AssemblerPredicate<(all_of FeatureSB), "sb">;
+ AssemblerPredicateWithAll<(all_of FeatureSB), "sb">;
def HasPredRes : Predicate<"Subtarget->hasPredRes()">,
- AssemblerPredicate<(all_of FeaturePredRes), "predres">;
+ AssemblerPredicateWithAll<(all_of FeaturePredRes), "predres">;
def HasCCDP : Predicate<"Subtarget->hasCCDP()">,
- AssemblerPredicate<(all_of FeatureCacheDeepPersist), "ccdp">;
+ AssemblerPredicateWithAll<(all_of FeatureCacheDeepPersist), "ccdp">;
def HasBTI : Predicate<"Subtarget->hasBTI()">,
- AssemblerPredicate<(all_of FeatureBranchTargetId), "bti">;
+ AssemblerPredicateWithAll<(all_of FeatureBranchTargetId), "bti">;
def HasMTE : Predicate<"Subtarget->hasMTE()">,
- AssemblerPredicate<(all_of FeatureMTE), "mte">;
+ AssemblerPredicateWithAll<(all_of FeatureMTE), "mte">;
def HasTME : Predicate<"Subtarget->hasTME()">,
- AssemblerPredicate<(all_of FeatureTME), "tme">;
+ AssemblerPredicateWithAll<(all_of FeatureTME), "tme">;
def HasETE : Predicate<"Subtarget->hasETE()">,
- AssemblerPredicate<(all_of FeatureETE), "ete">;
+ AssemblerPredicateWithAll<(all_of FeatureETE), "ete">;
def HasTRBE : Predicate<"Subtarget->hasTRBE()">,
- AssemblerPredicate<(all_of FeatureTRBE), "trbe">;
+ AssemblerPredicateWithAll<(all_of FeatureTRBE), "trbe">;
def HasBF16 : Predicate<"Subtarget->hasBF16()">,
- AssemblerPredicate<(all_of FeatureBF16), "bf16">;
+ AssemblerPredicateWithAll<(all_of FeatureBF16), "bf16">;
def HasMatMulInt8 : Predicate<"Subtarget->hasMatMulInt8()">,
- AssemblerPredicate<(all_of FeatureMatMulInt8), "i8mm">;
+ AssemblerPredicateWithAll<(all_of FeatureMatMulInt8), "i8mm">;
def HasMatMulFP32 : Predicate<"Subtarget->hasMatMulFP32()">,
- AssemblerPredicate<(all_of FeatureMatMulFP32), "f32mm">;
+ AssemblerPredicateWithAll<(all_of FeatureMatMulFP32), "f32mm">;
def HasMatMulFP64 : Predicate<"Subtarget->hasMatMulFP64()">,
- AssemblerPredicate<(all_of FeatureMatMulFP64), "f64mm">;
+ AssemblerPredicateWithAll<(all_of FeatureMatMulFP64), "f64mm">;
def HasXS : Predicate<"Subtarget->hasXS()">,
- AssemblerPredicate<(all_of FeatureXS), "xs">;
+ AssemblerPredicateWithAll<(all_of FeatureXS), "xs">;
def HasWFxT : Predicate<"Subtarget->hasWFxT()">,
- AssemblerPredicate<(all_of FeatureWFxT), "wfxt">;
+ AssemblerPredicateWithAll<(all_of FeatureWFxT), "wfxt">;
def HasLS64 : Predicate<"Subtarget->hasLS64()">,
- AssemblerPredicate<(all_of FeatureLS64), "ls64">;
+ AssemblerPredicateWithAll<(all_of FeatureLS64), "ls64">;
def HasBRBE : Predicate<"Subtarget->hasBRBE()">,
- AssemblerPredicate<(all_of FeatureBRBE), "brbe">;
+ AssemblerPredicateWithAll<(all_of FeatureBRBE), "brbe">;
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()">,
- AssemblerPredicate<(all_of FeatureHBC), "hbc">;
+ AssemblerPredicateWithAll<(all_of FeatureHBC), "hbc">;
def HasMOPS : Predicate<"Subtarget->hasMOPS()">,
- AssemblerPredicate<(all_of FeatureMOPS), "mops">;
+ AssemblerPredicateWithAll<(all_of FeatureMOPS), "mops">;
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 d71515255357..f3788175c48d 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -18,23 +18,23 @@ include "llvm/TableGen/SearchableTable.td"
//===----------------------------------------------------------------------===//
def HasCCPP : Predicate<"Subtarget->hasCCPP()">,
- AssemblerPredicate<(all_of FeatureCCPP), "ccpp">;
+ AssemblerPredicateWithAll<(all_of FeatureCCPP), "ccpp">;
def HasPAN : Predicate<"Subtarget->hasPAN()">,
- AssemblerPredicate<(all_of FeaturePAN),
+ AssemblerPredicateWithAll<(all_of FeaturePAN),
"ARM v8.1 Privileged Access-Never extension">;
def HasPsUAO : Predicate<"Subtarget->hasPsUAO()">,
- AssemblerPredicate<(all_of FeaturePsUAO),
+ AssemblerPredicateWithAll<(all_of FeaturePsUAO),
"ARM v8.2 UAO PState extension (psuao)">;
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">;
def HasCONTEXTIDREL2
: Predicate<"Subtarget->hasCONTEXTIDREL2()">,
- AssemblerPredicate<(all_of FeatureCONTEXTIDREL2),
+ AssemblerPredicateWithAll<(all_of FeatureCONTEXTIDREL2),
"Target contains CONTEXTIDR_EL2 RW operand">;
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index 5906a5d6b50b..71303611265c 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -634,7 +634,8 @@ namespace AArch64SysReg {
FeatureBitset FeaturesRequired;
bool haveFeatures(FeatureBitset ActiveFeatures) const {
- return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
+ return ActiveFeatures[llvm::AArch64::FeatureAll] ||
+ (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
}
};
diff --git a/llvm/test/CodeGen/AArch64/mattr-all.ll b/llvm/test/CodeGen/AArch64/mattr-all.ll
new file mode 100644
index 000000000000..c99880bfd2dc
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/mattr-all.ll
@@ -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()
diff --git a/llvm/test/MC/AArch64/alias-addsubimm.s b/llvm/test/MC/AArch64/alias-addsubimm.s
index 63bf4821e27d..8c2dbca78a49 100644
--- a/llvm/test/MC/AArch64/alias-addsubimm.s
+++ b/llvm/test/MC/AArch64/alias-addsubimm.s
@@ -2,6 +2,9 @@
// 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
+/// +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
sub w0, w2, #4096
// CHECK: add w0, w2, #1, lsl #12
diff --git a/llvm/test/MC/AArch64/armv8.6a-bf16.s b/llvm/test/MC/AArch64/armv8.6a-bf16.s
index a4eaa36b51cd..2117393a198c 100644
--- a/llvm/test/MC/AArch64/armv8.6a-bf16.s
+++ b/llvm/test/MC/AArch64/armv8.6a-bf16.s
@@ -1,5 +1,6 @@
// 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=+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 < %s 2>&1 | FileCheck %s --check-prefix=NOBF16
diff --git a/llvm/test/MC/Disassembler/AArch64/mattr-all.txt b/llvm/test/MC/Disassembler/AArch64/mattr-all.txt
new file mode 100644
index 000000000000..0d3f13fb76a9
--- /dev/null
+++ b/llvm/test/MC/Disassembler/AArch64/mattr-all.txt
@@ -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]
diff --git a/llvm/test/TableGen/AsmPredicateCombining.td b/llvm/test/TableGen/AsmPredicateCombining.td
index 1e713d3afd93..f7c0ae7c7111 100644
--- a/llvm/test/TableGen/AsmPredicateCombining.td
+++ b/llvm/test/TableGen/AsmPredicateCombining.td
@@ -47,16 +47,20 @@ def AsmCond2a: SubtargetFeature<"cond2a", "cond2a", "true", "">;
def AsmCond2b: SubtargetFeature<"cond2b", "cond2b", "true", "">;
def AsmCond3a: SubtargetFeature<"cond3a", "cond3a", "true", "">;
def AsmCond3b: SubtargetFeature<"cond3b", "cond3b", "true", "">;
+def AsmCond4 : SubtargetFeature<"cond4", "cond4", "true", "">;
def AsmPred1 : Predicate<"Pred1">, AssemblerPredicate<(all_of AsmCond1)>;
def AsmPred2 : Predicate<"Pred2">, AssemblerPredicate<(all_of AsmCond2a, AsmCond2b)>;
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-NEXT: Features.set(Feature_AsmPred1Bit);
// MATCHER-NEXT: if (FB[arch::AsmCond2a] && FB[arch::AsmCond2b])
// 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: if (FB[arch::AsmCond4] && !(FB[arch::AsmCond3a] || FB[arch::AsmCond3b]))
+// MATCHER-NEXT: Features.set(Feature_AsmPred4Bit);
def insn1 : TestInsn<1, [AsmPred1]>;
// DISASS: return (Bits[arch::AsmCond1]);
@@ -65,10 +69,10 @@ def insn2 : TestInsn<2, [AsmPred2]>;
// DISASS: return (Bits[arch::AsmCond2a] && Bits[arch::AsmCond2b])
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]>;
-// 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]>;
// DISASS: return (Bits[arch::AsmCond1] && (Bits[arch::AsmCond3a] || Bits[arch::AsmCond3b]))
diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index 2edac05afb89..1d738274c75a 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -999,6 +999,17 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (D->getNumArgs() == 0)
PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!");
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()) {
bool IsNeg = false;
diff --git a/llvm/utils/TableGen/DecoderEmitter.cpp b/llvm/utils/TableGen/DecoderEmitter.cpp
index b16a96eab498..8477e0639f90 100644
--- a/llvm/utils/TableGen/DecoderEmitter.cpp
+++ b/llvm/utils/TableGen/DecoderEmitter.cpp
@@ -509,6 +509,8 @@ class FilterChooser {
// Returns true if predicate matches were emitted, false otherwise.
bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
unsigned Opc) const;
+ bool emitPredicateMatchAux(const Init &Val, bool ParenIfBinOp,
+ raw_ostream &OS) const;
bool doesOpcodeNeedPredicate(unsigned Opc) const;
unsigned getPredicateIndex(DecoderTableInfo &TableInfo, StringRef P) const;
@@ -1226,6 +1228,40 @@ unsigned FilterChooser::getDecoderIndex(DecoderSet &Decoders,
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,
unsigned Opc) const {
ListInit *Predicates =
@@ -1239,40 +1275,11 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
if (!isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
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)
o << " && ";
-
- if (IsOr)
- o << "(";
-
- 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 << ")";
-
+ if (emitPredicateMatchAux(*Pred->getValueAsDag("AssemblerCondDag"),
+ Predicates->size() > 1, o))
+ PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
IsFirstEmission = false;
}
return !Predicates->empty();
diff --git a/llvm/utils/TableGen/SubtargetFeatureInfo.cpp b/llvm/utils/TableGen/SubtargetFeatureInfo.cpp
index 33a22776f2df..f4f360fb5be2 100644
--- a/llvm/utils/TableGen/SubtargetFeatureInfo.cpp
+++ b/llvm/utils/TableGen/SubtargetFeatureInfo.cpp
@@ -108,6 +108,39 @@ void SubtargetFeatureInfo::emitComputeAvailableFeatures(
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(
StringRef TargetName, StringRef ClassName, StringRef FuncName,
SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) {
@@ -118,37 +151,8 @@ void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
const SubtargetFeatureInfo &SFI = SF.second;
OS << " if (";
-
- const DagInit *D = SFI.TheDef->getValueAsDag("AssemblerCondDag");
- 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 << ")";
-
+ emitFeaturesAux(TargetName, *SFI.TheDef->getValueAsDag("AssemblerCondDag"),
+ /*ParenIfBinOp=*/false, OS);
OS << ")\n";
OS << " Features.set(" << SFI.getEnumBitName() << ");\n";
}
More information about the llvm-commits
mailing list