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
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index d9ae003..4e9c3a5 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -532,14 +532,16 @@
   }
   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 @@
     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 @@
     Define(Defs, "__amd64");
     Define(Defs, "__x86_64");
     Define(Defs, "__x86_64__");
-    Define(Defs, "__SSE3__");
   } else {
     DefineStd(Defs, "i386", Opts);
   }