@@ -173,6 +173,95 @@ 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: 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
+
176
265
ARMFrameLowering::ARMFrameLowering (const ARMSubtarget &sti)
177
266
: TargetFrameLowering(StackGrowsDown, sti.getStackAlignment(), 0, Align(4 )),
178
267
STI(sti) {}
@@ -791,81 +880,32 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
791
880
return ;
792
881
}
793
882
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 ;
869
909
}
870
910
}
871
911
@@ -895,7 +935,10 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
895
935
DefCFAOffsetCandidates.addInst (LastPush, GPRCS1Size, true );
896
936
}
897
937
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.
899
942
unsigned FPCXTOffset = NumBytes - ArgRegsSaveSize - FPCXTSaveSize;
900
943
unsigned GPRCS1Offset = FPCXTOffset - GPRCS1Size;
901
944
unsigned GPRCS2Offset = GPRCS1Offset - GPRCS2Size;
@@ -915,10 +958,19 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
915
958
}
916
959
int FramePtrOffsetInPush = 0 ;
917
960
if (HasFP) {
961
+ // Offset from the CFA to the saved frame pointer, will be negative.
918
962
int FPOffset = MFI.getObjectOffset (FramePtrSpillFI);
963
+ LLVM_DEBUG (dbgs () << " FramePtrSpillFI: " << FramePtrSpillFI
964
+ << " , FPOffset: " << FPOffset << " \n " );
919
965
assert (getMaxFPOffset (STI, *AFI, MF) <= FPOffset &&
920
966
" Max FP estimation is wrong" );
967
+ // Offset from the top of the GPRCS1 area to the saved frame pointer, will
968
+ // be negative.
921
969
FramePtrOffsetInPush = FPOffset + ArgRegsSaveSize + FPCXTSaveSize;
970
+ LLVM_DEBUG (dbgs () << " FramePtrOffsetInPush=" << FramePtrOffsetInPush
971
+ << " , FramePtrSpillOffset="
972
+ << (MFI.getObjectOffset (FramePtrSpillFI) + NumBytes)
973
+ << " \n " );
922
974
AFI->setFramePtrSpillOffset (MFI.getObjectOffset (FramePtrSpillFI) +
923
975
NumBytes);
924
976
}
@@ -1123,80 +1175,34 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
1123
1175
// Now that the prologue's actual instructions are finalised, we can insert
1124
1176
// the necessary DWARF cf instructions to describe the situation. Start by
1125
1177
// 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)) {
1130
1180
Register Reg = Entry.getReg ();
1131
1181
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);
1155
1187
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.
1181
1197
break ;
1182
1198
}
1183
- }
1184
- }
1185
1199
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))
1200
1206
.addCFIIndex (CFIIndex)
1201
1207
.setMIFlags (MachineInstr::FrameSetup);
1202
1208
}
0 commit comments