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