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
34using namespace llvm;
35
36M68kFrameLowering::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
43bool 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
53bool M68kFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
54 return !MF.getFrameInfo().hasVarSizedObjects() &&
55 !MF.getInfo<M68kMachineFunctionInfo>()->getHasPushSequences();
56}
57
58bool M68kFrameLowering::canSimplifyCallFramePseudos(
59 const MachineFunction &MF) const {
60 return hasReservedCallFrame(MF) ||
61 (hasFP(MF) && !TRI->hasStackRealignment(MF)) ||
62 TRI->hasBasePointer(MF);
63}
64
65bool 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.
75StackOffset
76M68kFrameLowering::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(ObjectIdx: 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(Fixed: Offset + SlotSize);
105 }
106
107 assert((-(Offset + StackSize)) % MFI.getObjectAlign(FI).value() == 0);
108 return StackOffset::getFixed(Fixed: Offset + StackSize);
109 }
110 if (TRI->hasStackRealignment(MF)) {
111 if (FI < 0) {
112 // Skip the saved FP.
113 return StackOffset::getFixed(Fixed: Offset + SlotSize);
114 }
115
116 assert((-(Offset + StackSize)) % MFI.getObjectAlign(FI).value() == 0);
117 return StackOffset::getFixed(Fixed: Offset + StackSize);
118 }
119
120 if (!HasFP)
121 return StackOffset::getFixed(Fixed: 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(Fixed: 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.
137static 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: *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(V: *AI);
165 }
166
167 for (auto CS : AvailableRegs)
168 if (!Uses.count(V: CS))
169 return CS;
170 }
171 }
172
173 return 0;
174}
175
176static bool isRegLiveIn(MachineBasicBlock &MBB, unsigned Reg) {
177 return llvm::any_of(Range: MBB.liveins(),
178 P: [Reg](MachineBasicBlock::RegisterMaskPair RegMask) {
179 return RegMask.PhysReg == Reg;
180 });
181}
182
183uint64_t
184M68kFrameLowering::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(Kind: "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
197void 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(BB&: MBB, I: MBBI, MIMD: DL, MCID: TII.get(Opcode: MovOp), DestReg: Tmp)
211 .addReg(RegNo: Reg)
212 .setMIFlag(MachineInstr::FrameSetup);
213
214 MachineInstr *MI = BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: TII.get(Opcode: AndOp), DestReg: Tmp)
215 .addReg(RegNo: Tmp)
216 .addImm(Val)
217 .setMIFlag(MachineInstr::FrameSetup);
218
219 // The CCR implicit def is dead.
220 MI->getOperand(i: 3).setIsDead();
221
222 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: TII.get(Opcode: MovOp), DestReg: Reg)
223 .addReg(RegNo: Tmp)
224 .setMIFlag(MachineInstr::FrameSetup);
225}
226
227MachineBasicBlock::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(i: 0).getImm() : 0;
235 uint64_t InternalAmt = (IsDestroy && Amount) ? I->getOperand(i: 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(Value: Amount, Align: StackAlign);
248
249 MachineModuleInfo &MMI = MF.getMMI();
250 const auto &Fn = MF.getFunction();
251 bool DwarfCFI = MMI.hasDebugInfo() || Fn.needsUnwindTableEntry();
252
253 // If we have any exception handlers in this function, and we adjust
254 // the SP before calls, we may need to indicate this to the unwinder
255 // using GNU_ARGS_SIZE. Note that this may be necessary even when
256 // Amount == 0, because the preceding function may have set a non-0
257 // GNU_ARGS_SIZE.
258 // TODO: We don't need to reset this between subsequent functions,
259 // if it didn't change.
260 bool HasDwarfEHHandlers = !MF.getLandingPads().empty();
261
262 if (HasDwarfEHHandlers && !IsDestroy &&
263 MF.getInfo<M68kMachineFunctionInfo>()->getHasPushSequences()) {
264 BuildCFI(MBB, MBBI: I, DL,
265 CFIInst: MCCFIInstruction::createGnuArgsSize(L: nullptr, Size: Amount));
266 }
267
268 if (Amount == 0)
269 return I;
270
271 // Factor out the amount that gets handled inside the sequence
272 // (Pushes of argument for frame setup, callee pops for frame destroy)
273 Amount -= InternalAmt;
274
275 // TODO: This is needed only if we require precise CFA.
276 // If this is a callee-pop calling convention, emit a CFA adjust for
277 // the amount the callee popped.
278 if (IsDestroy && InternalAmt && DwarfCFI && !hasFP(MF))
279 BuildCFI(MBB, MBBI: I, DL,
280 CFIInst: MCCFIInstruction::createAdjustCfaOffset(L: nullptr, Adjustment: -InternalAmt));
281
282 // Add Amount to SP to destroy a frame, or subtract to setup.
283 int64_t StackAdjustment = IsDestroy ? Amount : -Amount;
284 int64_t CfaAdjustment = -StackAdjustment;
285
286 if (StackAdjustment) {
287 // Merge with any previous or following adjustment instruction. Note: the
288 // instructions merged with here do not have CFI, so their stack
289 // adjustments do not feed into CfaAdjustment.
290 StackAdjustment += mergeSPUpdates(MBB, MBBI&: I, doMergeWithPrevious: true);
291 StackAdjustment += mergeSPUpdates(MBB, MBBI&: I, doMergeWithPrevious: false);
292
293 if (StackAdjustment) {
294 BuildStackAdjustment(MBB, MBBI: I, DL, Offset: StackAdjustment, InEpilogue: false);
295 }
296 }
297
298 if (DwarfCFI && !hasFP(MF)) {
299 // If we don't have FP, but need to generate unwind information,
300 // we need to set the correct CFA offset after the stack adjustment.
301 // How much we adjust the CFA offset depends on whether we're emitting
302 // CFI only for EH purposes or for debugging. EH only requires the CFA
303 // offset to be correct at each call site, while for debugging we want
304 // it to be more precise.
305
306 // TODO: When not using precise CFA, we also need to adjust for the
307 // InternalAmt here.
308 if (CfaAdjustment) {
309 BuildCFI(
310 MBB, MBBI: I, DL,
311 CFIInst: MCCFIInstruction::createAdjustCfaOffset(L: nullptr, Adjustment: CfaAdjustment));
312 }
313 }
314
315 return I;
316 }
317
318 if (IsDestroy && InternalAmt) {
319 // If we are performing frame pointer elimination and if the callee pops
320 // something off the stack pointer, add it back. We do this until we have
321 // more advanced stack pointer tracking ability.
322 // We are not tracking the stack pointer adjustment by the callee, so make
323 // sure we restore the stack pointer immediately after the call, there may
324 // be spill code inserted between the CALL and ADJCALLSTACKUP instructions.
325 MachineBasicBlock::iterator CI = I;
326 MachineBasicBlock::iterator B = MBB.begin();
327 while (CI != B && !std::prev(x: CI)->isCall())
328 --CI;
329 BuildStackAdjustment(MBB, MBBI: CI, DL, Offset: -InternalAmt, /*InEpilogue=*/false);
330 }
331
332 return I;
333}
334
335/// Emit a series of instructions to increment / decrement the stack pointer by
336/// a constant value.
337void M68kFrameLowering::emitSPUpdate(MachineBasicBlock &MBB,
338 MachineBasicBlock::iterator &MBBI,
339 int64_t NumBytes, bool InEpilogue) const {
340 bool IsSub = NumBytes < 0;
341 uint64_t Offset = IsSub ? -NumBytes : NumBytes;
342
343 uint64_t Chunk = (1LL << 31) - 1;
344 DebugLoc DL = MBB.findDebugLoc(MBBI);
345
346 while (Offset) {
347 if (Offset > Chunk) {
348 // Rather than emit a long series of instructions for large offsets,
349 // load the offset into a register and do one sub/add
350 Register Reg;
351
352 if (IsSub && !isRegLiveIn(MBB, M68k::D0))
353 Reg = M68k::D0;
354 else
355 Reg = findDeadCallerSavedReg(MBB, MBBI, TRI);
356
357 if (Reg) {
358 unsigned Opc = M68k::MOV32ri;
359 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: TII.get(Opcode: Opc), DestReg: Reg).addImm(Val: Offset);
360 Opc = IsSub ? M68k::SUB32ar : M68k::ADD32ar;
361 MachineInstr *MI = BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: TII.get(Opcode: Opc), DestReg: StackPtr)
362 .addReg(RegNo: StackPtr)
363 .addReg(RegNo: Reg);
364 // ??? still no CCR
365 MI->getOperand(i: 3).setIsDead(); // The CCR implicit def is dead.
366 Offset = 0;
367 continue;
368 }
369 }
370
371 uint64_t ThisVal = std::min(a: Offset, b: Chunk);
372
373 MachineInstrBuilder MI = BuildStackAdjustment(
374 MBB, MBBI, DL, Offset: IsSub ? -ThisVal : ThisVal, InEpilogue);
375 if (IsSub)
376 MI.setMIFlag(MachineInstr::FrameSetup);
377 else
378 MI.setMIFlag(MachineInstr::FrameDestroy);
379
380 Offset -= ThisVal;
381 }
382}
383
384int M68kFrameLowering::mergeSPUpdates(MachineBasicBlock &MBB,
385 MachineBasicBlock::iterator &MBBI,
386 bool MergeWithPrevious) const {
387 if ((MergeWithPrevious && MBBI == MBB.begin()) ||
388 (!MergeWithPrevious && MBBI == MBB.end()))
389 return 0;
390
391 MachineBasicBlock::iterator PI = MergeWithPrevious ? std::prev(x: MBBI) : MBBI;
392 MachineBasicBlock::iterator NI =
393 MergeWithPrevious ? nullptr : std::next(x: MBBI);
394 unsigned Opc = PI->getOpcode();
395 int Offset = 0;
396
397 if (!MergeWithPrevious && NI != MBB.end() &&
398 NI->getOpcode() == TargetOpcode::CFI_INSTRUCTION) {
399 // Don't merge with the next instruction if it has CFI.
400 return Offset;
401 }
402
403 if (Opc == M68k::ADD32ai && PI->getOperand(0).getReg() == StackPtr) {
404 assert(PI->getOperand(1).getReg() == StackPtr);
405 Offset += PI->getOperand(i: 2).getImm();
406 MBB.erase(I: PI);
407 if (!MergeWithPrevious)
408 MBBI = NI;
409 } else if (Opc == M68k::SUB32ai && PI->getOperand(0).getReg() == StackPtr) {
410 assert(PI->getOperand(1).getReg() == StackPtr);
411 Offset -= PI->getOperand(i: 2).getImm();
412 MBB.erase(I: PI);
413 if (!MergeWithPrevious)
414 MBBI = NI;
415 }
416
417 return Offset;
418}
419
420MachineInstrBuilder M68kFrameLowering::BuildStackAdjustment(
421 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
422 const DebugLoc &DL, int64_t Offset, bool InEpilogue) const {
423 assert(Offset != 0 && "zero offset stack adjustment requested");
424
425 // TODO can `lea` be used to adjust stack?
426
427 bool IsSub = Offset < 0;
428 uint64_t AbsOffset = IsSub ? -Offset : Offset;
429 unsigned Opc = IsSub ? M68k::SUB32ai : M68k::ADD32ai;
430
431 MachineInstrBuilder MI = BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: TII.get(Opcode: Opc), DestReg: StackPtr)
432 .addReg(RegNo: StackPtr)
433 .addImm(Val: AbsOffset);
434 // FIXME Update CCR as well. For now we just
435 // conservatively say CCR implicit def is dead
436 MI->getOperand(i: 3).setIsDead();
437 return MI;
438}
439
440void M68kFrameLowering::BuildCFI(MachineBasicBlock &MBB,
441 MachineBasicBlock::iterator MBBI,
442 const DebugLoc &DL,
443 const MCCFIInstruction &CFIInst) const {
444 MachineFunction &MF = *MBB.getParent();
445 unsigned CFIIndex = MF.addFrameInst(Inst: CFIInst);
446 BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: TII.get(Opcode: TargetOpcode::CFI_INSTRUCTION))
447 .addCFIIndex(CFIIndex);
448}
449
450void M68kFrameLowering::emitPrologueCalleeSavedFrameMoves(
451 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
452 const DebugLoc &DL) const {
453 MachineFunction &MF = *MBB.getParent();
454 MachineFrameInfo &MFI = MF.getFrameInfo();
455 MachineModuleInfo &MMI = MF.getMMI();
456 const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo();
457
458 // Add callee saved registers to move list.
459 const auto &CSI = MFI.getCalleeSavedInfo();
460 if (CSI.empty())
461 return;
462
463 // Calculate offsets.
464 for (const auto &I : CSI) {
465 int64_t Offset = MFI.getObjectOffset(ObjectIdx: I.getFrameIdx());
466 Register Reg = I.getReg();
467
468 unsigned DwarfReg = MRI->getDwarfRegNum(RegNum: Reg, isEH: true);
469 BuildCFI(MBB, MBBI, DL,
470 CFIInst: MCCFIInstruction::createOffset(L: nullptr, Register: DwarfReg, Offset));
471 }
472}
473
474void M68kFrameLowering::emitPrologue(MachineFunction &MF,
475 MachineBasicBlock &MBB) const {
476 assert(&STI == &MF.getSubtarget<M68kSubtarget>() &&
477 "MF used frame lowering for wrong subtarget");
478
479 MachineBasicBlock::iterator MBBI = MBB.begin();
480 MachineFrameInfo &MFI = MF.getFrameInfo();
481 const auto &Fn = MF.getFunction();
482 MachineModuleInfo &MMI = MF.getMMI();
483 M68kMachineFunctionInfo *MMFI = MF.getInfo<M68kMachineFunctionInfo>();
484 uint64_t MaxAlign = calculateMaxStackAlign(MF); // Desired stack alignment.
485 uint64_t StackSize = MFI.getStackSize(); // Number of bytes to allocate.
486 bool HasFP = hasFP(MF);
487 bool NeedsDwarfCFI = MMI.hasDebugInfo() || Fn.needsUnwindTableEntry();
488 Register FramePtr = TRI->getFrameRegister(MF);
489 const unsigned MachineFramePtr = FramePtr;
490 unsigned BasePtr = TRI->getBaseRegister();
491
492 // Debug location must be unknown since the first debug location is used
493 // to determine the end of the prologue.
494 DebugLoc DL;
495
496 // Add RETADDR move area to callee saved frame size.
497 int TailCallReturnAddrDelta = MMFI->getTCReturnAddrDelta();
498
499 if (TailCallReturnAddrDelta < 0) {
500 MMFI->setCalleeSavedFrameSize(MMFI->getCalleeSavedFrameSize() -
501 TailCallReturnAddrDelta);
502 }
503
504 // Insert stack pointer adjustment for later moving of return addr. Only
505 // applies to tail call optimized functions where the callee argument stack
506 // size is bigger than the callers.
507 if (TailCallReturnAddrDelta < 0) {
508 BuildStackAdjustment(MBB, MBBI, DL, Offset: TailCallReturnAddrDelta,
509 /*InEpilogue=*/false)
510 .setMIFlag(MachineInstr::FrameSetup);
511 }
512
513 // Mapping for machine moves:
514 //
515 // DST: VirtualFP AND
516 // SRC: VirtualFP => DW_CFA_def_cfa_offset
517 // ELSE => DW_CFA_def_cfa
518 //
519 // SRC: VirtualFP AND
520 // DST: Register => DW_CFA_def_cfa_register
521 //
522 // ELSE
523 // OFFSET < 0 => DW_CFA_offset_extended_sf
524 // REG < 64 => DW_CFA_offset + Reg
525 // ELSE => DW_CFA_offset_extended
526
527 uint64_t NumBytes = 0;
528 int stackGrowth = -SlotSize;
529
530 if (HasFP) {
531 // Calculate required stack adjustment.
532 uint64_t FrameSize = StackSize - SlotSize;
533 // If required, include space for extra hidden slot for stashing base
534 // pointer.
535 if (MMFI->getRestoreBasePointer())
536 FrameSize += SlotSize;
537
538 NumBytes = FrameSize - MMFI->getCalleeSavedFrameSize();
539
540 // Callee-saved registers are pushed on stack before the stack is realigned.
541 if (TRI->hasStackRealignment(MF))
542 NumBytes = alignTo(Value: NumBytes, Align: MaxAlign);
543
544 // Get the offset of the stack slot for the FP register, which is
545 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
546 // Update the frame offset adjustment.
547 MFI.setOffsetAdjustment(-NumBytes);
548
549 BuildMI(MBB, MBBI, DL, TII.get(M68k::LINK16))
550 .addReg(M68k::WA6, RegState::Kill)
551 .addImm(-NumBytes)
552 .setMIFlag(MachineInstr::FrameSetup);
553
554 if (NeedsDwarfCFI) {
555 // Mark the place where FP was saved.
556 // Define the current CFA rule to use the provided offset.
557 assert(StackSize);
558 BuildCFI(MBB, MBBI, DL,
559 CFIInst: MCCFIInstruction::cfiDefCfaOffset(L: nullptr, Offset: 2 * stackGrowth));
560
561 // Change the rule for the FramePtr to be an "offset" rule.
562 int DwarfFramePtr = TRI->getDwarfRegNum(MachineFramePtr, true);
563 assert(DwarfFramePtr > 0);
564 BuildCFI(MBB, MBBI, DL,
565 CFIInst: MCCFIInstruction::createOffset(L: nullptr, Register: DwarfFramePtr,
566 Offset: 2 * stackGrowth));
567 }
568
569 if (NeedsDwarfCFI) {
570 // Mark effective beginning of when frame pointer becomes valid.
571 // Define the current CFA to use the FP register.
572 unsigned DwarfFramePtr = TRI->getDwarfRegNum(MachineFramePtr, true);
573 BuildCFI(MBB, MBBI, DL,
574 CFIInst: MCCFIInstruction::createDefCfaRegister(L: nullptr, Register: DwarfFramePtr));
575 }
576
577 // Mark the FramePtr as live-in in every block. Don't do this again for
578 // funclet prologues.
579 for (MachineBasicBlock &EveryMBB : MF)
580 EveryMBB.addLiveIn(PhysReg: MachineFramePtr);
581 } else {
582 NumBytes = StackSize - MMFI->getCalleeSavedFrameSize();
583 }
584
585 // Skip the callee-saved push instructions.
586 bool PushedRegs = false;
587 int StackOffset = 2 * stackGrowth;
588
589 while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup) &&
590 MBBI->getOpcode() == M68k::PUSH32r) {
591 PushedRegs = true;
592 ++MBBI;
593
594 if (!HasFP && NeedsDwarfCFI) {
595 // Mark callee-saved push instruction.
596 // Define the current CFA rule to use the provided offset.
597 assert(StackSize);
598 BuildCFI(MBB, MBBI, DL,
599 CFIInst: MCCFIInstruction::cfiDefCfaOffset(L: nullptr, Offset: StackOffset));
600 StackOffset += stackGrowth;
601 }
602 }
603
604 // Realign stack after we pushed callee-saved registers (so that we'll be
605 // able to calculate their offsets from the frame pointer).
606 if (TRI->hasStackRealignment(MF)) {
607 assert(HasFP && "There should be a frame pointer if stack is realigned.");
608 BuildStackAlignAND(MBB, MBBI, DL, Reg: StackPtr, MaxAlign);
609 }
610
611 // If there is an SUB32ri of SP immediately before this instruction, merge
612 // the two. This can be the case when tail call elimination is enabled and
613 // the callee has more arguments then the caller.
614 NumBytes -= mergeSPUpdates(MBB, MBBI, MergeWithPrevious: true);
615
616 // Adjust stack pointer: ESP -= numbytes.
617 if (!HasFP)
618 emitSPUpdate(MBB, MBBI, NumBytes: -(int64_t)NumBytes, /*InEpilogue=*/false);
619
620 unsigned SPOrEstablisher = StackPtr;
621
622 // If we need a base pointer, set it up here. It's whatever the value
623 // of the stack pointer is at this point. Any variable size objects
624 // will be allocated after this, so we can still use the base pointer
625 // to reference locals.
626 if (TRI->hasBasePointer(MF)) {
627 // Update the base pointer with the current stack pointer.
628 BuildMI(MBB, MBBI, DL, TII.get(M68k::MOV32aa), BasePtr)
629 .addReg(SPOrEstablisher)
630 .setMIFlag(MachineInstr::FrameSetup);
631 if (MMFI->getRestoreBasePointer()) {
632 // Stash value of base pointer. Saving SP instead of FP shortens
633 // dependence chain. Used by SjLj EH.
634 unsigned Opm = M68k::MOV32ja;
635 M68k::addRegIndirectWithDisp(MIB: BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: TII.get(Opcode: Opm)),
636 Reg: FramePtr, IsKill: true,
637 Offset: MMFI->getRestoreBasePointerOffset())
638 .addReg(RegNo: SPOrEstablisher)
639 .setMIFlag(MachineInstr::FrameSetup);
640 }
641 }
642
643 if (((!HasFP && NumBytes) || PushedRegs) && NeedsDwarfCFI) {
644 // Mark end of stack pointer adjustment.
645 if (!HasFP && NumBytes) {
646 // Define the current CFA rule to use the provided offset.
647 assert(StackSize);
648 BuildCFI(
649 MBB, MBBI, DL,
650 CFIInst: MCCFIInstruction::cfiDefCfaOffset(L: nullptr, Offset: -StackSize + stackGrowth));
651 }
652
653 // Emit DWARF info specifying the offsets of the callee-saved registers.
654 if (PushedRegs)
655 emitPrologueCalleeSavedFrameMoves(MBB, MBBI, DL);
656 }
657
658 // TODO Interrupt handlers
659 // M68k Interrupt handling function cannot assume anything about the
660 // direction flag (DF in CCR register). Clear this flag by creating "cld"
661 // instruction in each prologue of interrupt handler function. The "cld"
662 // instruction should only in these cases:
663 // 1. The interrupt handling function uses any of the "rep" instructions.
664 // 2. Interrupt handling function calls another function.
665}
666
667static bool isTailCallOpcode(unsigned Opc) {
668 return Opc == M68k::TCRETURNj || Opc == M68k::TCRETURNq;
669}
670
671void M68kFrameLowering::emitEpilogue(MachineFunction &MF,
672 MachineBasicBlock &MBB) const {
673 const MachineFrameInfo &MFI = MF.getFrameInfo();
674 M68kMachineFunctionInfo *MMFI = MF.getInfo<M68kMachineFunctionInfo>();
675 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
676 std::optional<unsigned> RetOpcode;
677 if (MBBI != MBB.end())
678 RetOpcode = MBBI->getOpcode();
679 DebugLoc DL;
680 if (MBBI != MBB.end())
681 DL = MBBI->getDebugLoc();
682 Register FramePtr = TRI->getFrameRegister(MF);
683 unsigned MachineFramePtr = FramePtr;
684
685 // Get the number of bytes to allocate from the FrameInfo.
686 uint64_t StackSize = MFI.getStackSize();
687 uint64_t MaxAlign = calculateMaxStackAlign(MF);
688 unsigned CSSize = MMFI->getCalleeSavedFrameSize();
689 uint64_t NumBytes = 0;
690
691 if (hasFP(MF)) {
692 // Calculate required stack adjustment.
693 uint64_t FrameSize = StackSize - SlotSize;
694 NumBytes = FrameSize - CSSize;
695
696 // Callee-saved registers were pushed on stack before the stack was
697 // realigned.
698 if (TRI->hasStackRealignment(MF))
699 NumBytes = alignTo(Value: FrameSize, Align: MaxAlign);
700
701 } else {
702 NumBytes = StackSize - CSSize;
703 }
704
705 // Skip the callee-saved pop instructions.
706 while (MBBI != MBB.begin()) {
707 MachineBasicBlock::iterator PI = std::prev(x: MBBI);
708 unsigned Opc = PI->getOpcode();
709
710 if ((Opc != M68k::POP32r || !PI->getFlag(MachineInstr::FrameDestroy)) &&
711 Opc != M68k::DBG_VALUE && !PI->isTerminator())
712 break;
713
714 --MBBI;
715 }
716 MachineBasicBlock::iterator FirstCSPop = MBBI;
717
718 if (MBBI != MBB.end())
719 DL = MBBI->getDebugLoc();
720
721 // If there is an ADD32ri or SUB32ri of SP immediately before this
722 // instruction, merge the two instructions.
723 if (NumBytes || MFI.hasVarSizedObjects())
724 NumBytes += mergeSPUpdates(MBB, MBBI, MergeWithPrevious: true);
725
726 // If dynamic alloca is used, then reset SP to point to the last callee-saved
727 // slot before popping them off! Same applies for the case, when stack was
728 // realigned. Don't do this if this was a funclet epilogue, since the funclets
729 // will not do realignment or dynamic stack allocation.
730 if ((TRI->hasStackRealignment(MF) || MFI.hasVarSizedObjects())) {
731 if (TRI->hasStackRealignment(MF))
732 MBBI = FirstCSPop;
733 uint64_t LEAAmount = -CSSize;
734
735 // 'move %FramePtr, SP' will not be recognized as an epilogue sequence.
736 // However, we may use this sequence if we have a frame pointer because the
737 // effects of the prologue can safely be undone.
738 if (LEAAmount != 0) {
739 unsigned Opc = M68k::LEA32p;
740 M68k::addRegIndirectWithDisp(
741 MIB: BuildMI(BB&: MBB, I: MBBI, MIMD: DL, MCID: TII.get(Opcode: Opc), DestReg: StackPtr), Reg: FramePtr, IsKill: false,
742 Offset: LEAAmount);
743 --MBBI;
744 } else {
745 BuildMI(MBB, MBBI, DL, TII.get(M68k::UNLK))
746 .addReg(MachineFramePtr, RegState::Kill)
747 .setMIFlag(MachineInstr::FrameDestroy);
748 --MBBI;
749 }
750 } else if (hasFP(MF)) {
751 BuildMI(MBB, MBBI, DL, TII.get(M68k::UNLK))
752 .addReg(MachineFramePtr, RegState::Kill)
753 .setMIFlag(MachineInstr::FrameDestroy);
754 } else if (NumBytes) {
755 // Adjust stack pointer back: SP += numbytes.
756 emitSPUpdate(MBB, MBBI, NumBytes, /*InEpilogue=*/true);
757 --MBBI;
758 }
759
760 if (!RetOpcode || !isTailCallOpcode(Opc: *RetOpcode)) {
761 // Add the return addr area delta back since we are not tail calling.
762 int Offset = -1 * MMFI->getTCReturnAddrDelta();
763 assert(Offset >= 0 && "TCDelta should never be positive");
764 if (Offset) {
765 MBBI = MBB.getFirstTerminator();
766
767 // Check for possible merge with preceding ADD instruction.
768 Offset += mergeSPUpdates(MBB, MBBI, MergeWithPrevious: true);
769 emitSPUpdate(MBB, MBBI, NumBytes: Offset, /*InEpilogue=*/true);
770 }
771 }
772}
773
774void M68kFrameLowering::determineCalleeSaves(MachineFunction &MF,
775 BitVector &SavedRegs,
776 RegScavenger *RS) const {
777 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
778
779 MachineFrameInfo &MFI = MF.getFrameInfo();
780
781 M68kMachineFunctionInfo *M68kFI = MF.getInfo<M68kMachineFunctionInfo>();
782 int64_t TailCallReturnAddrDelta = M68kFI->getTCReturnAddrDelta();
783
784 if (TailCallReturnAddrDelta < 0) {
785 // create RETURNADDR area
786 // arg
787 // arg
788 // RETADDR
789 // { ...
790 // RETADDR area
791 // ...
792 // }
793 // [FP]
794 MFI.CreateFixedObject(Size: -TailCallReturnAddrDelta,
795 SPOffset: TailCallReturnAddrDelta - SlotSize, IsImmutable: true);
796 }
797
798 // Spill the BasePtr if it's used.
799 if (TRI->hasBasePointer(MF)) {
800 SavedRegs.set(TRI->getBaseRegister());
801 }
802}
803
804bool M68kFrameLowering::assignCalleeSavedSpillSlots(
805 MachineFunction &MF, const TargetRegisterInfo *TRI,
806 std::vector<CalleeSavedInfo> &CSI) const {
807 MachineFrameInfo &MFI = MF.getFrameInfo();
808 M68kMachineFunctionInfo *M68kFI = MF.getInfo<M68kMachineFunctionInfo>();
809
810 int SpillSlotOffset = getOffsetOfLocalArea() + M68kFI->getTCReturnAddrDelta();
811
812 if (hasFP(MF)) {
813 // emitPrologue always spills frame register the first thing.
814 SpillSlotOffset -= SlotSize;
815 MFI.CreateFixedSpillStackObject(Size: SlotSize, SPOffset: SpillSlotOffset);
816
817 // Since emitPrologue and emitEpilogue will handle spilling and restoring of
818 // the frame register, we can delete it from CSI list and not have to worry
819 // about avoiding it later.
820 Register FPReg = TRI->getFrameRegister(MF);
821 for (unsigned i = 0, e = CSI.size(); i < e; ++i) {
822 if (TRI->regsOverlap(RegA: CSI[i].getReg(), RegB: FPReg)) {
823 CSI.erase(position: CSI.begin() + i);
824 break;
825 }
826 }
827 }
828
829 // The rest is fine
830 return false;
831}
832
833bool M68kFrameLowering::spillCalleeSavedRegisters(
834 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
835 ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
836 auto &MRI = *static_cast<const M68kRegisterInfo *>(TRI);
837 auto DL = MBB.findDebugLoc(MBBI: MI);
838
839 int FI = 0;
840 unsigned Mask = 0;
841 for (const auto &Info : CSI) {
842 FI = std::max(a: FI, b: Info.getFrameIdx());
843 Register Reg = Info.getReg();
844 unsigned Shift = MRI.getSpillRegisterOrder(Reg);
845 Mask |= 1 << Shift;
846 }
847
848 auto I =
849 M68k::addFrameReference(BuildMI(MBB, MI, DL, TII.get(M68k::MOVM32pm)), FI)
850 .addImm(Mask)
851 .setMIFlag(MachineInstr::FrameSetup);
852
853 // Append implicit registers and mem locations
854 const MachineFunction &MF = *MBB.getParent();
855 const MachineRegisterInfo &RI = MF.getRegInfo();
856 for (const auto &Info : CSI) {
857 Register Reg = Info.getReg();
858 bool IsLiveIn = RI.isLiveIn(Reg);
859 if (!IsLiveIn)
860 MBB.addLiveIn(PhysReg: Reg);
861 I.addReg(Reg, IsLiveIn ? RegState::Implicit : RegState::ImplicitKill);
862 M68k::addMemOperand(MIB: I, FI: Info.getFrameIdx(), Offset: 0);
863 }
864
865 return true;
866}
867
868bool M68kFrameLowering::restoreCalleeSavedRegisters(
869 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
870 MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
871 auto &MRI = *static_cast<const M68kRegisterInfo *>(TRI);
872 auto DL = MBB.findDebugLoc(MBBI: MI);
873
874 int FI = 0;
875 unsigned Mask = 0;
876 for (const auto &Info : CSI) {
877 FI = std::max(a: FI, b: Info.getFrameIdx());
878 Register Reg = Info.getReg();
879 unsigned Shift = MRI.getSpillRegisterOrder(Reg);
880 Mask |= 1 << Shift;
881 }
882
883 auto I = M68k::addFrameReference(
884 BuildMI(MBB, MI, DL, TII.get(M68k::MOVM32mp)).addImm(Mask), FI)
885 .setMIFlag(MachineInstr::FrameDestroy);
886
887 // Append implicit registers and mem locations
888 for (const auto &Info : CSI) {
889 I.addReg(Info.getReg(), RegState::ImplicitDefine);
890 M68k::addMemOperand(MIB: I, FI: Info.getFrameIdx(), Offset: 0);
891 }
892
893 return true;
894}
895

source code of llvm/lib/Target/M68k/M68kFrameLowering.cpp