@@ -432,19 +432,61 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF,
432432 MachineModuleInfo &MMI = MF.getMMI ();
433433 const MCRegisterInfo *MRI = MMI.getContext ().getRegisterInfo ();
434434
435- // Adjust stack.
436- TII.adjustStackPtr (SP, -StackSize, MBB, MBBI);
435+ const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo ();
436+
437+ int64_t CalleeSavedStackSize;
438+ int64_t LoaclStackSize;
439+ // If we have two-step stack setup MBBI_2 will point to the
440+ // first instruction after calle-saves store sequence
441+ MachineBasicBlock::iterator MBBI_2 = MBBI;
442+
443+ if (MipsFI->isTwoStepStackSetup (MF)) {
444+
445+ CalleeSavedStackSize = MipsFI->getCalleeSavedStackSize ();
446+ unsigned NumOfCSI = MFI.getCalleeSavedInfo ().size ();
447+
448+ // Move MBBI_2 to point to the first instruction after
449+ // calle-saves store sequence. That's the place for the second
450+ // steck pointer adjustment.
451+ std::advance (MBBI_2, NumOfCSI);
452+
453+ // The first stack pointer adjustment to cover space needed
454+ // to spill callee-saved registers on stack.
455+ TII.adjustStackPtr (SP, -CalleeSavedStackSize, MBB, MBBI);
456+
457+ LoaclStackSize = StackSize - CalleeSavedStackSize;
437458
438- // emit ".cfi_def_cfa_offset StackSize"
439- unsigned CFIIndex =
440- MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , StackSize));
441- BuildMI (MBB, MBBI, dl, TII.get (TargetOpcode::CFI_INSTRUCTION))
442- .addCFIIndex (CFIIndex);
459+ // The second stack pointer adjustment to cover space needed
460+ // to spill local objects on stack.
461+ TII.adjustStackPtr (SP, -LoaclStackSize, MBB, MBBI_2);
462+
463+ } else
464+ // Adjust stack.
465+ TII.adjustStackPtr (SP, -StackSize, MBB, MBBI);
466+
467+ if (MipsFI->isTwoStepStackSetup (MF)) {
468+ // emit ".cfi_def_cfa_offset CalleeSavedStackSize"
469+ // emit ".cfi_def_cfa_offset StackSize = CalleeSavedStackSize +
470+ // LoaclStackSize"
471+ unsigned CFIIndex_1 = MF.addFrameInst (
472+ MCCFIInstruction::cfiDefCfaOffset (nullptr , CalleeSavedStackSize));
473+ unsigned CFIIndex_2 =
474+ MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , StackSize));
475+ BuildMI (MBB, MBBI, dl, TII.get (TargetOpcode::CFI_INSTRUCTION))
476+ .addCFIIndex (CFIIndex_1);
477+ BuildMI (MBB, MBBI_2, dl, TII.get (TargetOpcode::CFI_INSTRUCTION))
478+ .addCFIIndex (CFIIndex_2);
479+ } else {
480+ // emit ".cfi_def_cfa_offset StackSize"
481+ unsigned CFIIndex =
482+ MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , StackSize));
483+ BuildMI (MBB, MBBI, dl, TII.get (TargetOpcode::CFI_INSTRUCTION))
484+ .addCFIIndex (CFIIndex);
485+ }
443486
444487 if (MF.getFunction ().hasFnAttribute (" interrupt" ))
445488 emitInterruptPrologueStub (MF, MBB);
446489
447- const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo ();
448490
449491 if (!CSI.empty ()) {
450492 // Find the instruction past the last instruction that saves a callee-saved
@@ -531,6 +573,14 @@ void MipsSEFrameLowering::emitPrologue(MachineFunction &MF,
531573 BuildMI (MBB, MBBI, dl, TII.get (MOVE), FP).addReg (SP).addReg (ZERO)
532574 .setMIFlag (MachineInstr::FrameSetup);
533575
576+ if (MipsFI->isTwoStepStackSetup (MF))
577+ // If we have two-step stack setup insert instruction "move $fp, $sp"
578+ // after the second stack setup also
579+ BuildMI (MBB, MBBI_2, dl, TII.get (MOVE), FP)
580+ .addReg (SP)
581+ .addReg (ZERO)
582+ .setMIFlag (MachineInstr::FrameSetup);
583+
534584 // emit ".cfi_def_cfa_register $fp"
535585 unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::createDefCfaRegister (
536586 nullptr , MRI->getDwarfRegNum (FP, true )));
@@ -747,8 +797,26 @@ void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF,
747797 if (!StackSize)
748798 return ;
749799
750- // Adjust stack.
751- TII.adjustStackPtr (SP, StackSize, MBB, MBBI);
800+ if (MipsFI->isTwoStepStackSetup (MF)) {
801+
802+ int64_t CalleeSavedStackSize = MipsFI->getCalleeSavedStackSize ();
803+ int64_t LoaclStackSize = StackSize - CalleeSavedStackSize;
804+
805+ int64_t NumOfCSI = MFI.getCalleeSavedInfo ().size ();
806+
807+ MachineBasicBlock::iterator MBBI_2 = MBBI;
808+ // Move MBBI_2 to point to the first instruction in
809+ // calle-saved load sequence. That's the place where we
810+ // need to undo the second stack adjustment
811+ std::advance (MBBI_2, (-1 ) * NumOfCSI);
812+
813+ // Undo the second stack pointer adjustment
814+ TII.adjustStackPtr (SP, LoaclStackSize, MBB, MBBI_2);
815+ // Undo the first stack pointer adjustment
816+ TII.adjustStackPtr (SP, CalleeSavedStackSize, MBB, MBBI);
817+ } else
818+ // Adjust stack.
819+ TII.adjustStackPtr (SP, StackSize, MBB, MBBI);
752820}
753821
754822void MipsSEFrameLowering::emitInterruptEpilogueStub (
@@ -957,25 +1025,38 @@ bool MipsSEFrameLowering::assignCalleeSavedSpillSlots(
9571025 return Regs.at (First.getReg ()) < Regs.at (Second.getReg ());
9581026 };
9591027
960- // If CSI list has less than two callee-saved registers we can
961- // return from method since no insertions nor sorting is needed
962- if (CSI.size () < 2 )
963- return false ;
1028+ // If CSI list has less than two callee-saved registers
1029+ // no insertions nor sorting is needed
1030+ if (CSI.size () >= 2 ) {
1031+
1032+ SmallBitVector CSNumBitVector (11 );
1033+ for (CalleeSavedInfo &CS : CSI)
1034+ CSNumBitVector.set (Regs.at (CS.getReg ()));
9641035
965- SmallBitVector CSNumBitVector (11 );
966- for (CalleeSavedInfo &CS : CSI)
967- CSNumBitVector.set (Regs.at (CS.getReg ()));
1036+ int MinCSNum = CSNumBitVector.find_first ();
1037+ int MaxCSNum = CSNumBitVector.find_last ();
9681038
969- int MinCSNum = CSNumBitVector.find_first ();
970- int MaxCSNum = CSNumBitVector.find_last ();
1039+ // Inserting all of the missing callee-saved registers between min and max
1040+ // in order to allow further load-store optimizations
1041+ for (int i = MinCSNum + 1 ; i < MaxCSNum; ++i)
1042+ if (!CSNumBitVector.test (i))
1043+ CSI.push_back (CalleeSavedInfo (CSNumToReg.at (i)));
1044+
1045+ std::sort (CSI.begin (), CSI.end (), CompareCalleeSaves);
1046+ }
9711047
972- // Inserting all of the missing callee-saved registers between min and max
973- // in order to allow further load-store optimizations
974- for (int i = MinCSNum + 1 ; i < MaxCSNum; ++i)
975- if (!CSNumBitVector.test (i))
976- CSI.push_back (CalleeSavedInfo (CSNumToReg.at (i)));
1048+ MipsFunctionInfo *MipsFI = MF.getInfo <MipsFunctionInfo>();
1049+ const MachineRegisterInfo &MRI = MF.getRegInfo ();
1050+
1051+ unsigned CalleeSavedOffsetSize = 0 ;
1052+ for (CalleeSavedInfo &CS : CSI) {
1053+ Register Reg = CS.getReg ();
1054+ auto RegSize = TRI->getRegSizeInBits (Reg, MRI) / 8 ;
1055+ CalleeSavedOffsetSize += RegSize;
1056+ }
1057+ uint64_t AlignedCSStackSize = alignTo (CalleeSavedOffsetSize, 16 );
1058+ MipsFI->setCalleeSavedStackSize (AlignedCSStackSize);
9771059
978- std::sort (CSI.begin (), CSI.end (), CompareCalleeSaves);
9791060 return false ;
9801061}
9811062
0 commit comments