Index: lib/Target/MSP430/MSP430ISelLowering.cpp =================================================================== --- lib/Target/MSP430/MSP430ISelLowering.cpp +++ lib/Target/MSP430/MSP430ISelLowering.cpp @@ -250,6 +250,22 @@ #include "MSP430GenCallingConv.inc" +template +static void UpdateReturnAnalysis(SmallVectorImpl& RVLocs, + const SmallVectorImpl &Args) { + unsigned Size = Args.size(); + if (Size <= 1) + return; + + for (unsigned i = 0, e = Size / 2; i != e; ++i) { + CCValAssign &Left = RVLocs[i]; + CCValAssign &Right = RVLocs[Size - i - 1]; + CCValAssign Tmp = Left; + Left = Right; + Right = Tmp; + } +} + SDValue MSP430TargetLowering::LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, @@ -424,6 +440,7 @@ // Analize return values. CCInfo.AnalyzeReturn(Outs, RetCC_MSP430); + UpdateReturnAnalysis(RVLocs, Outs); SDValue Flag; SmallVector RetOps(1, Chain); @@ -611,6 +628,7 @@ getTargetMachine(), RVLocs, *DAG.getContext()); CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430); + UpdateReturnAnalysis(RVLocs, Ins); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { @@ -1026,7 +1044,6 @@ return false; } - const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { switch (Opcode) { default: return NULL; Index: test/CodeGen/MSP430/longret.ll =================================================================== --- /dev/null +++ test/CodeGen/MSP430/longret.ll @@ -0,0 +1,31 @@ +; 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" + +@var = common global i64 0, align 8 + +define i64 @callee() #0 { +entry: +; CHECK: callee: +; CHECK: mov.w #1800, r12 +; CHECK: mov.w #1286, r13 +; CHECK: mov.w #772, r14 +; CHECK: mov.w #258, r15 +; CHECK: ret + ret i64 72623859790382856 +} + +define void @caller() #0 { +; CHECK: caller: +; CHECK: call #callee + %1 = call i64 @callee() +; CHECK: mov.w r15, &var+6 +; CHECK: mov.w r14, &var+4 +; CHECK: mov.w r13, &var+2 +; CHECK: mov.w r12, &var + store i64 %1, i64* @var, align 8 + ret void +} + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }