xref: /llvm-project/llvm/lib/Target/Mips/Mips16FrameLowering.cpp (revision 73e89cf66d4b88d568ff4c718ae7bf55588ef2be)
1 //===- Mips16FrameLowering.cpp - Mips16 Frame Information -----------------===//
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 // This file contains the Mips16 implementation of TargetFrameLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "Mips16FrameLowering.h"
14 #include "Mips16InstrInfo.h"
15 #include "MipsInstrInfo.h"
16 #include "MipsRegisterInfo.h"
17 #include "MipsSubtarget.h"
18 #include "llvm/ADT/BitVector.h"
19 #include "llvm/CodeGen/MachineBasicBlock.h"
20 #include "llvm/CodeGen/MachineFrameInfo.h"
21 #include "llvm/CodeGen/MachineFunction.h"
22 #include "llvm/CodeGen/MachineInstr.h"
23 #include "llvm/CodeGen/MachineInstrBuilder.h"
24 #include "llvm/CodeGen/MachineModuleInfo.h"
25 #include "llvm/CodeGen/TargetFrameLowering.h"
26 #include "llvm/IR/DebugLoc.h"
27 #include "llvm/MC/MCContext.h"
28 #include "llvm/MC/MCDwarf.h"
29 #include "llvm/MC/MCRegisterInfo.h"
30 #include "llvm/Support/MathExtras.h"
31 #include <cstdint>
32 #include <vector>
33 
34 using namespace llvm;
35 
36 Mips16FrameLowering::Mips16FrameLowering(const MipsSubtarget &STI)
37     : MipsFrameLowering(STI, STI.getStackAlignment()) {}
38 
39 void Mips16FrameLowering::emitPrologue(MachineFunction &MF,
40                                        MachineBasicBlock &MBB) const {
41   MachineFrameInfo &MFI = MF.getFrameInfo();
42   const Mips16InstrInfo &TII =
43       *static_cast<const Mips16InstrInfo *>(STI.getInstrInfo());
44   MachineBasicBlock::iterator MBBI = MBB.begin();
45 
46   // Debug location must be unknown since the first debug location is used
47   // to determine the end of the prologue.
48   DebugLoc dl;
49 
50   uint64_t StackSize = MFI.getStackSize();
51 
52   // No need to allocate space on the stack.
53   if (StackSize == 0 && !MFI.adjustsStack()) return;
54 
55   const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();
56 
57   // Adjust stack.
58   TII.makeFrame(Mips::SP, StackSize, MBB, MBBI);
59 
60   // emit ".cfi_def_cfa_offset StackSize"
61   unsigned CFIIndex =
62       MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize));
63   BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
64       .addCFIIndex(CFIIndex);
65 
66   const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
67 
68   if (!CSI.empty()) {
69     const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
70 
71     for (const CalleeSavedInfo &I : CSI) {
72       int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());
73       Register Reg = I.getReg();
74       unsigned DReg = MRI->getDwarfRegNum(Reg, true);
75       unsigned CFIIndex = MF.addFrameInst(
76           MCCFIInstruction::createOffset(nullptr, DReg, Offset));
77       BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
78           .addCFIIndex(CFIIndex);
79     }
80   }
81   if (hasFP(MF))
82     BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0)
83       .addReg(Mips::SP).setMIFlag(MachineInstr::FrameSetup);
84 }
85 
86 void Mips16FrameLowering::emitEpilogue(MachineFunction &MF,
87                                  MachineBasicBlock &MBB) const {
88   MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
89   MachineFrameInfo &MFI = MF.getFrameInfo();
90   const Mips16InstrInfo &TII =
91       *static_cast<const Mips16InstrInfo *>(STI.getInstrInfo());
92   DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
93   uint64_t StackSize = MFI.getStackSize();
94 
95   if (!StackSize)
96     return;
97 
98   if (hasFP(MF))
99     BuildMI(MBB, MBBI, dl, TII.get(Mips::Move32R16), Mips::SP)
100       .addReg(Mips::S0);
101 
102   // Adjust stack.
103   // assumes stacksize multiple of 8
104   TII.restoreFrame(Mips::SP, StackSize, MBB, MBBI);
105 }
106 
107 bool Mips16FrameLowering::spillCalleeSavedRegisters(
108     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
109     ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
110   MachineFunction *MF = MBB.getParent();
111 
112   //
113   // Registers RA, S0,S1 are the callee saved registers and they
114   // will be saved with the "save" instruction
115   // during emitPrologue
116   //
117   for (const CalleeSavedInfo &I : CSI) {
118     // Add the callee-saved register as live-in. Do not add if the register is
119     // RA and return address is taken, because it has already been added in
120     // method MipsTargetLowering::lowerRETURNADDR.
121     // It's killed at the spill, unless the register is RA and return address
122     // is taken.
123     Register Reg = I.getReg();
124     bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA)
125       && MF->getFrameInfo().isReturnAddressTaken();
126     if (!IsRAAndRetAddrIsTaken)
127       MBB.addLiveIn(Reg);
128   }
129 
130   return true;
131 }
132 
133 bool Mips16FrameLowering::restoreCalleeSavedRegisters(
134     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
135     MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
136   //
137   // Registers RA,S0,S1 are the callee saved registers and they will be restored
138   // with the restore instruction during emitEpilogue.
139   // We need to override this virtual function, otherwise llvm will try and
140   // restore the registers on it's on from the stack.
141   //
142 
143   return true;
144 }
145 
146 bool
147 Mips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
148   const MachineFrameInfo &MFI = MF.getFrameInfo();
149   // Reserve call frame if the size of the maximum call frame fits into 15-bit
150   // immediate field and there are no variable sized objects on the stack.
151   return isInt<15>(MFI.getMaxCallFrameSize()) && !MFI.hasVarSizedObjects();
152 }
153 
154 void Mips16FrameLowering::determineCalleeSaves(MachineFunction &MF,
155                                                BitVector &SavedRegs,
156                                                RegScavenger *RS) const {
157   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
158   const Mips16InstrInfo &TII =
159       *static_cast<const Mips16InstrInfo *>(STI.getInstrInfo());
160   const MipsRegisterInfo &RI = TII.getRegisterInfo();
161   const BitVector Reserved = RI.getReservedRegs(MF);
162   bool SaveS2 = Reserved[Mips::S2];
163   if (SaveS2)
164     SavedRegs.set(Mips::S2);
165   if (hasFP(MF))
166     SavedRegs.set(Mips::S0);
167 }
168 
169 const MipsFrameLowering *
170 llvm::createMips16FrameLowering(const MipsSubtarget &ST) {
171   return new Mips16FrameLowering(ST);
172 }
173