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
M68kFrameLowering(const M68kSubtarget & STI,Align Alignment)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
hasFP(const MachineFunction & MF) const43 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
hasReservedCallFrame(const MachineFunction & MF) const53 bool M68kFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
54 return !MF.getFrameInfo().hasVarSizedObjects() &&
55 !MF.getInfo<M68kMachineFunctionInfo>()->getHasPushSequences();
56 }
57
canSimplifyCallFramePseudos(const MachineFunction & MF) const58 bool M68kFrameLowering::canSimplifyCallFramePseudos(
59 const MachineFunction &MF) const {
60 return hasReservedCallFrame(MF) ||
61 (hasFP(MF) && !TRI->hasStackRealignment(MF)) ||
62 TRI->hasBasePointer(MF);
63 }
64
needsFrameIndexResolution(const MachineFunction & MF) const65 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
getFrameIndexReference(const MachineFunction & MF,int FI,Register & FrameReg) const76 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.
findDeadCallerSavedReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator & MBBI,const M68kRegisterInfo * TRI)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
isRegLiveIn(MachineBasicBlock & MBB,unsigned Reg)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
calculateMaxStackAlign(const MachineFunction & MF) const184 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
BuildStackAlignAND(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,const DebugLoc & DL,unsigned Reg,uint64_t MaxAlign) const197 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
eliminateCallFramePseudoInstr(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator I) const227 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.
emitSPUpdate(MachineBasicBlock & MBB,MachineBasicBlock::iterator & MBBI,int64_t NumBytes,bool InEpilogue) const335 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
mergeSPUpdates(MachineBasicBlock & MBB,MachineBasicBlock::iterator & MBBI,bool MergeWithPrevious) const382 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
BuildStackAdjustment(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,const DebugLoc & DL,int64_t Offset,bool InEpilogue) const418 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
BuildCFI(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,const DebugLoc & DL,const MCCFIInstruction & CFIInst) const438 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
emitPrologueCalleeSavedFrameMoves(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,const DebugLoc & DL) const448 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
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const471 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
isTailCallOpcode(unsigned Opc)664 static bool isTailCallOpcode(unsigned Opc) {
665 return Opc == M68k::TCRETURNj || Opc == M68k::TCRETURNq;
666 }
667
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const668 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
determineCalleeSaves(MachineFunction & MF,BitVector & SavedRegs,RegScavenger * RS) const771 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
assignCalleeSavedSpillSlots(MachineFunction & MF,const TargetRegisterInfo * TRI,std::vector<CalleeSavedInfo> & CSI) const801 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
spillCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,ArrayRef<CalleeSavedInfo> CSI,const TargetRegisterInfo * TRI) const830 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
restoreCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,MutableArrayRef<CalleeSavedInfo> CSI,const TargetRegisterInfo * TRI) const865 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