1f09cf34dSArchibald Elliott //===-- ARMTargetParser - Parser for ARM target features --------*- C++ -*-===// 2f09cf34dSArchibald Elliott // 3f09cf34dSArchibald Elliott // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4f09cf34dSArchibald Elliott // See https://llvm.org/LICENSE.txt for license information. 5f09cf34dSArchibald Elliott // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6f09cf34dSArchibald Elliott // 7f09cf34dSArchibald Elliott //===----------------------------------------------------------------------===// 8f09cf34dSArchibald Elliott // 9f09cf34dSArchibald Elliott // This file implements a target parser to recognise ARM hardware features 10f09cf34dSArchibald Elliott // such as FPU/CPU/ARCH/extensions and specific support such as HWDIV. 11f09cf34dSArchibald Elliott // 12f09cf34dSArchibald Elliott //===----------------------------------------------------------------------===// 13f09cf34dSArchibald Elliott 14f09cf34dSArchibald Elliott #include "llvm/TargetParser/ARMTargetParser.h" 15f09cf34dSArchibald Elliott #include "llvm/ADT/StringSwitch.h" 1673779bb2SBalint Cristian #include "llvm/Support/Format.h" 1799594ba3SDavid Spickett #include "llvm/Support/raw_ostream.h" 18f09cf34dSArchibald Elliott #include "llvm/TargetParser/ARMTargetParserCommon.h" 19f09cf34dSArchibald Elliott #include "llvm/TargetParser/Triple.h" 20f09cf34dSArchibald Elliott #include <cctype> 21f09cf34dSArchibald Elliott 22f09cf34dSArchibald Elliott using namespace llvm; 23f09cf34dSArchibald Elliott 24f09cf34dSArchibald Elliott static StringRef getHWDivSynonym(StringRef HWDiv) { 25f09cf34dSArchibald Elliott return StringSwitch<StringRef>(HWDiv) 26f09cf34dSArchibald Elliott .Case("thumb,arm", "arm,thumb") 27f09cf34dSArchibald Elliott .Default(HWDiv); 28f09cf34dSArchibald Elliott } 29f09cf34dSArchibald Elliott 30f09cf34dSArchibald Elliott // Allows partial match, ex. "v7a" matches "armv7a". 31f09cf34dSArchibald Elliott ARM::ArchKind ARM::parseArch(StringRef Arch) { 32f09cf34dSArchibald Elliott Arch = getCanonicalArchName(Arch); 33f09cf34dSArchibald Elliott StringRef Syn = getArchSynonym(Arch); 34f09cf34dSArchibald Elliott for (const auto &A : ARMArchNames) { 35586ecdf2SKazu Hirata if (A.Name.ends_with(Syn)) 36f09cf34dSArchibald Elliott return A.ID; 37f09cf34dSArchibald Elliott } 38f09cf34dSArchibald Elliott return ArchKind::INVALID; 39f09cf34dSArchibald Elliott } 40f09cf34dSArchibald Elliott 41f09cf34dSArchibald Elliott // Version number (ex. v7 = 7). 42f09cf34dSArchibald Elliott unsigned ARM::parseArchVersion(StringRef Arch) { 43f09cf34dSArchibald Elliott Arch = getCanonicalArchName(Arch); 44f09cf34dSArchibald Elliott switch (parseArch(Arch)) { 45f09cf34dSArchibald Elliott case ArchKind::ARMV4: 46f09cf34dSArchibald Elliott case ArchKind::ARMV4T: 47f09cf34dSArchibald Elliott return 4; 48f09cf34dSArchibald Elliott case ArchKind::ARMV5T: 49f09cf34dSArchibald Elliott case ArchKind::ARMV5TE: 50f09cf34dSArchibald Elliott case ArchKind::IWMMXT: 51f09cf34dSArchibald Elliott case ArchKind::IWMMXT2: 52f09cf34dSArchibald Elliott case ArchKind::XSCALE: 53f09cf34dSArchibald Elliott case ArchKind::ARMV5TEJ: 54f09cf34dSArchibald Elliott return 5; 55f09cf34dSArchibald Elliott case ArchKind::ARMV6: 56f09cf34dSArchibald Elliott case ArchKind::ARMV6K: 57f09cf34dSArchibald Elliott case ArchKind::ARMV6T2: 58f09cf34dSArchibald Elliott case ArchKind::ARMV6KZ: 59f09cf34dSArchibald Elliott case ArchKind::ARMV6M: 60f09cf34dSArchibald Elliott return 6; 61f09cf34dSArchibald Elliott case ArchKind::ARMV7A: 62f09cf34dSArchibald Elliott case ArchKind::ARMV7VE: 63f09cf34dSArchibald Elliott case ArchKind::ARMV7R: 64f09cf34dSArchibald Elliott case ArchKind::ARMV7M: 65f09cf34dSArchibald Elliott case ArchKind::ARMV7S: 66f09cf34dSArchibald Elliott case ArchKind::ARMV7EM: 67f09cf34dSArchibald Elliott case ArchKind::ARMV7K: 68f09cf34dSArchibald Elliott return 7; 69f09cf34dSArchibald Elliott case ArchKind::ARMV8A: 70f09cf34dSArchibald Elliott case ArchKind::ARMV8_1A: 71f09cf34dSArchibald Elliott case ArchKind::ARMV8_2A: 72f09cf34dSArchibald Elliott case ArchKind::ARMV8_3A: 73f09cf34dSArchibald Elliott case ArchKind::ARMV8_4A: 74f09cf34dSArchibald Elliott case ArchKind::ARMV8_5A: 75f09cf34dSArchibald Elliott case ArchKind::ARMV8_6A: 76f09cf34dSArchibald Elliott case ArchKind::ARMV8_7A: 77f09cf34dSArchibald Elliott case ArchKind::ARMV8_8A: 78f09cf34dSArchibald Elliott case ArchKind::ARMV8_9A: 79f09cf34dSArchibald Elliott case ArchKind::ARMV8R: 80f09cf34dSArchibald Elliott case ArchKind::ARMV8MBaseline: 81f09cf34dSArchibald Elliott case ArchKind::ARMV8MMainline: 82f09cf34dSArchibald Elliott case ArchKind::ARMV8_1MMainline: 83f09cf34dSArchibald Elliott return 8; 84f09cf34dSArchibald Elliott case ArchKind::ARMV9A: 85f09cf34dSArchibald Elliott case ArchKind::ARMV9_1A: 86f09cf34dSArchibald Elliott case ArchKind::ARMV9_2A: 87f09cf34dSArchibald Elliott case ArchKind::ARMV9_3A: 88f09cf34dSArchibald Elliott case ArchKind::ARMV9_4A: 896bbaad1eSLucas Duarte Prates case ArchKind::ARMV9_5A: 90d0756caeSJonathan Thackray case ArchKind::ARMV9_6A: 91f09cf34dSArchibald Elliott return 9; 92f09cf34dSArchibald Elliott case ArchKind::INVALID: 93f09cf34dSArchibald Elliott return 0; 94f09cf34dSArchibald Elliott } 95f09cf34dSArchibald Elliott llvm_unreachable("Unhandled architecture"); 96f09cf34dSArchibald Elliott } 97f09cf34dSArchibald Elliott 98f09cf34dSArchibald Elliott static ARM::ProfileKind getProfileKind(ARM::ArchKind AK) { 99f09cf34dSArchibald Elliott switch (AK) { 100f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV6M: 101f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV7M: 102f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV7EM: 103f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8MMainline: 104f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8MBaseline: 105f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8_1MMainline: 106f09cf34dSArchibald Elliott return ARM::ProfileKind::M; 107f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV7R: 108f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8R: 109f09cf34dSArchibald Elliott return ARM::ProfileKind::R; 110f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV7A: 111f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV7VE: 112f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV7K: 113f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8A: 114f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8_1A: 115f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8_2A: 116f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8_3A: 117f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8_4A: 118f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8_5A: 119f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8_6A: 120f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8_7A: 121f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8_8A: 122f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV8_9A: 123f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV9A: 124f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV9_1A: 125f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV9_2A: 126f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV9_3A: 127f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV9_4A: 1286bbaad1eSLucas Duarte Prates case ARM::ArchKind::ARMV9_5A: 129d0756caeSJonathan Thackray case ARM::ArchKind::ARMV9_6A: 130f09cf34dSArchibald Elliott return ARM::ProfileKind::A; 131f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV4: 132f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV4T: 133f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV5T: 134f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV5TE: 135f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV5TEJ: 136f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV6: 137f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV6K: 138f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV6T2: 139f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV6KZ: 140f09cf34dSArchibald Elliott case ARM::ArchKind::ARMV7S: 141f09cf34dSArchibald Elliott case ARM::ArchKind::IWMMXT: 142f09cf34dSArchibald Elliott case ARM::ArchKind::IWMMXT2: 143f09cf34dSArchibald Elliott case ARM::ArchKind::XSCALE: 144f09cf34dSArchibald Elliott case ARM::ArchKind::INVALID: 145f09cf34dSArchibald Elliott return ARM::ProfileKind::INVALID; 146f09cf34dSArchibald Elliott } 147f09cf34dSArchibald Elliott llvm_unreachable("Unhandled architecture"); 148f09cf34dSArchibald Elliott } 149f09cf34dSArchibald Elliott 150f09cf34dSArchibald Elliott // Profile A/R/M 151f09cf34dSArchibald Elliott ARM::ProfileKind ARM::parseArchProfile(StringRef Arch) { 152f09cf34dSArchibald Elliott Arch = getCanonicalArchName(Arch); 153f09cf34dSArchibald Elliott return getProfileKind(parseArch(Arch)); 154f09cf34dSArchibald Elliott } 155f09cf34dSArchibald Elliott 15660bbf271SMichael Platings bool ARM::getFPUFeatures(ARM::FPUKind FPUKind, 15760bbf271SMichael Platings std::vector<StringRef> &Features) { 158f09cf34dSArchibald Elliott 159f09cf34dSArchibald Elliott if (FPUKind >= FK_LAST || FPUKind == FK_INVALID) 160f09cf34dSArchibald Elliott return false; 161f09cf34dSArchibald Elliott 162f09cf34dSArchibald Elliott static const struct FPUFeatureNameInfo { 163f09cf34dSArchibald Elliott const char *PlusName, *MinusName; 164f09cf34dSArchibald Elliott FPUVersion MinVersion; 165f09cf34dSArchibald Elliott FPURestriction MaxRestriction; 166f09cf34dSArchibald Elliott } FPUFeatureInfoList[] = { 167f09cf34dSArchibald Elliott // We have to specify the + and - versions of the name in full so 168f09cf34dSArchibald Elliott // that we can return them as static StringRefs. 169f09cf34dSArchibald Elliott // 170f09cf34dSArchibald Elliott // Also, the SubtargetFeatures ending in just "sp" are listed here 171f09cf34dSArchibald Elliott // under FPURestriction::None, which is the only FPURestriction in 172f09cf34dSArchibald Elliott // which they would be valid (since FPURestriction::SP doesn't 173f09cf34dSArchibald Elliott // exist). 174f09cf34dSArchibald Elliott {"+vfp2", "-vfp2", FPUVersion::VFPV2, FPURestriction::D16}, 175f09cf34dSArchibald Elliott {"+vfp2sp", "-vfp2sp", FPUVersion::VFPV2, FPURestriction::SP_D16}, 176f09cf34dSArchibald Elliott {"+vfp3", "-vfp3", FPUVersion::VFPV3, FPURestriction::None}, 177f09cf34dSArchibald Elliott {"+vfp3d16", "-vfp3d16", FPUVersion::VFPV3, FPURestriction::D16}, 178f09cf34dSArchibald Elliott {"+vfp3d16sp", "-vfp3d16sp", FPUVersion::VFPV3, FPURestriction::SP_D16}, 179f09cf34dSArchibald Elliott {"+vfp3sp", "-vfp3sp", FPUVersion::VFPV3, FPURestriction::None}, 180f09cf34dSArchibald Elliott {"+fp16", "-fp16", FPUVersion::VFPV3_FP16, FPURestriction::SP_D16}, 181f09cf34dSArchibald Elliott {"+vfp4", "-vfp4", FPUVersion::VFPV4, FPURestriction::None}, 182f09cf34dSArchibald Elliott {"+vfp4d16", "-vfp4d16", FPUVersion::VFPV4, FPURestriction::D16}, 183f09cf34dSArchibald Elliott {"+vfp4d16sp", "-vfp4d16sp", FPUVersion::VFPV4, FPURestriction::SP_D16}, 184f09cf34dSArchibald Elliott {"+vfp4sp", "-vfp4sp", FPUVersion::VFPV4, FPURestriction::None}, 185f09cf34dSArchibald Elliott {"+fp-armv8", "-fp-armv8", FPUVersion::VFPV5, FPURestriction::None}, 186f09cf34dSArchibald Elliott {"+fp-armv8d16", "-fp-armv8d16", FPUVersion::VFPV5, FPURestriction::D16}, 187f09cf34dSArchibald Elliott {"+fp-armv8d16sp", "-fp-armv8d16sp", FPUVersion::VFPV5, FPURestriction::SP_D16}, 188f09cf34dSArchibald Elliott {"+fp-armv8sp", "-fp-armv8sp", FPUVersion::VFPV5, FPURestriction::None}, 189f09cf34dSArchibald Elliott {"+fullfp16", "-fullfp16", FPUVersion::VFPV5_FULLFP16, FPURestriction::SP_D16}, 190f09cf34dSArchibald Elliott {"+fp64", "-fp64", FPUVersion::VFPV2, FPURestriction::D16}, 191f09cf34dSArchibald Elliott {"+d32", "-d32", FPUVersion::VFPV3, FPURestriction::None}, 192f09cf34dSArchibald Elliott }; 193f09cf34dSArchibald Elliott 194f09cf34dSArchibald Elliott for (const auto &Info: FPUFeatureInfoList) { 195f09cf34dSArchibald Elliott if (FPUNames[FPUKind].FPUVer >= Info.MinVersion && 196f09cf34dSArchibald Elliott FPUNames[FPUKind].Restriction <= Info.MaxRestriction) 197f09cf34dSArchibald Elliott Features.push_back(Info.PlusName); 198f09cf34dSArchibald Elliott else 199f09cf34dSArchibald Elliott Features.push_back(Info.MinusName); 200f09cf34dSArchibald Elliott } 201f09cf34dSArchibald Elliott 202f09cf34dSArchibald Elliott static const struct NeonFeatureNameInfo { 203f09cf34dSArchibald Elliott const char *PlusName, *MinusName; 204f09cf34dSArchibald Elliott NeonSupportLevel MinSupportLevel; 205f09cf34dSArchibald Elliott } NeonFeatureInfoList[] = { 206f09cf34dSArchibald Elliott {"+neon", "-neon", NeonSupportLevel::Neon}, 207f09cf34dSArchibald Elliott {"+sha2", "-sha2", NeonSupportLevel::Crypto}, 208f09cf34dSArchibald Elliott {"+aes", "-aes", NeonSupportLevel::Crypto}, 209f09cf34dSArchibald Elliott }; 210f09cf34dSArchibald Elliott 211f09cf34dSArchibald Elliott for (const auto &Info: NeonFeatureInfoList) { 212f09cf34dSArchibald Elliott if (FPUNames[FPUKind].NeonSupport >= Info.MinSupportLevel) 213f09cf34dSArchibald Elliott Features.push_back(Info.PlusName); 214f09cf34dSArchibald Elliott else 215f09cf34dSArchibald Elliott Features.push_back(Info.MinusName); 216f09cf34dSArchibald Elliott } 217f09cf34dSArchibald Elliott 218f09cf34dSArchibald Elliott return true; 219f09cf34dSArchibald Elliott } 220f09cf34dSArchibald Elliott 22160bbf271SMichael Platings ARM::FPUKind ARM::parseFPU(StringRef FPU) { 222f09cf34dSArchibald Elliott StringRef Syn = getFPUSynonym(FPU); 223f09cf34dSArchibald Elliott for (const auto &F : FPUNames) { 224f09cf34dSArchibald Elliott if (Syn == F.Name) 225f09cf34dSArchibald Elliott return F.ID; 226f09cf34dSArchibald Elliott } 227f09cf34dSArchibald Elliott return FK_INVALID; 228f09cf34dSArchibald Elliott } 229f09cf34dSArchibald Elliott 23060bbf271SMichael Platings ARM::NeonSupportLevel ARM::getFPUNeonSupportLevel(ARM::FPUKind FPUKind) { 231f09cf34dSArchibald Elliott if (FPUKind >= FK_LAST) 232f09cf34dSArchibald Elliott return NeonSupportLevel::None; 233f09cf34dSArchibald Elliott return FPUNames[FPUKind].NeonSupport; 234f09cf34dSArchibald Elliott } 235f09cf34dSArchibald Elliott 236f09cf34dSArchibald Elliott StringRef ARM::getFPUSynonym(StringRef FPU) { 237f09cf34dSArchibald Elliott return StringSwitch<StringRef>(FPU) 238f09cf34dSArchibald Elliott .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported 239f09cf34dSArchibald Elliott .Case("vfp2", "vfpv2") 240f09cf34dSArchibald Elliott .Case("vfp3", "vfpv3") 241f09cf34dSArchibald Elliott .Case("vfp4", "vfpv4") 242f09cf34dSArchibald Elliott .Case("vfp3-d16", "vfpv3-d16") 243f09cf34dSArchibald Elliott .Case("vfp4-d16", "vfpv4-d16") 244f09cf34dSArchibald Elliott .Cases("fp4-sp-d16", "vfpv4-sp-d16", "fpv4-sp-d16") 245f09cf34dSArchibald Elliott .Cases("fp4-dp-d16", "fpv4-dp-d16", "vfpv4-d16") 246f09cf34dSArchibald Elliott .Case("fp5-sp-d16", "fpv5-sp-d16") 247f09cf34dSArchibald Elliott .Cases("fp5-dp-d16", "fpv5-dp-d16", "fpv5-d16") 248f09cf34dSArchibald Elliott // FIXME: Clang uses it, but it's bogus, since neon defaults to vfpv3. 249f09cf34dSArchibald Elliott .Case("neon-vfpv3", "neon") 250f09cf34dSArchibald Elliott .Default(FPU); 251f09cf34dSArchibald Elliott } 252f09cf34dSArchibald Elliott 25360bbf271SMichael Platings StringRef ARM::getFPUName(ARM::FPUKind FPUKind) { 254f09cf34dSArchibald Elliott if (FPUKind >= FK_LAST) 255f09cf34dSArchibald Elliott return StringRef(); 256f09cf34dSArchibald Elliott return FPUNames[FPUKind].Name; 257f09cf34dSArchibald Elliott } 258f09cf34dSArchibald Elliott 25960bbf271SMichael Platings ARM::FPUVersion ARM::getFPUVersion(ARM::FPUKind FPUKind) { 260f09cf34dSArchibald Elliott if (FPUKind >= FK_LAST) 261f09cf34dSArchibald Elliott return FPUVersion::NONE; 262f09cf34dSArchibald Elliott return FPUNames[FPUKind].FPUVer; 263f09cf34dSArchibald Elliott } 264f09cf34dSArchibald Elliott 26560bbf271SMichael Platings ARM::FPURestriction ARM::getFPURestriction(ARM::FPUKind FPUKind) { 266f09cf34dSArchibald Elliott if (FPUKind >= FK_LAST) 267f09cf34dSArchibald Elliott return FPURestriction::None; 268f09cf34dSArchibald Elliott return FPUNames[FPUKind].Restriction; 269f09cf34dSArchibald Elliott } 270f09cf34dSArchibald Elliott 27160bbf271SMichael Platings ARM::FPUKind ARM::getDefaultFPU(StringRef CPU, ARM::ArchKind AK) { 272f09cf34dSArchibald Elliott if (CPU == "generic") 273f09cf34dSArchibald Elliott return ARM::ARMArchNames[static_cast<unsigned>(AK)].DefaultFPU; 274f09cf34dSArchibald Elliott 27560bbf271SMichael Platings return StringSwitch<ARM::FPUKind>(CPU) 276f09cf34dSArchibald Elliott #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 277f09cf34dSArchibald Elliott .Case(NAME, DEFAULT_FPU) 278f09cf34dSArchibald Elliott #include "llvm/TargetParser/ARMTargetParser.def" 279f09cf34dSArchibald Elliott .Default(ARM::FK_INVALID); 280f09cf34dSArchibald Elliott } 281f09cf34dSArchibald Elliott 282f09cf34dSArchibald Elliott uint64_t ARM::getDefaultExtensions(StringRef CPU, ARM::ArchKind AK) { 283f09cf34dSArchibald Elliott if (CPU == "generic") 284f09cf34dSArchibald Elliott return ARM::ARMArchNames[static_cast<unsigned>(AK)].ArchBaseExtensions; 285f09cf34dSArchibald Elliott 286f09cf34dSArchibald Elliott return StringSwitch<uint64_t>(CPU) 287f09cf34dSArchibald Elliott #define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \ 288f09cf34dSArchibald Elliott .Case(NAME, \ 289f09cf34dSArchibald Elliott ARMArchNames[static_cast<unsigned>(ArchKind::ID)].ArchBaseExtensions | \ 290f09cf34dSArchibald Elliott DEFAULT_EXT) 291f09cf34dSArchibald Elliott #include "llvm/TargetParser/ARMTargetParser.def" 292f09cf34dSArchibald Elliott .Default(ARM::AEK_INVALID); 293f09cf34dSArchibald Elliott } 294f09cf34dSArchibald Elliott 295f09cf34dSArchibald Elliott bool ARM::getHWDivFeatures(uint64_t HWDivKind, 296f09cf34dSArchibald Elliott std::vector<StringRef> &Features) { 297f09cf34dSArchibald Elliott 298f09cf34dSArchibald Elliott if (HWDivKind == AEK_INVALID) 299f09cf34dSArchibald Elliott return false; 300f09cf34dSArchibald Elliott 301f09cf34dSArchibald Elliott if (HWDivKind & AEK_HWDIVARM) 302f09cf34dSArchibald Elliott Features.push_back("+hwdiv-arm"); 303f09cf34dSArchibald Elliott else 304f09cf34dSArchibald Elliott Features.push_back("-hwdiv-arm"); 305f09cf34dSArchibald Elliott 306f09cf34dSArchibald Elliott if (HWDivKind & AEK_HWDIVTHUMB) 307f09cf34dSArchibald Elliott Features.push_back("+hwdiv"); 308f09cf34dSArchibald Elliott else 309f09cf34dSArchibald Elliott Features.push_back("-hwdiv"); 310f09cf34dSArchibald Elliott 311f09cf34dSArchibald Elliott return true; 312f09cf34dSArchibald Elliott } 313f09cf34dSArchibald Elliott 314f09cf34dSArchibald Elliott bool ARM::getExtensionFeatures(uint64_t Extensions, 315f09cf34dSArchibald Elliott std::vector<StringRef> &Features) { 316f09cf34dSArchibald Elliott 317f09cf34dSArchibald Elliott if (Extensions == AEK_INVALID) 318f09cf34dSArchibald Elliott return false; 319f09cf34dSArchibald Elliott 320f09cf34dSArchibald Elliott for (const auto &AE : ARCHExtNames) { 321f09cf34dSArchibald Elliott if ((Extensions & AE.ID) == AE.ID && !AE.Feature.empty()) 322f09cf34dSArchibald Elliott Features.push_back(AE.Feature); 323f09cf34dSArchibald Elliott else if (!AE.NegFeature.empty()) 324f09cf34dSArchibald Elliott Features.push_back(AE.NegFeature); 325f09cf34dSArchibald Elliott } 326f09cf34dSArchibald Elliott 327f09cf34dSArchibald Elliott return getHWDivFeatures(Extensions, Features); 328f09cf34dSArchibald Elliott } 329f09cf34dSArchibald Elliott 330f09cf34dSArchibald Elliott StringRef ARM::getArchName(ARM::ArchKind AK) { 331f09cf34dSArchibald Elliott return ARMArchNames[static_cast<unsigned>(AK)].Name; 332f09cf34dSArchibald Elliott } 333f09cf34dSArchibald Elliott 334f09cf34dSArchibald Elliott StringRef ARM::getCPUAttr(ARM::ArchKind AK) { 335f09cf34dSArchibald Elliott return ARMArchNames[static_cast<unsigned>(AK)].CPUAttr; 336f09cf34dSArchibald Elliott } 337f09cf34dSArchibald Elliott 338f09cf34dSArchibald Elliott StringRef ARM::getSubArch(ARM::ArchKind AK) { 339f09cf34dSArchibald Elliott return ARMArchNames[static_cast<unsigned>(AK)].getSubArch(); 340f09cf34dSArchibald Elliott } 341f09cf34dSArchibald Elliott 342f09cf34dSArchibald Elliott unsigned ARM::getArchAttr(ARM::ArchKind AK) { 343f09cf34dSArchibald Elliott return ARMArchNames[static_cast<unsigned>(AK)].ArchAttr; 344f09cf34dSArchibald Elliott } 345f09cf34dSArchibald Elliott 346f09cf34dSArchibald Elliott StringRef ARM::getArchExtName(uint64_t ArchExtKind) { 347f09cf34dSArchibald Elliott for (const auto &AE : ARCHExtNames) { 348f09cf34dSArchibald Elliott if (ArchExtKind == AE.ID) 349f09cf34dSArchibald Elliott return AE.Name; 350f09cf34dSArchibald Elliott } 351f09cf34dSArchibald Elliott return StringRef(); 352f09cf34dSArchibald Elliott } 353f09cf34dSArchibald Elliott 354f09cf34dSArchibald Elliott static bool stripNegationPrefix(StringRef &Name) { 355f5f2c313SKazu Hirata return Name.consume_front("no"); 356f09cf34dSArchibald Elliott } 357f09cf34dSArchibald Elliott 358f09cf34dSArchibald Elliott StringRef ARM::getArchExtFeature(StringRef ArchExt) { 359f09cf34dSArchibald Elliott bool Negated = stripNegationPrefix(ArchExt); 360f09cf34dSArchibald Elliott for (const auto &AE : ARCHExtNames) { 361f09cf34dSArchibald Elliott if (!AE.Feature.empty() && ArchExt == AE.Name) 362f09cf34dSArchibald Elliott return StringRef(Negated ? AE.NegFeature : AE.Feature); 363f09cf34dSArchibald Elliott } 364f09cf34dSArchibald Elliott 365f09cf34dSArchibald Elliott return StringRef(); 366f09cf34dSArchibald Elliott } 367f09cf34dSArchibald Elliott 36860bbf271SMichael Platings static ARM::FPUKind findDoublePrecisionFPU(ARM::FPUKind InputFPUKind) { 369b3c4f649SDominik Wójt if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE) 370b3c4f649SDominik Wójt return ARM::FK_INVALID; 371b3c4f649SDominik Wójt 372f09cf34dSArchibald Elliott const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind]; 373f09cf34dSArchibald Elliott 374f09cf34dSArchibald Elliott // If the input FPU already supports double-precision, then there 375f09cf34dSArchibald Elliott // isn't any different FPU we can return here. 376b3c4f649SDominik Wójt if (ARM::isDoublePrecision(InputFPU.Restriction)) 377b3c4f649SDominik Wójt return InputFPUKind; 378f09cf34dSArchibald Elliott 379f09cf34dSArchibald Elliott // Otherwise, look for an FPU entry with all the same fields, except 380b3c4f649SDominik Wójt // that it supports double precision. 381f09cf34dSArchibald Elliott for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) { 382f09cf34dSArchibald Elliott if (CandidateFPU.FPUVer == InputFPU.FPUVer && 383f09cf34dSArchibald Elliott CandidateFPU.NeonSupport == InputFPU.NeonSupport && 384b3c4f649SDominik Wójt ARM::has32Regs(CandidateFPU.Restriction) == 385b3c4f649SDominik Wójt ARM::has32Regs(InputFPU.Restriction) && 386b3c4f649SDominik Wójt ARM::isDoublePrecision(CandidateFPU.Restriction)) { 387b3c4f649SDominik Wójt return CandidateFPU.ID; 388b3c4f649SDominik Wójt } 389b3c4f649SDominik Wójt } 390b3c4f649SDominik Wójt 391b3c4f649SDominik Wójt // nothing found 392b3c4f649SDominik Wójt return ARM::FK_INVALID; 393b3c4f649SDominik Wójt } 394b3c4f649SDominik Wójt 395b3c4f649SDominik Wójt static ARM::FPUKind findSinglePrecisionFPU(ARM::FPUKind InputFPUKind) { 396b3c4f649SDominik Wójt if (InputFPUKind == ARM::FK_INVALID || InputFPUKind == ARM::FK_NONE) 397b3c4f649SDominik Wójt return ARM::FK_INVALID; 398b3c4f649SDominik Wójt 399b3c4f649SDominik Wójt const ARM::FPUName &InputFPU = ARM::FPUNames[InputFPUKind]; 400b3c4f649SDominik Wójt 401b3c4f649SDominik Wójt // If the input FPU already is single-precision only, then there 402b3c4f649SDominik Wójt // isn't any different FPU we can return here. 403b3c4f649SDominik Wójt if (!ARM::isDoublePrecision(InputFPU.Restriction)) 404b3c4f649SDominik Wójt return InputFPUKind; 405b3c4f649SDominik Wójt 406b3c4f649SDominik Wójt // Otherwise, look for an FPU entry with all the same fields, except 407b3c4f649SDominik Wójt // that it does not support double precision. 408b3c4f649SDominik Wójt for (const ARM::FPUName &CandidateFPU : ARM::FPUNames) { 409b3c4f649SDominik Wójt if (CandidateFPU.FPUVer == InputFPU.FPUVer && 410b3c4f649SDominik Wójt CandidateFPU.NeonSupport == InputFPU.NeonSupport && 411b3c4f649SDominik Wójt ARM::has32Regs(CandidateFPU.Restriction) == 412b3c4f649SDominik Wójt ARM::has32Regs(InputFPU.Restriction) && 413b3c4f649SDominik Wójt !ARM::isDoublePrecision(CandidateFPU.Restriction)) { 414f09cf34dSArchibald Elliott return CandidateFPU.ID; 415f09cf34dSArchibald Elliott } 416f09cf34dSArchibald Elliott } 417f09cf34dSArchibald Elliott 418f09cf34dSArchibald Elliott // nothing found 419f09cf34dSArchibald Elliott return ARM::FK_INVALID; 420f09cf34dSArchibald Elliott } 421f09cf34dSArchibald Elliott 422f09cf34dSArchibald Elliott bool ARM::appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK, 423f09cf34dSArchibald Elliott StringRef ArchExt, 424f09cf34dSArchibald Elliott std::vector<StringRef> &Features, 42560bbf271SMichael Platings ARM::FPUKind &ArgFPUKind) { 426f09cf34dSArchibald Elliott 427f09cf34dSArchibald Elliott size_t StartingNumFeatures = Features.size(); 428f09cf34dSArchibald Elliott const bool Negated = stripNegationPrefix(ArchExt); 429f09cf34dSArchibald Elliott uint64_t ID = parseArchExt(ArchExt); 430f09cf34dSArchibald Elliott 431f09cf34dSArchibald Elliott if (ID == AEK_INVALID) 432f09cf34dSArchibald Elliott return false; 433f09cf34dSArchibald Elliott 434f09cf34dSArchibald Elliott for (const auto &AE : ARCHExtNames) { 435f09cf34dSArchibald Elliott if (Negated) { 436f09cf34dSArchibald Elliott if ((AE.ID & ID) == ID && !AE.NegFeature.empty()) 437f09cf34dSArchibald Elliott Features.push_back(AE.NegFeature); 438f09cf34dSArchibald Elliott } else { 439f09cf34dSArchibald Elliott if ((AE.ID & ID) == AE.ID && !AE.Feature.empty()) 440f09cf34dSArchibald Elliott Features.push_back(AE.Feature); 441f09cf34dSArchibald Elliott } 442f09cf34dSArchibald Elliott } 443f09cf34dSArchibald Elliott 444f09cf34dSArchibald Elliott if (CPU == "") 445f09cf34dSArchibald Elliott CPU = "generic"; 446f09cf34dSArchibald Elliott 447f09cf34dSArchibald Elliott if (ArchExt == "fp" || ArchExt == "fp.dp") { 448b3c4f649SDominik Wójt const ARM::FPUKind DefaultFPU = getDefaultFPU(CPU, AK); 44960bbf271SMichael Platings ARM::FPUKind FPUKind; 450f09cf34dSArchibald Elliott if (ArchExt == "fp.dp") { 451b3c4f649SDominik Wójt const bool IsDP = ArgFPUKind != ARM::FK_INVALID && 452b3c4f649SDominik Wójt ArgFPUKind != ARM::FK_NONE && 453b3c4f649SDominik Wójt isDoublePrecision(getFPURestriction(ArgFPUKind)); 454f09cf34dSArchibald Elliott if (Negated) { 455b3c4f649SDominik Wójt /* If there is no FPU selected yet, we still need to set ArgFPUKind, as 456b3c4f649SDominik Wójt * leaving it as FK_INVALID, would cause default FPU to be selected 457b3c4f649SDominik Wójt * later and that could be double precision one. */ 458b3c4f649SDominik Wójt if (ArgFPUKind != ARM::FK_INVALID && !IsDP) 459f09cf34dSArchibald Elliott return true; 460b3c4f649SDominik Wójt FPUKind = findSinglePrecisionFPU(DefaultFPU); 461b3c4f649SDominik Wójt if (FPUKind == ARM::FK_INVALID) 462b3c4f649SDominik Wójt FPUKind = ARM::FK_NONE; 463b3c4f649SDominik Wójt } else { 464b3c4f649SDominik Wójt if (IsDP) 465b3c4f649SDominik Wójt return true; 466b3c4f649SDominik Wójt FPUKind = findDoublePrecisionFPU(DefaultFPU); 467b3c4f649SDominik Wójt if (FPUKind == ARM::FK_INVALID) 468b3c4f649SDominik Wójt return false; 469f09cf34dSArchibald Elliott } 470f09cf34dSArchibald Elliott } else if (Negated) { 471f09cf34dSArchibald Elliott FPUKind = ARM::FK_NONE; 472f09cf34dSArchibald Elliott } else { 473b3c4f649SDominik Wójt FPUKind = DefaultFPU; 474f09cf34dSArchibald Elliott } 47560bbf271SMichael Platings ArgFPUKind = FPUKind; 476b3c4f649SDominik Wójt return true; 477f09cf34dSArchibald Elliott } 478f09cf34dSArchibald Elliott return StartingNumFeatures != Features.size(); 479f09cf34dSArchibald Elliott } 480f09cf34dSArchibald Elliott 481f09cf34dSArchibald Elliott ARM::ArchKind ARM::convertV9toV8(ARM::ArchKind AK) { 482f09cf34dSArchibald Elliott if (getProfileKind(AK) != ProfileKind::A) 483f09cf34dSArchibald Elliott return ARM::ArchKind::INVALID; 484f09cf34dSArchibald Elliott if (AK < ARM::ArchKind::ARMV9A || AK > ARM::ArchKind::ARMV9_3A) 485f09cf34dSArchibald Elliott return ARM::ArchKind::INVALID; 486f09cf34dSArchibald Elliott unsigned AK_v8 = static_cast<unsigned>(ARM::ArchKind::ARMV8_5A); 487f09cf34dSArchibald Elliott AK_v8 += static_cast<unsigned>(AK) - 488f09cf34dSArchibald Elliott static_cast<unsigned>(ARM::ArchKind::ARMV9A); 489f09cf34dSArchibald Elliott return static_cast<ARM::ArchKind>(AK_v8); 490f09cf34dSArchibald Elliott } 491f09cf34dSArchibald Elliott 492f09cf34dSArchibald Elliott StringRef ARM::getDefaultCPU(StringRef Arch) { 493f09cf34dSArchibald Elliott ArchKind AK = parseArch(Arch); 494f09cf34dSArchibald Elliott if (AK == ArchKind::INVALID) 495f09cf34dSArchibald Elliott return StringRef(); 496f09cf34dSArchibald Elliott 497f09cf34dSArchibald Elliott // Look for multiple AKs to find the default for pair AK+Name. 498f09cf34dSArchibald Elliott for (const auto &CPU : CPUNames) { 499f09cf34dSArchibald Elliott if (CPU.ArchID == AK && CPU.Default) 500f09cf34dSArchibald Elliott return CPU.Name; 501f09cf34dSArchibald Elliott } 502f09cf34dSArchibald Elliott 503f09cf34dSArchibald Elliott // If we can't find a default then target the architecture instead 504f09cf34dSArchibald Elliott return "generic"; 505f09cf34dSArchibald Elliott } 506f09cf34dSArchibald Elliott 507f09cf34dSArchibald Elliott uint64_t ARM::parseHWDiv(StringRef HWDiv) { 508f09cf34dSArchibald Elliott StringRef Syn = getHWDivSynonym(HWDiv); 509f09cf34dSArchibald Elliott for (const auto &D : HWDivNames) { 510f09cf34dSArchibald Elliott if (Syn == D.Name) 511f09cf34dSArchibald Elliott return D.ID; 512f09cf34dSArchibald Elliott } 513f09cf34dSArchibald Elliott return AEK_INVALID; 514f09cf34dSArchibald Elliott } 515f09cf34dSArchibald Elliott 516f09cf34dSArchibald Elliott uint64_t ARM::parseArchExt(StringRef ArchExt) { 517f09cf34dSArchibald Elliott for (const auto &A : ARCHExtNames) { 518f09cf34dSArchibald Elliott if (ArchExt == A.Name) 519f09cf34dSArchibald Elliott return A.ID; 520f09cf34dSArchibald Elliott } 521f09cf34dSArchibald Elliott return AEK_INVALID; 522f09cf34dSArchibald Elliott } 523f09cf34dSArchibald Elliott 524f09cf34dSArchibald Elliott ARM::ArchKind ARM::parseCPUArch(StringRef CPU) { 525f09cf34dSArchibald Elliott for (const auto &C : CPUNames) { 526f09cf34dSArchibald Elliott if (CPU == C.Name) 527f09cf34dSArchibald Elliott return C.ArchID; 528f09cf34dSArchibald Elliott } 529f09cf34dSArchibald Elliott return ArchKind::INVALID; 530f09cf34dSArchibald Elliott } 531f09cf34dSArchibald Elliott 532f09cf34dSArchibald Elliott void ARM::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) { 533f09cf34dSArchibald Elliott for (const auto &Arch : CPUNames) { 534f09cf34dSArchibald Elliott if (Arch.ArchID != ArchKind::INVALID) 535f09cf34dSArchibald Elliott Values.push_back(Arch.Name); 536f09cf34dSArchibald Elliott } 537f09cf34dSArchibald Elliott } 538f09cf34dSArchibald Elliott 539f09cf34dSArchibald Elliott StringRef ARM::computeDefaultTargetABI(const Triple &TT, StringRef CPU) { 540f09cf34dSArchibald Elliott StringRef ArchName = 541f09cf34dSArchibald Elliott CPU.empty() ? TT.getArchName() : getArchName(parseCPUArch(CPU)); 542f09cf34dSArchibald Elliott 543f09cf34dSArchibald Elliott if (TT.isOSBinFormatMachO()) { 544f09cf34dSArchibald Elliott if (TT.getEnvironment() == Triple::EABI || 545f09cf34dSArchibald Elliott TT.getOS() == Triple::UnknownOS || 546f09cf34dSArchibald Elliott parseArchProfile(ArchName) == ProfileKind::M) 547f09cf34dSArchibald Elliott return "aapcs"; 548f09cf34dSArchibald Elliott if (TT.isWatchABI()) 549f09cf34dSArchibald Elliott return "aapcs16"; 550f09cf34dSArchibald Elliott return "apcs-gnu"; 551f09cf34dSArchibald Elliott } else if (TT.isOSWindows()) 552f09cf34dSArchibald Elliott // FIXME: this is invalid for WindowsCE. 553f09cf34dSArchibald Elliott return "aapcs"; 554f09cf34dSArchibald Elliott 555f09cf34dSArchibald Elliott // Select the default based on the platform. 556f09cf34dSArchibald Elliott switch (TT.getEnvironment()) { 557f09cf34dSArchibald Elliott case Triple::Android: 558f09cf34dSArchibald Elliott case Triple::GNUEABI: 559*387b37afSMichał Górny case Triple::GNUEABIT64: 560f09cf34dSArchibald Elliott case Triple::GNUEABIHF: 561*387b37afSMichał Górny case Triple::GNUEABIHFT64: 562f09cf34dSArchibald Elliott case Triple::MuslEABI: 563f09cf34dSArchibald Elliott case Triple::MuslEABIHF: 564a63dc79dSBrad Smith case Triple::OpenHOS: 565f09cf34dSArchibald Elliott return "aapcs-linux"; 566f09cf34dSArchibald Elliott case Triple::EABIHF: 567f09cf34dSArchibald Elliott case Triple::EABI: 568f09cf34dSArchibald Elliott return "aapcs"; 569f09cf34dSArchibald Elliott default: 570f09cf34dSArchibald Elliott if (TT.isOSNetBSD()) 571f09cf34dSArchibald Elliott return "apcs-gnu"; 5727cfe32d4SBrad Smith if (TT.isOSFreeBSD() || TT.isOSOpenBSD() || TT.isOSHaiku() || 5737cfe32d4SBrad Smith TT.isOHOSFamily()) 574f09cf34dSArchibald Elliott return "aapcs-linux"; 575f09cf34dSArchibald Elliott return "aapcs"; 576f09cf34dSArchibald Elliott } 577f09cf34dSArchibald Elliott } 578f09cf34dSArchibald Elliott 579f09cf34dSArchibald Elliott StringRef ARM::getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch) { 580f09cf34dSArchibald Elliott if (MArch.empty()) 581f09cf34dSArchibald Elliott MArch = Triple.getArchName(); 582f09cf34dSArchibald Elliott MArch = llvm::ARM::getCanonicalArchName(MArch); 583f09cf34dSArchibald Elliott 584f09cf34dSArchibald Elliott // Some defaults are forced. 585f09cf34dSArchibald Elliott switch (Triple.getOS()) { 586f09cf34dSArchibald Elliott case llvm::Triple::FreeBSD: 587f09cf34dSArchibald Elliott case llvm::Triple::NetBSD: 588f09cf34dSArchibald Elliott case llvm::Triple::OpenBSD: 5897cfe32d4SBrad Smith case llvm::Triple::Haiku: 590f09cf34dSArchibald Elliott if (!MArch.empty() && MArch == "v6") 591f09cf34dSArchibald Elliott return "arm1176jzf-s"; 592f09cf34dSArchibald Elliott if (!MArch.empty() && MArch == "v7") 593f09cf34dSArchibald Elliott return "cortex-a8"; 594f09cf34dSArchibald Elliott break; 595f09cf34dSArchibald Elliott case llvm::Triple::Win32: 596f09cf34dSArchibald Elliott // FIXME: this is invalid for WindowsCE 597f09cf34dSArchibald Elliott if (llvm::ARM::parseArchVersion(MArch) <= 7) 598f09cf34dSArchibald Elliott return "cortex-a9"; 599f09cf34dSArchibald Elliott break; 600f09cf34dSArchibald Elliott case llvm::Triple::IOS: 601f09cf34dSArchibald Elliott case llvm::Triple::MacOSX: 602f09cf34dSArchibald Elliott case llvm::Triple::TvOS: 603f09cf34dSArchibald Elliott case llvm::Triple::WatchOS: 604f09cf34dSArchibald Elliott case llvm::Triple::DriverKit: 605735adbf1SCyndy Ishida case llvm::Triple::XROS: 606f09cf34dSArchibald Elliott if (MArch == "v7k") 607f09cf34dSArchibald Elliott return "cortex-a7"; 608f09cf34dSArchibald Elliott break; 609f09cf34dSArchibald Elliott default: 610f09cf34dSArchibald Elliott break; 611f09cf34dSArchibald Elliott } 612f09cf34dSArchibald Elliott 613f09cf34dSArchibald Elliott if (MArch.empty()) 614f09cf34dSArchibald Elliott return StringRef(); 615f09cf34dSArchibald Elliott 616f09cf34dSArchibald Elliott StringRef CPU = llvm::ARM::getDefaultCPU(MArch); 617bb6df080SKazu Hirata if (!CPU.empty() && CPU != "invalid") 618f09cf34dSArchibald Elliott return CPU; 619f09cf34dSArchibald Elliott 620f09cf34dSArchibald Elliott // If no specific architecture version is requested, return the minimum CPU 621f09cf34dSArchibald Elliott // required by the OS and environment. 622f09cf34dSArchibald Elliott switch (Triple.getOS()) { 6237cfe32d4SBrad Smith case llvm::Triple::Haiku: 6247cfe32d4SBrad Smith return "arm1176jzf-s"; 625f09cf34dSArchibald Elliott case llvm::Triple::NetBSD: 626f09cf34dSArchibald Elliott switch (Triple.getEnvironment()) { 627f09cf34dSArchibald Elliott case llvm::Triple::EABI: 628f09cf34dSArchibald Elliott case llvm::Triple::EABIHF: 629f09cf34dSArchibald Elliott case llvm::Triple::GNUEABI: 630f09cf34dSArchibald Elliott case llvm::Triple::GNUEABIHF: 631f09cf34dSArchibald Elliott return "arm926ej-s"; 632f09cf34dSArchibald Elliott default: 633f09cf34dSArchibald Elliott return "strongarm"; 634f09cf34dSArchibald Elliott } 635f09cf34dSArchibald Elliott case llvm::Triple::NaCl: 636f09cf34dSArchibald Elliott case llvm::Triple::OpenBSD: 637f09cf34dSArchibald Elliott return "cortex-a8"; 638f09cf34dSArchibald Elliott default: 639f09cf34dSArchibald Elliott switch (Triple.getEnvironment()) { 640f09cf34dSArchibald Elliott case llvm::Triple::EABIHF: 641f09cf34dSArchibald Elliott case llvm::Triple::GNUEABIHF: 642*387b37afSMichał Górny case llvm::Triple::GNUEABIHFT64: 643f09cf34dSArchibald Elliott case llvm::Triple::MuslEABIHF: 644f09cf34dSArchibald Elliott return "arm1176jzf-s"; 645f09cf34dSArchibald Elliott default: 646f09cf34dSArchibald Elliott return "arm7tdmi"; 647f09cf34dSArchibald Elliott } 648f09cf34dSArchibald Elliott } 649f09cf34dSArchibald Elliott 650f09cf34dSArchibald Elliott llvm_unreachable("invalid arch name"); 651f09cf34dSArchibald Elliott } 65299594ba3SDavid Spickett 65373779bb2SBalint Cristian void ARM::PrintSupportedExtensions(StringMap<StringRef> DescMap) { 65473779bb2SBalint Cristian outs() << "All available -march extensions for ARM\n\n" 65573779bb2SBalint Cristian << " " << left_justify("Name", 20) 65673779bb2SBalint Cristian << (DescMap.empty() ? "\n" : "Description\n"); 65799594ba3SDavid Spickett for (const auto &Ext : ARCHExtNames) { 65899594ba3SDavid Spickett // Extensions without a feature cannot be used with -march. 65973779bb2SBalint Cristian if (!Ext.Feature.empty()) { 66073779bb2SBalint Cristian std::string Description = DescMap[Ext.Name].str(); 66173779bb2SBalint Cristian outs() << " " 66273779bb2SBalint Cristian << format(Description.empty() ? "%s\n" : "%-20s%s\n", 66373779bb2SBalint Cristian Ext.Name.str().c_str(), Description.c_str()); 66473779bb2SBalint Cristian } 66599594ba3SDavid Spickett } 66699594ba3SDavid Spickett } 667