@@ -199,11 +199,6 @@ SpillArea getSpillArea(Register Reg,
199
199
// push {r0-r10, r12} GPRCS1
200
200
// vpush {r8-d15} DPRCS1
201
201
// push {r11, lr} GPRCS2
202
- //
203
- // SplitR11AAPCSSignRA:
204
- // push {r0-r10, r12} GPRSC1
205
- // push {r11, lr} GPRCS2
206
- // vpush {r8-d15} DPRCS1
207
202
208
203
// If FPCXTNS is spilled (for CMSE secure entryfunctions), it is always at
209
204
// the top of the stack frame.
@@ -251,8 +246,7 @@ SpillArea getSpillArea(Register Reg,
251
246
return SpillArea::GPRCS1;
252
247
253
248
case ARM::LR:
254
- if (Variation == ARMSubtarget::SplitR11WindowsSEH ||
255
- Variation == ARMSubtarget::SplitR11AAPCSSignRA)
249
+ if (Variation == ARMSubtarget::SplitR11WindowsSEH)
256
250
return SpillArea::GPRCS2;
257
251
else
258
252
return SpillArea::GPRCS1;
@@ -869,9 +863,6 @@ static int getMaxFPOffset(const ARMSubtarget &STI, const ARMFunctionInfo &AFI,
869
863
// This is a conservative estimation: Assume the frame pointer being r7 and
870
864
// pc("r15") up to r8 getting spilled before (= 8 registers).
871
865
int MaxRegBytes = 8 * 4 ;
872
- if (PushPopSplit == ARMSubtarget::SplitR11AAPCSSignRA)
873
- // Here, r11 can be stored below all of r4-r15.
874
- MaxRegBytes = 11 * 4 ;
875
866
if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
876
867
// Here, r11 can be stored below all of r4-r15 plus d8-d15.
877
868
MaxRegBytes = 11 * 4 + 8 * 8 ;
@@ -944,23 +935,17 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
944
935
}
945
936
946
937
// Determine spill area sizes, and some important frame indices.
947
- SpillArea FramePtrSpillArea;
948
- bool BeforeFPPush = true ;
949
938
for (const CalleeSavedInfo &I : CSI) {
950
939
Register Reg = I.getReg ();
951
940
int FI = I.getFrameIdx ();
952
941
953
- SpillArea Area = getSpillArea (Reg, PushPopSplit,
954
- AFI->getNumAlignedDPRCS2Regs (), RegInfo);
955
-
956
- if (Reg == FramePtr) {
942
+ if (Reg == FramePtr)
957
943
FramePtrSpillFI = FI;
958
- FramePtrSpillArea = Area;
959
- }
960
944
if (Reg == ARM::D8)
961
945
D8SpillFI = FI;
962
946
963
- switch (Area) {
947
+ switch (getSpillArea (Reg, PushPopSplit, AFI->getNumAlignedDPRCS2Regs (),
948
+ RegInfo)) {
964
949
case SpillArea::FPCXT:
965
950
FPCXTSaveSize += 4 ;
966
951
break ;
@@ -987,23 +972,21 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
987
972
// Move past FPCXT area.
988
973
if (FPCXTSaveSize > 0 ) {
989
974
LastPush = MBBI++;
990
- DefCFAOffsetCandidates.addInst (LastPush, FPCXTSaveSize, BeforeFPPush );
975
+ DefCFAOffsetCandidates.addInst (LastPush, FPCXTSaveSize, true );
991
976
}
992
977
993
978
// Allocate the vararg register save area.
994
979
if (ArgRegsSaveSize) {
995
980
emitSPUpdate (isARM, MBB, MBBI, dl, TII, -ArgRegsSaveSize,
996
981
MachineInstr::FrameSetup);
997
982
LastPush = std::prev (MBBI);
998
- DefCFAOffsetCandidates.addInst (LastPush, ArgRegsSaveSize, BeforeFPPush );
983
+ DefCFAOffsetCandidates.addInst (LastPush, ArgRegsSaveSize, true );
999
984
}
1000
985
1001
986
// Move past area 1.
1002
987
if (GPRCS1Size > 0 ) {
1003
988
GPRCS1Push = LastPush = MBBI++;
1004
- DefCFAOffsetCandidates.addInst (LastPush, GPRCS1Size, BeforeFPPush);
1005
- if (FramePtrSpillArea == SpillArea::GPRCS1)
1006
- BeforeFPPush = false ;
989
+ DefCFAOffsetCandidates.addInst (LastPush, GPRCS1Size, true );
1007
990
}
1008
991
1009
992
// Determine starting offsets of spill areas. These offsets are all positive
@@ -1027,13 +1010,21 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1027
1010
} else {
1028
1011
DPRCSOffset = GPRCS2Offset - DPRGapSize - DPRCSSize;
1029
1012
}
1013
+ int FramePtrOffsetInPush = 0 ;
1030
1014
if (HasFP) {
1031
1015
// Offset from the CFA to the saved frame pointer, will be negative.
1032
1016
[[maybe_unused]] int FPOffset = MFI.getObjectOffset (FramePtrSpillFI);
1033
1017
LLVM_DEBUG (dbgs () << " FramePtrSpillFI: " << FramePtrSpillFI
1034
1018
<< " , FPOffset: " << FPOffset << " \n " );
1035
1019
assert (getMaxFPOffset (STI, *AFI, MF) <= FPOffset &&
1036
1020
" Max FP estimation is wrong" );
1021
+ // Offset from the top of the GPRCS1 area to the saved frame pointer, will
1022
+ // be negative.
1023
+ FramePtrOffsetInPush = FPOffset + ArgRegsSaveSize + FPCXTSaveSize;
1024
+ LLVM_DEBUG (dbgs () << " FramePtrOffsetInPush=" << FramePtrOffsetInPush
1025
+ << " , FramePtrSpillOffset="
1026
+ << (MFI.getObjectOffset (FramePtrSpillFI) + NumBytes)
1027
+ << " \n " );
1037
1028
AFI->setFramePtrSpillOffset (MFI.getObjectOffset (FramePtrSpillFI) +
1038
1029
NumBytes);
1039
1030
}
@@ -1045,9 +1036,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1045
1036
// after DPRCS1.
1046
1037
if (GPRCS2Size > 0 && PushPopSplit != ARMSubtarget::SplitR11WindowsSEH) {
1047
1038
GPRCS2Push = LastPush = MBBI++;
1048
- DefCFAOffsetCandidates.addInst (LastPush, GPRCS2Size, BeforeFPPush);
1049
- if (FramePtrSpillArea == SpillArea::GPRCS2)
1050
- BeforeFPPush = false ;
1039
+ DefCFAOffsetCandidates.addInst (LastPush, GPRCS2Size);
1051
1040
}
1052
1041
1053
1042
// Prolog/epilog inserter assumes we correctly align DPRs on the stack, so our
@@ -1060,7 +1049,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1060
1049
else {
1061
1050
emitSPUpdate (isARM, MBB, MBBI, dl, TII, -DPRGapSize,
1062
1051
MachineInstr::FrameSetup);
1063
- DefCFAOffsetCandidates.addInst (std::prev (MBBI), DPRGapSize, BeforeFPPush );
1052
+ DefCFAOffsetCandidates.addInst (std::prev (MBBI), DPRGapSize);
1064
1053
}
1065
1054
}
1066
1055
@@ -1069,8 +1058,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1069
1058
// Since vpush register list cannot have gaps, there may be multiple vpush
1070
1059
// instructions in the prologue.
1071
1060
while (MBBI != MBB.end () && MBBI->getOpcode () == ARM::VSTMDDB_UPD) {
1072
- DefCFAOffsetCandidates.addInst (MBBI, sizeOfSPAdjustment (*MBBI),
1073
- BeforeFPPush);
1061
+ DefCFAOffsetCandidates.addInst (MBBI, sizeOfSPAdjustment (*MBBI));
1074
1062
LastPush = MBBI++;
1075
1063
}
1076
1064
}
@@ -1089,9 +1077,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1089
1077
// Move GPRCS2, if using using SplitR11WindowsSEH.
1090
1078
if (GPRCS2Size > 0 && PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
1091
1079
GPRCS2Push = LastPush = MBBI++;
1092
- DefCFAOffsetCandidates.addInst (LastPush, GPRCS2Size, BeforeFPPush);
1093
- if (FramePtrSpillArea == SpillArea::GPRCS2)
1094
- BeforeFPPush = false ;
1080
+ DefCFAOffsetCandidates.addInst (LastPush, GPRCS2Size);
1095
1081
}
1096
1082
1097
1083
bool NeedsWinCFIStackAlloc = NeedsWinCFI;
@@ -1192,51 +1178,28 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1192
1178
// into spill area 1, including the FP in R11. In either case, it
1193
1179
// is in area one and the adjustment needs to take place just after
1194
1180
// that push.
1181
+ // FIXME: The above is not necessary true when PACBTI is enabled.
1182
+ // AAPCS requires use of R11, and PACBTI gets in the way of regular pushes,
1183
+ // so FP ends up on area two.
1195
1184
MachineBasicBlock::iterator AfterPush;
1196
1185
if (HasFP) {
1197
- MachineBasicBlock::iterator FPPushInst;
1198
- // Offset from SP immediately after the push which saved the FP to the FP
1199
- // save slot.
1200
- int64_t FPOffsetAfterPush;
1201
- switch (FramePtrSpillArea) {
1202
- case SpillArea::GPRCS1:
1203
- FPPushInst = GPRCS1Push;
1204
- FPOffsetAfterPush = MFI.getObjectOffset (FramePtrSpillFI) +
1205
- ArgRegsSaveSize + FPCXTSaveSize +
1206
- sizeOfSPAdjustment (*FPPushInst);
1207
- LLVM_DEBUG (dbgs () << " Frame pointer in GPRCS1, offset "
1208
- << FPOffsetAfterPush << " after that push\n " );
1209
- break ;
1210
- case SpillArea::GPRCS2:
1211
- FPPushInst = GPRCS2Push;
1212
- FPOffsetAfterPush = MFI.getObjectOffset (FramePtrSpillFI) +
1213
- ArgRegsSaveSize + FPCXTSaveSize + GPRCS1Size +
1214
- sizeOfSPAdjustment (*FPPushInst);
1215
- if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH)
1216
- FPOffsetAfterPush += DPRCSSize + DPRGapSize;
1217
- LLVM_DEBUG (dbgs () << " Frame pointer in GPRCS2, offset "
1218
- << FPOffsetAfterPush << " after that push\n " );
1219
- break ;
1220
- default :
1221
- llvm_unreachable (" frame pointer in unknown spill area" );
1222
- break ;
1186
+ AfterPush = std::next (GPRCS1Push);
1187
+ unsigned PushSize = sizeOfSPAdjustment (*GPRCS1Push);
1188
+ int FPOffset = PushSize + FramePtrOffsetInPush;
1189
+ if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
1190
+ AfterPush = std::next (GPRCS2Push);
1191
+ emitRegPlusImmediate (!AFI->isThumbFunction (), MBB, AfterPush, dl, TII,
1192
+ FramePtr, ARM::SP, 0 , MachineInstr::FrameSetup);
1193
+ } else {
1194
+ emitRegPlusImmediate (!AFI->isThumbFunction (), MBB, AfterPush, dl, TII,
1195
+ FramePtr, ARM::SP, FPOffset,
1196
+ MachineInstr::FrameSetup);
1223
1197
}
1224
- AfterPush = std::next (FPPushInst);
1225
- if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH)
1226
- assert (FPOffsetAfterPush == 0 );
1227
-
1228
- // Emit the MOV or ADD to set up the frame pointer register.
1229
- emitRegPlusImmediate (!AFI->isThumbFunction (), MBB, AfterPush, dl, TII,
1230
- FramePtr, ARM::SP, FPOffsetAfterPush,
1231
- MachineInstr::FrameSetup);
1232
-
1233
1198
if (!NeedsWinCFI) {
1234
- // Emit DWARF info to find the CFA using the frame pointer from this
1235
- // point onward.
1236
- if (FPOffsetAfterPush != 0 ) {
1199
+ if (FramePtrOffsetInPush + PushSize != 0 ) {
1237
1200
unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::cfiDefCfa (
1238
1201
nullptr , MRI->getDwarfRegNum (FramePtr, true ),
1239
- -MFI. getObjectOffset (FramePtrSpillFI) ));
1202
+ FPCXTSaveSize + ArgRegsSaveSize - FramePtrOffsetInPush ));
1240
1203
BuildMI (MBB, AfterPush, dl, TII.get (TargetOpcode::CFI_INSTRUCTION))
1241
1204
.addCFIIndex (CFIIndex)
1242
1205
.setMIFlags (MachineInstr::FrameSetup);
@@ -1749,8 +1712,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
1749
1712
if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt &&
1750
1713
!isCmseEntry && !isTrap && AFI->getArgumentStackToRestore () == 0 &&
1751
1714
STI.hasV5TOps () && MBB.succ_empty () && !hasPAC &&
1752
- (PushPopSplit != ARMSubtarget::SplitR11WindowsSEH &&
1753
- PushPopSplit != ARMSubtarget::SplitR11AAPCSSignRA)) {
1715
+ PushPopSplit != ARMSubtarget::SplitR11WindowsSEH) {
1754
1716
Reg = ARM::PC;
1755
1717
// Fold the return instruction into the LDM.
1756
1718
DeleteRet = true ;
@@ -2983,29 +2945,18 @@ bool ARMFrameLowering::assignCalleeSavedSpillSlots(
2983
2945
const auto &AFI = *MF.getInfo <ARMFunctionInfo>();
2984
2946
if (AFI.shouldSignReturnAddress ()) {
2985
2947
// The order of register must match the order we push them, because the
2986
- // PEI assigns frame indices in that order. That order depends on the
2987
- // PushPopSplitVariation, there are only two cases which we use with return
2988
- // address signing:
2989
- switch (STI.getPushPopSplitVariation (MF)) {
2990
- case ARMSubtarget::SplitR7:
2991
- // LR, R7, R6, R5, R4, <R12>, R11, R10, R9, R8, D15-D8
2992
- CSI.insert (find_if (CSI,
2993
- [=](const auto &CS) {
2994
- Register Reg = CS.getReg ();
2995
- return Reg == ARM::R10 || Reg == ARM::R11 ||
2996
- Reg == ARM::R8 || Reg == ARM::R9 ||
2997
- ARM::DPRRegClass.contains (Reg);
2998
- }),
2999
- CalleeSavedInfo (ARM::R12));
3000
- break ;
3001
- case ARMSubtarget::SplitR11AAPCSSignRA:
3002
- // With SplitR11AAPCSSignRA, R12 will always be the highest-addressed CSR
3003
- // on the stack.
3004
- CSI.insert (CSI.begin (), CalleeSavedInfo (ARM::R12));
3005
- break ;
3006
- default :
3007
- llvm_unreachable (" Unexpected CSR split with return address signing" );
3008
- }
2948
+ // PEI assigns frame indices in that order. When compiling for return
2949
+ // address sign and authenication, we use split push, therefore the orders
2950
+ // we want are:
2951
+ // LR, R7, R6, R5, R4, <R12>, R11, R10, R9, R8, D15-D8
2952
+ CSI.insert (find_if (CSI,
2953
+ [=](const auto &CS) {
2954
+ Register Reg = CS.getReg ();
2955
+ return Reg == ARM::R10 || Reg == ARM::R11 ||
2956
+ Reg == ARM::R8 || Reg == ARM::R9 ||
2957
+ ARM::DPRRegClass.contains (Reg);
2958
+ }),
2959
+ CalleeSavedInfo (ARM::R12));
3009
2960
}
3010
2961
3011
2962
return false ;
0 commit comments