diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Basic/Targets.cpp | 97 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 98 |
2 files changed, 99 insertions, 96 deletions
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index e0db82d2a81..bb568b149b4 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/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 diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 2a959b3c55a..a52498dc950 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -31,6 +31,13 @@ using namespace clang::driver; using namespace clang::driver::tools; +static const char *MakeFormattedString(const ArgList &Args, + const llvm::format_object_base &Fmt) { + std::string Str; + llvm::raw_string_ostream(Str) << Fmt; + return Args.MakeArgString(Str.c_str()); +} + void Clang::AddPreprocessingOptions(const Driver &D, const ArgList &Args, ArgStringList &CmdArgs, @@ -318,52 +325,48 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, false)) CmdArgs.push_back("--soft-float"); - // FIXME: Need target hooks. - if (memcmp(getToolChain().getPlatform().c_str(), "darwin", 6) == 0) { - if (getToolChain().getArchName() == "x86_64") - CmdArgs.push_back("--mcpu=core2"); - else if (getToolChain().getArchName() == "i386") - CmdArgs.push_back("--mcpu=yonah"); - } - - // FIXME: Ignores ordering. Also, we need to find a realistic - // solution for this. - static const struct { - options::ID Pos, Neg; - const char *Name; - } FeatureOptions[] = { - { options::OPT_mmmx, options::OPT_mno_mmx, "mmx" }, - { options::OPT_msse, options::OPT_mno_sse, "sse" }, - { options::OPT_msse2, options::OPT_mno_sse2, "sse2" }, - { options::OPT_msse3, options::OPT_mno_sse3, "sse3" }, - { options::OPT_mssse3, options::OPT_mno_ssse3, "ssse3" }, - { options::OPT_msse41, options::OPT_mno_sse41, "sse41" }, - { options::OPT_msse42, options::OPT_mno_sse42, "sse42" }, - { options::OPT_msse4a, options::OPT_mno_sse4a, "sse4a" }, - { options::OPT_m3dnow, options::OPT_mno_3dnow, "3dnow" }, - { options::OPT_m3dnowa, options::OPT_mno_3dnowa, "3dnowa" } - }; - const unsigned NumFeatureOptions = - sizeof(FeatureOptions)/sizeof(FeatureOptions[0]); - - // FIXME: Avoid std::string - std::string Attrs; - for (unsigned i=0; i < NumFeatureOptions; ++i) { - if (Args.hasArg(FeatureOptions[i].Pos)) { - if (!Attrs.empty()) - Attrs += ','; - Attrs += '+'; - Attrs += FeatureOptions[i].Name; - } else if (Args.hasArg(FeatureOptions[i].Neg)) { - if (!Attrs.empty()) - Attrs += ','; - Attrs += '-'; - Attrs += FeatureOptions[i].Name; + // FIXME: Handle -mtune=. + (void) Args.hasArg(options::OPT_mtune_EQ); + + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { + // FIXME: We made need some translation here from the options gcc + // takes to names the LLVM backend understand? + CmdArgs.push_back("-mcpu"); + CmdArgs.push_back(A->getValue(Args)); + } else { + // Select default CPU. + + // FIXME: Need target hooks. + if (memcmp(getToolChain().getOS().c_str(), "darwin", 6) == 0) { + if (getToolChain().getArchName() == "x86_64") + CmdArgs.push_back("--mcpu=core2"); + else if (getToolChain().getArchName() == "i386") + CmdArgs.push_back("--mcpu=pentium4"); } } - if (!Attrs.empty()) { - CmdArgs.push_back("--mattr"); - CmdArgs.push_back(Args.MakeArgString(Attrs.c_str())); + + // FIXME: Use iterator. + for (ArgList::const_iterator + it = Args.begin(), ie = Args.end(); it != ie; ++it) { + const Arg *A = *it; + if (A->getOption().matches(options::OPT_m_x86_Features_Group)) { + const char *Name = A->getOption().getName(); + + // Skip over "-m". + assert(Name[0] == '-' && Name[1] == 'm' && "Invalid feature name."); + Name += 2; + + bool IsNegative = memcmp(Name, "no-", 3) == 0; + if (IsNegative) + Name += 3; + + A->claim(); + CmdArgs.push_back("-target-feature"); + CmdArgs.push_back(MakeFormattedString(Args, + llvm::format("%c%s", + IsNegative ? '-' : '+', + Name))); + } } if (Args.hasFlag(options::OPT_fmath_errno, @@ -1215,13 +1218,6 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA, Dest.addCommand(new Command(Exec, CmdArgs)); } -static const char *MakeFormattedString(const ArgList &Args, - const llvm::format_object_base &Fmt) { - std::string Str; - llvm::raw_string_ostream(Str) << Fmt; - return Args.MakeArgString(Str.c_str()); -} - /// Helper routine for seeing if we should use dsymutil; this is a /// gcc compatible hack, we should remove it and use the input /// type information. |