@@ -199,11 +199,6 @@ SpillArea getSpillArea(Register Reg,
199199 // push {r0-r10, r12} GPRCS1
200200 // vpush {r8-d15} DPRCS1
201201 // push {r11, lr} GPRCS2
202- //
203- // SplitR11AAPCSSignRA:
204- // push {r0-r10, r12} GPRSC1
205- // push {r11, lr} GPRCS2
206- // vpush {r8-d15} DPRCS1
207202
208203 // If FPCXTNS is spilled (for CMSE secure entryfunctions), it is always at
209204 // the top of the stack frame.
@@ -251,8 +246,7 @@ SpillArea getSpillArea(Register Reg,
251246 return SpillArea::GPRCS1;
252247
253248 case ARM::LR:
254- if (Variation == ARMSubtarget::SplitR11WindowsSEH ||
255- Variation == ARMSubtarget::SplitR11AAPCSSignRA)
249+ if (Variation == ARMSubtarget::SplitR11WindowsSEH)
256250 return SpillArea::GPRCS2;
257251 else
258252 return SpillArea::GPRCS1;
@@ -869,9 +863,6 @@ static int getMaxFPOffset(const ARMSubtarget &STI, const ARMFunctionInfo &AFI,
869863 // This is a conservative estimation: Assume the frame pointer being r7 and
870864 // pc("r15") up to r8 getting spilled before (= 8 registers).
871865 int MaxRegBytes = 8 * 4 ;
872- if (PushPopSplit == ARMSubtarget::SplitR11AAPCSSignRA)
873- // Here, r11 can be stored below all of r4-r15.
874- MaxRegBytes = 11 * 4 ;
875866 if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
876867 // Here, r11 can be stored below all of r4-r15 plus d8-d15.
877868 MaxRegBytes = 11 * 4 + 8 * 8 ;
@@ -944,23 +935,17 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
944935 }
945936
946937 // Determine spill area sizes, and some important frame indices.
947- SpillArea FramePtrSpillArea;
948- bool BeforeFPPush = true ;
949938 for (const CalleeSavedInfo &I : CSI) {
950939 Register Reg = I.getReg ();
951940 int FI = I.getFrameIdx ();
952941
953- SpillArea Area = getSpillArea (Reg, PushPopSplit,
954- AFI->getNumAlignedDPRCS2Regs (), RegInfo);
955-
956- if (Reg == FramePtr) {
942+ if (Reg == FramePtr)
957943 FramePtrSpillFI = FI;
958- FramePtrSpillArea = Area;
959- }
960944 if (Reg == ARM::D8)
961945 D8SpillFI = FI;
962946
963- switch (Area) {
947+ switch (getSpillArea (Reg, PushPopSplit, AFI->getNumAlignedDPRCS2Regs (),
948+ RegInfo)) {
964949 case SpillArea::FPCXT:
965950 FPCXTSaveSize += 4 ;
966951 break ;
@@ -987,23 +972,21 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
987972 // Move past FPCXT area.
988973 if (FPCXTSaveSize > 0 ) {
989974 LastPush = MBBI++;
990- DefCFAOffsetCandidates.addInst (LastPush, FPCXTSaveSize, BeforeFPPush );
975+ DefCFAOffsetCandidates.addInst (LastPush, FPCXTSaveSize, true );
991976 }
992977
993978 // Allocate the vararg register save area.
994979 if (ArgRegsSaveSize) {
995980 emitSPUpdate (isARM, MBB, MBBI, dl, TII, -ArgRegsSaveSize,
996981 MachineInstr::FrameSetup);
997982 LastPush = std::prev (MBBI);
998- DefCFAOffsetCandidates.addInst (LastPush, ArgRegsSaveSize, BeforeFPPush );
983+ DefCFAOffsetCandidates.addInst (LastPush, ArgRegsSaveSize, true );
999984 }
1000985
1001986 // Move past area 1.
1002987 if (GPRCS1Size > 0 ) {
1003988 GPRCS1Push = LastPush = MBBI++;
1004- DefCFAOffsetCandidates.addInst (LastPush, GPRCS1Size, BeforeFPPush);
1005- if (FramePtrSpillArea == SpillArea::GPRCS1)
1006- BeforeFPPush = false ;
989+ DefCFAOffsetCandidates.addInst (LastPush, GPRCS1Size, true );
1007990 }
1008991
1009992 // Determine starting offsets of spill areas. These offsets are all positive
@@ -1027,13 +1010,21 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
10271010 } else {
10281011 DPRCSOffset = GPRCS2Offset - DPRGapSize - DPRCSSize;
10291012 }
1013+ int FramePtrOffsetInPush = 0 ;
10301014 if (HasFP) {
10311015 // Offset from the CFA to the saved frame pointer, will be negative.
10321016 [[maybe_unused]] int FPOffset = MFI.getObjectOffset (FramePtrSpillFI);
10331017 LLVM_DEBUG (dbgs () << " FramePtrSpillFI: " << FramePtrSpillFI
10341018 << " , FPOffset: " << FPOffset << " \n " );
10351019 assert (getMaxFPOffset (STI, *AFI, MF) <= FPOffset &&
10361020 " 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 " );
10371028 AFI->setFramePtrSpillOffset (MFI.getObjectOffset (FramePtrSpillFI) +
10381029 NumBytes);
10391030 }
@@ -1045,9 +1036,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
10451036 // after DPRCS1.
10461037 if (GPRCS2Size > 0 && PushPopSplit != ARMSubtarget::SplitR11WindowsSEH) {
10471038 GPRCS2Push = LastPush = MBBI++;
1048- DefCFAOffsetCandidates.addInst (LastPush, GPRCS2Size, BeforeFPPush);
1049- if (FramePtrSpillArea == SpillArea::GPRCS2)
1050- BeforeFPPush = false ;
1039+ DefCFAOffsetCandidates.addInst (LastPush, GPRCS2Size);
10511040 }
10521041
10531042 // Prolog/epilog inserter assumes we correctly align DPRs on the stack, so our
@@ -1060,7 +1049,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
10601049 else {
10611050 emitSPUpdate (isARM, MBB, MBBI, dl, TII, -DPRGapSize,
10621051 MachineInstr::FrameSetup);
1063- DefCFAOffsetCandidates.addInst (std::prev (MBBI), DPRGapSize, BeforeFPPush );
1052+ DefCFAOffsetCandidates.addInst (std::prev (MBBI), DPRGapSize);
10641053 }
10651054 }
10661055
@@ -1069,8 +1058,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
10691058 // Since vpush register list cannot have gaps, there may be multiple vpush
10701059 // instructions in the prologue.
10711060 while (MBBI != MBB.end () && MBBI->getOpcode () == ARM::VSTMDDB_UPD) {
1072- DefCFAOffsetCandidates.addInst (MBBI, sizeOfSPAdjustment (*MBBI),
1073- BeforeFPPush);
1061+ DefCFAOffsetCandidates.addInst (MBBI, sizeOfSPAdjustment (*MBBI));
10741062 LastPush = MBBI++;
10751063 }
10761064 }
@@ -1089,9 +1077,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
10891077 // Move GPRCS2, if using using SplitR11WindowsSEH.
10901078 if (GPRCS2Size > 0 && PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
10911079 GPRCS2Push = LastPush = MBBI++;
1092- DefCFAOffsetCandidates.addInst (LastPush, GPRCS2Size, BeforeFPPush);
1093- if (FramePtrSpillArea == SpillArea::GPRCS2)
1094- BeforeFPPush = false ;
1080+ DefCFAOffsetCandidates.addInst (LastPush, GPRCS2Size);
10951081 }
10961082
10971083 bool NeedsWinCFIStackAlloc = NeedsWinCFI;
@@ -1192,51 +1178,28 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
11921178 // into spill area 1, including the FP in R11. In either case, it
11931179 // is in area one and the adjustment needs to take place just after
11941180 // 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.
11951184 MachineBasicBlock::iterator AfterPush;
11961185 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);
12231197 }
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-
12331198 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 ) {
12371200 unsigned CFIIndex = MF.addFrameInst (MCCFIInstruction::cfiDefCfa (
12381201 nullptr , MRI->getDwarfRegNum (FramePtr, true ),
1239- -MFI. getObjectOffset (FramePtrSpillFI) ));
1202+ FPCXTSaveSize + ArgRegsSaveSize - FramePtrOffsetInPush ));
12401203 BuildMI (MBB, AfterPush, dl, TII.get (TargetOpcode::CFI_INSTRUCTION))
12411204 .addCFIIndex (CFIIndex)
12421205 .setMIFlags (MachineInstr::FrameSetup);
@@ -1749,8 +1712,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
17491712 if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt &&
17501713 !isCmseEntry && !isTrap && AFI->getArgumentStackToRestore () == 0 &&
17511714 STI.hasV5TOps () && MBB.succ_empty () && !hasPAC &&
1752- (PushPopSplit != ARMSubtarget::SplitR11WindowsSEH &&
1753- PushPopSplit != ARMSubtarget::SplitR11AAPCSSignRA)) {
1715+ PushPopSplit != ARMSubtarget::SplitR11WindowsSEH) {
17541716 Reg = ARM::PC;
17551717 // Fold the return instruction into the LDM.
17561718 DeleteRet = true ;
@@ -2983,29 +2945,18 @@ bool ARMFrameLowering::assignCalleeSavedSpillSlots(
29832945 const auto &AFI = *MF.getInfo <ARMFunctionInfo>();
29842946 if (AFI.shouldSignReturnAddress ()) {
29852947 // 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));
30092960 }
30102961
30112962 return false ;
0 commit comments