Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/M68k/M68kFrameLowering.cpp
35269 views
1
//===-- M68kFrameLowering.cpp - M68k Frame Information ----------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// This file contains the M68k implementation of TargetFrameLowering class.
11
///
12
//===----------------------------------------------------------------------===//
13
14
#include "M68kFrameLowering.h"
15
16
#include "M68kInstrBuilder.h"
17
#include "M68kInstrInfo.h"
18
#include "M68kMachineFunction.h"
19
#include "M68kSubtarget.h"
20
21
#include "llvm/ADT/SmallSet.h"
22
#include "llvm/CodeGen/MachineFrameInfo.h"
23
#include "llvm/CodeGen/MachineFunction.h"
24
#include "llvm/CodeGen/MachineInstrBuilder.h"
25
#include "llvm/CodeGen/MachineModuleInfo.h"
26
#include "llvm/CodeGen/MachineRegisterInfo.h"
27
#include "llvm/IR/DataLayout.h"
28
#include "llvm/IR/Function.h"
29
#include "llvm/Support/Alignment.h"
30
#include "llvm/Support/CommandLine.h"
31
#include "llvm/Target/TargetMachine.h"
32
#include "llvm/Target/TargetOptions.h"
33
34
using namespace llvm;
35
36
M68kFrameLowering::M68kFrameLowering(const M68kSubtarget &STI, Align Alignment)
37
: TargetFrameLowering(StackGrowsDown, Alignment, -4), STI(STI),
38
TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {
39
SlotSize = STI.getSlotSize();
40
StackPtr = TRI->getStackRegister();
41
}
42
43
bool M68kFrameLowering::hasFP(const MachineFunction &MF) const {
44
const MachineFrameInfo &MFI = MF.getFrameInfo();
45
const TargetRegisterInfo *TRI = STI.getRegisterInfo();
46
47
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
48
MFI.hasVarSizedObjects() || MFI.isFrameAddressTaken() ||
49
TRI->hasStackRealignment(MF);
50
}
51
52
// FIXME Make sure no other factors prevent us from reserving call frame
53
bool M68kFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
54
return !MF.getFrameInfo().hasVarSizedObjects() &&
55
!MF.getInfo<M68kMachineFunctionInfo>()->getHasPushSequences();
56
}
57
58
bool M68kFrameLowering::canSimplifyCallFramePseudos(
59
const MachineFunction &MF) const {
60
return hasReservedCallFrame(MF) ||
61
(hasFP(MF) && !TRI->hasStackRealignment(MF)) ||
62
TRI->hasBasePointer(MF);
63
}
64
65
bool M68kFrameLowering::needsFrameIndexResolution(
66
const MachineFunction &MF) const {
67
return MF.getFrameInfo().hasStackObjects() ||
68
MF.getInfo<M68kMachineFunctionInfo>()->getHasPushSequences();
69
}
70
71
// NOTE: this only has a subset of the full frame index logic. In
72
// particular, the FI < 0 and AfterFPPop logic is handled in
73
// M68kRegisterInfo::eliminateFrameIndex, but not here. Possibly
74
// (probably?) it should be moved into here.
75
StackOffset
76
M68kFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
77
Register &FrameReg) const {
78
const MachineFrameInfo &MFI = MF.getFrameInfo();
79
80
// We can't calculate offset from frame pointer if the stack is realigned,
81
// so enforce usage of stack/base pointer. The base pointer is used when we
82
// have dynamic allocas in addition to dynamic realignment.
83
if (TRI->hasBasePointer(MF))
84
FrameReg = TRI->getBaseRegister();
85
else if (TRI->hasStackRealignment(MF))
86
FrameReg = TRI->getStackRegister();
87
else
88
FrameReg = TRI->getFrameRegister(MF);
89
90
// Offset will hold the offset from the stack pointer at function entry to the
91
// object.
92
// We need to factor in additional offsets applied during the prologue to the
93
// frame, base, and stack pointer depending on which is used.
94
int Offset = MFI.getObjectOffset(FI) - getOffsetOfLocalArea();
95
const M68kMachineFunctionInfo *MMFI = MF.getInfo<M68kMachineFunctionInfo>();
96
uint64_t StackSize = MFI.getStackSize();
97
bool HasFP = hasFP(MF);
98
99
// TODO: Support tail calls
100
if (TRI->hasBasePointer(MF)) {
101
assert(HasFP && "VLAs and dynamic stack realign, but no FP?!");
102
if (FI < 0) {
103
// Skip the saved FP.
104
return StackOffset::getFixed(Offset + SlotSize);
105
}
106
107
assert((-(Offset + StackSize)) % MFI.getObjectAlign(FI).value() == 0);
108
return StackOffset::getFixed(Offset + StackSize);
109
}
110
if (TRI->hasStackRealignment(MF)) {
111
if (FI < 0) {
112
// Skip the saved FP.
113
return StackOffset::getFixed(Offset + SlotSize);
114
}
115
116
assert((-(Offset + StackSize)) % MFI.getObjectAlign(FI).value() == 0);
117
return StackOffset::getFixed(Offset + StackSize);
118
}
119
120
if (!HasFP)
121
return StackOffset::getFixed(Offset + StackSize);
122
123
// Skip the saved FP.
124
Offset += SlotSize;
125
126
// Skip the RETADDR move area
127
int TailCallReturnAddrDelta = MMFI->getTCReturnAddrDelta();
128
if (TailCallReturnAddrDelta < 0)
129
Offset -= TailCallReturnAddrDelta;
130
131
return StackOffset::getFixed(Offset);
132
}
133
134
/// Return a caller-saved register that isn't live
135
/// when it reaches the "return" instruction. We can then pop a stack object
136
/// to this register without worry about clobbering it.
137
static unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB,
138
MachineBasicBlock::iterator &MBBI,
139
const M68kRegisterInfo *TRI) {
140
const MachineFunction *MF = MBB.getParent();
141
if (MF->callsEHReturn())
142
return 0;
143
144
const TargetRegisterClass &AvailableRegs = *TRI->getRegsForTailCall(*MF);
145
146
if (MBBI == MBB.end())
147
return 0;
148
149
switch (MBBI->getOpcode()) {
150
default:
151
return 0;
152
case TargetOpcode::PATCHABLE_RET:
153
case M68k::RET: {
154
SmallSet<uint16_t, 8> Uses;
155
156
for (unsigned i = 0, e = MBBI->getNumOperands(); i != e; ++i) {
157
MachineOperand &MO = MBBI->getOperand(i);
158
if (!MO.isReg() || MO.isDef())
159
continue;
160
Register Reg = MO.getReg();
161
if (!Reg)
162
continue;
163
for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
164
Uses.insert(*AI);
165
}
166
167
for (auto CS : AvailableRegs)
168
if (!Uses.count(CS))
169
return CS;
170
}
171
}
172
173
return 0;
174
}
175
176
static bool isRegLiveIn(MachineBasicBlock &MBB, unsigned Reg) {
177
return llvm::any_of(MBB.liveins(),
178
[Reg](MachineBasicBlock::RegisterMaskPair RegMask) {
179
return RegMask.PhysReg == Reg;
180
});
181
}
182
183
uint64_t
184
M68kFrameLowering::calculateMaxStackAlign(const MachineFunction &MF) const {
185
const MachineFrameInfo &MFI = MF.getFrameInfo();
186
uint64_t MaxAlign = MFI.getMaxAlign().value(); // Desired stack alignment.
187
unsigned StackAlign = getStackAlignment(); // ABI alignment
188
if (MF.getFunction().hasFnAttribute("stackrealign")) {
189
if (MFI.hasCalls())
190
MaxAlign = (StackAlign > MaxAlign) ? StackAlign : MaxAlign;
191
else if (MaxAlign < SlotSize)
192
MaxAlign = SlotSize;
193
}
194
return MaxAlign;
195
}
196
197
void M68kFrameLowering::BuildStackAlignAND(MachineBasicBlock &MBB,
198
MachineBasicBlock::iterator MBBI,
199
const DebugLoc &DL, unsigned Reg,
200
uint64_t MaxAlign) const {
201
uint64_t Val = -MaxAlign;
202
unsigned AndOp = M68k::AND32di;
203
unsigned MovOp = M68k::MOV32rr;
204
205
// This function is normally used with SP which is Address Register, but AND,
206
// or any other logical instructions in M68k do not support ARs so we need
207
// to use a temp Data Register to perform the op.
208
unsigned Tmp = M68k::D0;
209
210
BuildMI(MBB, MBBI, DL, TII.get(MovOp), Tmp)
211
.addReg(Reg)
212
.setMIFlag(MachineInstr::FrameSetup);
213
214
MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(AndOp), Tmp)
215
.addReg(Tmp)
216
.addImm(Val)
217
.setMIFlag(MachineInstr::FrameSetup);
218
219
// The CCR implicit def is dead.
220
MI->getOperand(3).setIsDead();
221
222
BuildMI(MBB, MBBI, DL, TII.get(MovOp), Reg)
223
.addReg(Tmp)
224
.setMIFlag(MachineInstr::FrameSetup);
225
}
226
227
MachineBasicBlock::iterator M68kFrameLowering::eliminateCallFramePseudoInstr(
228
MachineFunction &MF, MachineBasicBlock &MBB,
229
MachineBasicBlock::iterator I) const {
230
bool ReserveCallFrame = hasReservedCallFrame(MF);
231
unsigned Opcode = I->getOpcode();
232
bool IsDestroy = Opcode == TII.getCallFrameDestroyOpcode();
233
DebugLoc DL = I->getDebugLoc();
234
uint64_t Amount = !ReserveCallFrame ? I->getOperand(0).getImm() : 0;
235
uint64_t InternalAmt = (IsDestroy && Amount) ? I->getOperand(1).getImm() : 0;
236
I = MBB.erase(I);
237
238
if (!ReserveCallFrame) {
239
// If the stack pointer can be changed after prologue, turn the
240
// adjcallstackup instruction into a 'sub %SP, <amt>' and the
241
// adjcallstackdown instruction into 'add %SP, <amt>'
242
243
// We need to keep the stack aligned properly. To do this, we round the
244
// amount of space needed for the outgoing arguments up to the next
245
// alignment boundary.
246
unsigned StackAlign = getStackAlignment();
247
Amount = alignTo(Amount, StackAlign);
248
249
bool DwarfCFI = MF.needsFrameMoves();
250
251
// If we have any exception handlers in this function, and we adjust
252
// the SP before calls, we may need to indicate this to the unwinder
253
// using GNU_ARGS_SIZE. Note that this may be necessary even when
254
// Amount == 0, because the preceding function may have set a non-0
255
// GNU_ARGS_SIZE.
256
// TODO: We don't need to reset this between subsequent functions,
257
// if it didn't change.
258
bool HasDwarfEHHandlers = !MF.getLandingPads().empty();
259
260
if (HasDwarfEHHandlers && !IsDestroy &&
261
MF.getInfo<M68kMachineFunctionInfo>()->getHasPushSequences()) {
262
BuildCFI(MBB, I, DL,
263
MCCFIInstruction::createGnuArgsSize(nullptr, Amount));
264
}
265
266
if (Amount == 0)
267
return I;
268
269
// Factor out the amount that gets handled inside the sequence
270
// (Pushes of argument for frame setup, callee pops for frame destroy)
271
Amount -= InternalAmt;
272
273
// TODO: This is needed only if we require precise CFA.
274
// If this is a callee-pop calling convention, emit a CFA adjust for
275
// the amount the callee popped.
276
if (IsDestroy && InternalAmt && DwarfCFI && !hasFP(MF))
277
BuildCFI(MBB, I, DL,
278
MCCFIInstruction::createAdjustCfaOffset(nullptr, -InternalAmt));
279
280
// Add Amount to SP to destroy a frame, or subtract to setup.
281
int64_t StackAdjustment = IsDestroy ? Amount : -Amount;
282
int64_t CfaAdjustment = -StackAdjustment;
283
284
if (StackAdjustment) {
285
// Merge with any previous or following adjustment instruction. Note: the
286
// instructions merged with here do not have CFI, so their stack
287
// adjustments do not feed into CfaAdjustment.
288
StackAdjustment += mergeSPUpdates(MBB, I, true);
289
StackAdjustment += mergeSPUpdates(MBB, I, false);
290
291
if (StackAdjustment) {
292
BuildStackAdjustment(MBB, I, DL, StackAdjustment, false);
293
}
294
}
295
296
if (DwarfCFI && !hasFP(MF)) {
297
// If we don't have FP, but need to generate unwind information,
298
// we need to set the correct CFA offset after the stack adjustment.
299
// How much we adjust the CFA offset depends on whether we're emitting
300
// CFI only for EH purposes or for debugging. EH only requires the CFA
301
// offset to be correct at each call site, while for debugging we want
302
// it to be more precise.
303
304
// TODO: When not using precise CFA, we also need to adjust for the
305
// InternalAmt here.
306
if (CfaAdjustment) {
307
BuildCFI(
308
MBB, I, DL,
309
MCCFIInstruction::createAdjustCfaOffset(nullptr, CfaAdjustment));
310
}
311
}
312
313
return I;
314
}
315
316
if (IsDestroy && InternalAmt) {
317
// If we are performing frame pointer elimination and if the callee pops
318
// something off the stack pointer, add it back. We do this until we have
319
// more advanced stack pointer tracking ability.
320
// We are not tracking the stack pointer adjustment by the callee, so make
321
// sure we restore the stack pointer immediately after the call, there may
322
// be spill code inserted between the CALL and ADJCALLSTACKUP instructions.
323
MachineBasicBlock::iterator CI = I;
324
MachineBasicBlock::iterator B = MBB.begin();
325
while (CI != B && !std::prev(CI)->isCall())
326
--CI;
327
BuildStackAdjustment(MBB, CI, DL, -InternalAmt, /*InEpilogue=*/false);
328
}
329
330
return I;
331
}
332
333
/// Emit a series of instructions to increment / decrement the stack pointer by
334
/// a constant value.
335
void M68kFrameLowering::emitSPUpdate(MachineBasicBlock &MBB,
336
MachineBasicBlock::iterator &MBBI,
337
int64_t NumBytes, bool InEpilogue) const {
338
bool IsSub = NumBytes < 0;
339
uint64_t Offset = IsSub ? -NumBytes : NumBytes;
340
341
uint64_t Chunk = (1LL << 31) - 1;
342
DebugLoc DL = MBB.findDebugLoc(MBBI);
343
344
while (Offset) {
345
if (Offset > Chunk) {
346
// Rather than emit a long series of instructions for large offsets,
347
// load the offset into a register and do one sub/add
348
Register Reg;
349
350
if (IsSub && !isRegLiveIn(MBB, M68k::D0))
351
Reg = M68k::D0;
352
else
353
Reg = findDeadCallerSavedReg(MBB, MBBI, TRI);
354
355
if (Reg) {
356
unsigned Opc = M68k::MOV32ri;
357
BuildMI(MBB, MBBI, DL, TII.get(Opc), Reg).addImm(Offset);
358
Opc = IsSub ? M68k::SUB32ar : M68k::ADD32ar;
359
MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr)
360
.addReg(StackPtr)
361
.addReg(Reg);
362
// ??? still no CCR
363
MI->getOperand(3).setIsDead(); // The CCR implicit def is dead.
364
Offset = 0;
365
continue;
366
}
367
}
368
369
uint64_t ThisVal = std::min(Offset, Chunk);
370
371
MachineInstrBuilder MI = BuildStackAdjustment(
372
MBB, MBBI, DL, IsSub ? -ThisVal : ThisVal, InEpilogue);
373
if (IsSub)
374
MI.setMIFlag(MachineInstr::FrameSetup);
375
else
376
MI.setMIFlag(MachineInstr::FrameDestroy);
377
378
Offset -= ThisVal;
379
}
380
}
381
382
int M68kFrameLowering::mergeSPUpdates(MachineBasicBlock &MBB,
383
MachineBasicBlock::iterator &MBBI,
384
bool MergeWithPrevious) const {
385
if ((MergeWithPrevious && MBBI == MBB.begin()) ||
386
(!MergeWithPrevious && MBBI == MBB.end()))
387
return 0;
388
389
MachineBasicBlock::iterator PI = MergeWithPrevious ? std::prev(MBBI) : MBBI;
390
MachineBasicBlock::iterator NI =
391
MergeWithPrevious ? nullptr : std::next(MBBI);
392
unsigned Opc = PI->getOpcode();
393
int Offset = 0;
394
395
if (!MergeWithPrevious && NI != MBB.end() &&
396
NI->getOpcode() == TargetOpcode::CFI_INSTRUCTION) {
397
// Don't merge with the next instruction if it has CFI.
398
return Offset;
399
}
400
401
if (Opc == M68k::ADD32ai && PI->getOperand(0).getReg() == StackPtr) {
402
assert(PI->getOperand(1).getReg() == StackPtr);
403
Offset += PI->getOperand(2).getImm();
404
MBB.erase(PI);
405
if (!MergeWithPrevious)
406
MBBI = NI;
407
} else if (Opc == M68k::SUB32ai && PI->getOperand(0).getReg() == StackPtr) {
408
assert(PI->getOperand(1).getReg() == StackPtr);
409
Offset -= PI->getOperand(2).getImm();
410
MBB.erase(PI);
411
if (!MergeWithPrevious)
412
MBBI = NI;
413
}
414
415
return Offset;
416
}
417
418
MachineInstrBuilder M68kFrameLowering::BuildStackAdjustment(
419
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
420
const DebugLoc &DL, int64_t Offset, bool InEpilogue) const {
421
assert(Offset != 0 && "zero offset stack adjustment requested");
422
423
// TODO can `lea` be used to adjust stack?
424
425
bool IsSub = Offset < 0;
426
uint64_t AbsOffset = IsSub ? -Offset : Offset;
427
unsigned Opc = IsSub ? M68k::SUB32ai : M68k::ADD32ai;
428
429
MachineInstrBuilder MI = BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr)
430
.addReg(StackPtr)
431
.addImm(AbsOffset);
432
// FIXME Update CCR as well. For now we just
433
// conservatively say CCR implicit def is dead
434
MI->getOperand(3).setIsDead();
435
return MI;
436
}
437
438
void M68kFrameLowering::BuildCFI(MachineBasicBlock &MBB,
439
MachineBasicBlock::iterator MBBI,
440
const DebugLoc &DL,
441
const MCCFIInstruction &CFIInst) const {
442
MachineFunction &MF = *MBB.getParent();
443
unsigned CFIIndex = MF.addFrameInst(CFIInst);
444
BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
445
.addCFIIndex(CFIIndex);
446
}
447
448
void M68kFrameLowering::emitPrologueCalleeSavedFrameMoves(
449
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
450
const DebugLoc &DL) const {
451
MachineFunction &MF = *MBB.getParent();
452
MachineFrameInfo &MFI = MF.getFrameInfo();
453
const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();
454
455
// Add callee saved registers to move list.
456
const auto &CSI = MFI.getCalleeSavedInfo();
457
if (CSI.empty())
458
return;
459
460
// Calculate offsets.
461
for (const auto &I : CSI) {
462
int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());
463
Register Reg = I.getReg();
464
465
unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);
466
BuildCFI(MBB, MBBI, DL,
467
MCCFIInstruction::createOffset(nullptr, DwarfReg, Offset));
468
}
469
}
470
471
void M68kFrameLowering::emitPrologue(MachineFunction &MF,
472
MachineBasicBlock &MBB) const {
473
assert(&STI == &MF.getSubtarget<M68kSubtarget>() &&
474
"MF used frame lowering for wrong subtarget");
475
476
MachineBasicBlock::iterator MBBI = MBB.begin();
477
MachineFrameInfo &MFI = MF.getFrameInfo();
478
const auto &Fn = MF.getFunction();
479
MachineModuleInfo &MMI = MF.getMMI();
480
M68kMachineFunctionInfo *MMFI = MF.getInfo<M68kMachineFunctionInfo>();
481
uint64_t MaxAlign = calculateMaxStackAlign(MF); // Desired stack alignment.
482
uint64_t StackSize = MFI.getStackSize(); // Number of bytes to allocate.
483
bool HasFP = hasFP(MF);
484
bool NeedsDwarfCFI = MMI.hasDebugInfo() || Fn.needsUnwindTableEntry();
485
Register FramePtr = TRI->getFrameRegister(MF);
486
const unsigned MachineFramePtr = FramePtr;
487
unsigned BasePtr = TRI->getBaseRegister();
488
489
// Debug location must be unknown since the first debug location is used
490
// to determine the end of the prologue.
491
DebugLoc DL;
492
493
// Add RETADDR move area to callee saved frame size.
494
int TailCallReturnAddrDelta = MMFI->getTCReturnAddrDelta();
495
496
if (TailCallReturnAddrDelta < 0) {
497
MMFI->setCalleeSavedFrameSize(MMFI->getCalleeSavedFrameSize() -
498
TailCallReturnAddrDelta);
499
}
500
501
// Insert stack pointer adjustment for later moving of return addr. Only
502
// applies to tail call optimized functions where the callee argument stack
503
// size is bigger than the callers.
504
if (TailCallReturnAddrDelta < 0) {
505
BuildStackAdjustment(MBB, MBBI, DL, TailCallReturnAddrDelta,
506
/*InEpilogue=*/false)
507
.setMIFlag(MachineInstr::FrameSetup);
508
}
509
510
// Mapping for machine moves:
511
//
512
// DST: VirtualFP AND
513
// SRC: VirtualFP => DW_CFA_def_cfa_offset
514
// ELSE => DW_CFA_def_cfa
515
//
516
// SRC: VirtualFP AND
517
// DST: Register => DW_CFA_def_cfa_register
518
//
519
// ELSE
520
// OFFSET < 0 => DW_CFA_offset_extended_sf
521
// REG < 64 => DW_CFA_offset + Reg
522
// ELSE => DW_CFA_offset_extended
523
524
uint64_t NumBytes = 0;
525
int stackGrowth = -SlotSize;
526
527
if (HasFP) {
528
// Calculate required stack adjustment.
529
uint64_t FrameSize = StackSize - SlotSize;
530
// If required, include space for extra hidden slot for stashing base
531
// pointer.
532
if (MMFI->getRestoreBasePointer())
533
FrameSize += SlotSize;
534
535
NumBytes = FrameSize - MMFI->getCalleeSavedFrameSize();
536
537
// Callee-saved registers are pushed on stack before the stack is realigned.
538
if (TRI->hasStackRealignment(MF))
539
NumBytes = alignTo(NumBytes, MaxAlign);
540
541
// Get the offset of the stack slot for the FP register, which is
542
// guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
543
// Update the frame offset adjustment.
544
MFI.setOffsetAdjustment(-NumBytes);
545
546
BuildMI(MBB, MBBI, DL, TII.get(M68k::LINK16))
547
.addReg(M68k::WA6, RegState::Kill)
548
.addImm(-NumBytes)
549
.setMIFlag(MachineInstr::FrameSetup);
550
551
if (NeedsDwarfCFI) {
552
// Mark the place where FP was saved.
553
// Define the current CFA rule to use the provided offset.
554
assert(StackSize);
555
BuildCFI(MBB, MBBI, DL,
556
MCCFIInstruction::cfiDefCfaOffset(nullptr, 2 * stackGrowth));
557
558
// Change the rule for the FramePtr to be an "offset" rule.
559
int DwarfFramePtr = TRI->getDwarfRegNum(MachineFramePtr, true);
560
assert(DwarfFramePtr > 0);
561
BuildCFI(MBB, MBBI, DL,
562
MCCFIInstruction::createOffset(nullptr, DwarfFramePtr,
563
2 * stackGrowth));
564
}
565
566
if (NeedsDwarfCFI) {
567
// Mark effective beginning of when frame pointer becomes valid.
568
// Define the current CFA to use the FP register.
569
unsigned DwarfFramePtr = TRI->getDwarfRegNum(MachineFramePtr, true);
570
BuildCFI(MBB, MBBI, DL,
571
MCCFIInstruction::createDefCfaRegister(nullptr, DwarfFramePtr));
572
}
573
574
// Mark the FramePtr as live-in in every block. Don't do this again for
575
// funclet prologues.
576
for (MachineBasicBlock &EveryMBB : MF)
577
EveryMBB.addLiveIn(MachineFramePtr);
578
} else {
579
NumBytes = StackSize - MMFI->getCalleeSavedFrameSize();
580
}
581
582
// Skip the callee-saved push instructions.
583
bool PushedRegs = false;
584
int StackOffset = 2 * stackGrowth;
585
586
while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup) &&
587
MBBI->getOpcode() == M68k::PUSH32r) {
588
PushedRegs = true;
589
++MBBI;
590
591
if (!HasFP && NeedsDwarfCFI) {
592
// Mark callee-saved push instruction.
593
// Define the current CFA rule to use the provided offset.
594
assert(StackSize);
595
BuildCFI(MBB, MBBI, DL,
596
MCCFIInstruction::cfiDefCfaOffset(nullptr, StackOffset));
597
StackOffset += stackGrowth;
598
}
599
}
600
601
// Realign stack after we pushed callee-saved registers (so that we'll be
602
// able to calculate their offsets from the frame pointer).
603
if (TRI->hasStackRealignment(MF)) {
604
assert(HasFP && "There should be a frame pointer if stack is realigned.");
605
BuildStackAlignAND(MBB, MBBI, DL, StackPtr, MaxAlign);
606
}
607
608
// If there is an SUB32ri of SP immediately before this instruction, merge
609
// the two. This can be the case when tail call elimination is enabled and
610
// the callee has more arguments then the caller.
611
NumBytes -= mergeSPUpdates(MBB, MBBI, true);
612
613
// Adjust stack pointer: ESP -= numbytes.
614
if (!HasFP)
615
emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, /*InEpilogue=*/false);
616
617
unsigned SPOrEstablisher = StackPtr;
618
619
// If we need a base pointer, set it up here. It's whatever the value
620
// of the stack pointer is at this point. Any variable size objects
621
// will be allocated after this, so we can still use the base pointer
622
// to reference locals.
623
if (TRI->hasBasePointer(MF)) {
624
// Update the base pointer with the current stack pointer.
625
BuildMI(MBB, MBBI, DL, TII.get(M68k::MOV32aa), BasePtr)
626
.addReg(SPOrEstablisher)
627
.setMIFlag(MachineInstr::FrameSetup);
628
if (MMFI->getRestoreBasePointer()) {
629
// Stash value of base pointer. Saving SP instead of FP shortens
630
// dependence chain. Used by SjLj EH.
631
unsigned Opm = M68k::MOV32ja;
632
M68k::addRegIndirectWithDisp(BuildMI(MBB, MBBI, DL, TII.get(Opm)),
633
FramePtr, true,
634
MMFI->getRestoreBasePointerOffset())
635
.addReg(SPOrEstablisher)
636
.setMIFlag(MachineInstr::FrameSetup);
637
}
638
}
639
640
if (((!HasFP && NumBytes) || PushedRegs) && NeedsDwarfCFI) {
641
// Mark end of stack pointer adjustment.
642
if (!HasFP && NumBytes) {
643
// Define the current CFA rule to use the provided offset.
644
assert(StackSize);
645
BuildCFI(
646
MBB, MBBI, DL,
647
MCCFIInstruction::cfiDefCfaOffset(nullptr, -StackSize + stackGrowth));
648
}
649
650
// Emit DWARF info specifying the offsets of the callee-saved registers.
651
if (PushedRegs)
652
emitPrologueCalleeSavedFrameMoves(MBB, MBBI, DL);
653
}
654
655
// TODO Interrupt handlers
656
// M68k Interrupt handling function cannot assume anything about the
657
// direction flag (DF in CCR register). Clear this flag by creating "cld"
658
// instruction in each prologue of interrupt handler function. The "cld"
659
// instruction should only in these cases:
660
// 1. The interrupt handling function uses any of the "rep" instructions.
661
// 2. Interrupt handling function calls another function.
662
}
663
664
static bool isTailCallOpcode(unsigned Opc) {
665
return Opc == M68k::TCRETURNj || Opc == M68k::TCRETURNq;
666
}
667
668
void M68kFrameLowering::emitEpilogue(MachineFunction &MF,
669
MachineBasicBlock &MBB) const {
670
const MachineFrameInfo &MFI = MF.getFrameInfo();
671
M68kMachineFunctionInfo *MMFI = MF.getInfo<M68kMachineFunctionInfo>();
672
MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
673
std::optional<unsigned> RetOpcode;
674
if (MBBI != MBB.end())
675
RetOpcode = MBBI->getOpcode();
676
DebugLoc DL;
677
if (MBBI != MBB.end())
678
DL = MBBI->getDebugLoc();
679
Register FramePtr = TRI->getFrameRegister(MF);
680
unsigned MachineFramePtr = FramePtr;
681
682
// Get the number of bytes to allocate from the FrameInfo.
683
uint64_t StackSize = MFI.getStackSize();
684
uint64_t MaxAlign = calculateMaxStackAlign(MF);
685
unsigned CSSize = MMFI->getCalleeSavedFrameSize();
686
uint64_t NumBytes = 0;
687
688
if (hasFP(MF)) {
689
// Calculate required stack adjustment.
690
uint64_t FrameSize = StackSize - SlotSize;
691
NumBytes = FrameSize - CSSize;
692
693
// Callee-saved registers were pushed on stack before the stack was
694
// realigned.
695
if (TRI->hasStackRealignment(MF))
696
NumBytes = alignTo(FrameSize, MaxAlign);
697
698
} else {
699
NumBytes = StackSize - CSSize;
700
}
701
702
// Skip the callee-saved pop instructions.
703
while (MBBI != MBB.begin()) {
704
MachineBasicBlock::iterator PI = std::prev(MBBI);
705
unsigned Opc = PI->getOpcode();
706
707
if ((Opc != M68k::POP32r || !PI->getFlag(MachineInstr::FrameDestroy)) &&
708
Opc != M68k::DBG_VALUE && !PI->isTerminator())
709
break;
710
711
--MBBI;
712
}
713
MachineBasicBlock::iterator FirstCSPop = MBBI;
714
715
if (MBBI != MBB.end())
716
DL = MBBI->getDebugLoc();
717
718
// If there is an ADD32ri or SUB32ri of SP immediately before this
719
// instruction, merge the two instructions.
720
if (NumBytes || MFI.hasVarSizedObjects())
721
NumBytes += mergeSPUpdates(MBB, MBBI, true);
722
723
// If dynamic alloca is used, then reset SP to point to the last callee-saved
724
// slot before popping them off! Same applies for the case, when stack was
725
// realigned. Don't do this if this was a funclet epilogue, since the funclets
726
// will not do realignment or dynamic stack allocation.
727
if ((TRI->hasStackRealignment(MF) || MFI.hasVarSizedObjects())) {
728
if (TRI->hasStackRealignment(MF))
729
MBBI = FirstCSPop;
730
uint64_t LEAAmount = -CSSize;
731
732
// 'move %FramePtr, SP' will not be recognized as an epilogue sequence.
733
// However, we may use this sequence if we have a frame pointer because the
734
// effects of the prologue can safely be undone.
735
if (LEAAmount != 0) {
736
unsigned Opc = M68k::LEA32p;
737
M68k::addRegIndirectWithDisp(
738
BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr), FramePtr, false,
739
LEAAmount);
740
--MBBI;
741
} else {
742
BuildMI(MBB, MBBI, DL, TII.get(M68k::UNLK))
743
.addReg(MachineFramePtr, RegState::Kill)
744
.setMIFlag(MachineInstr::FrameDestroy);
745
--MBBI;
746
}
747
} else if (hasFP(MF)) {
748
BuildMI(MBB, MBBI, DL, TII.get(M68k::UNLK))
749
.addReg(MachineFramePtr, RegState::Kill)
750
.setMIFlag(MachineInstr::FrameDestroy);
751
} else if (NumBytes) {
752
// Adjust stack pointer back: SP += numbytes.
753
emitSPUpdate(MBB, MBBI, NumBytes, /*InEpilogue=*/true);
754
--MBBI;
755
}
756
757
if (!RetOpcode || !isTailCallOpcode(*RetOpcode)) {
758
// Add the return addr area delta back since we are not tail calling.
759
int Offset = -1 * MMFI->getTCReturnAddrDelta();
760
assert(Offset >= 0 && "TCDelta should never be positive");
761
if (Offset) {
762
MBBI = MBB.getFirstTerminator();
763
764
// Check for possible merge with preceding ADD instruction.
765
Offset += mergeSPUpdates(MBB, MBBI, true);
766
emitSPUpdate(MBB, MBBI, Offset, /*InEpilogue=*/true);
767
}
768
}
769
}
770
771
void M68kFrameLowering::determineCalleeSaves(MachineFunction &MF,
772
BitVector &SavedRegs,
773
RegScavenger *RS) const {
774
TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
775
776
MachineFrameInfo &MFI = MF.getFrameInfo();
777
778
M68kMachineFunctionInfo *M68kFI = MF.getInfo<M68kMachineFunctionInfo>();
779
int64_t TailCallReturnAddrDelta = M68kFI->getTCReturnAddrDelta();
780
781
if (TailCallReturnAddrDelta < 0) {
782
// create RETURNADDR area
783
// arg
784
// arg
785
// RETADDR
786
// { ...
787
// RETADDR area
788
// ...
789
// }
790
// [FP]
791
MFI.CreateFixedObject(-TailCallReturnAddrDelta,
792
TailCallReturnAddrDelta - SlotSize, true);
793
}
794
795
// Spill the BasePtr if it's used.
796
if (TRI->hasBasePointer(MF)) {
797
SavedRegs.set(TRI->getBaseRegister());
798
}
799
}
800
801
bool M68kFrameLowering::assignCalleeSavedSpillSlots(
802
MachineFunction &MF, const TargetRegisterInfo *TRI,
803
std::vector<CalleeSavedInfo> &CSI) const {
804
MachineFrameInfo &MFI = MF.getFrameInfo();
805
M68kMachineFunctionInfo *M68kFI = MF.getInfo<M68kMachineFunctionInfo>();
806
807
int SpillSlotOffset = getOffsetOfLocalArea() + M68kFI->getTCReturnAddrDelta();
808
809
if (hasFP(MF)) {
810
// emitPrologue always spills frame register the first thing.
811
SpillSlotOffset -= SlotSize;
812
MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
813
814
// Since emitPrologue and emitEpilogue will handle spilling and restoring of
815
// the frame register, we can delete it from CSI list and not have to worry
816
// about avoiding it later.
817
Register FPReg = TRI->getFrameRegister(MF);
818
for (unsigned i = 0, e = CSI.size(); i < e; ++i) {
819
if (TRI->regsOverlap(CSI[i].getReg(), FPReg)) {
820
CSI.erase(CSI.begin() + i);
821
break;
822
}
823
}
824
}
825
826
// The rest is fine
827
return false;
828
}
829
830
bool M68kFrameLowering::spillCalleeSavedRegisters(
831
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
832
ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
833
auto &MRI = *static_cast<const M68kRegisterInfo *>(TRI);
834
auto DL = MBB.findDebugLoc(MI);
835
836
int FI = 0;
837
unsigned Mask = 0;
838
for (const auto &Info : CSI) {
839
FI = std::max(FI, Info.getFrameIdx());
840
Register Reg = Info.getReg();
841
unsigned Shift = MRI.getSpillRegisterOrder(Reg);
842
Mask |= 1 << Shift;
843
}
844
845
auto I =
846
M68k::addFrameReference(BuildMI(MBB, MI, DL, TII.get(M68k::MOVM32pm)), FI)
847
.addImm(Mask)
848
.setMIFlag(MachineInstr::FrameSetup);
849
850
// Append implicit registers and mem locations
851
const MachineFunction &MF = *MBB.getParent();
852
const MachineRegisterInfo &RI = MF.getRegInfo();
853
for (const auto &Info : CSI) {
854
Register Reg = Info.getReg();
855
bool IsLiveIn = RI.isLiveIn(Reg);
856
if (!IsLiveIn)
857
MBB.addLiveIn(Reg);
858
I.addReg(Reg, IsLiveIn ? RegState::Implicit : RegState::ImplicitKill);
859
M68k::addMemOperand(I, Info.getFrameIdx(), 0);
860
}
861
862
return true;
863
}
864
865
bool M68kFrameLowering::restoreCalleeSavedRegisters(
866
MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
867
MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
868
auto &MRI = *static_cast<const M68kRegisterInfo *>(TRI);
869
auto DL = MBB.findDebugLoc(MI);
870
871
int FI = 0;
872
unsigned Mask = 0;
873
for (const auto &Info : CSI) {
874
FI = std::max(FI, Info.getFrameIdx());
875
Register Reg = Info.getReg();
876
unsigned Shift = MRI.getSpillRegisterOrder(Reg);
877
Mask |= 1 << Shift;
878
}
879
880
auto I = M68k::addFrameReference(
881
BuildMI(MBB, MI, DL, TII.get(M68k::MOVM32mp)).addImm(Mask), FI)
882
.setMIFlag(MachineInstr::FrameDestroy);
883
884
// Append implicit registers and mem locations
885
for (const auto &Info : CSI) {
886
I.addReg(Info.getReg(), RegState::ImplicitDefine);
887
M68k::addMemOperand(I, Info.getFrameIdx(), 0);
888
}
889
890
return true;
891
}
892
893