@@ -177,6 +177,7 @@ enum class SpillArea {
177177 GPRCS2,
178178 DPRCS1,
179179 DPRCS2,
180+ GPRCS3,
180181 FPCXT,
181182};
182183
@@ -197,7 +198,7 @@ SpillArea getSpillArea(Register Reg,
197198 // SplitR11WindowsSEH:
198199 // push {r0-r10, r12} GPRCS1
199200 // vpush {r8-d15} DPRCS1
200- // push {r11, lr} GPRCS2
201+ // push {r11, lr} GPRCS3
201202 //
202203 // SplitR11AAPCSSignRA:
203204 // push {r0-r10, r12} GPRSC1
@@ -238,10 +239,13 @@ SpillArea getSpillArea(Register Reg,
238239 return SpillArea::GPRCS1;
239240
240241 case ARM::R11:
241- if (Variation == ARMSubtarget::NoSplit)
242- return SpillArea::GPRCS1;
243- else
242+ if (Variation == ARMSubtarget::SplitR7 ||
243+ Variation == ARMSubtarget::SplitR11AAPCSSignRA)
244244 return SpillArea::GPRCS2;
245+ if (Variation == ARMSubtarget::SplitR11WindowsSEH)
246+ return SpillArea::GPRCS3;
247+
248+ return SpillArea::GPRCS1;
245249
246250 case ARM::R12:
247251 if (Variation == ARMSubtarget::SplitR7)
@@ -250,11 +254,12 @@ SpillArea getSpillArea(Register Reg,
250254 return SpillArea::GPRCS1;
251255
252256 case ARM::LR:
253- if (Variation == ARMSubtarget::SplitR11WindowsSEH ||
254- Variation == ARMSubtarget::SplitR11AAPCSSignRA)
257+ if (Variation == ARMSubtarget::SplitR11AAPCSSignRA)
255258 return SpillArea::GPRCS2;
256- else
257- return SpillArea::GPRCS1;
259+ if (Variation == ARMSubtarget::SplitR11WindowsSEH)
260+ return SpillArea::GPRCS3;
261+
262+ return SpillArea::GPRCS1;
258263
259264 case ARM::D0:
260265 case ARM::D1:
@@ -912,7 +917,8 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
912917
913918 // Determine the sizes of each callee-save spill areas and record which frame
914919 // belongs to which callee-save spill areas.
915- unsigned GPRCS1Size = 0 , GPRCS2Size = 0 , DPRCSSize = 0 ;
920+ unsigned GPRCS1Size = 0 , GPRCS2Size = 0 , DPRCS1Size = 0 , GPRCS3Size = 0 ,
921+ DPRCS2Size = 0 ;
916922 int FramePtrSpillFI = 0 ;
917923 int D8SpillFI = 0 ;
918924
@@ -970,14 +976,19 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
970976 GPRCS2Size += 4 ;
971977 break ;
972978 case SpillArea::DPRCS1:
973- DPRCSSize += 8 ;
979+ DPRCS1Size += 8 ;
980+ break ;
981+ case SpillArea::GPRCS3:
982+ GPRCS3Size += 4 ;
974983 break ;
975984 case SpillArea::DPRCS2:
985+ DPRCS2Size += 4 ;
976986 break ;
977987 }
978988 }
979989
980- MachineBasicBlock::iterator LastPush = MBB.end (), GPRCS1Push, GPRCS2Push;
990+ MachineBasicBlock::iterator LastPush = MBB.end (), GPRCS1Push, GPRCS2Push,
991+ DPRCS1Push, GPRCS3Push;
981992
982993 // Move past the PAC computation.
983994 if (AFI->shouldSignReturnAddress ())
@@ -1012,20 +1023,14 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
10121023 unsigned FPCXTOffset = NumBytes - ArgRegsSaveSize - FPCXTSaveSize;
10131024 unsigned GPRCS1Offset = FPCXTOffset - GPRCS1Size;
10141025 unsigned GPRCS2Offset = GPRCS1Offset - GPRCS2Size;
1015- Align DPRAlign = DPRCSSize ? std::min (Align (8 ), Alignment) : Align (4 );
1016- unsigned DPRGapSize = GPRCS1Size + FPCXTSaveSize + ArgRegsSaveSize;
1017- if (PushPopSplit != ARMSubtarget::SplitR11WindowsSEH) {
1018- DPRGapSize += GPRCS2Size;
1019- }
1020- DPRGapSize %= DPRAlign.value ();
10211026
1022- unsigned DPRCSOffset ;
1023- if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
1024- DPRCSOffset = GPRCS1Offset - DPRGapSize - DPRCSSize;
1025- GPRCS2Offset = DPRCSOffset - GPRCS2Size ;
1026- } else {
1027- DPRCSOffset = GPRCS2Offset - DPRGapSize - DPRCSSize ;
1028- }
1027+ Align DPRAlign = DPRCS1Size ? std::min ( Align ( 8 ), Alignment) : Align ( 4 ) ;
1028+ unsigned DPRGapSize =
1029+ (ArgRegsSaveSize + FPCXTSaveSize + GPRCS1Size + GPRCS2Size) %
1030+ DPRAlign. value () ;
1031+
1032+ unsigned DPRCS1Offset = GPRCS2Offset - DPRGapSize - DPRCS1Size ;
1033+
10291034 if (HasFP) {
10301035 // Offset from the CFA to the saved frame pointer, will be negative.
10311036 [[maybe_unused]] int FPOffset = MFI.getObjectOffset (FramePtrSpillFI);
@@ -1038,11 +1043,11 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
10381043 }
10391044 AFI->setGPRCalleeSavedArea1Offset (GPRCS1Offset);
10401045 AFI->setGPRCalleeSavedArea2Offset (GPRCS2Offset);
1041- AFI->setDPRCalleeSavedAreaOffset (DPRCSOffset );
1046+ AFI->setDPRCalleeSavedArea1Offset (DPRCS1Offset );
10421047
1043- // Move GPRCS2, unless using SplitR11WindowsSEH, in which case it will be
1044- // after DPRCS1.
1045- if (GPRCS2Size > 0 && PushPopSplit != ARMSubtarget::SplitR11WindowsSEH) {
1048+ // Move past area 2.
1049+ if (GPRCS2Size > 0 ) {
1050+ assert ( PushPopSplit != ARMSubtarget::SplitR11WindowsSEH);
10461051 GPRCS2Push = LastPush = MBBI++;
10471052 DefCFAOffsetCandidates.addInst (LastPush, GPRCS2Size, BeforeFPPush);
10481053 if (FramePtrSpillArea == SpillArea::GPRCS2)
@@ -1063,33 +1068,34 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
10631068 }
10641069 }
10651070
1066- // Move past DPRCS1 .
1067- if (DPRCSSize > 0 ) {
1071+ // Move past DPRCS1Size .
1072+ if (DPRCS1Size > 0 ) {
10681073 // Since vpush register list cannot have gaps, there may be multiple vpush
10691074 // instructions in the prologue.
10701075 while (MBBI != MBB.end () && MBBI->getOpcode () == ARM::VSTMDDB_UPD) {
10711076 DefCFAOffsetCandidates.addInst (MBBI, sizeOfSPAdjustment (*MBBI),
10721077 BeforeFPPush);
1073- LastPush = MBBI++;
1078+ DPRCS1Push = LastPush = MBBI++;
10741079 }
10751080 }
10761081
10771082 // Move past the aligned DPRCS2 area.
1078- if (AFI-> getNumAlignedDPRCS2Regs () > 0 ) {
1083+ if (DPRCS2Size > 0 ) {
10791084 MBBI = skipAlignedDPRCS2Spills (MBBI, AFI->getNumAlignedDPRCS2Regs ());
10801085 // The code inserted by emitAlignedDPRCS2Spills realigns the stack, and
10811086 // leaves the stack pointer pointing to the DPRCS2 area.
10821087 //
10831088 // Adjust NumBytes to represent the stack slots below the DPRCS2 area.
10841089 NumBytes += MFI.getObjectOffset (D8SpillFI);
10851090 } else
1086- NumBytes = DPRCSOffset;
1087-
1088- // Move GPRCS2, if using using SplitR11WindowsSEH.
1089- if (GPRCS2Size > 0 && PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
1090- GPRCS2Push = LastPush = MBBI++;
1091- DefCFAOffsetCandidates.addInst (LastPush, GPRCS2Size, BeforeFPPush);
1092- if (FramePtrSpillArea == SpillArea::GPRCS2)
1091+ NumBytes = DPRCS1Offset;
1092+
1093+ // Move GPRCS3, if using using SplitR11WindowsSEH.
1094+ if (GPRCS3Size > 0 ) {
1095+ assert (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH);
1096+ GPRCS3Push = LastPush = MBBI++;
1097+ DefCFAOffsetCandidates.addInst (LastPush, GPRCS3Size, BeforeFPPush);
1098+ if (FramePtrSpillArea == SpillArea::GPRCS3)
10931099 BeforeFPPush = false ;
10941100 }
10951101
@@ -1211,11 +1217,18 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
12111217 FPOffsetAfterPush = MFI.getObjectOffset (FramePtrSpillFI) +
12121218 ArgRegsSaveSize + FPCXTSaveSize + GPRCS1Size +
12131219 sizeOfSPAdjustment (*FPPushInst);
1214- if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH)
1215- FPOffsetAfterPush += DPRCSSize + DPRGapSize;
12161220 LLVM_DEBUG (dbgs () << " Frame pointer in GPRCS2, offset "
12171221 << FPOffsetAfterPush << " after that push\n " );
12181222 break ;
1223+ case SpillArea::GPRCS3:
1224+ FPPushInst = GPRCS3Push;
1225+ FPOffsetAfterPush = MFI.getObjectOffset (FramePtrSpillFI) +
1226+ ArgRegsSaveSize + FPCXTSaveSize + GPRCS1Size +
1227+ GPRCS2Size + DPRCS1Size + DPRGapSize +
1228+ sizeOfSPAdjustment (*FPPushInst);
1229+ LLVM_DEBUG (dbgs () << " Frame pointer in GPRCS3, offset "
1230+ << FPOffsetAfterPush << " after that push\n " );
1231+ break ;
12191232 default :
12201233 llvm_unreachable (" frame pointer in unknown spill area" );
12211234 break ;
@@ -1279,7 +1292,10 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
12791292 CFIPos = std::next (GPRCS2Push);
12801293 break ;
12811294 case SpillArea::DPRCS1:
1282- CFIPos = std::next (LastPush);
1295+ CFIPos = std::next (DPRCS1Push);
1296+ break ;
1297+ case SpillArea::GPRCS3:
1298+ CFIPos = std::next (GPRCS3Push);
12831299 break ;
12841300 case SpillArea::FPCXT:
12851301 case SpillArea::DPRCS2:
@@ -1317,7 +1333,8 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
13171333 AFI->setGPRCalleeSavedArea1Size (GPRCS1Size);
13181334 AFI->setGPRCalleeSavedArea2Size (GPRCS2Size);
13191335 AFI->setDPRCalleeSavedGapSize (DPRGapSize);
1320- AFI->setDPRCalleeSavedAreaSize (DPRCSSize);
1336+ AFI->setDPRCalleeSavedArea1Size (DPRCS1Size);
1337+ AFI->setGPRCalleeSavedArea3Size (GPRCS3Size);
13211338
13221339 // If we need dynamic stack realignment, do it here. Be paranoid and make
13231340 // sure if we also have VLAs, we have a base pointer for frame access.
@@ -1438,12 +1455,11 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
14381455 }
14391456
14401457 // Move SP to start of FP callee save spill area.
1441- NumBytes -= (ReservedArgStack +
1442- AFI->getFPCXTSaveAreaSize () +
1443- AFI->getGPRCalleeSavedArea1Size () +
1444- AFI->getGPRCalleeSavedArea2Size () +
1445- AFI->getDPRCalleeSavedGapSize () +
1446- AFI->getDPRCalleeSavedAreaSize ());
1458+ NumBytes -=
1459+ (ReservedArgStack + AFI->getFPCXTSaveAreaSize () +
1460+ AFI->getGPRCalleeSavedArea1Size () + AFI->getGPRCalleeSavedArea2Size () +
1461+ AFI->getDPRCalleeSavedGapSize () + AFI->getDPRCalleeSavedArea1Size () +
1462+ AFI->getGPRCalleeSavedArea3Size ());
14471463
14481464 // Reset SP based on frame pointer only if the stack frame extends beyond
14491465 // frame pointer stack slot or target is ELF and the function has FP.
@@ -1491,11 +1507,12 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
14911507 MachineInstr::FrameDestroy);
14921508
14931509 // Increment past our save areas.
1494- if (AFI->getGPRCalleeSavedArea2Size () &&
1495- PushPopSplit == ARMSubtarget::SplitR11WindowsSEH)
1510+ if (AFI->getGPRCalleeSavedArea3Size ()) {
1511+ assert ( PushPopSplit == ARMSubtarget::SplitR11WindowsSEH);
14961512 MBBI++;
1513+ }
14971514
1498- if (MBBI != MBB.end () && AFI->getDPRCalleeSavedAreaSize ()) {
1515+ if (MBBI != MBB.end () && AFI->getDPRCalleeSavedArea1Size ()) {
14991516 MBBI++;
15001517 // Since vpop register list cannot have gaps, there may be multiple vpop
15011518 // instructions in the epilogue.
@@ -1509,9 +1526,10 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
15091526 MachineInstr::FrameDestroy);
15101527 }
15111528
1512- if (AFI->getGPRCalleeSavedArea2Size () &&
1513- PushPopSplit != ARMSubtarget::SplitR11WindowsSEH)
1529+ if (AFI->getGPRCalleeSavedArea2Size ()) {
1530+ assert ( PushPopSplit != ARMSubtarget::SplitR11WindowsSEH);
15141531 MBBI++;
1532+ }
15151533 if (AFI->getGPRCalleeSavedArea1Size ()) MBBI++;
15161534
15171535 if (ReservedArgStack || IncomingArgStackToRestore) {
@@ -2128,19 +2146,14 @@ bool ARMFrameLowering::spillCalleeSavedRegisters(
21282146 auto IsDPRCS1 = [&CheckRegArea](unsigned Reg) {
21292147 return CheckRegArea (Reg, SpillArea::DPRCS1);
21302148 };
2149+ auto IsGPRCS3 = [&CheckRegArea](unsigned Reg) {
2150+ return CheckRegArea (Reg, SpillArea::GPRCS3);
2151+ };
21312152
2132- // Windows SEH requires the floating-point registers to be pushed between the
2133- // two blocks of GPRs in some situations. In all other cases, they are pushed
2134- // below the GPRs.
2135- if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
2136- emitPushInst (MBB, MI, CSI, PushOpc, PushOneOpc, false , IsGPRCS1);
2137- emitPushInst (MBB, MI, CSI, FltOpc, 0 , true , IsDPRCS1);
2138- emitPushInst (MBB, MI, CSI, PushOpc, PushOneOpc, false , IsGPRCS2);
2139- } else {
2140- emitPushInst (MBB, MI, CSI, PushOpc, PushOneOpc, false , IsGPRCS1);
2141- emitPushInst (MBB, MI, CSI, PushOpc, PushOneOpc, false , IsGPRCS2);
2142- emitPushInst (MBB, MI, CSI, FltOpc, 0 , true , IsDPRCS1);
2143- }
2153+ emitPushInst (MBB, MI, CSI, PushOpc, PushOneOpc, false , IsGPRCS1);
2154+ emitPushInst (MBB, MI, CSI, PushOpc, PushOneOpc, false , IsGPRCS2);
2155+ emitPushInst (MBB, MI, CSI, FltOpc, 0 , true , IsDPRCS1);
2156+ emitPushInst (MBB, MI, CSI, PushOpc, PushOneOpc, false , IsGPRCS3);
21442157
21452158 // The code above does not insert spill code for the aligned DPRCS2 registers.
21462159 // The stack realignment code will be inserted between the push instructions
@@ -2190,16 +2203,14 @@ bool ARMFrameLowering::restoreCalleeSavedRegisters(
21902203 auto IsDPRCS1 = [&CheckRegArea](unsigned Reg) {
21912204 return CheckRegArea (Reg, SpillArea::DPRCS1);
21922205 };
2206+ auto IsGPRCS3 = [&CheckRegArea](unsigned Reg) {
2207+ return CheckRegArea (Reg, SpillArea::GPRCS3);
2208+ };
21932209
2194- if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
2195- emitPopInst (MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false , IsGPRCS2);
2196- emitPopInst (MBB, MI, CSI, FltOpc, 0 , isVarArg, true , IsDPRCS1);
2197- emitPopInst (MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false , IsGPRCS1);
2198- } else {
2199- emitPopInst (MBB, MI, CSI, FltOpc, 0 , isVarArg, true , IsDPRCS1);
2200- emitPopInst (MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false , IsGPRCS2);
2201- emitPopInst (MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false , IsGPRCS1);
2202- }
2210+ emitPopInst (MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false , IsGPRCS3);
2211+ emitPopInst (MBB, MI, CSI, FltOpc, 0 , isVarArg, true , IsDPRCS1);
2212+ emitPopInst (MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false , IsGPRCS2);
2213+ emitPopInst (MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false , IsGPRCS1);
22032214
22042215 return true ;
22052216}
0 commit comments