diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -345,12 +345,68 @@ Features.push_back("-crc"); } + int V8Version = -1; + int V9Version = -1; + bool HasNoSM4 = false; + bool HasNoSHA3 = false; + bool HasNoSHA2 = false; + bool HasNoAES = false; + bool HasSM4 = false; + bool HasSHA3 = false; + bool HasSHA2 = false; + bool HasAES = false; + bool HasCrypto = false; + bool HasNoCrypto = false; + bool HasFullFP16 = false; + bool HasNoFullFP16 = false; + bool HasFP16FML = false; + bool HasNoFP16FML = false; + int ArchFeatPos = -1; + + for (auto I = Features.begin(), E = Features.end(); I != E; I++) { + if (*I == "+v8a") V8Version = 0; + else if (*I == "+v8.1a") V8Version = 1; + else if (*I == "+v8.2a") V8Version = 2; + else if (*I == "+v8.3a") V8Version = 3; + else if (*I == "+v8.4a") V8Version = 4; + else if (*I == "+v8.5a") V8Version = 5; + else if (*I == "+v8.6a") V8Version = 6; + else if (*I == "+v8.7a") V8Version = 7; + else if (*I == "+v8.8a") V8Version = 8; + else if (*I == "+v8.9a") V8Version = 9; + else if (*I == "+v9a") V9Version = 0; + else if (*I == "+v9.1a") V9Version = 1; + else if (*I == "+v9.2a") V9Version = 2; + else if (*I == "+v9.3a") V9Version = 3; + else if (*I == "+v9.4a") V9Version = 4; + else if (*I == "+sm4") HasSM4 = true; + else if (*I == "+sha3") HasSHA3 = true; + else if (*I == "+sha2") HasSHA2 = true; + else if (*I == "+aes") HasAES = true; + else if (*I == "-sm4") HasNoSM4 = true; + else if (*I == "-sha3") HasNoSHA3 = true; + else if (*I == "-sha2") HasNoSHA2 = true; + else if (*I == "-aes") HasNoAES = true; + // Whichever option comes after (right-most option) will win + else if (*I == "+crypto") { + HasCrypto = true; + HasNoCrypto = false; + } + else if (*I == "-crypto") { + HasCrypto = false; + HasNoCrypto = true; + } + // Register the iterator position if this is an architecture feature + if (ArchFeatPos == -1 && (V8Version != -1 || V9Version != -1)) + ArchFeatPos = I - Features.begin(); + } + // Handle (arch-dependent) fp16fml/fullfp16 relationship. // FIXME: this fp16fml option handling will be reimplemented after the // TargetParser rewrite. const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(), "-fullfp16"); const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(), "+fp16fml"); - if (llvm::is_contained(Features, "+v8.4a")) { + if (V8Version == 4) { const auto ItRFullFP16 = std::find(Features.rbegin(), Features.rend(), "+fullfp16"); if (ItRFullFP16 < ItRNoFullFP16 && ItRFullFP16 < ItRFP16FML) { // Only entangled feature that can be to the right of this +fullfp16 is -fp16fml. @@ -375,56 +431,23 @@ // Context sensitive meaning of Crypto: // 1) For Arch >= ARMv8.4a: crypto = sm4 + sha3 + sha2 + aes // 2) For Arch <= ARMv8.3a: crypto = sha2 + aes - const auto ItBegin = Features.begin(); - const auto ItEnd = Features.end(); - const auto ItRBegin = Features.rbegin(); - const auto ItREnd = Features.rend(); - const auto ItRCrypto = std::find(ItRBegin, ItREnd, "+crypto"); - const auto ItRNoCrypto = std::find(ItRBegin, ItREnd, "-crypto"); - const auto HasCrypto = ItRCrypto != ItREnd; - const auto HasNoCrypto = ItRNoCrypto != ItREnd; - const ptrdiff_t PosCrypto = ItRCrypto - ItRBegin; - const ptrdiff_t PosNoCrypto = ItRNoCrypto - ItRBegin; - - bool NoCrypto = false; - if (HasCrypto && HasNoCrypto) { - if (PosNoCrypto < PosCrypto) - NoCrypto = true; - } - - if (std::find(ItBegin, ItEnd, "+v8.4a") != ItEnd || - std::find(ItBegin, ItEnd, "+v8.5a") != ItEnd || - std::find(ItBegin, ItEnd, "+v8.6a") != ItEnd || - std::find(ItBegin, ItEnd, "+v8.7a") != ItEnd || - std::find(ItBegin, ItEnd, "+v8.8a") != ItEnd || - std::find(ItBegin, ItEnd, "+v9a") != ItEnd || - std::find(ItBegin, ItEnd, "+v9.1a") != ItEnd || - std::find(ItBegin, ItEnd, "+v9.2a") != ItEnd || - std::find(ItBegin, ItEnd, "+v9.3a") != ItEnd) { - if (HasCrypto && !NoCrypto) { + if (V8Version >= 4 || V9Version >= 0) { + if (HasCrypto && !HasNoCrypto) { // Check if we have NOT disabled an algorithm with something like: // +crypto, -algorithm // And if "-algorithm" does not occur, we enable that crypto algorithm. - const bool HasSM4 = (std::find(ItBegin, ItEnd, "-sm4") == ItEnd); - const bool HasSHA3 = (std::find(ItBegin, ItEnd, "-sha3") == ItEnd); - const bool HasSHA2 = (std::find(ItBegin, ItEnd, "-sha2") == ItEnd); - const bool HasAES = (std::find(ItBegin, ItEnd, "-aes") == ItEnd); - if (HasSM4) + if (!HasNoSM4) Features.push_back("+sm4"); - if (HasSHA3) + if (!HasNoSHA3) Features.push_back("+sha3"); - if (HasSHA2) + if (!HasNoSHA2) Features.push_back("+sha2"); - if (HasAES) + if (!HasNoAES) Features.push_back("+aes"); } else if (HasNoCrypto) { // Check if we have NOT enabled a crypto algorithm with something like: // -crypto, +algorithm // And if "+algorithm" does not occur, we disable that crypto algorithm. - const bool HasSM4 = (std::find(ItBegin, ItEnd, "+sm4") != ItEnd); - const bool HasSHA3 = (std::find(ItBegin, ItEnd, "+sha3") != ItEnd); - const bool HasSHA2 = (std::find(ItBegin, ItEnd, "+sha2") != ItEnd); - const bool HasAES = (std::find(ItBegin, ItEnd, "+aes") != ItEnd); if (!HasSM4) Features.push_back("-sm4"); if (!HasSHA3) @@ -435,24 +458,17 @@ Features.push_back("-aes"); } } else { - if (HasCrypto && !NoCrypto) { - const bool HasSHA2 = (std::find(ItBegin, ItEnd, "-sha2") == ItEnd); - const bool HasAES = (std::find(ItBegin, ItEnd, "-aes") == ItEnd); - if (HasSHA2) + if (HasCrypto && !HasNoCrypto) { + if (!HasNoSHA2) Features.push_back("+sha2"); - if (HasAES) + if (!HasNoAES) Features.push_back("+aes"); } else if (HasNoCrypto) { - const bool HasSHA2 = (std::find(ItBegin, ItEnd, "+sha2") != ItEnd); - const bool HasAES = (std::find(ItBegin, ItEnd, "+aes") != ItEnd); - const bool HasV82a = (std::find(ItBegin, ItEnd, "+v8.2a") != ItEnd); - const bool HasV83a = (std::find(ItBegin, ItEnd, "+v8.3a") != ItEnd); - const bool HasV84a = (std::find(ItBegin, ItEnd, "+v8.4a") != ItEnd); if (!HasSHA2) Features.push_back("-sha2"); if (!HasAES) Features.push_back("-aes"); - if (HasV82a || HasV83a || HasV84a) { + if (V8Version == 2 || V8Version == 3) { Features.push_back("-sm4"); Features.push_back("-sha3"); } @@ -461,21 +477,15 @@ // FIXME: these insertions should ideally be automated using default // extensions support from the backend target parser. - const char *v8691OrLater[] = {"+v8.6a", "+v8.7a", "+v8.8a", - "+v9.1a", "+v9.2a", "+v9.3a"}; - auto Pos = - std::find_first_of(Features.begin(), Features.end(), - std::begin(v8691OrLater), std::end(v8691OrLater)); - if (Pos != std::end(Features)) - Pos = Features.insert(std::next(Pos), {"+i8mm", "+bf16"}); + if (V8Version >= 6 || V9Version >= 1) + Features.insert(std::next(Features.begin() + ArchFeatPos), + {"+i8mm", "+bf16"}); // For Armv8.8-a/Armv9.3-a or later, FEAT_HBC and FEAT_MOPS are enabled by // default. - const char *v8893OrLater[] = {"+v8.8a", "+v9.3a"}; - Pos = std::find_first_of(Features.begin(), Features.end(), - std::begin(v8893OrLater), std::end(v8893OrLater)); - if (Pos != std::end(Features)) - Pos = Features.insert(std::next(Pos), {"+hbc", "+mops"}); + if (V8Version >= 8 || V9Version >= 3) + Features.insert(std::next(Features.begin() + ArchFeatPos), + {"+hbc", "+mops"}); if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) {