Have the driver pass CPU and target feature information to cc1as.

When creating the MCSubtargetInfo, the assembler driver uses the CPU and
feature string to construct a more accurate model of what instructions
are and are not legal.

rdar://10840476


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150273 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index 84aeced..fc8c5dc 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -63,8 +63,17 @@
   /// @name Target Options
   /// @{
 
+  /// The name of the target triple to assemble for.
   std::string Triple;
 
+  /// If given, the name of the target CPU to determine which instructions
+  /// are legal.
+  std::string CPU;
+
+  /// The list of target specific features to enable or disable -- this should
+  /// be a list of strings starting with '+' or '-'.
+  std::vector<std::string> Features;
+
   /// @}
   /// @name Language Options
   /// @{
@@ -158,9 +167,13 @@
   // Construct the invocation.
 
   // Target Options
-  Opts.Triple = Triple::normalize(Args->getLastArgValue(OPT_triple));
-  if (Opts.Triple.empty()) // Use the default target triple if unspecified.
-    Opts.Triple = sys::getDefaultTargetTriple();
+  Opts.Triple = llvm::Triple::normalize(Args->getLastArgValue(OPT_triple));
+  Opts.CPU = Args->getLastArgValue(OPT_target_cpu);
+  Opts.Features = Args->getAllArgValues(OPT_target_feature);
+
+  // Use the default target triple if unspecified.
+  if (Opts.Triple.empty())
+    Opts.Triple = llvm::sys::getDefaultTargetTriple();
 
   // Language Options
   Opts.IncludePaths = Args->getAllArgValues(OPT_I);
@@ -293,11 +306,19 @@
   if (!Opts.DwarfDebugFlags.empty())
     Ctx.setDwarfDebugFlags(StringRef(Opts.DwarfDebugFlags));
 
+  // Build up the feature string from the target feature list.
+  std::string FS;
+  if (!Opts.Features.empty()) {
+    FS = Opts.Features[0];
+    for (unsigned i = 1, e = Opts.Features.size(); i != e; ++i)
+      FS += "," + Opts.Features[i];
+  }
+
   OwningPtr<MCStreamer> Str;
 
   OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
   OwningPtr<MCSubtargetInfo>
-    STI(TheTarget->createMCSubtargetInfo(Opts.Triple, "", ""));
+    STI(TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));
 
   // FIXME: There is a bit of code duplication with addPassesToEmitFile.
   if (Opts.OutputType == AssemblerInvocation::FT_Asm) {