19
19
#include " llvm/CodeGen/MachineFrameInfo.h"
20
20
#include " llvm/CodeGen/MachineFunction.h"
21
21
#include " llvm/CodeGen/MachineInstrBuilder.h"
22
+ #include " llvm/CodeGen/MachineModuleInfo.h"
22
23
#include " llvm/CodeGen/MachineRegisterInfo.h"
23
24
#include " llvm/CodeGen/RegisterScavenging.h"
24
25
#include " llvm/IR/CallingConv.h"
25
26
#include " llvm/IR/Function.h"
27
+ #include " llvm/MC/MCContext.h"
26
28
#include " llvm/Support/CommandLine.h"
27
29
#include " llvm/Target/TargetOptions.h"
28
30
@@ -129,11 +131,24 @@ static void emitSPUpdate(bool isARM, MachineBasicBlock &MBB,
129
131
MIFlags, Pred, PredReg);
130
132
}
131
133
134
+ static int sizeOfSPAdjustment (const MachineInstr *MI) {
135
+ assert (MI->getOpcode () == ARM::VSTMDDB_UPD);
136
+ int count = 0 ;
137
+ // ARM and Thumb2 push/pop insts have explicit "sp, sp" operands (+
138
+ // pred) so the list starts at 4.
139
+ for (int i = MI->getNumOperands () - 1 ; i >= 4 ; --i)
140
+ count += 8 ;
141
+ return count;
142
+ }
143
+
132
144
void ARMFrameLowering::emitPrologue (MachineFunction &MF) const {
133
145
MachineBasicBlock &MBB = MF.front ();
134
146
MachineBasicBlock::iterator MBBI = MBB.begin ();
135
147
MachineFrameInfo *MFI = MF.getFrameInfo ();
136
148
ARMFunctionInfo *AFI = MF.getInfo <ARMFunctionInfo>();
149
+ MachineModuleInfo &MMI = MF.getMMI ();
150
+ MCContext &Context = MMI.getContext ();
151
+ const MCRegisterInfo *MRI = Context.getRegisterInfo ();
137
152
const ARMBaseRegisterInfo *RegInfo =
138
153
static_cast <const ARMBaseRegisterInfo*>(MF.getTarget ().getRegisterInfo ());
139
154
const ARMBaseInstrInfo &TII =
@@ -147,6 +162,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
147
162
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo ();
148
163
DebugLoc dl = MBBI != MBB.end () ? MBBI->getDebugLoc () : DebugLoc ();
149
164
unsigned FramePtr = RegInfo->getFrameRegister (MF);
165
+ int CFAOffset = 0 ;
150
166
151
167
// Determine the sizes of each callee-save spill areas and record which frame
152
168
// belongs to which callee-save spill areas.
@@ -160,21 +176,46 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
160
176
return ;
161
177
162
178
// Allocate the vararg register save area. This is not counted in NumBytes.
163
- if (ArgRegsSaveSize)
179
+ if (ArgRegsSaveSize) {
164
180
emitSPUpdate (isARM, MBB, MBBI, dl, TII, -ArgRegsSaveSize,
165
181
MachineInstr::FrameSetup);
182
+ MCSymbol *SPLabel = Context.CreateTempSymbol ();
183
+ BuildMI (MBB, MBBI, dl, TII.get (TargetOpcode::PROLOG_LABEL))
184
+ .addSym (SPLabel);
185
+ CFAOffset -= ArgRegsSaveSize;
186
+ MMI.addFrameInst (
187
+ MCCFIInstruction::createDefCfaOffset (SPLabel, CFAOffset));
188
+ }
166
189
167
190
if (!AFI->hasStackFrame ()) {
168
- if (NumBytes != 0 )
191
+ if (NumBytes != 0 ) {
169
192
emitSPUpdate (isARM, MBB, MBBI, dl, TII, -NumBytes,
170
193
MachineInstr::FrameSetup);
194
+ MCSymbol *SPLabel = Context.CreateTempSymbol ();
195
+ BuildMI (MBB, MBBI, dl, TII.get (TargetOpcode::PROLOG_LABEL))
196
+ .addSym (SPLabel);
197
+ CFAOffset -= NumBytes;
198
+ MMI.addFrameInst (MCCFIInstruction::createDefCfaOffset (SPLabel,
199
+ CFAOffset));
200
+ }
171
201
return ;
172
202
}
173
203
204
+ // Determine spill area sizes.
174
205
for (unsigned i = 0 , e = CSI.size (); i != e; ++i) {
175
206
unsigned Reg = CSI[i].getReg ();
176
207
int FI = CSI[i].getFrameIdx ();
177
208
switch (Reg) {
209
+ case ARM::R8:
210
+ case ARM::R9:
211
+ case ARM::R10:
212
+ case ARM::R11:
213
+ case ARM::R12:
214
+ if (STI.isTargetMachO ()) {
215
+ GPRCS2Size += 4 ;
216
+ break ;
217
+ }
218
+ // fallthrough
178
219
case ARM::R0:
179
220
case ARM::R1:
180
221
case ARM::R2:
@@ -188,18 +229,6 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
188
229
FramePtrSpillFI = FI;
189
230
GPRCS1Size += 4 ;
190
231
break ;
191
- case ARM::R8:
192
- case ARM::R9:
193
- case ARM::R10:
194
- case ARM::R11:
195
- case ARM::R12:
196
- if (Reg == FramePtr)
197
- FramePtrSpillFI = FI;
198
- if (STI.isTargetMachO ())
199
- GPRCS2Size += 4 ;
200
- else
201
- GPRCS1Size += 4 ;
202
- break ;
203
232
default :
204
233
// This is a DPR. Exclude the aligned DPRCS2 spills.
205
234
if (Reg == ARM::D8)
@@ -210,9 +239,10 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
210
239
}
211
240
212
241
// Move past area 1.
213
- MachineBasicBlock::iterator LastPush = MBB.end (), FramePtrPush;
242
+ MachineBasicBlock::iterator LastPush = MBB.end (), GPRCS1Push, GPRCS2Push,
243
+ DPRCSPush;
214
244
if (GPRCS1Size > 0 )
215
- FramePtrPush = LastPush = MBBI++;
245
+ GPRCS1Push = LastPush = MBBI++;
216
246
217
247
// Determine starting offsets of spill areas.
218
248
bool HasFP = hasFP (MF);
@@ -230,13 +260,12 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
230
260
AFI->setDPRCalleeSavedAreaOffset (DPRCSOffset);
231
261
232
262
// Move past area 2.
233
- if (GPRCS2Size > 0 ) {
234
- LastPush = MBBI++;
235
- }
263
+ if (GPRCS2Size > 0 )
264
+ GPRCS2Push = LastPush = MBBI++;
236
265
237
266
// Move past area 3.
238
267
if (DPRCSSize > 0 ) {
239
- LastPush = MBBI++ ;
268
+ DPRCSPush = MBBI;
240
269
// Since vpush register list cannot have gaps, there may be multiple vpush
241
270
// instructions in the prologue.
242
271
while (MBBI->getOpcode () == ARM::VSTMDDB_UPD)
@@ -254,11 +283,15 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
254
283
} else
255
284
NumBytes = DPRCSOffset;
256
285
286
+ unsigned adjustedGPRCS1Size = GPRCS1Size;
257
287
if (NumBytes) {
258
288
// Adjust SP after all the callee-save spills.
259
289
if (tryFoldSPUpdateIntoPushPop (STI, MF, LastPush, NumBytes)) {
260
- if (LastPush == FramePtrPush)
290
+ if (LastPush == GPRCS1Push) {
261
291
FramePtrOffsetInPush += NumBytes;
292
+ adjustedGPRCS1Size += NumBytes;
293
+ NumBytes = 0 ;
294
+ }
262
295
} else
263
296
emitSPUpdate (isARM, MBB, MBBI, dl, TII, -NumBytes,
264
297
MachineInstr::FrameSetup);
@@ -275,17 +308,142 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
275
308
AFI->setShouldRestoreSPFromFP (true );
276
309
}
277
310
311
+ if (adjustedGPRCS1Size > 0 ) {
312
+ MCSymbol *SPLabel = Context.CreateTempSymbol ();
313
+ BuildMI (MBB, ++GPRCS1Push, dl, TII.get (TargetOpcode::PROLOG_LABEL))
314
+ .addSym (SPLabel);
315
+ CFAOffset -= adjustedGPRCS1Size;
316
+ MMI.addFrameInst (
317
+ MCCFIInstruction::createDefCfaOffset (SPLabel, CFAOffset));
318
+ for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin (),
319
+ E = CSI.end (); I != E; ++I) {
320
+ unsigned Reg = I->getReg ();
321
+ int FI = I->getFrameIdx ();
322
+ switch (Reg) {
323
+ case ARM::R8:
324
+ case ARM::R9:
325
+ case ARM::R10:
326
+ case ARM::R11:
327
+ case ARM::R12:
328
+ if (STI.isTargetMachO ())
329
+ break ;
330
+ // fallthrough
331
+ case ARM::R0:
332
+ case ARM::R1:
333
+ case ARM::R2:
334
+ case ARM::R3:
335
+ case ARM::R4:
336
+ case ARM::R5:
337
+ case ARM::R6:
338
+ case ARM::R7:
339
+ case ARM::LR:
340
+ MMI.addFrameInst (MCCFIInstruction::createOffset (SPLabel,
341
+ MRI->getDwarfRegNum (Reg, true ),
342
+ MFI->getObjectOffset (FI) - ArgRegsSaveSize));
343
+ break ;
344
+ }
345
+ }
346
+ }
347
+
278
348
// Set FP to point to the stack slot that contains the previous FP.
279
349
// For iOS, FP is R7, which has now been stored in spill area 1.
280
350
// Otherwise, if this is not iOS, all the callee-saved registers go
281
351
// into spill area 1, including the FP in R11. In either case, it
282
352
// is in area one and the adjustment needs to take place just after
283
353
// that push.
284
- if (HasFP)
285
- emitRegPlusImmediate (!AFI->isThumbFunction (), MBB, ++FramePtrPush , dl, TII,
354
+ if (HasFP) {
355
+ emitRegPlusImmediate (!AFI->isThumbFunction (), MBB, GPRCS1Push , dl, TII,
286
356
FramePtr, ARM::SP, FramePtrOffsetInPush,
287
357
MachineInstr::FrameSetup);
358
+ MCSymbol *SPLabel = Context.CreateTempSymbol ();
359
+ BuildMI (MBB, GPRCS1Push, dl, TII.get (TargetOpcode::PROLOG_LABEL))
360
+ .addSym (SPLabel);
361
+ if (FramePtrOffsetInPush) {
362
+ CFAOffset += FramePtrOffsetInPush;
363
+ MMI.addFrameInst (
364
+ MCCFIInstruction::createDefCfa (SPLabel,
365
+ MRI->getDwarfRegNum (FramePtr, true ), CFAOffset));
366
+ } else
367
+ MMI.addFrameInst (
368
+ MCCFIInstruction::createDefCfaRegister (SPLabel,
369
+ MRI->getDwarfRegNum (FramePtr, true )));
370
+ }
288
371
372
+ if (GPRCS2Size > 0 ) {
373
+ MCSymbol *SPLabel = Context.CreateTempSymbol ();
374
+ BuildMI (MBB, ++GPRCS2Push, dl, TII.get (TargetOpcode::PROLOG_LABEL))
375
+ .addSym (SPLabel);
376
+ if (!HasFP) {
377
+ CFAOffset -= GPRCS2Size;
378
+ MMI.addFrameInst (
379
+ MCCFIInstruction::createDefCfaOffset (SPLabel, CFAOffset));
380
+ }
381
+ for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin (),
382
+ E = CSI.end (); I != E; ++I) {
383
+ unsigned Reg = I->getReg ();
384
+ int FI = I->getFrameIdx ();
385
+ switch (Reg) {
386
+ case ARM::R8:
387
+ case ARM::R9:
388
+ case ARM::R10:
389
+ case ARM::R11:
390
+ case ARM::R12:
391
+ if (STI.isTargetMachO ()) {
392
+ unsigned DwarfReg = MRI->getDwarfRegNum (Reg, true );
393
+ unsigned Offset = MFI->getObjectOffset (FI) - ArgRegsSaveSize;
394
+ MMI.addFrameInst (
395
+ MCCFIInstruction::createOffset (SPLabel, DwarfReg, Offset));
396
+ }
397
+ break ;
398
+ }
399
+ }
400
+ }
401
+
402
+ if (DPRCSSize > 0 ) {
403
+ // Since vpush register list cannot have gaps, there may be multiple vpush
404
+ // instructions in the prologue.
405
+ MCSymbol *SPLabel = NULL ;
406
+ do {
407
+ MachineBasicBlock::iterator Push = DPRCSPush++;
408
+ if (!HasFP) {
409
+ SPLabel = Context.CreateTempSymbol ();
410
+ BuildMI (MBB, DPRCSPush, dl, TII.get (TargetOpcode::PROLOG_LABEL))
411
+ .addSym (SPLabel);
412
+ CFAOffset -= sizeOfSPAdjustment (Push);;
413
+ MMI.addFrameInst (
414
+ MCCFIInstruction::createDefCfaOffset (SPLabel, CFAOffset));
415
+ }
416
+ } while (DPRCSPush->getOpcode () == ARM::VSTMDDB_UPD);
417
+
418
+ if (!SPLabel) {
419
+ SPLabel = Context.CreateTempSymbol ();
420
+ BuildMI (MBB, DPRCSPush, dl, TII.get (TargetOpcode::PROLOG_LABEL))
421
+ .addSym (SPLabel);
422
+ }
423
+ for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin (),
424
+ E = CSI.end (); I != E; ++I) {
425
+ unsigned Reg = I->getReg ();
426
+ int FI = I->getFrameIdx ();
427
+ if ((Reg >= ARM::D0 && Reg <= ARM::D31) &&
428
+ (Reg < ARM::D8 || Reg >= ARM::D8 + AFI->getNumAlignedDPRCS2Regs ())) {
429
+ unsigned DwarfReg = MRI->getDwarfRegNum (Reg, true );
430
+ unsigned Offset = MFI->getObjectOffset (FI);
431
+ MMI.addFrameInst (MCCFIInstruction::createOffset (SPLabel, DwarfReg,
432
+ Offset));
433
+ }
434
+ }
435
+ }
436
+
437
+ if (NumBytes) {
438
+ if (!HasFP) {
439
+ MCSymbol *SPLabel = Context.CreateTempSymbol ();
440
+ BuildMI (MBB, MBBI, dl, TII.get (TargetOpcode::PROLOG_LABEL))
441
+ .addSym (SPLabel);
442
+ CFAOffset -= NumBytes;
443
+ MMI.addFrameInst (
444
+ MCCFIInstruction::createDefCfaOffset (SPLabel, CFAOffset));
445
+ }
446
+ }
289
447
290
448
if (STI.isTargetELF () && hasFP (MF))
291
449
MFI->setOffsetAdjustment (MFI->getOffsetAdjustment () -
0 commit comments