@@ -173,6 +173,127 @@ static MachineBasicBlock::iterator
173173skipAlignedDPRCS2Spills (MachineBasicBlock::iterator MI,
174174 unsigned NumAlignedDPRCS2Regs);
175175
176+ enum class SpillArea {
177+ GPRCS1,
178+ GPRCS2,
179+ DPRCS1,
180+ DPRCS2,
181+ FPCXT,
182+ };
183+
184+ // / Get the spill area that Reg should be saved into in the prologue.
185+ SpillArea getSpillArea (Register Reg,
186+ ARMSubtarget::PushPopSplitVariation Variation,
187+ unsigned NumAlignedDPRCS2Regs,
188+ const ARMBaseRegisterInfo *RegInfo) {
189+ // NoSplit:
190+ // push {r0-r12, lr} GPRCS1
191+ // vpush {r8-d15} DPRCS1
192+ //
193+ // SplitR7:
194+ // push {r0-r7, lr} GPRCS1
195+ // push {r8-r12} GPRCS2
196+ // vpush {r8-d15} DPRCS1
197+ //
198+ // SplitR11WindowsSEH:
199+ // push {r0-r10, r12} GPRCS1
200+ // vpush {r8-d15} DPRCS1
201+ // push {r11, lr} GPRCS2
202+
203+ // If FPCXTNS is spilled (for CMSE secure entryfunctions), it is always at
204+ // the top of the stack frame.
205+ // The DPRCS2 region is used for ABIs which only guarantee 4-byte alignment
206+ // of SP. If used, it will be below the other save areas, after the stack has
207+ // been re-aligned.
208+
209+ switch (Reg) {
210+ default :
211+ dbgs () << " Don't know where to spill " << printReg (Reg, RegInfo) << " \n " ;
212+ llvm_unreachable (" Don't know where to spill this register" );
213+ break ;
214+
215+ case ARM::FPCXTNS:
216+ return SpillArea::FPCXT;
217+
218+ case ARM::R0:
219+ case ARM::R1:
220+ case ARM::R2:
221+ case ARM::R3:
222+ case ARM::R4:
223+ case ARM::R5:
224+ case ARM::R6:
225+ case ARM::R7:
226+ return SpillArea::GPRCS1;
227+
228+ case ARM::R8:
229+ case ARM::R9:
230+ case ARM::R10:
231+ if (Variation == ARMSubtarget::SplitR7)
232+ return SpillArea::GPRCS2;
233+ else
234+ return SpillArea::GPRCS1;
235+
236+ case ARM::R11:
237+ if (Variation == ARMSubtarget::NoSplit)
238+ return SpillArea::GPRCS1;
239+ else
240+ return SpillArea::GPRCS2;
241+
242+ case ARM::R12:
243+ if (Variation == ARMSubtarget::SplitR7)
244+ return SpillArea::GPRCS2;
245+ else
246+ return SpillArea::GPRCS1;
247+
248+ case ARM::LR:
249+ if (Variation == ARMSubtarget::SplitR11WindowsSEH)
250+ return SpillArea::GPRCS2;
251+ else
252+ return SpillArea::GPRCS1;
253+
254+ case ARM::D0:
255+ case ARM::D1:
256+ case ARM::D2:
257+ case ARM::D3:
258+ case ARM::D4:
259+ case ARM::D5:
260+ case ARM::D6:
261+ case ARM::D7:
262+ return SpillArea::DPRCS1;
263+
264+ case ARM::D8:
265+ case ARM::D9:
266+ case ARM::D10:
267+ case ARM::D11:
268+ case ARM::D12:
269+ case ARM::D13:
270+ case ARM::D14:
271+ case ARM::D15:
272+ if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
273+ return SpillArea::DPRCS2;
274+ else
275+ return SpillArea::DPRCS1;
276+
277+ case ARM::D16:
278+ case ARM::D17:
279+ case ARM::D18:
280+ case ARM::D19:
281+ case ARM::D20:
282+ case ARM::D21:
283+ case ARM::D22:
284+ case ARM::D23:
285+ case ARM::D24:
286+ case ARM::D25:
287+ case ARM::D26:
288+ case ARM::D27:
289+ case ARM::D28:
290+ case ARM::D29:
291+ case ARM::D30:
292+ case ARM::D31:
293+ return SpillArea::DPRCS1;
294+ }
295+ }
296+
176297ARMFrameLowering::ARMFrameLowering (const ARMSubtarget &sti)
177298 : TargetFrameLowering(StackGrowsDown, sti.getStackAlignment(), 0, Align(4 )),
178299 STI(sti) {}
@@ -791,81 +912,32 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
791912 return ;
792913 }
793914
794- // Determine spill area sizes.
795- if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
796- for (const CalleeSavedInfo &I : CSI) {
797- Register Reg = I.getReg ();
798- int FI = I.getFrameIdx ();
799- switch (Reg) {
800- case ARM::R11:
801- case ARM::LR:
802- if (Reg == FramePtr)
803- FramePtrSpillFI = FI;
804- GPRCS2Size += 4 ;
805- break ;
806- case ARM::R0:
807- case ARM::R1:
808- case ARM::R2:
809- case ARM::R3:
810- case ARM::R4:
811- case ARM::R5:
812- case ARM::R6:
813- case ARM::R7:
814- case ARM::R8:
815- case ARM::R9:
816- case ARM::R10:
817- case ARM::R12:
818- GPRCS1Size += 4 ;
819- break ;
820- case ARM::FPCXTNS:
821- FPCXTSaveSize = 4 ;
822- break ;
823- default :
824- // This is a DPR. Exclude the aligned DPRCS2 spills.
825- if (Reg == ARM::D8)
826- D8SpillFI = FI;
827- if (Reg < ARM::D8 || Reg >= ARM::D8 + AFI->getNumAlignedDPRCS2Regs ())
828- DPRCSSize += 8 ;
829- }
830- }
831- } else {
832- for (const CalleeSavedInfo &I : CSI) {
833- Register Reg = I.getReg ();
834- int FI = I.getFrameIdx ();
835- switch (Reg) {
836- case ARM::R8:
837- case ARM::R9:
838- case ARM::R10:
839- case ARM::R11:
840- case ARM::R12:
841- if (PushPopSplit == ARMSubtarget::SplitR7) {
842- GPRCS2Size += 4 ;
843- break ;
844- }
845- [[fallthrough]];
846- case ARM::R0:
847- case ARM::R1:
848- case ARM::R2:
849- case ARM::R3:
850- case ARM::R4:
851- case ARM::R5:
852- case ARM::R6:
853- case ARM::R7:
854- case ARM::LR:
855- if (Reg == FramePtr)
856- FramePtrSpillFI = FI;
857- GPRCS1Size += 4 ;
858- break ;
859- case ARM::FPCXTNS:
860- FPCXTSaveSize = 4 ;
861- break ;
862- default :
863- // This is a DPR. Exclude the aligned DPRCS2 spills.
864- if (Reg == ARM::D8)
865- D8SpillFI = FI;
866- if (Reg < ARM::D8 || Reg >= ARM::D8 + AFI->getNumAlignedDPRCS2Regs ())
867- DPRCSSize += 8 ;
868- }
915+ // Determine spill area sizes, and some important frame indices.
916+ for (const CalleeSavedInfo &I : CSI) {
917+ Register Reg = I.getReg ();
918+ int FI = I.getFrameIdx ();
919+
920+ if (Reg == FramePtr)
921+ FramePtrSpillFI = FI;
922+ if (Reg == ARM::D8)
923+ D8SpillFI = FI;
924+
925+ switch (getSpillArea (Reg, PushPopSplit, AFI->getNumAlignedDPRCS2Regs (),
926+ RegInfo)) {
927+ case SpillArea::FPCXT:
928+ FPCXTSaveSize += 4 ;
929+ break ;
930+ case SpillArea::GPRCS1:
931+ GPRCS1Size += 4 ;
932+ break ;
933+ case SpillArea::GPRCS2:
934+ GPRCS2Size += 4 ;
935+ break ;
936+ case SpillArea::DPRCS1:
937+ DPRCSSize += 8 ;
938+ break ;
939+ case SpillArea::DPRCS2:
940+ break ;
869941 }
870942 }
871943
@@ -895,7 +967,10 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
895967 DefCFAOffsetCandidates.addInst (LastPush, GPRCS1Size, true );
896968 }
897969
898- // Determine starting offsets of spill areas.
970+ // Determine starting offsets of spill areas. These offsets are all positive
971+ // offsets from the bottom of the lowest-addressed callee-save area
972+ // (excluding DPRCS2, which is th the re-aligned stack region) to the bottom
973+ // of the spill area in question.
899974 unsigned FPCXTOffset = NumBytes - ArgRegsSaveSize - FPCXTSaveSize;
900975 unsigned GPRCS1Offset = FPCXTOffset - GPRCS1Size;
901976 unsigned GPRCS2Offset = GPRCS1Offset - GPRCS2Size;
@@ -915,10 +990,19 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
915990 }
916991 int FramePtrOffsetInPush = 0 ;
917992 if (HasFP) {
993+ // Offset from the CFA to the saved frame pointer, will be negative.
918994 int FPOffset = MFI.getObjectOffset (FramePtrSpillFI);
995+ LLVM_DEBUG (dbgs () << " FramePtrSpillFI: " << FramePtrSpillFI
996+ << " , FPOffset: " << FPOffset << " \n " );
919997 assert (getMaxFPOffset (STI, *AFI, MF) <= FPOffset &&
920998 " Max FP estimation is wrong" );
999+ // Offset from the top of the GPRCS1 area to the saved frame pointer, will
1000+ // be negative.
9211001 FramePtrOffsetInPush = FPOffset + ArgRegsSaveSize + FPCXTSaveSize;
1002+ LLVM_DEBUG (dbgs () << " FramePtrOffsetInPush=" << FramePtrOffsetInPush
1003+ << " , FramePtrSpillOffset="
1004+ << (MFI.getObjectOffset (FramePtrSpillFI) + NumBytes)
1005+ << " \n " );
9221006 AFI->setFramePtrSpillOffset (MFI.getObjectOffset (FramePtrSpillFI) +
9231007 NumBytes);
9241008 }
@@ -1123,80 +1207,35 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
11231207 // Now that the prologue's actual instructions are finalised, we can insert
11241208 // the necessary DWARF cf instructions to describe the situation. Start by
11251209 // recording where each register ended up:
1126- if (GPRCS1Size > 0 && !NeedsWinCFI) {
1127- MachineBasicBlock::iterator Pos = std::next (GPRCS1Push);
1128- int CFIIndex;
1129- for (const auto &Entry : CSI) {
1210+ if (!NeedsWinCFI) {
1211+ for (const auto &Entry : reverse (CSI)) {
11301212 Register Reg = Entry.getReg ();
11311213 int FI = Entry.getFrameIdx ();
1132- switch (Reg) {
1133- case ARM::R8:
1134- case ARM::R9:
1135- case ARM::R10:
1136- case ARM::R11:
1137- case ARM::R12:
1138- if (PushPopSplit == ARMSubtarget::SplitR7)
1139- break ;
1140- [[fallthrough]];
1141- case ARM::R0:
1142- case ARM::R1:
1143- case ARM::R2:
1144- case ARM::R3:
1145- case ARM::R4:
1146- case ARM::R5:
1147- case ARM::R6:
1148- case ARM::R7:
1149- case ARM::LR:
1150- CFIIndex = MF.addFrameInst (MCCFIInstruction::createOffset (
1151- nullptr , MRI->getDwarfRegNum (Reg, true ), MFI.getObjectOffset (FI)));
1152- BuildMI (MBB, Pos, dl, TII.get (TargetOpcode::CFI_INSTRUCTION))
1153- .addCFIIndex (CFIIndex)
1154- .setMIFlags (MachineInstr::FrameSetup);
1214+ MachineBasicBlock::iterator CFIPos;
1215+ switch (getSpillArea (Reg, PushPopSplit, AFI->getNumAlignedDPRCS2Regs (),
1216+ RegInfo)) {
1217+ case SpillArea::GPRCS1:
1218+ CFIPos = std::next (GPRCS1Push);
11551219 break ;
1156- }
1157- }
1158- }
1159-
1160- if (GPRCS2Size > 0 && !NeedsWinCFI) {
1161- MachineBasicBlock::iterator Pos = std::next (GPRCS2Push);
1162- for (const auto &Entry : CSI) {
1163- Register Reg = Entry.getReg ();
1164- int FI = Entry.getFrameIdx ();
1165- switch (Reg) {
1166- case ARM::R8:
1167- case ARM::R9:
1168- case ARM::R10:
1169- case ARM::R11:
1170- case ARM::R12:
1171- if (PushPopSplit == ARMSubtarget::SplitR7) {
1172- unsigned DwarfReg = MRI->getDwarfRegNum (
1173- Reg == ARM::R12 ? ARM::RA_AUTH_CODE : Reg, true );
1174- int64_t Offset = MFI.getObjectOffset (FI);
1175- unsigned CFIIndex = MF.addFrameInst (
1176- MCCFIInstruction::createOffset (nullptr , DwarfReg, Offset));
1177- BuildMI (MBB, Pos, dl, TII.get (TargetOpcode::CFI_INSTRUCTION))
1178- .addCFIIndex (CFIIndex)
1179- .setMIFlags (MachineInstr::FrameSetup);
1180- }
1220+ case SpillArea::GPRCS2:
1221+ CFIPos = std::next (GPRCS2Push);
1222+ break ;
1223+ case SpillArea::DPRCS1:
1224+ CFIPos = std::next (LastPush);
1225+ break ;
1226+ case SpillArea::FPCXT:
1227+ case SpillArea::DPRCS2:
1228+ // FPCXT and DPRCS2 are not represented in the DWARF info.
11811229 break ;
11821230 }
1183- }
1184- }
11851231
1186- if (DPRCSSize > 0 && !NeedsWinCFI) {
1187- // Since vpush register list cannot have gaps, there may be multiple vpush
1188- // instructions in the prologue.
1189- MachineBasicBlock::iterator Pos = std::next (LastPush);
1190- for (const auto &Entry : CSI) {
1191- Register Reg = Entry.getReg ();
1192- int FI = Entry.getFrameIdx ();
1193- if ((Reg >= ARM::D0 && Reg <= ARM::D31) &&
1194- (Reg < ARM::D8 || Reg >= ARM::D8 + AFI->getNumAlignedDPRCS2Regs ())) {
1195- unsigned DwarfReg = MRI->getDwarfRegNum (Reg, true );
1196- int64_t Offset = MFI.getObjectOffset (FI);
1197- unsigned CFIIndex = MF.addFrameInst (
1198- MCCFIInstruction::createOffset (nullptr , DwarfReg, Offset));
1199- BuildMI (MBB, Pos, dl, TII.get (TargetOpcode::CFI_INSTRUCTION))
1232+ if (CFIPos.isValid ()) {
1233+ int CFIIndex = MF.addFrameInst (MCCFIInstruction::createOffset (
1234+ nullptr ,
1235+ MRI->getDwarfRegNum (Reg == ARM::R12 ? ARM::RA_AUTH_CODE : Reg,
1236+ true ),
1237+ MFI.getObjectOffset (FI)));
1238+ BuildMI (MBB, CFIPos, dl, TII.get (TargetOpcode::CFI_INSTRUCTION))
12001239 .addCFIIndex (CFIIndex)
12011240 .setMIFlags (MachineInstr::FrameSetup);
12021241 }
0 commit comments