diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -556,6 +556,13 @@ FeatureSpecRestrict ]>; +// Only intended to be used by disassemblers. +def FeatureAll + : SubtargetFeature<"all", "IsAll", "true", "Enable all instructions", []>; + +class AssemblerPredicateWithAll + : 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 --- 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 --- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td +++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td @@ -18,23 +18,23 @@ //===----------------------------------------------------------------------===// 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 --- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -634,7 +634,8 @@ 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 --- /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 --- 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 --- 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 --- /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 --- a/llvm/test/TableGen/AsmPredicateCombining.td +++ b/llvm/test/TableGen/AsmPredicateCombining.td @@ -47,16 +47,20 @@ 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 @@ // 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 --- a/llvm/utils/TableGen/AsmWriterEmitter.cpp +++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp @@ -999,6 +999,17 @@ 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(D->getArg(1))) { + DagInit *RHS = dyn_cast(D->getArg(1)); + SmallVector Args{D->getArg(0)}; + SmallVector 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 --- a/llvm/utils/TableGen/DecoderEmitter.cpp +++ b/llvm/utils/TableGen/DecoderEmitter.cpp @@ -509,6 +509,8 @@ // 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 @@ 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(&Val)) { + if (!D->getDef()->isSubClassOf("SubtargetFeature")) + return true; + OS << "Bits[" << Emitter->PredicateNamespace << "::" << D->getAsString() + << "]"; + return false; + } + if (auto *D = dyn_cast(&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 @@ if (!isa(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(Arg)) { - if (NotArg->getOperator()->getAsString() != "not" || - NotArg->getNumArgs() != 1) - PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!"); - Arg = NotArg->getArg(0); - o << "!"; - } - if (!isa(Arg) || - !cast(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 --- a/llvm/utils/TableGen/SubtargetFeatureInfo.cpp +++ b/llvm/utils/TableGen/SubtargetFeatureInfo.cpp @@ -108,6 +108,39 @@ 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(&Val)) { + if (!D->getDef()->isSubClassOf("SubtargetFeature")) + return true; + OS << "FB[" << TargetName << "::" << D->getAsString() << "]"; + return false; + } + if (auto *D = dyn_cast(&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 @@ 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(Arg)) { - if (NotArg->getOperator()->getAsString() != "not" || - NotArg->getNumArgs() != 1) - PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!"); - Arg = NotArg->getArg(0); - OS << "!"; - } - if (!isa(Arg) || - !cast(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"; }