diff options
-rw-r--r-- | Driver/clang.cpp | 34 | ||||
-rw-r--r-- | include/clang/Basic/TargetInfo.h | 19 | ||||
-rw-r--r-- | lib/Basic/Targets.cpp | 49 |
3 files changed, 72 insertions, 30 deletions
diff --git a/Driver/clang.cpp b/Driver/clang.cpp index 54e93f8031..9ecddd8cd5 100644 --- a/Driver/clang.cpp +++ b/Driver/clang.cpp @@ -517,10 +517,10 @@ Trigraphs("trigraphs", llvm::cl::desc("Process trigraph sequences.")); static llvm::cl::opt<bool> Ansi("ansi", llvm::cl::desc("Equivalent to specifying -std=c89.")); - static llvm::cl::list<std::string> -TargetOptions("m", llvm::cl::Prefix, llvm::cl::value_desc("option"), - llvm::cl::desc("Target-specific options, such as -msse3")); +TargetFeatures("mattr", llvm::cl::CommaSeparated, + llvm::cl::desc("Target specific attributes (-mattr=help for details)")); + // FIXME: add: @@ -530,19 +530,25 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK, // Allow the target to set the default the langauge options as it sees fit. Target->getDefaultLangOptions(Options); - // If the user specified any -mfoo options, pass them to the target for - // validation and processing. - if (!TargetOptions.empty()) { + // If there are any -mattr options, pass them to the target for validation and + // processing. The driver should have already consolidated all the + // target-feature settings and passed them to us in the -mattr list. The + // -mattr list is treated by the code generator as a diff against the -mcpu + // setting, but the driver should pass all enabled options as "+" settings. + // This means that the target should only look at + settings. + if (!TargetFeatures.empty() + // FIXME: The driver is not quite yet ready for this. + && 0) { std::string ErrorStr; - int Opt = Target->HandleTargetOptions(&TargetOptions[0], - TargetOptions.size(), ErrorStr); + int Opt = Target->HandleTargetFeatures(&TargetFeatures[0], + TargetFeatures.size(), ErrorStr); if (Opt != -1) { if (ErrorStr.empty()) - fprintf(stderr, "invalid command line option '%s'\n", - TargetOptions[Opt].c_str()); + fprintf(stderr, "invalid feature '%s'\n", + TargetFeatures[Opt].c_str()); else - fprintf(stderr, "command line option '%s': %s\n", - TargetOptions[Opt].c_str(), ErrorStr.c_str()); + fprintf(stderr, "feature '%s': %s\n", + TargetFeatures[Opt].c_str(), ErrorStr.c_str()); exit(1); } } @@ -1253,10 +1259,6 @@ static llvm::cl::opt<std::string> TargetCPU("mcpu", llvm::cl::desc("Target a specific cpu type (-mcpu=help for details)")); -static llvm::cl::list<std::string> -TargetFeatures("mattr", - llvm::cl::desc("Target specific attributes (-mattr=help for details)")); - static void InitializeCompileOptions(CompileOptions &Opts) { Opts.OptimizeSize = OptSize; if (OptSize) { diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index b9c8b14e09..6a889cb70f 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -249,12 +249,19 @@ public: /// options. virtual void getDefaultLangOptions(LangOptions &Opts) {} - /// 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. - virtual int HandleTargetOptions(std::string *StrArray, unsigned NumStrs, - std::string &ErrorReason) { + /// HandleTargetFeatures - Handle target-specific options like -mattr=+sse2 + /// 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. + /// + /// Note that the driver should have already consolidated all the + /// target-feature settings and passed them to us in the -mattr list. The + /// -mattr list is treated by the code generator as a diff against the -mcpu + /// setting, but the driver should pass all enabled options as "+" settings. + /// This means that the target should only look at + settings. + virtual int HandleTargetFeatures(std::string *StrArray, unsigned NumStrs, + std::string &ErrorReason) { if (NumStrs == 0) return -1; return 0; diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index bb9c861a17..04ab3afdb1 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -420,7 +420,10 @@ class X86TargetInfo : public TargetInfo { } SSELevel; public: X86TargetInfo(const std::string& triple) - : TargetInfo(triple), SSELevel(SSE2) { + : TargetInfo(triple), + // FIXME: hard coding to SSE2 for now. This should change to NoMMXSSE so + // that the driver controls this. + SSELevel(SSE2) { LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; } virtual void getTargetBuiltins(const Builtin::Info *&Records, @@ -449,19 +452,49 @@ public: } virtual void getTargetDefines(std::vector<char> &Defines) const; - virtual int HandleTargetOptions(std::string *StrArray, unsigned NumStrs, - std::string &ErrorReason); + virtual int HandleTargetFeatures(std::string *StrArray, unsigned NumStrs, + std::string &ErrorReason); }; /// 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::HandleTargetOptions(std::string *StrArray, unsigned NumStrs, - std::string &ErrorReason) { - if (NumStrs == 0) - return -1; - return 0; +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; } /// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines |