From 9c467a8b3b93317e47902e85c386647e072264d8 Mon Sep 17 00:00:00 2001 From: Vadzim Dambrouski Date: Thu, 2 Mar 2017 20:25:10 +0000 Subject: [PATCH] [MSP430] Add SRet support to MSP430 target This patch adds support for struct return values to the MSP430 target backend. It also reverses the order of argument and return registers in the calling convention to bring it into closer alignment with the published EABI from TI. Patch by Andrew Wygle (awygle). Differential Revision: https://reviews.llvm.org/D29069 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296807 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/MSP430/MSP430CallingConv.td | 8 +- lib/Target/MSP430/MSP430ISelLowering.cpp | 85 ++++++++++++++----- lib/Target/MSP430/MSP430ISelLowering.h | 6 ++ lib/Target/MSP430/MSP430MachineFunctionInfo.h | 10 ++- test/CodeGen/MSP430/AddrMode-bis-rx.ll | 14 +-- test/CodeGen/MSP430/AddrMode-bis-xr.ll | 14 +-- test/CodeGen/MSP430/AddrMode-mov-rx.ll | 14 +-- test/CodeGen/MSP430/AddrMode-mov-xr.ll | 14 +-- test/CodeGen/MSP430/Inst16mr.ll | 12 +-- test/CodeGen/MSP430/Inst16ri.ll | 10 +-- test/CodeGen/MSP430/Inst16rm.ll | 10 +-- test/CodeGen/MSP430/Inst16rr.ll | 12 +-- test/CodeGen/MSP430/Inst8mr.ll | 12 +-- test/CodeGen/MSP430/Inst8ri.ll | 10 +-- test/CodeGen/MSP430/Inst8rm.ll | 10 +-- test/CodeGen/MSP430/Inst8rr.ll | 10 +-- test/CodeGen/MSP430/bit.ll | 20 ++--- test/CodeGen/MSP430/byval.ll | 2 +- test/CodeGen/MSP430/cc_args.ll | 63 +++++++++----- test/CodeGen/MSP430/cc_ret.ll | 12 +-- test/CodeGen/MSP430/indirectbr2.ll | 2 +- test/CodeGen/MSP430/jumptable.ll | 4 +- test/CodeGen/MSP430/memset.ll | 6 +- test/CodeGen/MSP430/setcc.ll | 56 ++++++------ test/CodeGen/MSP430/struct-return.ll | 23 +++++ test/CodeGen/MSP430/vararg.ll | 10 +-- 26 files changed, 277 insertions(+), 172 deletions(-) create mode 100644 test/CodeGen/MSP430/struct-return.ll diff --git a/lib/Target/MSP430/MSP430CallingConv.td b/lib/Target/MSP430/MSP430CallingConv.td index b38f5781c84a..0434f8abfbf4 100644 --- a/lib/Target/MSP430/MSP430CallingConv.td +++ b/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]>> ]>; //===----------------------------------------------------------------------===// diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp index cb2c62029454..5b20273a7d44 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -246,13 +246,20 @@ MSP430TargetLowering::getRegForInlineAsmConstraint( template static void ParseFunctionArgs(const SmallVectorImpl &Args, SmallVectorImpl &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; } } } @@ -276,7 +283,7 @@ static void AnalyzeArguments(CCState &State, SmallVectorImpl &ArgLocs, const SmallVectorImpl &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); @@ -289,7 +296,7 @@ static void AnalyzeArguments(CCState &State, 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++) { @@ -317,20 +324,22 @@ static void AnalyzeArguments(CCState &State, 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::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); } @@ -352,10 +361,6 @@ static void AnalyzeReturnValues(CCState &State, SmallVectorImpl &RVLocs, const SmallVectorImpl &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( @@ -497,9 +502,33 @@ SDValue MSP430TargetLowering::LowerCCCArguments( } } + 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 &Outs, + LLVMContext &Context) const { + SmallVector RVLocs; + CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context); + return CCInfo.CheckReturn(Outs, RetCC_MSP430); +} + SDValue MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, @@ -507,6 +536,8 @@ MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, const SmallVectorImpl &OutVals, const SDLoc &dl, SelectionDAG &DAG) const { + MachineFunction &MF = DAG.getMachineFunction(); + // CCValAssign - represent the assignment of the return value to a location SmallVector RVLocs; @@ -538,6 +569,22 @@ MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); } + if (MF.getFunction()->hasStructRetAttr()) { + MSP430MachineFunctionInfo *FuncInfo = MF.getInfo(); + 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); diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h index 8864807e999e..3a729623c99a 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.h +++ b/lib/Target/MSP430/MSP430ISelLowering.h @@ -158,6 +158,12 @@ namespace llvm { LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl &InVals) const override; + bool CanLowerReturn(CallingConv::ID CallConv, + MachineFunction &MF, + bool IsVarArg, + const SmallVectorImpl &Outs, + LLVMContext &Context) const override; + SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, diff --git a/lib/Target/MSP430/MSP430MachineFunctionInfo.h b/lib/Target/MSP430/MSP430MachineFunctionInfo.h index 2d937318c7e5..fcaa8a1d6c72 100644 --- a/lib/Target/MSP430/MSP430MachineFunctionInfo.h +++ b/lib/Target/MSP430/MSP430MachineFunctionInfo.h @@ -33,15 +33,23 @@ class MSP430MachineFunctionInfo : public MachineFunctionInfo { /// 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; } diff --git a/test/CodeGen/MSP430/AddrMode-bis-rx.ll b/test/CodeGen/MSP430/AddrMode-bis-rx.ll index 941ee2dc2ce9..f4cb30f2d014 100644 --- a/test/CodeGen/MSP430/AddrMode-bis-rx.ll +++ b/test/CodeGen/MSP430/AddrMode-bis-rx.ll @@ -8,7 +8,7 @@ define i16 @am1(i16 %x, i16* %a) nounwind { 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 @@ define i16 @am2(i16 %x) nounwind { 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 @@ define i8 @am3(i8 %x, i16 %n) nounwind { 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 @@ define i16 @am4(i16 %x) nounwind { 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 @@ define i16 @am5(i16 %x, i16* %a) nounwind { 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 @@ define i16 @am6(i16 %x) nounwind { 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 @@ define i8 @am7(i8 %x, i16 %n) nounwind { ret i8 %4 } ; CHECK-LABEL: am7: -; CHECK: bis.b duh+2(r14), r15 +; CHECK: bis.b duh+2(r13), r12 diff --git a/test/CodeGen/MSP430/AddrMode-bis-xr.ll b/test/CodeGen/MSP430/AddrMode-bis-xr.ll index 4b8f367a8880..1e150f382062 100644 --- a/test/CodeGen/MSP430/AddrMode-bis-xr.ll +++ b/test/CodeGen/MSP430/AddrMode-bis-xr.ll @@ -9,7 +9,7 @@ define void @am1(i16* %a, i16 %x) nounwind { 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 @@ define void @am2(i16 %x) nounwind { 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 @@ define void @am3(i16 %i, i8 %x) nounwind { 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 @@ define void @am4(i16 %x) nounwind { 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 @@ define void @am5(i16* %a, i16 %x) readonly { 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 @@ define void @am6(i16 %x) nounwind { 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 @@ define void @am7(i16 %n, i8 %x) nounwind { ret void } ; CHECK-LABEL: am7: -; CHECK: bis.b r14, duh+2(r15) +; CHECK: bis.b r13, duh+2(r12) diff --git a/test/CodeGen/MSP430/AddrMode-mov-rx.ll b/test/CodeGen/MSP430/AddrMode-mov-rx.ll index cdee931bf96d..808aca0ea10b 100644 --- a/test/CodeGen/MSP430/AddrMode-mov-rx.ll +++ b/test/CodeGen/MSP430/AddrMode-mov-rx.ll @@ -7,7 +7,7 @@ define i16 @am1(i16* %a) nounwind { 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 @@ define i16 @am2() nounwind { 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 @@ define i8 @am3(i16 %n) nounwind { 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 @@ define i16 @am5(i16* %a) nounwind { 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 @@ define i16 @am6() nounwind { 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 @@ define i8 @am7(i16 %n) nounwind { ret i8 %3 } ; CHECK-LABEL: am7: -; CHECK: mov.b duh+2(r15), r15 +; CHECK: mov.b duh+2(r12), r12 diff --git a/test/CodeGen/MSP430/AddrMode-mov-xr.ll b/test/CodeGen/MSP430/AddrMode-mov-xr.ll index ccb42886e9b4..c336289a60d7 100644 --- a/test/CodeGen/MSP430/AddrMode-mov-xr.ll +++ b/test/CodeGen/MSP430/AddrMode-mov-xr.ll @@ -7,7 +7,7 @@ define void @am1(i16* %a, i16 %b) nounwind { 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 @@ define void @am2(i16 %a) nounwind { 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 @@ define void @am3(i16 %i, i8 %a) nounwind { 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 @@ define void @am5(i16* nocapture %p, i16 %a) nounwind readonly { 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 @@ define void @am6(i16 %a) nounwind { 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 @@ define void @am7(i16 %n, i8 %a) nounwind { ret void } ; CHECK-LABEL: am7: -; CHECK: mov.b r14, duh+2(r15) +; CHECK: mov.b r13, duh+2(r12) diff --git a/test/CodeGen/MSP430/Inst16mr.ll b/test/CodeGen/MSP430/Inst16mr.ll index 50dc4c0b6731..847c093f4088 100644 --- a/test/CodeGen/MSP430/Inst16mr.ll +++ b/test/CodeGen/MSP430/Inst16mr.ll @@ -5,14 +5,14 @@ target triple = "msp430-generic-generic" 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 @add(i16 %a) nounwind { 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 @and(i16 %a) nounwind { 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 @bis(i16 %a) nounwind { 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 @bic(i16 zeroext %m) nounwind { 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 diff --git a/test/CodeGen/MSP430/Inst16ri.ll b/test/CodeGen/MSP430/Inst16ri.ll index f89f686ab567..3a4bb6a93d99 100644 --- a/test/CodeGen/MSP430/Inst16ri.ll +++ b/test/CodeGen/MSP430/Inst16ri.ll @@ -4,34 +4,34 @@ target triple = "msp430-generic-generic" 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 } diff --git a/test/CodeGen/MSP430/Inst16rm.ll b/test/CodeGen/MSP430/Inst16rm.ll index 4f6998ee68df..44b8f39d8fa6 100644 --- a/test/CodeGen/MSP430/Inst16rm.ll +++ b/test/CodeGen/MSP430/Inst16rm.ll @@ -5,7 +5,7 @@ target triple = "msp430-generic-generic" 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 @add(i16 %a) nounwind { 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 @and(i16 %a) nounwind { 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 @bis(i16 %a) nounwind { 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 @bic(i16 %a) nounwind { 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 diff --git a/test/CodeGen/MSP430/Inst16rr.ll b/test/CodeGen/MSP430/Inst16rr.ll index d74bfae9b938..75440ca2b403 100644 --- a/test/CodeGen/MSP430/Inst16rr.ll +++ b/test/CodeGen/MSP430/Inst16rr.ll @@ -4,34 +4,34 @@ target triple = "msp430-generic-generic" 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 @bic(i16 %a, i16 %b) nounwind { 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 } diff --git a/test/CodeGen/MSP430/Inst8mr.ll b/test/CodeGen/MSP430/Inst8mr.ll index f03c7e1a659b..7fbdff257fe7 100644 --- a/test/CodeGen/MSP430/Inst8mr.ll +++ b/test/CodeGen/MSP430/Inst8mr.ll @@ -5,14 +5,14 @@ target triple = "msp430-generic-generic" 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 @and(i8 %a) nounwind { 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 @add(i8 %a) nounwind { 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 @bis(i8 %a) nounwind { 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 @bic(i8 zeroext %m) nounwind { 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 diff --git a/test/CodeGen/MSP430/Inst8ri.ll b/test/CodeGen/MSP430/Inst8ri.ll index ec0dff9c563e..0e50f17f2a55 100644 --- a/test/CodeGen/MSP430/Inst8ri.ll +++ b/test/CodeGen/MSP430/Inst8ri.ll @@ -4,34 +4,34 @@ target triple = "msp430-generic-generic" 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 } diff --git a/test/CodeGen/MSP430/Inst8rm.ll b/test/CodeGen/MSP430/Inst8rm.ll index e1a970395578..826a3c65ec94 100644 --- a/test/CodeGen/MSP430/Inst8rm.ll +++ b/test/CodeGen/MSP430/Inst8rm.ll @@ -5,7 +5,7 @@ target triple = "msp430-generic-generic" 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 @add(i8 %a) nounwind { 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 @and(i8 %a) nounwind { 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 @bis(i8 %a) nounwind { 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 @bic(i8 %a) nounwind { 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 diff --git a/test/CodeGen/MSP430/Inst8rr.ll b/test/CodeGen/MSP430/Inst8rr.ll index 76e8d1911282..f37bc32a28fe 100644 --- a/test/CodeGen/MSP430/Inst8rr.ll +++ b/test/CodeGen/MSP430/Inst8rr.ll @@ -4,7 +4,7 @@ target triple = "msp430-generic-generic" 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 @add(i8 %a, i8 %b) nounwind { 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 @bic(i8 %a, i8 %b) nounwind { 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 } diff --git a/test/CodeGen/MSP430/bit.ll b/test/CodeGen/MSP430/bit.ll index 45964f97f1bf..172822fbb5fe 100644 --- a/test/CodeGen/MSP430/bit.ll +++ b/test/CodeGen/MSP430/bit.ll @@ -12,7 +12,7 @@ define i8 @bitbrr(i8 %a, i8 %b) nounwind { 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 @@ define i8 @bitbri(i8 %a) nounwind { 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 @@ define i8 @bitbir(i8 %a) nounwind { 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 @@ define i8 @bitbrm(i8 %a) nounwind { 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 @@ define i8 @bitbmr(i8 %a) nounwind { 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 @@ define i16 @bitwrr(i16 %a, i16 %b) nounwind { 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 @@ define i16 @bitwri(i16 %a) nounwind { 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 @@ define i16 @bitwir(i16 %a) nounwind { 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 @@ define i16 @bitwrm(i16 %a) nounwind { 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 @@ define i16 @bitwmr(i16 %a) nounwind { 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 diff --git a/test/CodeGen/MSP430/byval.ll b/test/CodeGen/MSP430/byval.ll index 410a6b047b6e..401896b43c20 100644 --- a/test/CodeGen/MSP430/byval.ll +++ b/test/CodeGen/MSP430/byval.ll @@ -9,7 +9,7 @@ target triple = "msp430---elf" 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 diff --git a/test/CodeGen/MSP430/cc_args.ll b/test/CodeGen/MSP430/cc_args.ll index 39e99e263744..70ac901f7e4e 100644 --- a/test/CodeGen/MSP430/cc_args.ll +++ b/test/CodeGen/MSP430/cc_args.ll @@ -7,12 +7,12 @@ define void @test() #0 { 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 @@ entry: ; 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 @@ entry: 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_i64(i64 %a) #0 { 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 } diff --git a/test/CodeGen/MSP430/cc_ret.ll b/test/CodeGen/MSP430/cc_ret.ll index c2a9ae664509..937db6dbf3bf 100644 --- a/test/CodeGen/MSP430/cc_ret.ll +++ b/test/CodeGen/MSP430/cc_ret.ll @@ -8,13 +8,13 @@ entry: ; 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 @@ entry: 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 } diff --git a/test/CodeGen/MSP430/indirectbr2.ll b/test/CodeGen/MSP430/indirectbr2.ll index b0b4f1cbfd24..ab8015a858c6 100644 --- a/test/CodeGen/MSP430/indirectbr2.ll +++ b/test/CodeGen/MSP430/indirectbr2.ll @@ -5,7 +5,7 @@ define internal i16 @foo(i16 %i) nounwind { entry: %tmp1 = getelementptr inbounds [5 x i8*], [5 x i8*]* @C.0.2070, i16 0, i16 %i ; [#uses=1] %gotovar.4.0 = load i8*, i8** %tmp1, align 4 ; [#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 diff --git a/test/CodeGen/MSP430/jumptable.ll b/test/CodeGen/MSP430/jumptable.ll index 4ba930b04e39..5ccdbb701db1 100644 --- a/test/CodeGen/MSP430/jumptable.ll +++ b/test/CodeGen/MSP430/jumptable.ll @@ -11,9 +11,9 @@ entry: %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 diff --git a/test/CodeGen/MSP430/memset.ll b/test/CodeGen/MSP430/memset.ll index 76cfb29586d7..a24bfafc2005 100644 --- a/test/CodeGen/MSP430/memset.ll +++ b/test/CodeGen/MSP430/memset.ll @@ -9,9 +9,9 @@ define void @test() nounwind { 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 diff --git a/test/CodeGen/MSP430/setcc.ll b/test/CodeGen/MSP430/setcc.ll index d5a8057ddd6c..6e2ec8ea3ea1 100644 --- a/test/CodeGen/MSP430/setcc.ll +++ b/test/CodeGen/MSP430/setcc.ll @@ -9,10 +9,10 @@ define i16 @sccweqand(i16 %a, i16 %b) nounwind { 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 @@ define i16 @sccwneand(i16 %a, i16 %b) nounwind { 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 @@ define i16 @sccwne(i16 %a, i16 %b) nounwind { 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 @@ define i16 @sccweq(i16 %a, i16 %b) nounwind { 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 @@ define i16 @sccwugt(i16 %a, i16 %b) nounwind { 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 @@ define i16 @sccwuge(i16 %a, i16 %b) nounwind { 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 @@ define i16 @sccwult(i16 %a, i16 %b) nounwind { 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 @@ define i16 @sccwule(i16 %a, i16 %b) nounwind { 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 diff --git a/test/CodeGen/MSP430/struct-return.ll b/test/CodeGen/MSP430/struct-return.ll new file mode 100644 index 000000000000..c28bf06af439 --- /dev/null +++ b/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 } diff --git a/test/CodeGen/MSP430/vararg.ll b/test/CodeGen/MSP430/vararg.ll index 9e511fce956f..6c8bceff5de9 100644 --- a/test/CodeGen/MSP430/vararg.ll +++ b/test/CodeGen/MSP430/vararg.ll @@ -25,13 +25,13 @@ define i16 @va_arg(i8* %vl) nounwind { 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 @@ entry: ; 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 }