@@ -246,13 +246,20 @@ MSP430TargetLowering::getRegForInlineAsmConstraint(
246246template <typename ArgT>
247247static void ParseFunctionArgs (const SmallVectorImpl<ArgT> &Args,
248248 SmallVectorImpl<unsigned > &Out) {
249- unsigned CurrentArgIndex = ~0U ;
250- for (unsigned i = 0 , e = Args.size (); i != e; i++) {
251- if (CurrentArgIndex == Args[i].OrigArgIndex ) {
252- Out.back ()++;
249+ unsigned CurrentArgIndex;
250+
251+ if (Args.empty ())
252+ return ;
253+
254+ CurrentArgIndex = Args[0 ].OrigArgIndex ;
255+ Out.push_back (0 );
256+
257+ for (auto &Arg : Args) {
258+ if (CurrentArgIndex == Arg.OrigArgIndex ) {
259+ Out.back () += 1 ;
253260 } else {
254261 Out.push_back (1 );
255- CurrentArgIndex++ ;
262+ CurrentArgIndex = Arg. OrigArgIndex ;
256263 }
257264 }
258265}
@@ -276,7 +283,7 @@ static void AnalyzeArguments(CCState &State,
276283 SmallVectorImpl<CCValAssign> &ArgLocs,
277284 const SmallVectorImpl<ArgT> &Args) {
278285 static const MCPhysReg RegList[] = {
279- MSP430::R15 , MSP430::R14 , MSP430::R13 , MSP430::R12
286+ MSP430::R12 , MSP430::R13 , MSP430::R14 , MSP430::R15
280287 };
281288 static const unsigned NbRegs = array_lengthof (RegList);
282289
@@ -289,7 +296,7 @@ static void AnalyzeArguments(CCState &State,
289296 ParseFunctionArgs (Args, ArgsParts);
290297
291298 unsigned RegsLeft = NbRegs;
292- bool UseStack = false ;
299+ bool UsedStack = false ;
293300 unsigned ValNo = 0 ;
294301
295302 for (unsigned i = 0 , e = ArgsParts.size (); i != e; i++) {
@@ -317,20 +324,22 @@ static void AnalyzeArguments(CCState &State,
317324
318325 unsigned Parts = ArgsParts[i];
319326
320- if (!UseStack && Parts <= RegsLeft) {
321- unsigned FirstVal = ValNo;
327+ if (!UsedStack && Parts == 2 && RegsLeft == 1 ) {
328+ // Special case for 32-bit register split, see EABI section 3.3.3
329+ unsigned Reg = State.AllocateReg (RegList);
330+ State.addLoc (CCValAssign::getReg (ValNo++, ArgVT, Reg, LocVT, LocInfo));
331+ RegsLeft -= 1 ;
332+
333+ UsedStack = true ;
334+ CC_MSP430_AssignStack (ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
335+ } else if (Parts <= RegsLeft) {
322336 for (unsigned j = 0 ; j < Parts; j++) {
323337 unsigned Reg = State.AllocateReg (RegList);
324338 State.addLoc (CCValAssign::getReg (ValNo++, ArgVT, Reg, LocVT, LocInfo));
325339 RegsLeft--;
326340 }
327-
328- // Reverse the order of the pieces to agree with the "big endian" format
329- // required in the calling convention ABI.
330- SmallVectorImpl<CCValAssign>::iterator B = ArgLocs.begin () + FirstVal;
331- std::reverse (B, B + Parts);
332341 } else {
333- UseStack = true ;
342+ UsedStack = true ;
334343 for (unsigned j = 0 ; j < Parts; j++)
335344 CC_MSP430_AssignStack (ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
336345 }
@@ -352,10 +361,6 @@ static void AnalyzeReturnValues(CCState &State,
352361 SmallVectorImpl<CCValAssign> &RVLocs,
353362 const SmallVectorImpl<ArgT> &Args) {
354363 AnalyzeRetResult (State, Args);
355-
356- // Reverse splitted return values to get the "big endian" format required
357- // to agree with the calling convention ABI.
358- std::reverse (RVLocs.begin (), RVLocs.end ());
359364}
360365
361366SDValue MSP430TargetLowering::LowerFormalArguments (
@@ -497,16 +502,42 @@ SDValue MSP430TargetLowering::LowerCCCArguments(
497502 }
498503 }
499504
505+ for (unsigned i = 0 , e = ArgLocs.size (); i != e; ++i) {
506+ if (Ins[i].Flags .isSRet ()) {
507+ unsigned Reg = FuncInfo->getSRetReturnReg ();
508+ if (!Reg) {
509+ Reg = MF.getRegInfo ().createVirtualRegister (
510+ getRegClassFor (MVT::i16 ));
511+ FuncInfo->setSRetReturnReg (Reg);
512+ }
513+ SDValue Copy = DAG.getCopyToReg (DAG.getEntryNode (), dl, Reg, InVals[i]);
514+ Chain = DAG.getNode (ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
515+ }
516+ }
517+
500518 return Chain;
501519}
502520
521+ bool
522+ MSP430TargetLowering::CanLowerReturn (CallingConv::ID CallConv,
523+ MachineFunction &MF,
524+ bool IsVarArg,
525+ const SmallVectorImpl<ISD::OutputArg> &Outs,
526+ LLVMContext &Context) const {
527+ SmallVector<CCValAssign, 16 > RVLocs;
528+ CCState CCInfo (CallConv, IsVarArg, MF, RVLocs, Context);
529+ return CCInfo.CheckReturn (Outs, RetCC_MSP430);
530+ }
531+
503532SDValue
504533MSP430TargetLowering::LowerReturn (SDValue Chain, CallingConv::ID CallConv,
505534 bool isVarArg,
506535 const SmallVectorImpl<ISD::OutputArg> &Outs,
507536 const SmallVectorImpl<SDValue> &OutVals,
508537 const SDLoc &dl, SelectionDAG &DAG) const {
509538
539+ MachineFunction &MF = DAG.getMachineFunction ();
540+
510541 // CCValAssign - represent the assignment of the return value to a location
511542 SmallVector<CCValAssign, 16 > RVLocs;
512543
@@ -538,6 +569,22 @@ MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
538569 RetOps.push_back (DAG.getRegister (VA.getLocReg (), VA.getLocVT ()));
539570 }
540571
572+ if (MF.getFunction ()->hasStructRetAttr ()) {
573+ MSP430MachineFunctionInfo *FuncInfo = MF.getInfo <MSP430MachineFunctionInfo>();
574+ unsigned Reg = FuncInfo->getSRetReturnReg ();
575+
576+ if (!Reg)
577+ llvm_unreachable (" sret virtual register not created in entry block" );
578+
579+ SDValue Val =
580+ DAG.getCopyFromReg (Chain, dl, Reg, getPointerTy (DAG.getDataLayout ()));
581+ unsigned R12 = MSP430::R12;
582+
583+ Chain = DAG.getCopyToReg (Chain, dl, R12, Val, Flag);
584+ Flag = Chain.getValue (1 );
585+ RetOps.push_back (DAG.getRegister (R12, getPointerTy (DAG.getDataLayout ())));
586+ }
587+
541588 unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
542589 MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
543590
0 commit comments