diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index eca5b3b..e40b8f0 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -834,75 +834,101 @@ DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
   // Add the arch options based on the particular spelling of -arch, to match
   // how the driver driver works.
   if (BoundArch) {
-    StringRef Name = BoundArch;
+    tools::darwin::CPUArch CPUArch =
+      tools::darwin::getCPUArchTypeForDarwinArchName(BoundArch);
+
     const Option MCpu = Opts.getOption(options::OPT_mcpu_EQ);
     const Option MArch = Opts.getOption(options::OPT_march_EQ);
 
     // This code must be kept in sync with LLVM's getArchTypeForDarwinArch,
     // which defines the list of which architectures we accept.
-    if (Name == "ppc")
-      ;
-    else if (Name == "ppc601")
+    switch(CPUArch) {
+    case tools::darwin::CA_PPC:
+      break;
+    case tools::darwin::CA_PPC601:
       DAL->AddJoinedArg(0, MCpu, "601");
-    else if (Name == "ppc603")
+      break;
+    case tools::darwin::CA_PPC603:
       DAL->AddJoinedArg(0, MCpu, "603");
-    else if (Name == "ppc604")
+      break;
+    case tools::darwin::CA_PPC604:
       DAL->AddJoinedArg(0, MCpu, "604");
-    else if (Name == "ppc604e")
+      break;
+    case tools::darwin::CA_PPC604e:
       DAL->AddJoinedArg(0, MCpu, "604e");
-    else if (Name == "ppc750")
+      break;
+    case tools::darwin::CA_PPC750:
       DAL->AddJoinedArg(0, MCpu, "750");
-    else if (Name == "ppc7400")
+      break;
+    case tools::darwin::CA_PPC7400:
       DAL->AddJoinedArg(0, MCpu, "7400");
-    else if (Name == "ppc7450")
+      break;
+    case tools::darwin::CA_PPC7450:
       DAL->AddJoinedArg(0, MCpu, "7450");
-    else if (Name == "ppc970")
+      break;
+    case tools::darwin::CA_PPC970:
       DAL->AddJoinedArg(0, MCpu, "970");
-
-    else if (Name == "ppc64")
+      break;
+    case tools::darwin::CA_PPC64:
       DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
-
-    else if (Name == "i386")
-      ;
-    else if (Name == "i486")
+      break;
+    case tools::darwin::CA_I386:
+      break;
+    case tools::darwin::CA_I486:
       DAL->AddJoinedArg(0, MArch, "i486");
-    else if (Name == "i586")
+      break;
+    case tools::darwin::CA_I586:
       DAL->AddJoinedArg(0, MArch, "i586");
-    else if (Name == "i686")
+      break;
+    case tools::darwin::CA_I686:
       DAL->AddJoinedArg(0, MArch, "i686");
-    else if (Name == "pentium")
+      break;
+    case tools::darwin::CA_Pentium:
       DAL->AddJoinedArg(0, MArch, "pentium");
-    else if (Name == "pentium2")
+      break;
+    case tools::darwin::CA_Pentium2:
       DAL->AddJoinedArg(0, MArch, "pentium2");
-    else if (Name == "pentpro")
+      break;
+    case tools::darwin::CA_Pentpro:
       DAL->AddJoinedArg(0, MArch, "pentiumpro");
-    else if (Name == "pentIIm3")
+      break;
+    case tools::darwin::CA_PentIIm3:
       DAL->AddJoinedArg(0, MArch, "pentium2");
-
-    else if (Name == "x86_64")
+      break;
+    case tools::darwin::CA_X86_64:
       DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
-
-    else if (Name == "arm")
+      break;
+    case tools::darwin::CA_ARM:
       DAL->AddJoinedArg(0, MArch, "armv4t");
-    else if (Name == "armv4t")
+      break;
+    case tools::darwin::CA_ARMv4t:
       DAL->AddJoinedArg(0, MArch, "armv4t");
-    else if (Name == "armv5")
+      break;
+    case tools::darwin::CA_ARMv5:
       DAL->AddJoinedArg(0, MArch, "armv5tej");
-    else if (Name == "xscale")
+      break;
+    case tools::darwin::CA_XScale:
       DAL->AddJoinedArg(0, MArch, "xscale");
-    else if (Name == "armv6")
+      break;
+    case tools::darwin::CA_ARMv6:
       DAL->AddJoinedArg(0, MArch, "armv6k");
-    else if (Name == "armv7")
+      break;
+    case tools::darwin::CA_ARMv7:
       DAL->AddJoinedArg(0, MArch, "armv7a");
-    else if (Name == "armv7f")
+      break;
+    case tools::darwin::CA_ARMv7f:
       DAL->AddJoinedArg(0, MArch, "armv7f");
-    else if (Name == "armv7k")
+      break;
+    case tools::darwin::CA_ARMv7k:
       DAL->AddJoinedArg(0, MArch, "armv7k");
-    else if (Name == "armv7s")
+      break;
+    case tools::darwin::CA_ARMv7s:
       DAL->AddJoinedArg(0, MArch, "armv7s");
-
-    else
+      break;
+    case tools::darwin::CA_UnknownCPUArch:
       llvm_unreachable("invalid Darwin arch");
+      break;
+    }
   }
 
   // Add an explicit version min argument for the deployment target. We do this
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 95db821..c0428f8 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -3527,6 +3527,56 @@ void hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA,
 // Hexagon tools end.
 
 llvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) {
+  CPUArch CA = getCPUArchTypeForDarwinArchName(Str);
+  return getArchTypeForDarwinCPUArch(CA);
+}
+
+llvm::Triple::ArchType darwin::getArchTypeForDarwinCPUArch(CPUArch CA) {
+  switch (CA) {
+  case darwin::CA_UnknownCPUArch:
+    return llvm::Triple::UnknownArch;
+
+  case darwin::CA_PPC:
+  case darwin::CA_PPC601:
+  case darwin::CA_PPC603:
+  case darwin::CA_PPC604:
+  case darwin::CA_PPC604e:
+  case darwin::CA_PPC750:
+  case darwin::CA_PPC7400:
+  case darwin::CA_PPC7450:
+  case darwin::CA_PPC970:
+    return llvm::Triple::ppc;
+
+  case darwin::CA_PPC64:
+    return llvm::Triple::ppc64;
+
+  case darwin::CA_I386:
+  case darwin::CA_I486:
+  case darwin::CA_I586:
+  case darwin::CA_I686:
+  case darwin::CA_Pentium:
+  case darwin::CA_Pentium2:
+  case darwin::CA_Pentpro:
+  case darwin::CA_PentIIm3:
+    return llvm::Triple::x86;
+
+  case darwin::CA_X86_64:
+    return llvm::Triple::x86_64;
+
+  case darwin::CA_ARM:
+  case darwin::CA_ARMv4t:
+  case darwin::CA_ARMv5:
+  case darwin::CA_XScale:
+  case darwin::CA_ARMv6:
+  case darwin::CA_ARMv7:
+  case darwin::CA_ARMv7f:
+  case darwin::CA_ARMv7k:
+  case darwin::CA_ARMv7s:
+    return llvm::Triple::arm;
+  }
+}
+
+darwin::CPUArch darwin::getCPUArchTypeForDarwinArchName(StringRef Arch) {
   // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
   // archs which Darwin doesn't use.
 
@@ -3539,23 +3589,36 @@ llvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) {
   // This code must be kept in sync with Clang's Darwin specific argument
   // translation.
 
-  return llvm::StringSwitch<llvm::Triple::ArchType>(Str)
-    .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc)
-    .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc)
-    .Case("ppc64", llvm::Triple::ppc64)
-    .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86)
-    .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
-           llvm::Triple::x86)
-    .Case("x86_64", llvm::Triple::x86_64)
-    // This is derived from the driver driver.
-    .Cases("arm", "armv4t", "armv5", "armv6", llvm::Triple::arm)
-    .Cases("armv7", "armv7f", "armv7k", "armv7s", "xscale", llvm::Triple::arm)
-    .Case("r600", llvm::Triple::r600)
-    .Case("nvptx", llvm::Triple::nvptx)
-    .Case("nvptx64", llvm::Triple::nvptx64)
-    .Case("amdil", llvm::Triple::amdil)
-    .Case("spir", llvm::Triple::spir)
-    .Default(llvm::Triple::UnknownArch);
+  return llvm::StringSwitch<darwin::CPUArch>(Arch)
+    .Case("ppc", darwin::CA_PPC)
+    .Case("ppc601", darwin::CA_PPC601)
+    .Case("ppc603", darwin::CA_PPC603)
+    .Case("ppc604", darwin::CA_PPC604)
+    .Case("ppc604e", darwin::CA_PPC604e)
+    .Case("ppc750", darwin::CA_PPC750)
+    .Case("ppc7400", darwin::CA_PPC7400)
+    .Case("ppc7450", darwin::CA_PPC7450)
+    .Case("ppc970", darwin::CA_PPC970)
+    .Case("ppc64", darwin::CA_PPC64)
+    .Case("i386", darwin::CA_I386)
+    .Case("i486", darwin::CA_I486)
+    .Case("i586", darwin::CA_I586)
+    .Case("i686", darwin::CA_I686)
+    .Case("pentium", darwin::CA_Pentium)
+    .Case("pentium2", darwin::CA_Pentium2)
+    .Case("pentpro", darwin::CA_Pentpro)
+    .Case("pentIIm3", darwin::CA_PentIIm3)
+    .Case("x86_64", darwin::CA_X86_64)
+    .Case("arm", darwin::CA_ARM)
+    .Case("armv4t", darwin::CA_ARMv4t)
+    .Case("armv5", darwin::CA_ARMv5)
+    .Case("xscale", darwin::CA_XScale)
+    .Case("armv6", darwin::CA_ARMv6)
+    .Case("armv7", darwin::CA_ARMv7)
+    .Case("armv7f", darwin::CA_ARMv7f)
+    .Case("armv7k", darwin::CA_ARMv7k)
+    .Case("armv7s", darwin::CA_ARMv7s)
+    .Default(darwin::CA_UnknownCPUArch);
 }
 
 const char *darwin::CC1::getCC1Name(types::ID Type) const {
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
index 5898c66..26daec4 100644
--- a/lib/Driver/Tools.h
+++ b/lib/Driver/Tools.h
@@ -202,6 +202,40 @@ namespace hexagon {
 
 
 namespace darwin {
+  enum CPUArch {
+    CA_PPC,
+    CA_PPC601,
+    CA_PPC603,
+    CA_PPC604,
+    CA_PPC604e,
+    CA_PPC750,
+    CA_PPC7400,
+    CA_PPC7450,
+    CA_PPC970,
+    CA_PPC64,
+    CA_I386,
+    CA_I486,
+    CA_I586,
+    CA_I686,
+    CA_Pentium,
+    CA_Pentium2,
+    CA_Pentpro,
+    CA_PentIIm3,
+    CA_X86_64,
+    CA_ARM,
+    CA_ARMv4t,
+    CA_ARMv5,
+    CA_XScale,
+    CA_ARMv6,
+    CA_ARMv7,
+    CA_ARMv7f,
+    CA_ARMv7k,
+    CA_ARMv7s,
+    CA_UnknownCPUArch
+  };
+
+  CPUArch getCPUArchTypeForDarwinArchName(StringRef Str);
+  llvm::Triple::ArchType getArchTypeForDarwinCPUArch(CPUArch Arch);
   llvm::Triple::ArchType getArchTypeForDarwinArchName(StringRef Str);
 
   class LLVM_LIBRARY_VISIBILITY DarwinTool : public Tool {
