@@ -245,13 +245,20 @@ MSP430TargetLowering::getRegForInlineAsmConstraint(
245245template <typename ArgT>
246246static void ParseFunctionArgs (const SmallVectorImpl<ArgT> &Args,
247247 SmallVectorImpl<unsigned > &Out) {
248- unsigned CurrentArgIndex = ~0U ;
249- for (unsigned i = 0 , e = Args.size (); i != e; i++) {
250- if (CurrentArgIndex == Args[i].OrigArgIndex ) {
251- Out.back ()++;
248+ unsigned CurrentArgIndex;
249+
250+ if (Args.empty ())
251+ return ;
252+
253+ CurrentArgIndex = Args[0 ].OrigArgIndex ;
254+ Out.push_back (0 );
255+
256+ for (auto &Arg : Args) {
257+ if (CurrentArgIndex == Arg.OrigArgIndex ) {
258+ Out.back () += 1 ;
252259 } else {
253260 Out.push_back (1 );
254- CurrentArgIndex++ ;
261+ CurrentArgIndex = Arg. OrigArgIndex ;
255262 }
256263 }
257264}
@@ -275,7 +282,7 @@ static void AnalyzeArguments(CCState &State,
275282 SmallVectorImpl<CCValAssign> &ArgLocs,
276283 const SmallVectorImpl<ArgT> &Args) {
277284 static const MCPhysReg RegList[] = {
278- MSP430::R15 , MSP430::R14 , MSP430::R13 , MSP430::R12
285+ MSP430::R12 , MSP430::R13 , MSP430::R14 , MSP430::R15
279286 };
280287 static const unsigned NbRegs = array_lengthof (RegList);
281288
@@ -288,7 +295,7 @@ static void AnalyzeArguments(CCState &State,
288295 ParseFunctionArgs (Args, ArgsParts);
289296
290297 unsigned RegsLeft = NbRegs;
291- bool UseStack = false ;
298+ bool UsedStack = false ;
292299 unsigned ValNo = 0 ;
293300
294301 for (unsigned i = 0 , e = ArgsParts.size (); i != e; i++) {
@@ -316,20 +323,22 @@ static void AnalyzeArguments(CCState &State,
316323
317324 unsigned Parts = ArgsParts[i];
318325
319- if (!UseStack && Parts <= RegsLeft) {
320- unsigned FirstVal = ValNo;
326+ if (!UsedStack && Parts == 2 && RegsLeft == 1 ) {
327+ // Special case for 32-bit register split, see EABI section 3.3.3
328+ unsigned Reg = State.AllocateReg (RegList);
329+ State.addLoc (CCValAssign::getReg (ValNo++, ArgVT, Reg, LocVT, LocInfo));
330+ RegsLeft -= 1 ;
331+
332+ UsedStack = true ;
333+ CC_MSP430_AssignStack (ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
334+ } else if (Parts <= RegsLeft) {
321335 for (unsigned j = 0 ; j < Parts; j++) {
322336 unsigned Reg = State.AllocateReg (RegList);
323337 State.addLoc (CCValAssign::getReg (ValNo++, ArgVT, Reg, LocVT, LocInfo));
324338 RegsLeft--;
325339 }
326-
327- // Reverse the order of the pieces to agree with the "big endian" format
328- // required in the calling convention ABI.
329- SmallVectorImpl<CCValAssign>::iterator B = ArgLocs.begin () + FirstVal;
330- std::reverse (B, B + Parts);
331340 } else {
332- UseStack = true ;
341+ UsedStack = true ;
333342 for (unsigned j = 0 ; j < Parts; j++)
334343 CC_MSP430_AssignStack (ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
335344 }
@@ -351,10 +360,6 @@ static void AnalyzeReturnValues(CCState &State,
351360 SmallVectorImpl<CCValAssign> &RVLocs,
352361 const SmallVectorImpl<ArgT> &Args) {
353362 AnalyzeRetResult (State, Args);
354-
355- // Reverse splitted return values to get the "big endian" format required
356- // to agree with the calling convention ABI.
357- std::reverse (RVLocs.begin (), RVLocs.end ());
358363}
359364
360365SDValue MSP430TargetLowering::LowerFormalArguments (
@@ -496,16 +501,42 @@ SDValue MSP430TargetLowering::LowerCCCArguments(
496501 }
497502 }
498503
504+ for (unsigned i = 0 , e = ArgLocs.size (); i != e; ++i) {
505+ if (Ins[i].Flags .isSRet ()) {
506+ unsigned Reg = FuncInfo->getSRetReturnReg ();
507+ if (!Reg) {
508+ Reg = MF.getRegInfo ().createVirtualRegister (
509+ getRegClassFor (MVT::i16 ));
510+ FuncInfo->setSRetReturnReg (Reg);
511+ }
512+ SDValue Copy = DAG.getCopyToReg (DAG.getEntryNode (), dl, Reg, InVals[i]);
513+ Chain = DAG.getNode (ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
514+ }
515+ }
516+
499517 return Chain;
500518}
501519
520+ bool
521+ MSP430TargetLowering::CanLowerReturn (CallingConv::ID CallConv,
522+ MachineFunction &MF,
523+ bool IsVarArg,
524+ const SmallVectorImpl<ISD::OutputArg> &Outs,
525+ LLVMContext &Context) const {
526+ SmallVector<CCValAssign, 16 > RVLocs;
527+ CCState CCInfo (CallConv, IsVarArg, MF, RVLocs, Context);
528+ return CCInfo.CheckReturn (Outs, RetCC_MSP430);
529+ }
530+
502531SDValue
503532MSP430TargetLowering::LowerReturn (SDValue Chain, CallingConv::ID CallConv,
504533 bool isVarArg,
505534 const SmallVectorImpl<ISD::OutputArg> &Outs,
506535 const SmallVectorImpl<SDValue> &OutVals,
507536 const SDLoc &dl, SelectionDAG &DAG) const {
508537
538+ MachineFunction &MF = DAG.getMachineFunction ();
539+
509540 // CCValAssign - represent the assignment of the return value to a location
510541 SmallVector<CCValAssign, 16 > RVLocs;
511542
@@ -537,6 +568,22 @@ MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
537568 RetOps.push_back (DAG.getRegister (VA.getLocReg (), VA.getLocVT ()));
538569 }
539570
571+ if (MF.getFunction ()->hasStructRetAttr ()) {
572+ MSP430MachineFunctionInfo *FuncInfo = MF.getInfo <MSP430MachineFunctionInfo>();
573+ unsigned Reg = FuncInfo->getSRetReturnReg ();
574+
575+ if (!Reg)
576+ llvm_unreachable (" sret virtual register not created in entry block" );
577+
578+ SDValue Val =
579+ DAG.getCopyFromReg (Chain, dl, Reg, getPointerTy (DAG.getDataLayout ()));
580+ unsigned R12 = MSP430::R12;
581+
582+ Chain = DAG.getCopyToReg (Chain, dl, R12, Val, Flag);
583+ Flag = Chain.getValue (1 );
584+ RetOps.push_back (DAG.getRegister (R12, getPointerTy (DAG.getDataLayout ())));
585+ }
586+
540587 unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
541588 MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
542589
0 commit comments