Index: include/llvm/Support/TargetParser.h =================================================================== --- include/llvm/Support/TargetParser.h +++ include/llvm/Support/TargetParser.h @@ -122,22 +122,24 @@ // Arch extension modifiers for CPUs. enum ArchExtKind { - AEK_INVALID = 0, - AEK_CRC, - AEK_CRYPTO, - AEK_FP, - AEK_HWDIV, - AEK_MP, - AEK_SIMD, - AEK_SEC, - AEK_VIRT, + AEK_INVALID = 0x0, + AEK_NONE = 0x1, + AEK_CRC = 0x2, + AEK_CRYPTO = 0x4, + AEK_FP = 0x8, + AEK_HWDIV = 0x10, + AEK_HWDIVARM = 0x20, + AEK_MP = 0x40, + AEK_SIMD = 0x80, + AEK_SEC = 0x100, + AEK_VIRT = 0x200, // Unsupported extensions. - AEK_OS, - AEK_IWMMXT, - AEK_IWMMXT2, - AEK_MAVERICK, - AEK_XSCALE, - AEK_LAST + AEK_OS = 0x400, + AEK_IWMMXT = 0x800, + AEK_IWMMXT2 = 0x1000, + AEK_MAVERICK = 0x2000, + AEK_XSCALE = 0x4000, + AEK_LAST = 0x8000 }; // ISA kinds. @@ -167,6 +169,7 @@ // Target Parsers, one per architecture. class ARMTargetParser { + static StringRef getHWDivSynonym(StringRef HWDiv); static StringRef getFPUSynonym(StringRef FPU); static StringRef getArchSynonym(StringRef Arch); @@ -182,6 +185,8 @@ // FIXME: This should be moved to TargetTuple once it exists static bool getFPUFeatures(unsigned FPUKind, std::vector &Features); + static bool getHWDivFeatures(unsigned HWDivKind, + std::vector &Features); static const char * getArchName(unsigned ArchKind); static unsigned getArchAttr(unsigned ArchKind); static const char * getCPUAttr(unsigned ArchKind); @@ -190,6 +195,7 @@ static const char * getDefaultCPU(StringRef Arch); // Parser + static unsigned parseHWDiv(StringRef HWDiv); static unsigned parseFPU(StringRef FPU); static unsigned parseArch(StringRef Arch); static unsigned parseArchExt(StringRef ArchExt); Index: lib/Support/TargetParser.cpp =================================================================== --- lib/Support/TargetParser.cpp +++ lib/Support/TargetParser.cpp @@ -115,20 +115,35 @@ const char *Name; ARM::ArchExtKind ID; } ARCHExtNames[] = { - { "invalid", ARM::AEK_INVALID }, - { "crc", ARM::AEK_CRC }, - { "crypto", ARM::AEK_CRYPTO }, - { "fp", ARM::AEK_FP }, - { "idiv", ARM::AEK_HWDIV }, - { "mp", ARM::AEK_MP }, - { "simd", ARM::AEK_SIMD }, - { "sec", ARM::AEK_SEC }, - { "virt", ARM::AEK_VIRT }, - { "os", ARM::AEK_OS }, - { "iwmmxt", ARM::AEK_IWMMXT }, - { "iwmmxt2", ARM::AEK_IWMMXT2 }, - { "maverick", ARM::AEK_MAVERICK }, - { "xscale", ARM::AEK_XSCALE } + { "invalid", ARM::AEK_INVALID }, + { "none", ARM::AEK_NONE }, + { "crc", ARM::AEK_CRC }, + { "crypto", ARM::AEK_CRYPTO }, + { "fp", ARM::AEK_FP }, + { "hwdiv", ARM::AEK_HWDIV }, + { "hwdiv-arm", ARM::AEK_HWDIVARM }, + { "mp", ARM::AEK_MP }, + { "simd", ARM::AEK_SIMD }, + { "sec", ARM::AEK_SEC }, + { "virt", ARM::AEK_VIRT }, + { "os", ARM::AEK_OS }, + { "iwmmxt", ARM::AEK_IWMMXT }, + { "iwmmxt2", ARM::AEK_IWMMXT2 }, + { "maverick", ARM::AEK_MAVERICK }, + { "xscale", ARM::AEK_XSCALE } +}; +// List of HWDiv names (use getHWDivSynonym) and which architectural +// features they correspond to (use getHWDivFeatures). +// FIXME: TableGen this. +struct { + const char *Name; + unsigned ID; +} HWDivNames[] = { + { "invalid", ARM::AEK_INVALID }, + { "none", ARM::AEK_NONE }, + { "thumb", ARM::AEK_HWDIV }, + { "arm", ARM::AEK_HWDIVARM }, + { "arm,thumb", (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV) } }; // List of CPU names and their arches. // The same CPU can have multiple arches and can be default on multiple arches. @@ -266,6 +281,33 @@ return ARM::FK_INVALID; } +bool ARMTargetParser::getHWDivFeatures(unsigned HWDivKind, + std::vector &Features) { + + switch (HWDivKind) { + case ARM::AEK_NONE: + Features.push_back("-hwdiv-arm"); + Features.push_back("-hwdiv"); + break; + case ARM::AEK_HWDIV: + Features.push_back("-hwdiv-arm"); + Features.push_back("+hwdiv"); + break; + case ARM::AEK_HWDIVARM: + Features.push_back("+hwdiv-arm"); + Features.push_back("-hwdiv"); + break; + case (ARM::AEK_HWDIVARM | ARM::AEK_HWDIV): + Features.push_back("+hwdiv-arm"); + Features.push_back("+hwdiv"); + break; + default: + return false; + } + + return true; +} + bool ARMTargetParser::getFPUFeatures(unsigned FPUKind, std::vector &Features) { @@ -394,6 +436,12 @@ // Parsers // ======================================================= // +StringRef ARMTargetParser::getHWDivSynonym(StringRef HWDiv) { + return StringSwitch(HWDiv) + .Case("thumb,arm", "arm,thumb") + .Default(HWDiv); +} + StringRef ARMTargetParser::getFPUSynonym(StringRef FPU) { return StringSwitch(FPU) .Cases("fpa", "fpe2", "fpe3", "maverick", "invalid") // Unsupported @@ -477,6 +525,15 @@ return A; } +unsigned ARMTargetParser::parseHWDiv(StringRef HWDiv) { + StringRef Syn = getHWDivSynonym(HWDiv); + for (const auto D : HWDivNames) { + if (Syn == D.Name) + return D.ID; + } + return ARM::AEK_INVALID; +} + unsigned ARMTargetParser::parseFPU(StringRef FPU) { StringRef Syn = getFPUSynonym(FPU); for (const auto F : FPUNames) {