@@ -173,6 +173,95 @@ 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: case ARM::R1: case ARM::R2: case ARM::R3:
219+ case ARM::R4: case ARM::R5: case ARM::R6: case ARM::R7:
220+ return SpillArea::GPRCS1;
221+
222+ case ARM::R8: case ARM::R9: case ARM::R10:
223+ if (Variation == ARMSubtarget::SplitR7)
224+ return SpillArea::GPRCS2;
225+ else
226+ return SpillArea::GPRCS1;
227+
228+ case ARM::R11:
229+ if (Variation == ARMSubtarget::NoSplit)
230+ return SpillArea::GPRCS1;
231+ else
232+ return SpillArea::GPRCS2;
233+
234+ case ARM::R12:
235+ if (Variation == ARMSubtarget::SplitR7)
236+ return SpillArea::GPRCS2;
237+ else
238+ return SpillArea::GPRCS1;
239+
240+ case ARM::LR:
241+ if (Variation == ARMSubtarget::SplitR11WindowsSEH)
242+ return SpillArea::GPRCS2;
243+ else
244+ return SpillArea::GPRCS1;
245+
246+ case ARM::D0: case ARM::D1: case ARM::D2: case ARM::D3:
247+ case ARM::D4: case ARM::D5: case ARM::D6: case ARM::D7:
248+ return SpillArea::DPRCS1;
249+
250+ case ARM::D8: case ARM::D9: case ARM::D10: case ARM::D11:
251+ case ARM::D12: case ARM::D13: case ARM::D14: case ARM::D15:
252+ if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs)
253+ return SpillArea::DPRCS2;
254+ else
255+ return SpillArea::DPRCS1;
256+
257+ case ARM::D16: case ARM::D17: case ARM::D18: case ARM::D19:
258+ case ARM::D20: case ARM::D21: case ARM::D22: case ARM::D23:
259+ case ARM::D24: case ARM::D25: case ARM::D26: case ARM::D27:
260+ case ARM::D28: case ARM::D29: case ARM::D30: case ARM::D31:
261+ return SpillArea::DPRCS1;
262+ }
263+ }
264+
176265ARMFrameLowering::ARMFrameLowering (const ARMSubtarget &sti)
177266 : TargetFrameLowering(StackGrowsDown, sti.getStackAlignment(), 0, Align(4 )),
178267 STI(sti) {}
@@ -791,81 +880,32 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
791880 return ;
792881 }
793882
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- }
883+ // Determine spill area sizes, and some important frame indices.
884+ for (const CalleeSavedInfo &I : CSI) {
885+ Register Reg = I.getReg ();
886+ int FI = I.getFrameIdx ();
887+
888+ if (Reg == FramePtr)
889+ FramePtrSpillFI = FI;
890+ if (Reg == ARM::D8)
891+ D8SpillFI = FI;
892+
893+ switch (getSpillArea (Reg, PushPopSplit, AFI->getNumAlignedDPRCS2Regs (),
894+ RegInfo)) {
895+ case SpillArea::FPCXT:
896+ FPCXTSaveSize += 4 ;
897+ break ;
898+ case SpillArea::GPRCS1:
899+ GPRCS1Size += 4 ;
900+ break ;
901+ case SpillArea::GPRCS2:
902+ GPRCS2Size += 4 ;
903+ break ;
904+ case SpillArea::DPRCS1:
905+ DPRCSSize += 8 ;
906+ break ;
907+ case SpillArea::DPRCS2:
908+ break ;
869909 }
870910 }
871911
@@ -895,7 +935,10 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
895935 DefCFAOffsetCandidates.addInst (LastPush, GPRCS1Size, true );
896936 }
897937
898- // Determine starting offsets of spill areas.
938+ // Determine starting offsets of spill areas. These offsets are all positive
939+ // offsets from the bottom of the lowest-addressed callee-save area
940+ // (excluding DPRCS2, which is th the re-aligned stack region) to the bottom
941+ // of the spill area in question.
899942 unsigned FPCXTOffset = NumBytes - ArgRegsSaveSize - FPCXTSaveSize;
900943 unsigned GPRCS1Offset = FPCXTOffset - GPRCS1Size;
901944 unsigned GPRCS2Offset = GPRCS1Offset - GPRCS2Size;
@@ -915,10 +958,19 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
915958 }
916959 int FramePtrOffsetInPush = 0 ;
917960 if (HasFP) {
961+ // Offset from the CFA to the saved frame pointer, will be negative.
918962 int FPOffset = MFI.getObjectOffset (FramePtrSpillFI);
963+ LLVM_DEBUG (dbgs () << " FramePtrSpillFI: " << FramePtrSpillFI
964+ << " , FPOffset: " << FPOffset << " \n " );
919965 assert (getMaxFPOffset (STI, *AFI, MF) <= FPOffset &&
920966 " Max FP estimation is wrong" );
967+ // Offset from the top of the GPRCS1 area to the saved frame pointer, will
968+ // be negative.
921969 FramePtrOffsetInPush = FPOffset + ArgRegsSaveSize + FPCXTSaveSize;
970+ LLVM_DEBUG (dbgs () << " FramePtrOffsetInPush=" << FramePtrOffsetInPush
971+ << " , FramePtrSpillOffset="
972+ << (MFI.getObjectOffset (FramePtrSpillFI) + NumBytes)
973+ << " \n " );
922974 AFI->setFramePtrSpillOffset (MFI.getObjectOffset (FramePtrSpillFI) +
923975 NumBytes);
924976 }
@@ -1123,80 +1175,34 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
11231175 // Now that the prologue's actual instructions are finalised, we can insert
11241176 // the necessary DWARF cf instructions to describe the situation. Start by
11251177 // 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) {
1178+ if (!NeedsWinCFI) {
1179+ for (const auto &Entry : reverse (CSI)) {
11301180 Register Reg = Entry.getReg ();
11311181 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);
1182+ MachineBasicBlock::iterator CFIPos;
1183+ switch (getSpillArea (Reg, PushPopSplit, AFI->getNumAlignedDPRCS2Regs (),
1184+ RegInfo)) {
1185+ case SpillArea::GPRCS1:
1186+ CFIPos = std::next (GPRCS1Push);
11551187 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- }
1188+ case SpillArea::GPRCS2:
1189+ CFIPos = std::next (GPRCS2Push);
1190+ break ;
1191+ case SpillArea::DPRCS1:
1192+ CFIPos = std::next (LastPush);
1193+ break ;
1194+ case SpillArea::FPCXT:
1195+ case SpillArea::DPRCS2:
1196+ // FPCXT and DPRCS2 are not represented in the DWARF info.
11811197 break ;
11821198 }
1183- }
1184- }
11851199
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))
1200+ if (CFIPos.isValid ()) {
1201+ int CFIIndex = MF.addFrameInst (MCCFIInstruction::createOffset (
1202+ nullptr ,
1203+ MRI->getDwarfRegNum (Reg == ARM::R12 ? ARM::RA_AUTH_CODE : Reg, true ),
1204+ MFI.getObjectOffset (FI)));
1205+ BuildMI (MBB, CFIPos, dl, TII.get (TargetOpcode::CFI_INSTRUCTION))
12001206 .addCFIIndex (CFIIndex)
12011207 .setMIFlags (MachineInstr::FrameSetup);
12021208 }
0 commit comments