================ @@ -150,3 +153,137 @@ void AArch64::PrintSupportedExtensions(StringMap<StringRef> DescMap) { } } } + +const llvm::AArch64::ExtensionInfo & +lookupExtensionByID(llvm::AArch64::ArchExtKind ExtID) { + for (const auto &E : llvm::AArch64::Extensions) + if (E.ID == ExtID) + return E; + assert(false && "Invalid extension ID"); +} + +void AArch64::ExtensionSet::enable(ArchExtKind E) { + if (Enabled.test(E)) + return; + + LLVM_DEBUG(llvm::dbgs() << "Enable " << lookupExtensionByID(E).Name << "\n"); + + Touched.set(E); + Enabled.set(E); + + // Recursively enable all features that this one depends on. This handles all + // of the simple cases, where the behaviour doesn't depend on the base + // architecture version. + for (auto Dep : ExtensionDependencies) + if (E == Dep.Later) + enable(Dep.Earlier); + + // Special cases for dependencies which vary depending on the base + // architecture version. + if (BaseArch) { + // +sve implies +f32mm if the base architecture is v8.6A+ or v9.1A+ + // It isn't the case in general that sve implies both f64mm and f32mm + if (E == AEK_SVE && BaseArch->is_superset(ARMV8_6A)) + enable(AEK_F32MM); + + // +fp16 implies +fp16fml for v8.4A+, but not v9.0-A+ + if (E == AEK_FP16 && BaseArch->is_superset(ARMV8_4A) && + !BaseArch->is_superset(ARMV9A)) + enable(AEK_FP16FML); + + // For all architectures, +crypto enables +aes and +sha2. + if (E == AEK_CRYPTO) { + enable(AEK_AES); + enable(AEK_SHA2); + } + + // For v8.4A+ and v9.0A+, +crypto also enables +sha3 and +sm4. + if (E == AEK_CRYPTO && BaseArch->is_superset(ARMV8_4A)) { + enable(AEK_SHA3); + enable(AEK_SM4); + } + } +} + +void AArch64::ExtensionSet::disable(ArchExtKind E) { + // -crypto always disables aes, sha2, sha3 and sm4, even for architectures + // where the latter two would not be enabled by +crypto. + if (E == AEK_CRYPTO) { + disable(AEK_AES); + disable(AEK_SHA2); + disable(AEK_SHA3); + disable(AEK_SM4); + } + + if (!Enabled.test(E)) + return; + + LLVM_DEBUG(llvm::dbgs() << "Disable " << lookupExtensionByID(E).Name << "\n"); + + Touched.set(E); + Enabled.reset(E); + + // Recursively disable all features that depends on this one. + for (auto Dep : ExtensionDependencies) + if (E == Dep.Earlier) + disable(Dep.Later); +} + +void AArch64::ExtensionSet::toLLVMFeatureList( + std::vector<StringRef> &Features) const { + if (BaseArch && !BaseArch->ArchFeature.empty()) + Features.push_back(BaseArch->ArchFeature); + + for (const auto &E : Extensions) { + if (E.Feature.empty() || !Touched.test(E.ID)) + continue; + if (Enabled.test(E.ID)) + Features.push_back(E.Feature); + else + Features.push_back(E.NegFeature); ---------------- tmatheson-arm wrote:
When exactly do we need negative features? https://github.com/llvm/llvm-project/pull/78270 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits