@@ -502,6 +502,25 @@ SDValue LM32TargetLowering::LowerVASTART(SDValue Op,
502
502
// For mips eabi see http://www.cygwin.com/ml/binutils/2003-06/msg00436.html
503
503
// Elements may have been used from SparcTargetLowering::LowerArguments.
504
504
// ===----------------------------------------------------------------------===//
505
+ // / HandleByVal - byval parameters that fit in the remaining registers
506
+ // / will be passed in those, if it doesn't fit, the whole parameter will be
507
+ // / passed on stack and all remaining registers are confiscated.
508
+ void LM32TargetLowering::HandleByVal (CCState *State, unsigned &Size ) const {
509
+ static const unsigned ArgRegList[] = {
510
+ LM32::R1, LM32::R2, LM32::R3, LM32::R4, LM32::R5, LM32::R6, LM32::R7,
511
+ LM32::R8
512
+ };
513
+ unsigned NumWords = (Size + 3 )/4 ;
514
+ unsigned NewSize = 0 ;
515
+ for (unsigned i = 0 ; i < NumWords; ++i) {
516
+ if (!State->AllocateReg (ArgRegList, 8 )) {
517
+ NewSize = NumWords*4 ;
518
+ break ;
519
+ }
520
+ }
521
+ Size = NewSize;
522
+ }
523
+
505
524
// / Monarch call implementation
506
525
// / LowerCall - This hook must be implemented to lower calls into the
507
526
// / the specified DAG. The outgoing arguments to the call are described
@@ -557,11 +576,14 @@ LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
557
576
SmallVector<std::pair<unsigned , SDValue>, 16 > RegsToPass;
558
577
SmallVector<SDValue, 8 > MemOpChains;
559
578
579
+ unsigned ArgRegEnd = LM32::R0;
580
+
560
581
// Walk the register/memloc assignments, inserting copies/loads.
561
582
// This was based on Sparc but the Sparc code has been updated.
562
583
for (unsigned i = 0 , e = ArgLocs.size (); i != e; ++i) {
563
584
CCValAssign &VA = ArgLocs[i];
564
585
SDValue Arg = OutVals[i];
586
+ ISD::ArgFlagsTy Flags = Outs[i].Flags ;
565
587
566
588
// Promote the value if needed.
567
589
switch (VA.getLocInfo ()) {
@@ -581,7 +603,39 @@ LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
581
603
// Arguments that can be passed on register must be kept at
582
604
// RegsToPass vector
583
605
if (VA.isRegLoc ()) {
584
- RegsToPass.push_back (std::make_pair (VA.getLocReg (), Arg));
606
+ ArgRegEnd = VA.getLocReg ();
607
+ RegsToPass.push_back (std::make_pair (ArgRegEnd, Arg));
608
+ } else if (Flags.isByVal ()) {
609
+ unsigned NumWords = (Flags.getByValSize () + 3 )/4 ;
610
+ if (NumWords <= (LM32::R8 - ArgRegEnd)) {
611
+ // Load byval aggregate into argument registers.
612
+ for (unsigned i = 0 ; i < NumWords; ++i) {
613
+ SDValue AddArg = DAG.getNode (ISD::ADD, dl, getPointerTy (), Arg,
614
+ DAG.getConstant (i*4 , MVT::i32));
615
+ SDValue Load = DAG.getLoad (getPointerTy (), dl, Chain, AddArg,
616
+ MachinePointerInfo (),
617
+ false , false , false , 0 );
618
+ MemOpChains.push_back (Load.getValue (1 ));
619
+ RegsToPass.push_back (std::make_pair (++ArgRegEnd, Load));
620
+ }
621
+ continue ;
622
+ }
623
+ // Byval aggregate didn't fit in the argument registers,
624
+ // pass it on the stack.
625
+ SDValue StackPtr = DAG.getCopyFromReg (Chain, dl, LM32::RSP,
626
+ getPointerTy ());
627
+ int Offset = VA.getLocMemOffset ();
628
+ Offset += Subtarget->hasSPBias () ? 4 : 0 ;
629
+ SDValue StackOffset = DAG.getIntPtrConstant (Offset);
630
+ SDValue Dst = DAG.getNode (ISD::ADD, dl, getPointerTy (), StackPtr,
631
+ StackOffset);
632
+ SDValue SizeNode = DAG.getConstant (NumWords*4 , MVT::i32);
633
+ MemOpChains.push_back (DAG.getMemcpy (Chain, dl, Dst, Arg, SizeNode,
634
+ Flags.getByValAlign (),
635
+ /* isVolatile=*/ false ,
636
+ /* AlwaysInline=*/ false ,
637
+ MachinePointerInfo (0 ),
638
+ MachinePointerInfo (0 )));
585
639
} else {
586
640
assert (VA.isMemLoc ());
587
641
@@ -702,6 +756,7 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
702
756
const SmallVectorImpl<ISD::InputArg> &Ins,
703
757
DebugLoc dl, SelectionDAG &DAG,
704
758
SmallVectorImpl<SDValue> &InVals) const {
759
+ SmallVector<SDValue, 8 > OutChains;
705
760
MachineFunction &MF = DAG.getMachineFunction ();
706
761
MachineFrameInfo *MFI = MF.getFrameInfo ();
707
762
LM32FunctionInfo *LM32FI = MF.getInfo <LM32FunctionInfo>();
@@ -721,6 +776,7 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
721
776
722
777
for (unsigned i = 0 , e = ArgLocs.size (); i != e; ++i) {
723
778
CCValAssign &VA = ArgLocs[i];
779
+ ISD::ArgFlagsTy Flags = Ins[i].Flags ;
724
780
725
781
// Arguments stored on registers
726
782
if (VA.isRegLoc ()) {
@@ -760,6 +816,32 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
760
816
}
761
817
762
818
InVals.push_back (ArgValue);
819
+ } else if (Flags.isByVal ()) {
820
+ unsigned NumWords = (Flags.getByValSize () + 3 )/4 ;
821
+ unsigned Size = NumWords*4 ;
822
+ unsigned Align = Flags.getByValAlign ();
823
+ int FI = 0 ;
824
+ if (NumWords <= (LM32::R8 - ArgRegEnd)) {
825
+ // Store the argument registers onto the local stack
826
+ FI = MFI->CreateStackObject (Size , Align, false );
827
+ for (unsigned i = 0 ; i < NumWords; ++i) {
828
+ unsigned LiveReg = MF.addLiveIn (++ArgRegEnd, LM32::GPRRegisterClass);
829
+ SDValue AddArg = DAG.getNode (ISD::ADD, dl, MVT::i32,
830
+ DAG.getFrameIndex (FI, getPointerTy ()),
831
+ DAG.getConstant (i*4 , MVT::i32));
832
+ OutChains.push_back (DAG.getStore (Chain, dl,
833
+ DAG.getRegister (LiveReg, MVT::i32),
834
+ AddArg,
835
+ MachinePointerInfo (),
836
+ false , false , 0 ));
837
+ }
838
+ } else {
839
+ // Byval arguments didn't fit in registers, mark all as occupied.
840
+ ArgRegEnd = LM32::R8;
841
+ nextLocMemOffset = VA.getLocMemOffset () + Size ;
842
+ FI = MFI->CreateFixedObject (Size , VA.getLocMemOffset (), true );
843
+ }
844
+ InVals.push_back (DAG.getFrameIndex (FI, getPointerTy ()));
763
845
} else { // VA.isRegLoc()
764
846
assert (ArgRegEnd == LM32::R8 &&
765
847
" We should have used all argument registers" );
@@ -821,9 +903,6 @@ DEBUG((cast<LoadSDNode>(/* SDNode* */lod.getNode()))->dump());
821
903
DEBUG (errs () << " All varargs on stack getVarArgsFrameIndex() to:" <<
822
904
LM32FI->getVarArgsFrameIndex () << " \n " );
823
905
} else {
824
- // Used to acumulate store chains.
825
- std::vector<SDValue> OutChains;
826
-
827
906
TargetRegisterClass *RC = LM32::GPRRegisterClass;
828
907
829
908
// We'll save all argument registers not already saved on the stack. Store
@@ -851,16 +930,16 @@ DEBUG((cast<LoadSDNode>(/* SDNode* */lod.getNode()))->dump());
851
930
// which is a value necessary to VASTART.
852
931
DEBUG (errs () << " setVarArgsFrameIndex to:" << FI << " \n " );
853
932
LM32FI->setVarArgsFrameIndex (FI);
854
-
855
- // All stores are grouped in one node to allow the matching between
856
- // the size of Ins and InVals. This only happens when on varg functions
857
- if (!OutChains.empty ()) {
858
- OutChains.push_back (Chain);
859
- Chain = DAG.getNode (ISD::TokenFactor, dl, MVT::Other,
860
- &OutChains[0 ], OutChains.size ());
861
- }
862
933
}
863
934
}
935
+ // All stores are grouped in one node to allow the matching between
936
+ // the size of Ins and InVals. This only happens when on varg functions and
937
+ // byval arguments
938
+ if (!OutChains.empty ()) {
939
+ OutChains.push_back (Chain);
940
+ Chain = DAG.getNode (ISD::TokenFactor, dl, MVT::Other,
941
+ &OutChains[0 ], OutChains.size ());
942
+ }
864
943
return Chain;
865
944
}
866
945
0 commit comments