diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 8d2f4a6d84efd2ecc2ab036de3ff950bb21ad3d2..0555d44297d6d15a7028fe60ab25c349d25d66bd 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -217,6 +217,12 @@ def Xclang : Separate<"-Xclang">,
   Flags<[NoForward]>;
 def Xlinker : Separate<"-Xlinker">, Flags<[LinkerInput, RenderAsInput]>,
   HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">;
+def Xllc : Separate<"-Xllc">, Flags<[RenderAsInput]>,
+  HelpText<"Pass <arg> to the bitcode compiler llc (Patmos only)">, 
+  MetaVarName<"<arg>">;
+def Xgold : Separate<"-Xgold">, Flags<[LinkerInput, RenderAsInput]>,
+  HelpText<"Pass <arg> to the gold ELF linker (Patmos only)">, 
+  MetaVarName<"<arg>">;
 def Xpreprocessor : Separate<"-Xpreprocessor">,
   HelpText<"Pass <arg> to the preprocessor">, MetaVarName<"<arg>">;
 def X_Flag : Flag<"-X">;
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 4fd3d882db3cb26a828b98e01d06f9bbb41d3b13..949766b9bdbc87bcb0859a39077fa4eb09601254 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -1602,6 +1602,27 @@ PatmosToolChain::~PatmosToolChain() {
       delete it->second;
 }
 
+std::string PatmosToolChain::ComputeLLVMTriple(const ArgList &Args,
+                               types::ID InputType) const
+{
+  if (getTriple().getArch() != llvm::Triple::patmos) {
+    llvm_unreachable("Invalid architecture for Patmos tool chain");
+  }
+
+  std::string Triple = getTripleString();
+
+  // This is a bit of a workaround: when we call patmos-clang without
+  // -target, then clang uses 'patmos' as default target (the prefix of the
+  // program call). To avoid target-name mismatches, we normalize that to
+  // the full default triple.
+  if (Triple == "patmos") {
+    return "patmos-unknown-elf";
+  }
+
+  return Triple;
+}
+
+
 Tool &PatmosToolChain::SelectTool(const Compilation &C, const JobAction &JA,
                                   const ActionList &Inputs) const {
   Action::ActionClass Key = JA.getKind();
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index 4f75f1c2a495469e997f60e864d4adc171ee0dd1..314db0a3452c22cf02b765c4ba5564d0eddebdd5 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -576,6 +576,9 @@ public:
   PatmosToolChain(const Driver &D, const llvm::Triple& Triple);
   ~PatmosToolChain();
 
+  virtual std::string ComputeLLVMTriple(const ArgList &Args,
+                                 types::ID InputType = types::TY_INVALID) const;
+
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
                            const ActionList &Inputs) const;
 
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index c58adfa8e49733084b0f307455d569a814a1b3cf..b8cac1cd0cdbafca978efe3f62f4cba664b86f00 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -3179,6 +3179,7 @@ void patmos::PatmosBaseTool::AddInputFiles(const ArgList &Args,
       }
       else if (A.getOption().matches(options::OPT_Wl_COMMA) ||
                A.getOption().matches(options::OPT_Xlinker) ||
+               A.getOption().matches(options::OPT_Xgold) ||
                A.getOption().matches(options::OPT_L)) {
         // already handled
         continue;
@@ -3326,6 +3327,10 @@ void patmos::PatmosBaseTool::ConstructLLCJob(const Tool &Creator,
       A->claim();
       A->render(Args, LLCArgs);
     }
+    else if (A->getOption().matches(options::OPT_Xllc)) {
+      A->claim();
+      A->renderAsInput(Args, LLCArgs);
+    }
   }
 
   if (ChangedFloatABI) {
@@ -3367,6 +3372,8 @@ void patmos::Compile::ConstructJob(Compilation &C, const JobAction &JA,
                                const char *LinkingOutput) const
 {
   // TODO to make this more standard-compliant, set to false
+  // Note: by default, patmos-clang emits .bc even with no --emit-llvm
+  //       This is done in Driver::IsUsingLTO() (returns always true for patmos)
   bool EmitLLVM = true;
   // only used when EmitLLVM is false
   bool EmitAsm = false;
@@ -3402,7 +3409,9 @@ void patmos::Compile::ConstructJob(Compilation &C, const JobAction &JA,
 
   // If this is not the last phase or if we emit llvm-code, we just call clang
   if (EmitLLVM || !IsLastPhase) {
+
     Clang::ConstructJob(C, JA, Output, Inputs, Args, LinkingOutput);
+
   } else {
     // Run llc afterwards, no linking phase
     const char *BCFilename = CreateOutputFilename(C, Output, "clang-",
@@ -3439,7 +3448,18 @@ void patmos::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
   const InputInfo &Input = Inputs[0];
 
   CmdArgs.push_back("-triple");
-  CmdArgs.push_back(TC.getTripleString().c_str());
+  CmdArgs.push_back(Args.MakeArgString(TC.ComputeLLVMTriple(Args)));
+
+  for (ArgList::const_iterator
+         it = Args.begin(), ie = Args.end(); it != ie; ++it) {
+    Arg *A = *it;
+
+    if (A->getOption().matches(options::OPT_Wa_COMMA) ||
+        A->getOption().matches(options::OPT_Xassembler)) {
+      A->claim();
+      A->renderAsInput(Args, CmdArgs);
+    }
+  }
 
   CmdArgs.push_back("-assemble");
   CmdArgs.push_back("-filetype=obj");
@@ -3566,7 +3586,8 @@ void patmos::Link::ConstructJob(Compilation &C, const JobAction &JA,
       A->renderAsInput(Args, CmdArgs);
     }
     else if ((A->getOption().isLinkerInput() &&
-              !A->getOption().matches(options::OPT_l)) ||
+              !A->getOption().matches(options::OPT_l) &&
+              !A->getOption().matches(options::OPT_Xgold)) ||
              A->getOption().matches(options::OPT_v))
     {
       // It is unfortunate that we have to claim here, as this means
@@ -3688,6 +3709,16 @@ void patmos::Link::ConstructJob(Compilation &C, const JobAction &JA,
   //----------------------------------------------------------------------------
   // linking options
 
+  for (ArgList::const_iterator
+         it = Args.begin(), ie = Args.end(); it != ie; ++it) {
+    Arg *A = *it;
+
+    if (A->getOption().matches(options::OPT_Xgold)) {
+      A->claim();
+      A->renderAsInput(Args, LDArgs);
+    }
+  }
+
   Args.AddAllArgs(LDArgs, options::OPT_T_Group);
 
   Args.AddAllArgs(LDArgs, options::OPT_e);