summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/Targets.cpp97
-rw-r--r--clang/lib/Driver/Tools.cpp98
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.
OpenPOWER on IntegriCloud