@@ -177,6 +177,7 @@ enum class SpillArea {
177
177
GPRCS2,
178
178
DPRCS1,
179
179
DPRCS2,
180
+ GPRCS3,
180
181
FPCXT,
181
182
};
182
183
@@ -197,7 +198,7 @@ SpillArea getSpillArea(Register Reg,
197
198
// SplitR11WindowsSEH:
198
199
// push {r0-r10, r12} GPRCS1
199
200
// vpush {r8-d15} DPRCS1
200
- // push {r11, lr} GPRCS2
201
+ // push {r11, lr} GPRCS3
201
202
//
202
203
// SplitR11AAPCSSignRA:
203
204
// push {r0-r10, r12} GPRSC1
@@ -238,10 +239,13 @@ SpillArea getSpillArea(Register Reg,
238
239
return SpillArea::GPRCS1;
239
240
240
241
case ARM::R11:
241
- if (Variation == ARMSubtarget::NoSplit)
242
- return SpillArea::GPRCS1;
243
- else
242
+ if (Variation == ARMSubtarget::SplitR7 ||
243
+ Variation == ARMSubtarget::SplitR11AAPCSSignRA)
244
244
return SpillArea::GPRCS2;
245
+ if (Variation == ARMSubtarget::SplitR11WindowsSEH)
246
+ return SpillArea::GPRCS3;
247
+
248
+ return SpillArea::GPRCS1;
245
249
246
250
case ARM::R12:
247
251
if (Variation == ARMSubtarget::SplitR7)
@@ -250,11 +254,12 @@ SpillArea getSpillArea(Register Reg,
250
254
return SpillArea::GPRCS1;
251
255
252
256
case ARM::LR:
253
- if (Variation == ARMSubtarget::SplitR11WindowsSEH ||
254
- Variation == ARMSubtarget::SplitR11AAPCSSignRA)
257
+ if (Variation == ARMSubtarget::SplitR11AAPCSSignRA)
255
258
return SpillArea::GPRCS2;
256
- else
257
- return SpillArea::GPRCS1;
259
+ if (Variation == ARMSubtarget::SplitR11WindowsSEH)
260
+ return SpillArea::GPRCS3;
261
+
262
+ return SpillArea::GPRCS1;
258
263
259
264
case ARM::D0:
260
265
case ARM::D1:
@@ -912,7 +917,8 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
912
917
913
918
// Determine the sizes of each callee-save spill areas and record which frame
914
919
// 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 ;
916
922
int FramePtrSpillFI = 0 ;
917
923
int D8SpillFI = 0 ;
918
924
@@ -970,14 +976,19 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
970
976
GPRCS2Size += 4 ;
971
977
break ;
972
978
case SpillArea::DPRCS1:
973
- DPRCSSize += 8 ;
979
+ DPRCS1Size += 8 ;
980
+ break ;
981
+ case SpillArea::GPRCS3:
982
+ GPRCS3Size += 4 ;
974
983
break ;
975
984
case SpillArea::DPRCS2:
985
+ DPRCS2Size += 4 ;
976
986
break ;
977
987
}
978
988
}
979
989
980
- MachineBasicBlock::iterator LastPush = MBB.end (), GPRCS1Push, GPRCS2Push;
990
+ MachineBasicBlock::iterator LastPush = MBB.end (), GPRCS1Push, GPRCS2Push,
991
+ DPRCS1Push, GPRCS3Push;
981
992
982
993
// Move past the PAC computation.
983
994
if (AFI->shouldSignReturnAddress ())
@@ -1012,20 +1023,14 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1012
1023
unsigned FPCXTOffset = NumBytes - ArgRegsSaveSize - FPCXTSaveSize;
1013
1024
unsigned GPRCS1Offset = FPCXTOffset - GPRCS1Size;
1014
1025
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 ();
1021
1026
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
+
1029
1034
if (HasFP) {
1030
1035
// Offset from the CFA to the saved frame pointer, will be negative.
1031
1036
[[maybe_unused]] int FPOffset = MFI.getObjectOffset (FramePtrSpillFI);
@@ -1038,11 +1043,11 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1038
1043
}
1039
1044
AFI->setGPRCalleeSavedArea1Offset (GPRCS1Offset);
1040
1045
AFI->setGPRCalleeSavedArea2Offset (GPRCS2Offset);
1041
- AFI->setDPRCalleeSavedAreaOffset (DPRCSOffset );
1046
+ AFI->setDPRCalleeSavedArea1Offset (DPRCS1Offset );
1042
1047
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);
1046
1051
GPRCS2Push = LastPush = MBBI++;
1047
1052
DefCFAOffsetCandidates.addInst (LastPush, GPRCS2Size, BeforeFPPush);
1048
1053
if (FramePtrSpillArea == SpillArea::GPRCS2)
@@ -1063,33 +1068,34 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1063
1068
}
1064
1069
}
1065
1070
1066
- // Move past DPRCS1 .
1067
- if (DPRCSSize > 0 ) {
1071
+ // Move past DPRCS1Size .
1072
+ if (DPRCS1Size > 0 ) {
1068
1073
// Since vpush register list cannot have gaps, there may be multiple vpush
1069
1074
// instructions in the prologue.
1070
1075
while (MBBI != MBB.end () && MBBI->getOpcode () == ARM::VSTMDDB_UPD) {
1071
1076
DefCFAOffsetCandidates.addInst (MBBI, sizeOfSPAdjustment (*MBBI),
1072
1077
BeforeFPPush);
1073
- LastPush = MBBI++;
1078
+ DPRCS1Push = LastPush = MBBI++;
1074
1079
}
1075
1080
}
1076
1081
1077
1082
// Move past the aligned DPRCS2 area.
1078
- if (AFI-> getNumAlignedDPRCS2Regs () > 0 ) {
1083
+ if (DPRCS2Size > 0 ) {
1079
1084
MBBI = skipAlignedDPRCS2Spills (MBBI, AFI->getNumAlignedDPRCS2Regs ());
1080
1085
// The code inserted by emitAlignedDPRCS2Spills realigns the stack, and
1081
1086
// leaves the stack pointer pointing to the DPRCS2 area.
1082
1087
//
1083
1088
// Adjust NumBytes to represent the stack slots below the DPRCS2 area.
1084
1089
NumBytes += MFI.getObjectOffset (D8SpillFI);
1085
1090
} 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)
1093
1099
BeforeFPPush = false ;
1094
1100
}
1095
1101
@@ -1211,11 +1217,18 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1211
1217
FPOffsetAfterPush = MFI.getObjectOffset (FramePtrSpillFI) +
1212
1218
ArgRegsSaveSize + FPCXTSaveSize + GPRCS1Size +
1213
1219
sizeOfSPAdjustment (*FPPushInst);
1214
- if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH)
1215
- FPOffsetAfterPush += DPRCSSize + DPRGapSize;
1216
1220
LLVM_DEBUG (dbgs () << " Frame pointer in GPRCS2, offset "
1217
1221
<< FPOffsetAfterPush << " after that push\n " );
1218
1222
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 ;
1219
1232
default :
1220
1233
llvm_unreachable (" frame pointer in unknown spill area" );
1221
1234
break ;
@@ -1279,7 +1292,10 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1279
1292
CFIPos = std::next (GPRCS2Push);
1280
1293
break ;
1281
1294
case SpillArea::DPRCS1:
1282
- CFIPos = std::next (LastPush);
1295
+ CFIPos = std::next (DPRCS1Push);
1296
+ break ;
1297
+ case SpillArea::GPRCS3:
1298
+ CFIPos = std::next (GPRCS3Push);
1283
1299
break ;
1284
1300
case SpillArea::FPCXT:
1285
1301
case SpillArea::DPRCS2:
@@ -1317,7 +1333,8 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1317
1333
AFI->setGPRCalleeSavedArea1Size (GPRCS1Size);
1318
1334
AFI->setGPRCalleeSavedArea2Size (GPRCS2Size);
1319
1335
AFI->setDPRCalleeSavedGapSize (DPRGapSize);
1320
- AFI->setDPRCalleeSavedAreaSize (DPRCSSize);
1336
+ AFI->setDPRCalleeSavedArea1Size (DPRCS1Size);
1337
+ AFI->setGPRCalleeSavedArea3Size (GPRCS3Size);
1321
1338
1322
1339
// If we need dynamic stack realignment, do it here. Be paranoid and make
1323
1340
// sure if we also have VLAs, we have a base pointer for frame access.
@@ -1438,12 +1455,11 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
1438
1455
}
1439
1456
1440
1457
// 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 ());
1447
1463
1448
1464
// Reset SP based on frame pointer only if the stack frame extends beyond
1449
1465
// frame pointer stack slot or target is ELF and the function has FP.
@@ -1491,11 +1507,12 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
1491
1507
MachineInstr::FrameDestroy);
1492
1508
1493
1509
// Increment past our save areas.
1494
- if (AFI->getGPRCalleeSavedArea2Size () &&
1495
- PushPopSplit == ARMSubtarget::SplitR11WindowsSEH)
1510
+ if (AFI->getGPRCalleeSavedArea3Size ()) {
1511
+ assert ( PushPopSplit == ARMSubtarget::SplitR11WindowsSEH);
1496
1512
MBBI++;
1513
+ }
1497
1514
1498
- if (MBBI != MBB.end () && AFI->getDPRCalleeSavedAreaSize ()) {
1515
+ if (MBBI != MBB.end () && AFI->getDPRCalleeSavedArea1Size ()) {
1499
1516
MBBI++;
1500
1517
// Since vpop register list cannot have gaps, there may be multiple vpop
1501
1518
// instructions in the epilogue.
@@ -1509,9 +1526,10 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
1509
1526
MachineInstr::FrameDestroy);
1510
1527
}
1511
1528
1512
- if (AFI->getGPRCalleeSavedArea2Size () &&
1513
- PushPopSplit != ARMSubtarget::SplitR11WindowsSEH)
1529
+ if (AFI->getGPRCalleeSavedArea2Size ()) {
1530
+ assert ( PushPopSplit != ARMSubtarget::SplitR11WindowsSEH);
1514
1531
MBBI++;
1532
+ }
1515
1533
if (AFI->getGPRCalleeSavedArea1Size ()) MBBI++;
1516
1534
1517
1535
if (ReservedArgStack || IncomingArgStackToRestore) {
@@ -2128,19 +2146,14 @@ bool ARMFrameLowering::spillCalleeSavedRegisters(
2128
2146
auto IsDPRCS1 = [&CheckRegArea](unsigned Reg) {
2129
2147
return CheckRegArea (Reg, SpillArea::DPRCS1);
2130
2148
};
2149
+ auto IsGPRCS3 = [&CheckRegArea](unsigned Reg) {
2150
+ return CheckRegArea (Reg, SpillArea::GPRCS3);
2151
+ };
2131
2152
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);
2144
2157
2145
2158
// The code above does not insert spill code for the aligned DPRCS2 registers.
2146
2159
// The stack realignment code will be inserted between the push instructions
@@ -2190,16 +2203,14 @@ bool ARMFrameLowering::restoreCalleeSavedRegisters(
2190
2203
auto IsDPRCS1 = [&CheckRegArea](unsigned Reg) {
2191
2204
return CheckRegArea (Reg, SpillArea::DPRCS1);
2192
2205
};
2206
+ auto IsGPRCS3 = [&CheckRegArea](unsigned Reg) {
2207
+ return CheckRegArea (Reg, SpillArea::GPRCS3);
2208
+ };
2193
2209
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);
2203
2214
2204
2215
return true ;
2205
2216
}
0 commit comments