aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-05-06 21:07:50 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-05-06 21:07:50 +0000
commit17ca3638e852ba81f389e9f896ed0420b52ae606 (patch)
tree43558224b95c2af403a7edb86eaa6a9e6de2bafe
parente6863644c6b34bc40cd867e758de1c809d9a55b4 (diff)
More x86 target feature support.
- Apologies for the extremely gross code duplication, I want to get this working and then decide how to get this information out of the back end. - This replaces -m[no-]sse4[12] by -m[no-]sse4, it appears gcc doesn't distinguish them? - -msse, etc. now properly disable/enable related features. - Don't always define __SSE3__... - The main missing functionality bit here is that we don't initialize the features based on the CPU for all -march options. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71117 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/TargetInfo.h12
-rw-r--r--include/clang/Driver/Options.def6
-rw-r--r--lib/Basic/Targets.cpp62
-rw-r--r--test/Preprocessor/x86_target_features.c25
-rw-r--r--tools/clang-cc/clang-cc.cpp12
5 files changed, 99 insertions, 18 deletions
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index ce54db7581..f577d6b322 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -340,7 +340,17 @@ public:
/// the \args CPU; this should include all legal feature strings on
/// the target.
virtual void getDefaultFeatures(const std::string &CPU,
- llvm::StringMap<bool> &Features) {
+ llvm::StringMap<bool> &Features) const {
+ }
+
+ /// setFeatureEnabled - Enable or disable a specific target feature,
+ /// the feature name must be valid.
+ ///
+ /// \return - False on error (invalid feature name).
+ virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
+ const std::string &Name,
+ bool Enabled) const {
+ return false;
}
/// HandleTargetOptions - Perform initialization based on the user
diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def
index cf077be969..31b32f8ebf 100644
--- a/include/clang/Driver/Options.def
+++ b/include/clang/Driver/Options.def
@@ -498,9 +498,8 @@ OPTION("-mno-red-zone", mno_red_zone, Flag, m_Group, INVALID, "", 0, 0, 0)
OPTION("-mno-soft-float", mno_soft_float, Flag, m_Group, INVALID, "", 0, 0, 0)
OPTION("-mno-sse2", mno_sse2, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-mno-sse3", mno_sse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-sse41", mno_sse41, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-mno-sse42", mno_sse42, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-mno-sse4a", mno_sse4a, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-mno-sse4", mno_sse4, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-mno-sse", mno_sse, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-mno-ssse3", mno_ssse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-mno-warn-nonportable-cfstrings", mno_warn_nonportable_cfstrings, Flag, m_Group, INVALID, "", 0, 0, 0)
@@ -509,9 +508,8 @@ OPTION("-mred-zone", mred_zone, Flag, m_Group, INVALID, "", 0, 0, 0)
OPTION("-msoft-float", msoft_float, Flag, m_Group, INVALID, "", 0, 0, 0)
OPTION("-msse2", msse2, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-msse3", msse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-msse41", msse41, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
-OPTION("-msse42", msse42, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-msse4a", msse4a, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
+OPTION("-msse4", msse4, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-msse", msse, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-mssse3", mssse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
OPTION("-mtune=", mtune_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index d9ae003689..4e9c3a57a9 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -532,14 +532,16 @@ public:
}
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &Defines) const;
-
+ virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
+ const std::string &Name,
+ bool Enabled) const;
virtual void getDefaultFeatures(const std::string &CPU,
- llvm::StringMap<bool> &Features);
+ llvm::StringMap<bool> &Features) const;
virtual void HandleTargetFeatures(const llvm::StringMap<bool> &Features);
};
void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
- llvm::StringMap<bool> &Features) {
+ llvm::StringMap<bool> &Features) const {
// FIXME: This should not be here.
Features["3dnow"] = false;
Features["3dnowa"] = false;
@@ -572,6 +574,59 @@ void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
Features["sse2"] = Features["sse"] = Features["mmx"] = true;
}
+bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
+ const std::string &Name,
+ bool Enabled) const {
+ // FIXME: This *really* should not be here.
+ if (!Features.count(Name) && Name != "sse4")
+ return false;
+
+ if (Enabled) {
+ if (Name == "mmx")
+ Features["mmx"] = true;
+ else if (Name == "sse")
+ Features["mmx"] = Features["sse"] = true;
+ else if (Name == "sse2")
+ Features["mmx"] = Features["sse"] = Features["sse2"] = true;
+ else if (Name == "sse3")
+ Features["mmx"] = Features["sse"] = Features["sse2"] =
+ Features["sse3"] = true;
+ else if (Name == "ssse3")
+ Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+ Features["ssse3"] = true;
+ else if (Name == "sse4")
+ Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+ Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
+ else if (Name == "3dnow")
+ Features["3dnowa"] = true;
+ else if (Name == "3dnowa")
+ Features["3dnow"] = Features["3dnowa"] = true;
+ } else {
+ if (Name == "mmx")
+ Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+ Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
+ else if (Name == "sse")
+ Features["sse"] = Features["sse2"] = Features["sse3"] =
+ Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
+ else if (Name == "sse2")
+ Features["sse2"] = Features["sse3"] = Features["ssse3"] =
+ Features["sse41"] = Features["sse42"] = false;
+ else if (Name == "sse3")
+ Features["sse3"] = Features["ssse3"] = Features["sse41"] =
+ Features["sse42"] = false;
+ else if (Name == "ssse3")
+ Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
+ else if (Name == "sse4")
+ Features["sse41"] = Features["sse42"] = false;
+ else if (Name == "3dnow")
+ Features["3dnow"] = Features["3dnowa"] = false;
+ else if (Name == "3dnowa")
+ Features["3dnowa"] = false;
+ }
+
+ return true;
+}
+
/// HandleTargetOptions - Perform initialization based on the user
/// configured set of features.
void X86TargetInfo::HandleTargetFeatures(const llvm::StringMap<bool>&Features) {
@@ -603,7 +658,6 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Define(Defs, "__amd64");
Define(Defs, "__x86_64");
Define(Defs, "__x86_64__");
- Define(Defs, "__SSE3__");
} else {
DefineStd(Defs, "i386", Opts);
}
diff --git a/test/Preprocessor/x86_target_features.c b/test/Preprocessor/x86_target_features.c
new file mode 100644
index 0000000000..456c4fcf3a
--- /dev/null
+++ b/test/Preprocessor/x86_target_features.c
@@ -0,0 +1,25 @@
+// FIXME: Use -triple, not -ccc-host-triple.
+
+// RUN: clang -ccc-host-triple i386-unknown-unknown -march=core2 -msse4 -x c -E -dM -o %t %s &&
+// RUN: grep '#define __SSE2_MATH__ 1' %t &&
+// RUN: grep '#define __SSE2__ 1' %t &&
+// RUN: grep '#define __SSE3__ 1' %t &&
+// RUN: grep '#define __SSE4_1__ 1' %t &&
+// RUN: grep '#define __SSE4_2__ 1' %t &&
+// RUN: grep '#define __SSE_MATH__ 1' %t &&
+// RUN: grep '#define __SSE__ 1' %t &&
+// RUN: grep '#define __SSSE3__ 1' %t &&
+
+// RUN: clang -ccc-host-triple i386-unknown-unknown -march=core2 -msse4 -mno-sse2 -x c -E -dM -o %t %s &&
+// RUN: grep '#define __SSE2_MATH__ 1' %t | count 0 &&
+// RUN: grep '#define __SSE2__ 1' %t | count 0 &&
+// RUN: grep '#define __SSE3__ 1' %t | count 0 &&
+// RUN: grep '#define __SSE4_1__ 1' %t | count 0 &&
+// RUN: grep '#define __SSE4_2__ 1' %t | count 0 &&
+// RUN: grep '#define __SSE_MATH__ 1' %t &&
+// RUN: grep '#define __SSE__ 1' %t &&
+// RUN: grep '#define __SSSE3__ 1' %t | count 0 &&
+
+// RUN: true
+
+
diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp
index cdb606cb81..3282c193de 100644
--- a/tools/clang-cc/clang-cc.cpp
+++ b/tools/clang-cc/clang-cc.cpp
@@ -1426,17 +1426,11 @@ static void ComputeFeatureMap(TargetInfo *Target,
Name);
exit(1);
}
-
- llvm::StringMap<bool>::iterator it = Features.find(Name + 1);
- if (it == Features.end()) {
- fprintf(stderr, "error: clang-cc: invalid target feature string: %s\n",
- Name);
+ if (!Target->setFeatureEnabled(Features, Name + 1, (Name[0] == '+'))) {
+ fprintf(stderr, "error: clang-cc: invalid target feature name: %s\n",
+ Name + 1);
exit(1);
}
-
- // FIXME: Actually, we need to apply all the features implied by
- // this feature.
- it->second = (Name[0] == '+');
}
}