@@ -173,6 +173,127 @@ static MachineBasicBlock::iterator
173
173
skipAlignedDPRCS2Spills (MachineBasicBlock::iterator MI,
174
174
unsigned NumAlignedDPRCS2Regs);
175
175
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
+
176
297
ARMFrameLowering::ARMFrameLowering (const ARMSubtarget &sti)
177
298
: TargetFrameLowering(StackGrowsDown, sti.getStackAlignment(), 0, Align(4 )),
178
299
STI(sti) {}
@@ -791,81 +912,32 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
791
912
return ;
792
913
}
793
914
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 ;
869
941
}
870
942
}
871
943
@@ -895,7 +967,10 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
895
967
DefCFAOffsetCandidates.addInst (LastPush, GPRCS1Size, true );
896
968
}
897
969
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.
899
974
unsigned FPCXTOffset = NumBytes - ArgRegsSaveSize - FPCXTSaveSize;
900
975
unsigned GPRCS1Offset = FPCXTOffset - GPRCS1Size;
901
976
unsigned GPRCS2Offset = GPRCS1Offset - GPRCS2Size;
@@ -915,10 +990,19 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
915
990
}
916
991
int FramePtrOffsetInPush = 0 ;
917
992
if (HasFP) {
993
+ // Offset from the CFA to the saved frame pointer, will be negative.
918
994
int FPOffset = MFI.getObjectOffset (FramePtrSpillFI);
995
+ LLVM_DEBUG (dbgs () << " FramePtrSpillFI: " << FramePtrSpillFI
996
+ << " , FPOffset: " << FPOffset << " \n " );
919
997
assert (getMaxFPOffset (STI, *AFI, MF) <= FPOffset &&
920
998
" Max FP estimation is wrong" );
999
+ // Offset from the top of the GPRCS1 area to the saved frame pointer, will
1000
+ // be negative.
921
1001
FramePtrOffsetInPush = FPOffset + ArgRegsSaveSize + FPCXTSaveSize;
1002
+ LLVM_DEBUG (dbgs () << " FramePtrOffsetInPush=" << FramePtrOffsetInPush
1003
+ << " , FramePtrSpillOffset="
1004
+ << (MFI.getObjectOffset (FramePtrSpillFI) + NumBytes)
1005
+ << " \n " );
922
1006
AFI->setFramePtrSpillOffset (MFI.getObjectOffset (FramePtrSpillFI) +
923
1007
NumBytes);
924
1008
}
@@ -1123,80 +1207,35 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1123
1207
// Now that the prologue's actual instructions are finalised, we can insert
1124
1208
// the necessary DWARF cf instructions to describe the situation. Start by
1125
1209
// 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)) {
1130
1212
Register Reg = Entry.getReg ();
1131
1213
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);
1155
1219
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.
1181
1229
break ;
1182
1230
}
1183
- }
1184
- }
1185
1231
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))
1200
1239
.addCFIIndex (CFIIndex)
1201
1240
.setMIFlags (MachineInstr::FrameSetup);
1202
1241
}
0 commit comments