@@ -245,13 +245,20 @@ MSP430TargetLowering::getRegForInlineAsmConstraint(
245
245
template <typename ArgT>
246
246
static void ParseFunctionArgs (const SmallVectorImpl<ArgT> &Args,
247
247
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 ;
252
259
} else {
253
260
Out.push_back (1 );
254
- CurrentArgIndex++ ;
261
+ CurrentArgIndex = Arg. OrigArgIndex ;
255
262
}
256
263
}
257
264
}
@@ -275,7 +282,7 @@ static void AnalyzeArguments(CCState &State,
275
282
SmallVectorImpl<CCValAssign> &ArgLocs,
276
283
const SmallVectorImpl<ArgT> &Args) {
277
284
static const MCPhysReg RegList[] = {
278
- MSP430::R15 , MSP430::R14 , MSP430::R13 , MSP430::R12
285
+ MSP430::R12 , MSP430::R13 , MSP430::R14 , MSP430::R15
279
286
};
280
287
static const unsigned NbRegs = array_lengthof (RegList);
281
288
@@ -288,7 +295,7 @@ static void AnalyzeArguments(CCState &State,
288
295
ParseFunctionArgs (Args, ArgsParts);
289
296
290
297
unsigned RegsLeft = NbRegs;
291
- bool UseStack = false ;
298
+ bool UsedStack = false ;
292
299
unsigned ValNo = 0 ;
293
300
294
301
for (unsigned i = 0 , e = ArgsParts.size (); i != e; i++) {
@@ -316,20 +323,22 @@ static void AnalyzeArguments(CCState &State,
316
323
317
324
unsigned Parts = ArgsParts[i];
318
325
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) {
321
335
for (unsigned j = 0 ; j < Parts; j++) {
322
336
unsigned Reg = State.AllocateReg (RegList);
323
337
State.addLoc (CCValAssign::getReg (ValNo++, ArgVT, Reg, LocVT, LocInfo));
324
338
RegsLeft--;
325
339
}
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);
331
340
} else {
332
- UseStack = true ;
341
+ UsedStack = true ;
333
342
for (unsigned j = 0 ; j < Parts; j++)
334
343
CC_MSP430_AssignStack (ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
335
344
}
@@ -351,10 +360,6 @@ static void AnalyzeReturnValues(CCState &State,
351
360
SmallVectorImpl<CCValAssign> &RVLocs,
352
361
const SmallVectorImpl<ArgT> &Args) {
353
362
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 ());
358
363
}
359
364
360
365
SDValue MSP430TargetLowering::LowerFormalArguments (
@@ -496,16 +501,42 @@ SDValue MSP430TargetLowering::LowerCCCArguments(
496
501
}
497
502
}
498
503
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
+
499
517
return Chain;
500
518
}
501
519
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
+
502
531
SDValue
503
532
MSP430TargetLowering::LowerReturn (SDValue Chain, CallingConv::ID CallConv,
504
533
bool isVarArg,
505
534
const SmallVectorImpl<ISD::OutputArg> &Outs,
506
535
const SmallVectorImpl<SDValue> &OutVals,
507
536
const SDLoc &dl, SelectionDAG &DAG) const {
508
537
538
+ MachineFunction &MF = DAG.getMachineFunction ();
539
+
509
540
// CCValAssign - represent the assignment of the return value to a location
510
541
SmallVector<CCValAssign, 16 > RVLocs;
511
542
@@ -537,6 +568,22 @@ MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
537
568
RetOps.push_back (DAG.getRegister (VA.getLocReg (), VA.getLocVT ()));
538
569
}
539
570
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
+
540
587
unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
541
588
MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
542
589
0 commit comments