Index: lib/Target/MSP430/MSP430CallingConv.td
===================================================================
--- lib/Target/MSP430/MSP430CallingConv.td
+++ lib/Target/MSP430/MSP430CallingConv.td
@@ -13,11 +13,11 @@
 // MSP430 Return Value Calling Convention
 //===----------------------------------------------------------------------===//
 def RetCC_MSP430 : CallingConv<[
-  // i8 are returned in registers R15B, R14B, R13B, R12B
-  CCIfType<[i8], CCAssignToReg<[R15B, R14B, R13B, R12B]>>,
+  // i8 are returned in registers R12B, R13B, R14B, R15B
+  CCIfType<[i8], CCAssignToReg<[R12B, R13B, R14B, R15B]>>,
 
-  // i16 are returned in registers R15, R14, R13, R12
-  CCIfType<[i16], CCAssignToReg<[R15, R14, R13, R12]>>
+  // i16 are returned in registers R12, R13, R14, R15
+  CCIfType<[i16], CCAssignToReg<[R12, R13, R14, R15]>>
 ]>;
 
 //===----------------------------------------------------------------------===//
Index: lib/Target/MSP430/MSP430ISelLowering.h
===================================================================
--- lib/Target/MSP430/MSP430ISelLowering.h
+++ lib/Target/MSP430/MSP430ISelLowering.h
@@ -158,6 +158,12 @@
       LowerCall(TargetLowering::CallLoweringInfo &CLI,
                 SmallVectorImpl<SDValue> &InVals) const override;
 
+    bool CanLowerReturn(CallingConv::ID CallConv,
+                        MachineFunction &MF,
+                        bool IsVarArg,
+                        const SmallVectorImpl<ISD::OutputArg> &Outs,
+                        LLVMContext &Context) const;
+
     SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
                         const SmallVectorImpl<ISD::OutputArg> &Outs,
                         const SmallVectorImpl<SDValue> &OutVals,
Index: lib/Target/MSP430/MSP430ISelLowering.cpp
===================================================================
--- lib/Target/MSP430/MSP430ISelLowering.cpp
+++ lib/Target/MSP430/MSP430ISelLowering.cpp
@@ -245,13 +245,20 @@
 template<typename ArgT>
 static void ParseFunctionArgs(const SmallVectorImpl<ArgT> &Args,
                               SmallVectorImpl<unsigned> &Out) {
-  unsigned CurrentArgIndex = ~0U;
-  for (unsigned i = 0, e = Args.size(); i != e; i++) {
-    if (CurrentArgIndex == Args[i].OrigArgIndex) {
-      Out.back()++;
+  unsigned CurrentArgIndex;
+
+  if (Args.empty())
+    return;
+
+  CurrentArgIndex = Args[0].OrigArgIndex;
+  Out.push_back(0);
+
+  for (auto &Arg : Args) {
+    if (CurrentArgIndex == Arg.OrigArgIndex) {
+      Out.back() += 1;
     } else {
       Out.push_back(1);
-      CurrentArgIndex++;
+      CurrentArgIndex = Arg.OrigArgIndex;
     }
   }
 }
@@ -275,7 +282,7 @@
                              SmallVectorImpl<CCValAssign> &ArgLocs,
                              const SmallVectorImpl<ArgT> &Args) {
   static const MCPhysReg RegList[] = {
-    MSP430::R15, MSP430::R14, MSP430::R13, MSP430::R12
+    MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
   };
   static const unsigned NbRegs = array_lengthof(RegList);
 
@@ -288,7 +295,7 @@
   ParseFunctionArgs(Args, ArgsParts);
 
   unsigned RegsLeft = NbRegs;
-  bool UseStack = false;
+  bool UsedStack = false;
   unsigned ValNo = 0;
 
   for (unsigned i = 0, e = ArgsParts.size(); i != e; i++) {
@@ -316,20 +323,22 @@
 
     unsigned Parts = ArgsParts[i];
 
-    if (!UseStack && Parts <= RegsLeft) {
-      unsigned FirstVal = ValNo;
+    if (!UsedStack && Parts == 2 && RegsLeft == 1) {
+      // Special case for 32-bit register split, see EABI section 3.3.3
+      unsigned Reg = State.AllocateReg(RegList);
+      State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
+      RegsLeft -= 1;
+
+      UsedStack = true;
+      CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
+    } else if (Parts <= RegsLeft) {
       for (unsigned j = 0; j < Parts; j++) {
         unsigned Reg = State.AllocateReg(RegList);
         State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
         RegsLeft--;
       }
-
-      // Reverse the order of the pieces to agree with the "big endian" format
-      // required in the calling convention ABI.
-      SmallVectorImpl<CCValAssign>::iterator B = ArgLocs.begin() + FirstVal;
-      std::reverse(B, B + Parts);
     } else {
-      UseStack = true;
+      UsedStack = true;
       for (unsigned j = 0; j < Parts; j++)
         CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
     }
@@ -351,10 +360,6 @@
                                 SmallVectorImpl<CCValAssign> &RVLocs,
                                 const SmallVectorImpl<ArgT> &Args) {
   AnalyzeRetResult(State, Args);
-
-  // Reverse splitted return values to get the "big endian" format required
-  // to agree with the calling convention ABI.
-  std::reverse(RVLocs.begin(), RVLocs.end());
 }
 
 SDValue MSP430TargetLowering::LowerFormalArguments(
@@ -496,9 +501,33 @@
     }
   }
 
+  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+    if (Ins[i].Flags.isSRet()) {
+      unsigned Reg = FuncInfo->getSRetReturnReg();
+      if (!Reg) {
+        Reg = MF.getRegInfo().createVirtualRegister(
+            getRegClassFor(MVT::i16));
+        FuncInfo->setSRetReturnReg(Reg);
+      }
+      SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[i]);
+      Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
+    }
+  }
+
   return Chain;
 }
 
+bool
+MSP430TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
+                                     MachineFunction &MF,
+                                     bool IsVarArg,
+                                     const SmallVectorImpl<ISD::OutputArg> &Outs,
+                                     LLVMContext &Context) const {
+  SmallVector<CCValAssign, 16> RVLocs;
+  CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
+  return CCInfo.CheckReturn(Outs, RetCC_MSP430);
+}
+
 SDValue
 MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
                                   bool isVarArg,
@@ -506,6 +535,8 @@
                                   const SmallVectorImpl<SDValue> &OutVals,
                                   const SDLoc &dl, SelectionDAG &DAG) const {
 
+  MachineFunction &MF = DAG.getMachineFunction();
+
   // CCValAssign - represent the assignment of the return value to a location
   SmallVector<CCValAssign, 16> RVLocs;
 
@@ -537,6 +568,22 @@
     RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
   }
 
+  if (MF.getFunction()->hasStructRetAttr()) {
+    MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
+    unsigned Reg = FuncInfo->getSRetReturnReg();
+
+    if (!Reg)
+      llvm_unreachable("sret virtual register not created in entry block");
+
+    SDValue Val =
+      DAG.getCopyFromReg(Chain, dl, Reg, getPointerTy(DAG.getDataLayout()));
+    unsigned R12 = MSP430::R12;
+
+    Chain = DAG.getCopyToReg(Chain, dl, R12, Val, Flag);
+    Flag = Chain.getValue(1);
+    RetOps.push_back(DAG.getRegister(R12, getPointerTy(DAG.getDataLayout())));
+  }
+
   unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
                   MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
 
Index: lib/Target/MSP430/MSP430MachineFunctionInfo.h
===================================================================
--- lib/Target/MSP430/MSP430MachineFunctionInfo.h
+++ lib/Target/MSP430/MSP430MachineFunctionInfo.h
@@ -33,15 +33,23 @@
   /// VarArgsFrameIndex - FrameIndex for start of varargs area.
   int VarArgsFrameIndex;
 
+  /// SRetReturnReg - Some subtargets require that sret lowering includes
+  /// returning the value of the returned struct in a register. This field
+  /// holds the virtual register into which the sret argument is passed.
+  unsigned SRetReturnReg;
+
 public:
   MSP430MachineFunctionInfo() : CalleeSavedFrameSize(0) {}
 
   explicit MSP430MachineFunctionInfo(MachineFunction &MF)
-    : CalleeSavedFrameSize(0), ReturnAddrIndex(0) {}
+    : CalleeSavedFrameSize(0), ReturnAddrIndex(0), SRetReturnReg(0) {}
 
   unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; }
   void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; }
 
+  unsigned getSRetReturnReg() const { return SRetReturnReg; }
+  void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
+
   int getRAIndex() const { return ReturnAddrIndex; }
   void setRAIndex(int Index) { ReturnAddrIndex = Index; }
 
Index: test/CodeGen/MSP430/AddrMode-bis-rx.ll
===================================================================
--- test/CodeGen/MSP430/AddrMode-bis-rx.ll
+++ test/CodeGen/MSP430/AddrMode-bis-rx.ll
@@ -8,7 +8,7 @@
 	ret i16 %2
 }
 ; CHECK-LABEL: am1:
-; CHECK:		bis.w	0(r14), r15
+; CHECK:		bis.w	0(r13), r12
 
 @foo = external global i16
 
@@ -18,7 +18,7 @@
 	ret i16 %2
 }
 ; CHECK-LABEL: am2:
-; CHECK:		bis.w	&foo, r15
+; CHECK:		bis.w	&foo, r12
 
 @bar = internal constant [2 x i8] [ i8 32, i8 64 ]
 
@@ -29,7 +29,7 @@
 	ret i8 %3
 }
 ; CHECK-LABEL: am3:
-; CHECK:		bis.b	bar(r14), r15
+; CHECK:		bis.b	bar(r13), r12
 
 define i16 @am4(i16 %x) nounwind {
 	%1 = load volatile i16, i16* inttoptr(i16 32 to i16*)
@@ -37,7 +37,7 @@
 	ret i16 %2
 }
 ; CHECK-LABEL: am4:
-; CHECK:		bis.w	&32, r15
+; CHECK:		bis.w	&32, r12
 
 define i16 @am5(i16 %x, i16* %a) nounwind {
 	%1 = getelementptr i16, i16* %a, i16 2
@@ -46,7 +46,7 @@
 	ret i16 %3
 }
 ; CHECK-LABEL: am5:
-; CHECK:		bis.w	4(r14), r15
+; CHECK:		bis.w	4(r13), r12
 
 %S = type { i16, i16 }
 @baz = common global %S zeroinitializer, align 1
@@ -57,7 +57,7 @@
 	ret i16 %2
 }
 ; CHECK-LABEL: am6:
-; CHECK:		bis.w	&baz+2, r15
+; CHECK:		bis.w	&baz+2, r12
 
 %T = type { i16, [2 x i8] }
 @duh = internal constant %T { i16 16, [2 x i8][i8 32, i8 64 ] }
@@ -70,5 +70,5 @@
 	ret i8 %4
 }
 ; CHECK-LABEL: am7:
-; CHECK:		bis.b	duh+2(r14), r15
+; CHECK:		bis.b	duh+2(r13), r12
 
Index: test/CodeGen/MSP430/AddrMode-bis-xr.ll
===================================================================
--- test/CodeGen/MSP430/AddrMode-bis-xr.ll
+++ test/CodeGen/MSP430/AddrMode-bis-xr.ll
@@ -9,7 +9,7 @@
 	ret void
 }
 ; CHECK-LABEL: am1:
-; CHECK:		bis.w	r14, 0(r15)
+; CHECK:		bis.w	r13, 0(r12)
 
 @foo = external global i16
 
@@ -20,7 +20,7 @@
 	ret void
 }
 ; CHECK-LABEL: am2:
-; CHECK:		bis.w	r15, &foo
+; CHECK:		bis.w	r12, &foo
 
 @bar = external global [2 x i8]
 
@@ -32,7 +32,7 @@
 	ret void
 }
 ; CHECK-LABEL: am3:
-; CHECK:		bis.b	r14, bar(r15)
+; CHECK:		bis.b	r13, bar(r12)
 
 define void @am4(i16 %x) nounwind {
 	%1 = load volatile i16, i16* inttoptr(i16 32 to i16*)
@@ -41,7 +41,7 @@
 	ret void
 }
 ; CHECK-LABEL: am4:
-; CHECK:		bis.w	r15, &32
+; CHECK:		bis.w	r12, &32
 
 define void @am5(i16* %a, i16 %x) readonly {
 	%1 = getelementptr inbounds i16, i16* %a, i16 2
@@ -51,7 +51,7 @@
 	ret void
 }
 ; CHECK-LABEL: am5:
-; CHECK:		bis.w	r14, 4(r15)
+; CHECK:		bis.w	r13, 4(r12)
 
 %S = type { i16, i16 }
 @baz = common global %S zeroinitializer
@@ -63,7 +63,7 @@
 	ret void
 }
 ; CHECK-LABEL: am6:
-; CHECK:		bis.w	r15, &baz+2
+; CHECK:		bis.w	r12, &baz+2
 
 %T = type { i16, [2 x i8] }
 @duh = external global %T
@@ -77,5 +77,5 @@
 	ret void
 }
 ; CHECK-LABEL: am7:
-; CHECK:		bis.b	r14, duh+2(r15)
+; CHECK:		bis.b	r13, duh+2(r12)
 
Index: test/CodeGen/MSP430/AddrMode-mov-rx.ll
===================================================================
--- test/CodeGen/MSP430/AddrMode-mov-rx.ll
+++ test/CodeGen/MSP430/AddrMode-mov-rx.ll
@@ -7,7 +7,7 @@
 	ret i16 %1
 }
 ; CHECK-LABEL: am1:
-; CHECK:		mov.w	0(r15), r15
+; CHECK:		mov.w	0(r12), r12
 
 @foo = external global i16
 
@@ -16,7 +16,7 @@
 	ret i16 %1
 }
 ; CHECK-LABEL: am2:
-; CHECK:		mov.w	&foo, r15
+; CHECK:		mov.w	&foo, r12
 
 @bar = internal constant [2 x i8] [ i8 32, i8 64 ]
 
@@ -26,14 +26,14 @@
 	ret i8 %2
 }
 ; CHECK-LABEL: am3:
-; CHECK:		mov.b	bar(r15), r15
+; CHECK:		mov.b	bar(r12), r12
 
 define i16 @am4() nounwind {
 	%1 = load volatile i16, i16* inttoptr(i16 32 to i16*)
 	ret i16 %1
 }
 ; CHECK-LABEL: am4:
-; CHECK:		mov.w	&32, r15
+; CHECK:		mov.w	&32, r12
 
 define i16 @am5(i16* %a) nounwind {
 	%1 = getelementptr i16, i16* %a, i16 2
@@ -41,7 +41,7 @@
 	ret i16 %2
 }
 ; CHECK-LABEL: am5:
-; CHECK:		mov.w	4(r15), r15
+; CHECK:		mov.w	4(r12), r12
 
 %S = type { i16, i16 }
 @baz = common global %S zeroinitializer, align 1
@@ -51,7 +51,7 @@
 	ret i16 %1
 }
 ; CHECK-LABEL: am6:
-; CHECK:		mov.w	&baz+2, r15
+; CHECK:		mov.w	&baz+2, r12
 
 %T = type { i16, [2 x i8] }
 @duh = internal constant %T { i16 16, [2 x i8][i8 32, i8 64 ] }
@@ -63,5 +63,5 @@
 	ret i8 %3
 }
 ; CHECK-LABEL: am7:
-; CHECK:		mov.b	duh+2(r15), r15
+; CHECK:		mov.b	duh+2(r12), r12
 
Index: test/CodeGen/MSP430/AddrMode-mov-xr.ll
===================================================================
--- test/CodeGen/MSP430/AddrMode-mov-xr.ll
+++ test/CodeGen/MSP430/AddrMode-mov-xr.ll
@@ -7,7 +7,7 @@
 	ret void
 }
 ; CHECK-LABEL: am1:
-; CHECK:		mov.w	r14, 0(r15)
+; CHECK:		mov.w	r13, 0(r12)
 
 @foo = external global i16
 
@@ -16,7 +16,7 @@
 	ret void
 }
 ; CHECK-LABEL: am2:
-; CHECK:		mov.w	r15, &foo
+; CHECK:		mov.w	r12, &foo
 
 @bar = external global [2 x i8]
 
@@ -26,14 +26,14 @@
 	ret void
 }
 ; CHECK-LABEL: am3:
-; CHECK:		mov.b	r14, bar(r15)
+; CHECK:		mov.b	r13, bar(r12)
 
 define void @am4(i16 %a) nounwind {
 	store volatile i16 %a, i16* inttoptr(i16 32 to i16*)
 	ret void
 }
 ; CHECK-LABEL: am4:
-; CHECK:		mov.w	r15, &32
+; CHECK:		mov.w	r12, &32
 
 define void @am5(i16* nocapture %p, i16 %a) nounwind readonly {
 	%1 = getelementptr inbounds i16, i16* %p, i16 2
@@ -41,7 +41,7 @@
 	ret void
 }
 ; CHECK-LABEL: am5:
-; CHECK:		mov.w	r14, 4(r15)
+; CHECK:		mov.w	r13, 4(r12)
 
 %S = type { i16, i16 }
 @baz = common global %S zeroinitializer, align 1
@@ -51,7 +51,7 @@
 	ret void
 }
 ; CHECK-LABEL: am6:
-; CHECK:		mov.w	r15, &baz+2
+; CHECK:		mov.w	r12, &baz+2
 
 %T = type { i16, [2 x i8] }
 @duh = external global %T
@@ -63,5 +63,5 @@
 	ret void
 }
 ; CHECK-LABEL: am7:
-; CHECK:		mov.b	r14, duh+2(r15)
+; CHECK:		mov.b	r13, duh+2(r12)
 
Index: test/CodeGen/MSP430/Inst16mr.ll
===================================================================
--- test/CodeGen/MSP430/Inst16mr.ll
+++ test/CodeGen/MSP430/Inst16mr.ll
@@ -5,14 +5,14 @@
 
 define void @mov(i16 %a) nounwind {
 ; CHECK-LABEL: mov:
-; CHECK: mov.w	r15, &foo
+; CHECK: mov.w	r12, &foo
 	store i16 %a, i16* @foo
 	ret void
 }
 
 define void @add(i16 %a) nounwind {
 ; CHECK-LABEL: add:
-; CHECK: add.w	r15, &foo
+; CHECK: add.w	r12, &foo
 	%1 = load i16, i16* @foo
 	%2 = add i16 %a, %1
 	store i16 %2, i16* @foo
@@ -21,7 +21,7 @@
 
 define void @and(i16 %a) nounwind {
 ; CHECK-LABEL: and:
-; CHECK: and.w	r15, &foo
+; CHECK: and.w	r12, &foo
 	%1 = load i16, i16* @foo
 	%2 = and i16 %a, %1
 	store i16 %2, i16* @foo
@@ -30,7 +30,7 @@
 
 define void @bis(i16 %a) nounwind {
 ; CHECK-LABEL: bis:
-; CHECK: bis.w	r15, &foo
+; CHECK: bis.w	r12, &foo
 	%1 = load i16, i16* @foo
 	%2 = or i16 %a, %1
 	store i16 %2, i16* @foo
@@ -39,7 +39,7 @@
 
 define void @bic(i16 zeroext %m) nounwind {
 ; CHECK-LABEL: bic:
-; CHECK: bic.w   r15, &foo
+; CHECK: bic.w   r12, &foo
         %1 = xor i16 %m, -1
         %2 = load i16, i16* @foo
         %3 = and i16 %2, %1
@@ -49,7 +49,7 @@
 
 define void @xor(i16 %a) nounwind {
 ; CHECK-LABEL: xor:
-; CHECK: xor.w	r15, &foo
+; CHECK: xor.w	r12, &foo
 	%1 = load i16, i16* @foo
 	%2 = xor i16 %a, %1
 	store i16 %2, i16* @foo
Index: test/CodeGen/MSP430/Inst16ri.ll
===================================================================
--- test/CodeGen/MSP430/Inst16ri.ll
+++ test/CodeGen/MSP430/Inst16ri.ll
@@ -4,34 +4,34 @@
 
 define i16 @mov() nounwind {
 ; CHECK-LABEL: mov:
-; CHECK: mov.w	#1, r15
+; CHECK: mov.w	#1, r12
 	ret i16 1
 }
 
 define i16 @add(i16 %a, i16 %b) nounwind {
 ; CHECK-LABEL: add:
-; CHECK: add.w	#1, r15
+; CHECK: add.w	#1, r12
 	%1 = add i16 %a, 1
 	ret i16 %1
 }
 
 define i16 @and(i16 %a, i16 %b) nounwind {
 ; CHECK-LABEL: and:
-; CHECK: and.w	#1, r15
+; CHECK: and.w	#1, r12
 	%1 = and i16 %a, 1
 	ret i16 %1
 }
 
 define i16 @bis(i16 %a, i16 %b) nounwind {
 ; CHECK-LABEL: bis:
-; CHECK: bis.w	#1, r15
+; CHECK: bis.w	#1, r12
 	%1 = or i16 %a, 1
 	ret i16 %1
 }
 
 define i16 @xor(i16 %a, i16 %b) nounwind {
 ; CHECK-LABEL: xor:
-; CHECK: xor.w	#1, r15
+; CHECK: xor.w	#1, r12
 	%1 = xor i16 %a, 1
 	ret i16 %1
 }
Index: test/CodeGen/MSP430/Inst16rm.ll
===================================================================
--- test/CodeGen/MSP430/Inst16rm.ll
+++ test/CodeGen/MSP430/Inst16rm.ll
@@ -5,7 +5,7 @@
 
 define i16 @add(i16 %a) nounwind {
 ; CHECK-LABEL: add:
-; CHECK: add.w	&foo, r15
+; CHECK: add.w	&foo, r12
 	%1 = load i16, i16* @foo
 	%2 = add i16 %a, %1
 	ret i16 %2
@@ -13,7 +13,7 @@
 
 define i16 @and(i16 %a) nounwind {
 ; CHECK-LABEL: and:
-; CHECK: and.w	&foo, r15
+; CHECK: and.w	&foo, r12
 	%1 = load i16, i16* @foo
 	%2 = and i16 %a, %1
 	ret i16 %2
@@ -21,7 +21,7 @@
 
 define i16 @bis(i16 %a) nounwind {
 ; CHECK-LABEL: bis:
-; CHECK: bis.w	&foo, r15
+; CHECK: bis.w	&foo, r12
 	%1 = load i16, i16* @foo
 	%2 = or i16 %a, %1
 	ret i16 %2
@@ -29,7 +29,7 @@
 
 define i16  @bic(i16 %a) nounwind {
 ; CHECK-LABEL: bic:
-; CHECK: bic.w	&foo, r15
+; CHECK: bic.w	&foo, r12
         %1 = load i16, i16* @foo
         %2 = xor i16 %1, -1
         %3 = and i16 %a, %2
@@ -38,7 +38,7 @@
 
 define i16 @xor(i16 %a) nounwind {
 ; CHECK-LABEL: xor:
-; CHECK: xor.w	&foo, r15
+; CHECK: xor.w	&foo, r12
 	%1 = load i16, i16* @foo
 	%2 = xor i16 %a, %1
 	ret i16 %2
Index: test/CodeGen/MSP430/Inst16rr.ll
===================================================================
--- test/CodeGen/MSP430/Inst16rr.ll
+++ test/CodeGen/MSP430/Inst16rr.ll
@@ -4,34 +4,34 @@
 
 define i16 @mov(i16 %a, i16 %b) nounwind {
 ; CHECK-LABEL: mov:
-; CHECK: mov.w	r14, r15
+; CHECK: mov.w	r13, r12
 	ret i16 %b
 }
 
 define i16 @add(i16 %a, i16 %b) nounwind {
 ; CHECK-LABEL: add:
-; CHECK: add.w	r14, r15
+; CHECK: add.w	r13, r12
 	%1 = add i16 %a, %b
 	ret i16 %1
 }
 
 define i16 @and(i16 %a, i16 %b) nounwind {
 ; CHECK-LABEL: and:
-; CHECK: and.w	r14, r15
+; CHECK: and.w	r13, r12
 	%1 = and i16 %a, %b
 	ret i16 %1
 }
 
 define i16 @bis(i16 %a, i16 %b) nounwind {
 ; CHECK-LABEL: bis:
-; CHECK: bis.w	r14, r15
+; CHECK: bis.w	r13, r12
 	%1 = or i16 %a, %b
 	ret i16 %1
 }
 
 define i16 @bic(i16 %a, i16 %b) nounwind {
 ; CHECK-LABEL: bic:
-; CHECK: bic.w	r14, r15
+; CHECK: bic.w	r13, r12
         %1 = xor i16 %b, -1
         %2 = and i16 %a, %1
         ret i16 %2
@@ -39,7 +39,7 @@
 
 define i16 @xor(i16 %a, i16 %b) nounwind {
 ; CHECK-LABEL: xor:
-; CHECK: xor.w	r14, r15
+; CHECK: xor.w	r13, r12
 	%1 = xor i16 %a, %b
 	ret i16 %1
 }
Index: test/CodeGen/MSP430/Inst8mr.ll
===================================================================
--- test/CodeGen/MSP430/Inst8mr.ll
+++ test/CodeGen/MSP430/Inst8mr.ll
@@ -5,14 +5,14 @@
 
 define void @mov(i8 %a) nounwind {
 ; CHECK-LABEL: mov:
-; CHECK: mov.b	r15, &foo
+; CHECK: mov.b	r12, &foo
 	store i8 %a, i8* @foo
 	ret void
 }
 
 define void @and(i8 %a) nounwind {
 ; CHECK-LABEL: and:
-; CHECK: and.b	r15, &foo
+; CHECK: and.b	r12, &foo
 	%1 = load i8, i8* @foo
 	%2 = and i8 %a, %1
 	store i8 %2, i8* @foo
@@ -21,7 +21,7 @@
 
 define void @add(i8 %a) nounwind {
 ; CHECK-LABEL: add:
-; CHECK: add.b	r15, &foo
+; CHECK: add.b	r12, &foo
 	%1 = load i8, i8* @foo
 	%2 = add i8 %a, %1
 	store i8 %2, i8* @foo
@@ -30,7 +30,7 @@
 
 define void @bis(i8 %a) nounwind {
 ; CHECK-LABEL: bis:
-; CHECK: bis.b	r15, &foo
+; CHECK: bis.b	r12, &foo
 	%1 = load i8, i8* @foo
 	%2 = or i8 %a, %1
 	store i8 %2, i8* @foo
@@ -39,7 +39,7 @@
 
 define void @bic(i8 zeroext %m) nounwind {
 ; CHECK-LABEL: bic:
-; CHECK: bic.b   r15, &foo
+; CHECK: bic.b   r12, &foo
         %1 = xor i8 %m, -1
         %2 = load i8, i8* @foo
         %3 = and i8 %2, %1
@@ -49,7 +49,7 @@
 
 define void @xor(i8 %a) nounwind {
 ; CHECK-LABEL: xor:
-; CHECK: xor.b	r15, &foo
+; CHECK: xor.b	r12, &foo
 	%1 = load i8, i8* @foo
 	%2 = xor i8 %a, %1
 	store i8 %2, i8* @foo
Index: test/CodeGen/MSP430/Inst8ri.ll
===================================================================
--- test/CodeGen/MSP430/Inst8ri.ll
+++ test/CodeGen/MSP430/Inst8ri.ll
@@ -4,34 +4,34 @@
 
 define i8 @mov() nounwind {
 ; CHECK-LABEL: mov:
-; CHECK: mov.b	#1, r15
+; CHECK: mov.b	#1, r12
 	ret i8 1
 }
 
 define i8 @add(i8 %a, i8 %b) nounwind {
 ; CHECK-LABEL: add:
-; CHECK: add.b	#1, r15
+; CHECK: add.b	#1, r12
 	%1 = add i8 %a, 1
 	ret i8 %1
 }
 
 define i8 @and(i8 %a, i8 %b) nounwind {
 ; CHECK-LABEL: and:
-; CHECK: and.b	#1, r15
+; CHECK: and.b	#1, r12
 	%1 = and i8 %a, 1
 	ret i8 %1
 }
 
 define i8 @bis(i8 %a, i8 %b) nounwind {
 ; CHECK-LABEL: bis:
-; CHECK: bis.b	#1, r15
+; CHECK: bis.b	#1, r12
 	%1 = or i8 %a, 1
 	ret i8 %1
 }
 
 define i8 @xor(i8 %a, i8 %b) nounwind {
 ; CHECK-LABEL: xor:
-; CHECK: xor.b	#1, r15
+; CHECK: xor.b	#1, r12
 	%1 = xor i8 %a, 1
 	ret i8 %1
 }
Index: test/CodeGen/MSP430/Inst8rm.ll
===================================================================
--- test/CodeGen/MSP430/Inst8rm.ll
+++ test/CodeGen/MSP430/Inst8rm.ll
@@ -5,7 +5,7 @@
 
 define i8 @add(i8 %a) nounwind {
 ; CHECK-LABEL: add:
-; CHECK: add.b	&foo, r15
+; CHECK: add.b	&foo, r12
 	%1 = load i8, i8* @foo
 	%2 = add i8 %a, %1
 	ret i8 %2
@@ -13,7 +13,7 @@
 
 define i8 @and(i8 %a) nounwind {
 ; CHECK-LABEL: and:
-; CHECK: and.b	&foo, r15
+; CHECK: and.b	&foo, r12
 	%1 = load i8, i8* @foo
 	%2 = and i8 %a, %1
 	ret i8 %2
@@ -21,7 +21,7 @@
 
 define i8 @bis(i8 %a) nounwind {
 ; CHECK-LABEL: bis:
-; CHECK: bis.b	&foo, r15
+; CHECK: bis.b	&foo, r12
 	%1 = load i8, i8* @foo
 	%2 = or i8 %a, %1
 	ret i8 %2
@@ -29,7 +29,7 @@
 
 define i8  @bic(i8 %a) nounwind {
 ; CHECK-LABEL: bic:
-; CHECK: bic.b  &foo, r15
+; CHECK: bic.b  &foo, r12
         %1 = load i8, i8* @foo
         %2 = xor i8 %1, -1
         %3 = and i8 %a, %2
@@ -38,7 +38,7 @@
 
 define i8 @xor(i8 %a) nounwind {
 ; CHECK-LABEL: xor:
-; CHECK: xor.b	&foo, r15
+; CHECK: xor.b	&foo, r12
 	%1 = load i8, i8* @foo
 	%2 = xor i8 %a, %1
 	ret i8 %2
Index: test/CodeGen/MSP430/Inst8rr.ll
===================================================================
--- test/CodeGen/MSP430/Inst8rr.ll
+++ test/CodeGen/MSP430/Inst8rr.ll
@@ -4,7 +4,7 @@
 
 define i8 @mov(i8 %a, i8 %b) nounwind {
 ; CHECK-LABEL: mov:
-; CHECK: mov.{{[bw]}} r14, r15
+; CHECK: mov.{{[bw]}} r13, r12
 	ret i8 %b
 }
 
@@ -17,21 +17,21 @@
 
 define i8 @and(i8 %a, i8 %b) nounwind {
 ; CHECK-LABEL: and:
-; CHECK: and.w	r14, r15
+; CHECK: and.w	r13, r12
 	%1 = and i8 %a, %b
 	ret i8 %1
 }
 
 define i8 @bis(i8 %a, i8 %b) nounwind {
 ; CHECK-LABEL: bis:
-; CHECK: bis.w	r14, r15
+; CHECK: bis.w	r13, r12
 	%1 = or i8 %a, %b
 	ret i8 %1
 }
 
 define i8 @bic(i8 %a, i8 %b) nounwind {
 ; CHECK-LABEL: bic:
-; CHECK: bic.b  r14, r15
+; CHECK: bic.b  r13, r12
         %1 = xor i8 %b, -1
         %2 = and i8 %a, %1
         ret i8 %2
@@ -39,7 +39,7 @@
 
 define i8 @xor(i8 %a, i8 %b) nounwind {
 ; CHECK-LABEL: xor:
-; CHECK: xor.w	r14, r15
+; CHECK: xor.w	r13, r12
 	%1 = xor i8 %a, %b
 	ret i8 %1
 }
Index: test/CodeGen/MSP430/bit.ll
===================================================================
--- test/CodeGen/MSP430/bit.ll
+++ test/CodeGen/MSP430/bit.ll
@@ -12,7 +12,7 @@
 	ret i8 %t3
 }
 ; CHECK-LABEL: bitbrr:
-; CHECK: bit.b	r14, r15
+; CHECK: bit.b	r13, r12
 
 define i8 @bitbri(i8 %a) nounwind {
 	%t1 = and i8 %a, 15
@@ -21,7 +21,7 @@
 	ret i8 %t3
 }
 ; CHECK-LABEL: bitbri:
-; CHECK: bit.b	#15, r15
+; CHECK: bit.b	#15, r12
 
 define i8 @bitbir(i8 %a) nounwind {
 	%t1 = and i8 15, %a
@@ -30,7 +30,7 @@
 	ret i8 %t3
 }
 ; CHECK-LABEL: bitbir:
-; CHECK: bit.b	#15, r15
+; CHECK: bit.b	#15, r12
 
 define i8 @bitbmi() nounwind {
 	%t1 = load i8, i8* @foo8
@@ -60,7 +60,7 @@
 	ret i8 %t4
 }
 ; CHECK-LABEL: bitbrm:
-; CHECK: bit.b	&foo8, r15
+; CHECK: bit.b	&foo8, r12
 
 define i8 @bitbmr(i8 %a) nounwind {
 	%t1 = load i8, i8* @foo8
@@ -70,7 +70,7 @@
 	ret i8 %t4
 }
 ; CHECK-LABEL: bitbmr:
-; CHECK: bit.b	r15, &foo8
+; CHECK: bit.b	r12, &foo8
 
 define i8 @bitbmm() nounwind {
 	%t1 = load i8, i8* @foo8
@@ -93,7 +93,7 @@
 	ret i16 %t3
 }
 ; CHECK-LABEL: bitwrr:
-; CHECK: bit.w	r14, r15
+; CHECK: bit.w	r13, r12
 
 define i16 @bitwri(i16 %a) nounwind {
 	%t1 = and i16 %a, 4080
@@ -102,7 +102,7 @@
 	ret i16 %t3
 }
 ; CHECK-LABEL: bitwri:
-; CHECK: bit.w	#4080, r15
+; CHECK: bit.w	#4080, r12
 
 define i16 @bitwir(i16 %a) nounwind {
 	%t1 = and i16 4080, %a
@@ -111,7 +111,7 @@
 	ret i16 %t3
 }
 ; CHECK-LABEL: bitwir:
-; CHECK: bit.w	#4080, r15
+; CHECK: bit.w	#4080, r12
 
 define i16 @bitwmi() nounwind {
 	%t1 = load i16, i16* @foo16
@@ -141,7 +141,7 @@
 	ret i16 %t4
 }
 ; CHECK-LABEL: bitwrm:
-; CHECK: bit.w	&foo16, r15
+; CHECK: bit.w	&foo16, r12
 
 define i16 @bitwmr(i16 %a) nounwind {
 	%t1 = load i16, i16* @foo16
@@ -151,7 +151,7 @@
 	ret i16 %t4
 }
 ; CHECK-LABEL: bitwmr:
-; CHECK: bit.w	r15, &foo16
+; CHECK: bit.w	r12, &foo16
 
 define i16 @bitwmm() nounwind {
 	%t1 = load i16, i16* @foo16
Index: test/CodeGen/MSP430/byval.ll
===================================================================
--- test/CodeGen/MSP430/byval.ll
+++ test/CodeGen/MSP430/byval.ll
@@ -9,7 +9,7 @@
 define i16 @callee(%struct.Foo* byval %f) nounwind {
 entry:
 ; CHECK-LABEL: callee:
-; CHECK: mov.w 2(r1), r15
+; CHECK: mov.w 2(r1), r12
   %0 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i32 0, i32 0
   %1 = load i16, i16* %0, align 2
   ret i16 %1
Index: test/CodeGen/MSP430/cc_args.ll
===================================================================
--- test/CodeGen/MSP430/cc_args.ll
+++ test/CodeGen/MSP430/cc_args.ll
@@ -7,12 +7,12 @@
 entry:
 ; CHECK: test:
 
-; CHECK: mov.w #1, r15
+; CHECK: mov.w #1, r12
 ; CHECK: call #f_i16
   call void @f_i16(i16 1)
 
-; CHECK: mov.w #772, r14
-; CHECK: mov.w #258, r15
+; CHECK: mov.w #772, r12
+; CHECK: mov.w #258, r13
 ; CHECK: call #f_i32
   call void @f_i32(i32 16909060)
 
@@ -23,26 +23,34 @@
 ; CHECK: call #f_i64
   call void @f_i64(i64 72623859790382856)
 
-; CHECK: mov.w #772, r14
-; CHECK: mov.w #258, r15
-; CHECK: mov.w #1800, r12
-; CHECK: mov.w #1286, r13
+; CHECK: mov.w #772, r12
+; CHECK: mov.w #258, r13
+; CHECK: mov.w #1800, r14
+; CHECK: mov.w #1286, r15
 ; CHECK: call #f_i32_i32
   call void @f_i32_i32(i32 16909060, i32 84281096)
 
-; CHECK: mov.w #1, r15
+; CHECK: mov.w #1, r12
 ; CHECK: mov.w #772, r13
 ; CHECK: mov.w #258, r14
-; CHECK: mov.w #2, r12
+; CHECK: mov.w #2, r15
 ; CHECK: call #f_i16_i32_i16
   call void @f_i16_i32_i16(i16 1, i32 16909060, i16 2)
 
-; CHECK: mov.w #2, 8(r1)
+; CHECK: mov.w #1286, 0(r1)
+; CHECK: mov.w #1, r12
+; CHECK: mov.w #772, r13
+; CHECK: mov.w #258, r14
+; CHECK: mov.w #1800, r15
+; CHECK: call #f_i16_i32_i32
+  call void @f_i16_i32_i32(i16 1, i32 16909060, i32 84281096)
+  
 ; CHECK: mov.w #258, 6(r1)
 ; CHECK: mov.w #772, 4(r1)
 ; CHECK: mov.w #1286, 2(r1)
 ; CHECK: mov.w #1800, 0(r1)
-; CHECK: mov.w #1, r15
+; CHECK: mov.w #1, r12
+; CHECK: mov.w #2, r13
 ; CHECK: call #f_i16_i64_i16
   call void @f_i16_i64_i16(i16 1, i64 72623859790382856, i16 2)
 
@@ -55,15 +63,15 @@
 
 define void @f_i16(i16 %a) #0 {
 ; CHECK: f_i16:
-; CHECK: mov.w r15, &g_i16
+; CHECK: mov.w r12, &g_i16
   store volatile i16 %a, i16* @g_i16, align 2
   ret void
 }
 
 define void @f_i32(i32 %a) #0 {
 ; CHECK: f_i32:
-; CHECK: mov.w r15, &g_i32+2
-; CHECK: mov.w r14, &g_i32
+; CHECK: mov.w r13, &g_i32+2
+; CHECK: mov.w r12, &g_i32
   store volatile i32 %a, i32* @g_i32, align 2
   ret void
 }
@@ -80,37 +88,50 @@
 
 define void @f_i32_i32(i32 %a, i32 %b) #0 {
 ; CHECK: f_i32_i32:
-; CHECK: mov.w r15, &g_i32+2
-; CHECK: mov.w r14, &g_i32
-  store volatile i32 %a, i32* @g_i32, align 2
 ; CHECK: mov.w r13, &g_i32+2
 ; CHECK: mov.w r12, &g_i32
+  store volatile i32 %a, i32* @g_i32, align 2
+; CHECK: mov.w r15, &g_i32+2
+; CHECK: mov.w r14, &g_i32
   store volatile i32 %b, i32* @g_i32, align 2
   ret void
 }
 
+define void @f_i16_i32_i32(i16 %a, i32 %b, i32 %c) #0 {
+; CHECK: f_i16_i32_i32:
+; CHECK: mov.w r12, &g_i16
+  store volatile i16 %a, i16* @g_i16, align 2
+; CHECK: mov.w r14, &g_i32+2
+; CHECK: mov.w r13, &g_i32
+  store volatile i32 %b, i32* @g_i32, align 2
+; CHECK: mov.w r15, &g_i32
+; CHECK: mov.w 4(r4), &g_i32+2
+  store volatile i32 %c, i32* @g_i32, align 2
+  ret void
+}
+
 define void @f_i16_i32_i16(i16 %a, i32 %b, i16 %c) #0 {
 ; CHECK: f_i16_i32_i16:
-; CHECK: mov.w r15, &g_i16
+; CHECK: mov.w r12, &g_i16
   store volatile i16 %a, i16* @g_i16, align 2
 ; CHECK: mov.w r14, &g_i32+2
 ; CHECK: mov.w r13, &g_i32
   store volatile i32 %b, i32* @g_i32, align 2
-; CHECK: mov.w r12, &g_i16
+; CHECK: mov.w r15, &g_i16
   store volatile i16 %c, i16* @g_i16, align 2
   ret void
 }
 
 define void @f_i16_i64_i16(i16 %a, i64 %b, i16 %c) #0 {
 ; CHECK: f_i16_i64_i16:
-; CHECK: mov.w r15, &g_i16
+; CHECK: mov.w r12, &g_i16
   store volatile i16 %a, i16* @g_i16, align 2
 ;CHECK: mov.w 10(r4), &g_i64+6
 ;CHECK: mov.w 8(r4), &g_i64+4
 ;CHECK: mov.w 6(r4), &g_i64+2
 ;CHECK: mov.w 4(r4), &g_i64
   store volatile i64 %b, i64* @g_i64, align 2
-;CHECK: mov.w 12(r4), &g_i16
+;CHECK: mov.w r13, &g_i16
   store volatile i16 %c, i16* @g_i16, align 2
   ret void
 }
Index: test/CodeGen/MSP430/cc_ret.ll
===================================================================
--- test/CodeGen/MSP430/cc_ret.ll
+++ test/CodeGen/MSP430/cc_ret.ll
@@ -8,13 +8,13 @@
 ; CHECK: test:
 
 ; CHECK: call #f_i16
-; CHECK: mov.w r15, &g_i16
+; CHECK: mov.w r12, &g_i16
   %0 = call i16 @f_i16()
   store volatile i16 %0, i16* @g_i16
 
 ; CHECK: call #f_i32
-; CHECK: mov.w r15, &g_i32+2
-; CHECK: mov.w r14, &g_i32
+; CHECK: mov.w r13, &g_i32+2
+; CHECK: mov.w r12, &g_i32
   %1 = call i32 @f_i32()
   store volatile i32 %1, i32* @g_i32
 
@@ -35,15 +35,15 @@
 
 define i16 @f_i16() #0 {
 ; CHECK: f_i16:
-; CHECK: mov.w #1, r15
+; CHECK: mov.w #1, r12
 ; CHECK: ret
   ret i16 1
 }
 
 define i32 @f_i32() #0 {
 ; CHECK: f_i32:
-; CHECK: mov.w #772, r14
-; CHECK: mov.w #258, r15
+; CHECK: mov.w #772, r12
+; CHECK: mov.w #258, r13
 ; CHECK: ret
   ret i32 16909060
 }
Index: test/CodeGen/MSP430/indirectbr2.ll
===================================================================
--- test/CodeGen/MSP430/indirectbr2.ll
+++ test/CodeGen/MSP430/indirectbr2.ll
@@ -5,7 +5,7 @@
 entry:
   %tmp1 = getelementptr inbounds [5 x i8*], [5 x i8*]* @C.0.2070, i16 0, i16 %i ; <i8**> [#uses=1]
   %gotovar.4.0 = load i8*, i8** %tmp1, align 4        ; <i8*> [#uses=1]
-; CHECK: br .LC.0.2070(r12)
+; CHECK: br .LC.0.2070(r13)
   indirectbr i8* %gotovar.4.0, [label %L5, label %L4, label %L3, label %L2, label %L1]
 
 L5:                                               ; preds = %bb2
Index: test/CodeGen/MSP430/jumptable.ll
===================================================================
--- test/CodeGen/MSP430/jumptable.ll
+++ test/CodeGen/MSP430/jumptable.ll
@@ -11,9 +11,9 @@
   %i.addr = alloca i16, align 2
   store i16 %i, i16* %i.addr, align 2
   %0 = load i16, i16* %i.addr, align 2
-; CHECK: mov.w #2, r14
+; CHECK: mov.w #2, r13
 ; CHECK: call #__mulhi3hw_noint
-; CHECK: br .LJTI0_0(r15)
+; CHECK: br .LJTI0_0(r12)
   switch i16 %0, label %sw.default [
     i16 0, label %sw.bb
     i16 1, label %sw.bb1
Index: test/CodeGen/MSP430/memset.ll
===================================================================
--- test/CodeGen/MSP430/memset.ll
+++ test/CodeGen/MSP430/memset.ll
@@ -9,9 +9,9 @@
 entry:
 ; CHECK-LABEL: test:
   %0 = load i8*, i8** @buf, align 2
-; CHECK: mov.w &buf, r15
-; CHECK-NEXT: mov.w #5, r14
-; CHECK-NEXT: mov.w #128, r13
+; CHECK: mov.w &buf, r12
+; CHECK-NEXT: mov.w #5, r13
+; CHECK-NEXT: mov.w #128, r14
 ; CHECK-NEXT: call #memset
   call void @llvm.memset.p0i8.i16(i8* %0, i8 5, i16 128, i32 1, i1 false)
   ret void
Index: test/CodeGen/MSP430/setcc.ll
===================================================================
--- test/CodeGen/MSP430/setcc.ll
+++ test/CodeGen/MSP430/setcc.ll
@@ -9,10 +9,10 @@
 	ret i16 %t3
 }
 ; CHECK-LABEL: sccweqand:
-; CHECK:	bit.w	r14, r15
-; CHECK:	mov.w	r2, r15
-; CHECK:	rra.w   r15
-; CHECK:	and.w	#1, r15
+; CHECK:	bit.w	r13, r12
+; CHECK:	mov.w	r2, r12
+; CHECK:	rra.w   r12
+; CHECK:	and.w	#1, r12
 
 define i16 @sccwneand(i16 %a, i16 %b) nounwind {
 	%t1 = and i16 %a, %b
@@ -21,9 +21,9 @@
 	ret i16 %t3
 }
 ; CHECK-LABEL: sccwneand:
-; CHECK: 	bit.w	r14, r15
-; CHECK:	mov.w	r2, r15
-; CHECK:	and.w	#1, r15
+; CHECK: 	bit.w	r13, r12
+; CHECK:	mov.w	r2, r12
+; CHECK:	and.w	#1, r12
 
 define i16 @sccwne(i16 %a, i16 %b) nounwind {
 	%t1 = icmp ne i16 %a, %b
@@ -31,11 +31,11 @@
 	ret i16 %t2
 }
 ; CHECK-LABEL:sccwne:
-; CHECK:	cmp.w	r14, r15
-; CHECK:	mov.w	r2, r12
-; CHECK:	rra.w	r12
-; CHECK:	mov.w	#1, r15
-; CHECK:	bic.w	r12, r15
+; CHECK:	cmp.w	r13, r12
+; CHECK:	mov.w	r2, r13
+; CHECK:	rra.w	r13
+; CHECK:	mov.w	#1, r12
+; CHECK:	bic.w	r13, r12
 
 define i16 @sccweq(i16 %a, i16 %b) nounwind {
 	%t1 = icmp eq i16 %a, %b
@@ -43,10 +43,10 @@
 	ret i16 %t2
 }
 ; CHECK-LABEL:sccweq:
-; CHECK:	cmp.w	r14, r15
-; CHECK:	mov.w	r2, r15
-; CHECK:	rra.w	r15
-; CHECK:	and.w	#1, r15
+; CHECK:	cmp.w	r13, r12
+; CHECK:	mov.w	r2, r12
+; CHECK:	rra.w	r12
+; CHECK:	and.w	#1, r12
 
 define i16 @sccwugt(i16 %a, i16 %b) nounwind {
 	%t1 = icmp ugt i16 %a, %b
@@ -54,9 +54,9 @@
 	ret i16 %t2
 }
 ; CHECK-LABEL:sccwugt:
-; CHECK:	cmp.w	r15, r14
-; CHECK:	mov.w	#1, r15
-; CHECK:	bic.w	r2, r15
+; CHECK:	cmp.w	r12, r13
+; CHECK:	mov.w	#1, r12
+; CHECK:	bic.w	r2, r12
 
 define i16 @sccwuge(i16 %a, i16 %b) nounwind {
 	%t1 = icmp uge i16 %a, %b
@@ -64,9 +64,9 @@
 	ret i16 %t2
 }
 ; CHECK-LABEL:sccwuge:
-; CHECK:	cmp.w	r14, r15
-; CHECK:	mov.w	r2, r15
-; CHECK:	and.w	#1, r15
+; CHECK:	cmp.w	r13, r12
+; CHECK:	mov.w	r2, r12
+; CHECK:	and.w	#1, r12
 
 define i16 @sccwult(i16 %a, i16 %b) nounwind {
 	%t1 = icmp ult i16 %a, %b
@@ -74,9 +74,9 @@
 	ret i16 %t2
 }
 ; CHECK-LABEL:sccwult:
-; CHECK:	cmp.w	r14, r15
-; CHECK:	mov.w	#1, r15
-; CHECK:	bic.w	r2, r15
+; CHECK:	cmp.w	r13, r12
+; CHECK:	mov.w	#1, r12
+; CHECK:	bic.w	r2, r12
 
 define i16 @sccwule(i16 %a, i16 %b) nounwind {
 	%t1 = icmp ule i16 %a, %b
@@ -84,9 +84,9 @@
 	ret i16 %t2
 }
 ; CHECK-LABEL:sccwule:
-; CHECK:	cmp.w	r15, r14
-; CHECK:	mov.w	r2, r15
-; CHECK:	and.w	#1, r15
+; CHECK:	cmp.w	r12, r13
+; CHECK:	mov.w	r2, r12
+; CHECK:	and.w	#1, r12
 
 define i16 @sccwsgt(i16 %a, i16 %b) nounwind {
 	%t1 = icmp sgt i16 %a, %b
Index: test/CodeGen/MSP430/struct-return.ll
===================================================================
--- test/CodeGen/MSP430/struct-return.ll
+++ test/CodeGen/MSP430/struct-return.ll
@@ -0,0 +1,23 @@
+; RUN: llc < %s | FileCheck %s
+
+target datalayout = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"
+target triple = "msp430---elf"
+
+; Allow simple structures to be returned by value.
+
+%s = type { i64, i64 }
+
+define %s @fred() #0 {
+; CHECK-LABEL: fred:
+; CHECK: mov.w	#2314, 14(r12)
+; CHECK: mov.w	#2828, 12(r12)
+; CHECK: mov.w	#3342, 10(r12)
+; CHECK: mov.w	#3840, 8(r12)
+; CHECK: mov.w	#258, 6(r12)
+; CHECK: mov.w	#772, 4(r12)
+; CHECK: mov.w	#1286, 2(r12)
+; CHECK: mov.w	#1800, 0(r12)
+  ret %s {i64 72623859790382856, i64 651345242494996224} 
+}
+
+attributes #0 = { nounwind }
Index: test/CodeGen/MSP430/vararg.ll
===================================================================
--- test/CodeGen/MSP430/vararg.ll
+++ test/CodeGen/MSP430/vararg.ll
@@ -25,13 +25,13 @@
 entry:
 ; CHECK-LABEL: va_arg:
   %vl.addr = alloca i8*, align 2
-; CHECK: mov.w r15, 0(r1)
+; CHECK: mov.w r12, 0(r1)
   store i8* %vl, i8** %vl.addr, align 2
-; CHECK: mov.w r15, [[REG:r[0-9]+]]
+; CHECK: mov.w r12, [[REG:r[0-9]+]]
 ; CHECK-NEXT: add.w #2, [[REG]]
 ; CHECK-NEXT: mov.w [[REG]], 0(r1)
   %0 = va_arg i8** %vl.addr, i16
-; CHECK-NEXT: mov.w 0(r15), r15
+; CHECK-NEXT: mov.w 0(r12), r12
   ret i16 %0
 }
 
@@ -40,11 +40,11 @@
 ; CHECK-LABEL: va_copy:
   %vl.addr = alloca i8*, align 2
   %vl2 = alloca i8*, align 2
-; CHECK: mov.w r15, 2(r1)
+; CHECK: mov.w r12, 2(r1)
   store i8* %vl, i8** %vl.addr, align 2
   %0 = bitcast i8** %vl2 to i8*
   %1 = bitcast i8** %vl.addr to i8*
-; CHECK-NEXT: mov.w r15, 0(r1)
+; CHECK-NEXT: mov.w r12, 0(r1)
   call void @llvm.va_copy(i8* %0, i8* %1)
   ret void
 }