diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-05-06 03:16:41 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-05-06 03:16:41 +0000 |
commit | 868bd0aa9281929ef50d2e9a8c82a036906f53f5 (patch) | |
tree | 112dd090bf8ad85dac458a0b669ff7f582d8128a /lib/Basic/Targets.cpp | |
parent | 02f7ed72fa0d4674e2123a1bd54d7972812f8cc7 (diff) |
Improve handling of (X86) target features.
- This is a WIP...
- This adds -march= handling to the driver, and fixes the defaulting
of -mcpu on Darwin (which was using the wrong test).
Instead of handling -m{sse, ...} in the driver, pass them to clang-cc as
-target-feature [+-]name
In clang-cc, communicate with the (clang) target to discover the legal
features of a target, and the features which are enabled based on
-mcpu. This is currently hardcoded just enough to not be a feature
regression, we need to get this information from the backend's
TableGen information somehow.
This is used to construct the full list of features which are being
used, which is in turn used to initialize the predefines.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71061 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Basic/Targets.cpp')
-rw-r--r-- | lib/Basic/Targets.cpp | 97 |
1 files changed, 52 insertions, 45 deletions
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index e0db82d2a8..bb568b149b 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -503,10 +503,7 @@ class X86TargetInfo : public TargetInfo { } SSELevel; public: X86TargetInfo(const std::string& triple) - : TargetInfo(triple), - // FIXME: hard coding to SSE2 for now. This should change to NoMMXSSE so - // that the driver controls this. - SSELevel(SSE2) { + : TargetInfo(triple), SSELevel(NoMMXSSE) { LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; } virtual void getTargetBuiltins(const Builtin::Info *&Records, @@ -536,49 +533,59 @@ public: virtual void getTargetDefines(const LangOptions &Opts, std::vector<char> &Defines) const; - virtual int HandleTargetFeatures(std::string *StrArray, unsigned NumStrs, - std::string &ErrorReason); + virtual void getDefaultFeatures(const std::string &CPU, + llvm::StringMap<bool> &Features); + virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features); }; -/// HandleTargetOptions - Handle target-specific options like -msse2 and -/// friends. An array of arguments is passed in: if they are all valid, this -/// should handle them and return -1. If there is an error, the index of the -/// invalid argument should be returned along with an optional error string. -int X86TargetInfo::HandleTargetFeatures(std::string *StrArray, unsigned NumStrs, - std::string &ErrorReason) { - for (unsigned i = 0; i != NumStrs; ++i) { - const std::string &Feature = StrArray[i]; - if (Feature.size() < 2) return i; - // Ignore explicitly disabled features. - if (Feature[0] == '-') continue; - - // Feature strings are of the form "+feature". - if (Feature[0] != '+') return i; - - // The set of supported subtarget features is defined in - // lib/Target/X86/X86.td. Here we recognize and map onto our internal - // state. - if (Feature == "+mmx") - SSELevel = std::max(SSELevel, MMX); - else if (Feature == "+sse") - SSELevel = std::max(SSELevel, SSE1); - else if (Feature == "+sse2") - SSELevel = std::max(SSELevel, SSE2); - else if (Feature == "+sse3") - SSELevel = std::max(SSELevel, SSE3); - else if (Feature == "+ssse3") - SSELevel = std::max(SSELevel, SSSE3); - else if (Feature == "+sse41") - SSELevel = std::max(SSELevel, SSE41); - else if (Feature == "+sse42") - SSELevel = std::max(SSELevel, SSE42); - else if (Feature == "+64bit" || Feature == "+slow-bt-mem") - // Ignore these features. - continue; - else - return i; - } - return -1; +void X86TargetInfo::getDefaultFeatures(const std::string &CPU, + llvm::StringMap<bool> &Features) { + // FIXME: This should not be here. + Features["3dnow"] = false; + Features["3dnowa"] = false; + Features["mmx"] = false; + Features["sse"] = false; + Features["sse2"] = false; + Features["sse3"] = false; + Features["ssse3"] = false; + Features["sse41"] = false; + Features["sse42"] = false; + + // LLVM does not currently recognize this. + // Features["sse4a"] = false; + + // FIXME: This *really* should not be here. + + // X86_64 always has SSE2. + if (PointerWidth == 64) + Features["sse2"] = Features["sse"] = Features["mmx"] = true; + + // FIXME: LLVM says core2 has SSSE3, but gcc doesn't define + // __SSSE3__ with it? What else is going on here? + if (CPU == "core2") + Features["ssse3"] = Features["sse3"] = Features["sse2"] = Features["sse"] = + Features["mmx"] = true; + else if (CPU == "pentium4") + Features["sse2"] = Features["sse"] = Features["mmx"] = true; +} + +/// HandleTargetOptions - Perform initialization based on the user +/// configured set of features. +void X86TargetInfo::HandleTargetFeatures(const llvm::StringMap<bool>&Features) { + if (Features.lookup("sse42")) + SSELevel = SSE42; + else if (Features.lookup("sse41")) + SSELevel = SSE41; + else if (Features.lookup("ssse3")) + SSELevel = SSSE3; + else if (Features.lookup("sse3")) + SSELevel = SSE3; + else if (Features.lookup("sse2")) + SSELevel = SSE2; + else if (Features.lookup("sse")) + SSELevel = SSE1; + else if (Features.lookup("mmx")) + SSELevel = MMX; } /// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines |