xref: /llvm-project/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp (revision 1a935d7a17519e9b75d12c3caf9a54a3405a0af3)
1 //===- MipsSEFrameLowering.cpp - Mips32/64 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 Mips32/64 implementation of TargetFrameLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MipsSEFrameLowering.h"
14 #include "MCTargetDesc/MipsABIInfo.h"
15 #include "MipsMachineFunction.h"
16 #include "MipsRegisterInfo.h"
17 #include "MipsSEInstrInfo.h"
18 #include "MipsSubtarget.h"
19 #include "llvm/ADT/BitVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/StringSwitch.h"
22 #include "llvm/CodeGen/MachineBasicBlock.h"
23 #include "llvm/CodeGen/MachineFrameInfo.h"
24 #include "llvm/CodeGen/MachineFunction.h"
25 #include "llvm/CodeGen/MachineInstr.h"
26 #include "llvm/CodeGen/MachineInstrBuilder.h"
27 #include "llvm/CodeGen/MachineModuleInfo.h"
28 #include "llvm/CodeGen/MachineOperand.h"
29 #include "llvm/CodeGen/MachineRegisterInfo.h"
30 #include "llvm/CodeGen/RegisterScavenging.h"
31 #include "llvm/CodeGen/TargetInstrInfo.h"
32 #include "llvm/CodeGen/TargetRegisterInfo.h"
33 #include "llvm/CodeGen/TargetSubtargetInfo.h"
34 #include "llvm/IR/DebugLoc.h"
35 #include "llvm/IR/Function.h"
36 #include "llvm/MC/MCDwarf.h"
37 #include "llvm/MC/MCRegisterInfo.h"
38 #include "llvm/Support/CodeGen.h"
39 #include "llvm/Support/ErrorHandling.h"
40 #include "llvm/Support/MathExtras.h"
41 #include <cassert>
42 #include <cstdint>
43 #include <utility>
44 #include <vector>
45 
46 using namespace llvm;
47 
48 static std::pair<unsigned, unsigned> getMFHiLoOpc(unsigned Src) {
49   if (Mips::ACC64RegClass.contains(Src))
50     return std::make_pair((unsigned)Mips::PseudoMFHI,
51                           (unsigned)Mips::PseudoMFLO);
52 
53   if (Mips::ACC64DSPRegClass.contains(Src))
54     return std::make_pair((unsigned)Mips::MFHI_DSP, (unsigned)Mips::MFLO_DSP);
55 
56   if (Mips::ACC128RegClass.contains(Src))
57     return std::make_pair((unsigned)Mips::PseudoMFHI64,
58                           (unsigned)Mips::PseudoMFLO64);
59 
60   return std::make_pair(0, 0);
61 }
62 
63 namespace {
64 
65 /// Helper class to expand pseudos.
66 class ExpandPseudo {
67 public:
68   ExpandPseudo(MachineFunction &MF);
69   bool expand();
70 
71 private:
72   using Iter = MachineBasicBlock::iterator;
73 
74   bool expandInstr(MachineBasicBlock &MBB, Iter I);
75   void expandLoadCCond(MachineBasicBlock &MBB, Iter I);
76   void expandStoreCCond(MachineBasicBlock &MBB, Iter I);
77   void expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize);
78   void expandStoreACC(MachineBasicBlock &MBB, Iter I, unsigned MFHiOpc,
79                       unsigned MFLoOpc, unsigned RegSize);
80   bool expandCopy(MachineBasicBlock &MBB, Iter I);
81   bool expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned MFHiOpc,
82                      unsigned MFLoOpc);
83   bool expandBuildPairF64(MachineBasicBlock &MBB,
84                           MachineBasicBlock::iterator I, bool FP64) const;
85   bool expandExtractElementF64(MachineBasicBlock &MBB,
86                                MachineBasicBlock::iterator I, bool FP64) const;
87 
88   MachineFunction &MF;
89   MachineRegisterInfo &MRI;
90   const MipsSubtarget &Subtarget;
91   const MipsSEInstrInfo &TII;
92   const MipsRegisterInfo &RegInfo;
93 };
94 
95 } // end anonymous namespace
96 
97 ExpandPseudo::ExpandPseudo(MachineFunction &MF_)
98     : MF(MF_), MRI(MF.getRegInfo()),
99       Subtarget(MF.getSubtarget<MipsSubtarget>()),
100       TII(*static_cast<const MipsSEInstrInfo *>(Subtarget.getInstrInfo())),
101       RegInfo(*Subtarget.getRegisterInfo()) {}
102 
103 bool ExpandPseudo::expand() {
104   bool Expanded = false;
105 
106   for (auto &MBB : MF) {
107     for (Iter I = MBB.begin(), End = MBB.end(); I != End;)
108       Expanded |= expandInstr(MBB, I++);
109   }
110 
111   return Expanded;
112 }
113 
114 bool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) {
115   switch(I->getOpcode()) {
116   case Mips::LOAD_CCOND_DSP:
117     expandLoadCCond(MBB, I);
118     break;
119   case Mips::STORE_CCOND_DSP:
120     expandStoreCCond(MBB, I);
121     break;
122   case Mips::LOAD_ACC64:
123   case Mips::LOAD_ACC64DSP:
124     expandLoadACC(MBB, I, 4);
125     break;
126   case Mips::LOAD_ACC128:
127     expandLoadACC(MBB, I, 8);
128     break;
129   case Mips::STORE_ACC64:
130     expandStoreACC(MBB, I, Mips::PseudoMFHI, Mips::PseudoMFLO, 4);
131     break;
132   case Mips::STORE_ACC64DSP:
133     expandStoreACC(MBB, I, Mips::MFHI_DSP, Mips::MFLO_DSP, 4);
134     break;
135   case Mips::STORE_ACC128:
136     expandStoreACC(MBB, I, Mips::PseudoMFHI64, Mips::PseudoMFLO64, 8);
137     break;
138   case Mips::BuildPairF64:
139     if (expandBuildPairF64(MBB, I, false))
140       MBB.erase(I);
141     return false;
142   case Mips::BuildPairF64_64:
143     if (expandBuildPairF64(MBB, I, true))
144       MBB.erase(I);
145     return false;
146   case Mips::ExtractElementF64:
147     if (expandExtractElementF64(MBB, I, false))
148       MBB.erase(I);
149     return false;
150   case Mips::ExtractElementF64_64:
151     if (expandExtractElementF64(MBB, I, true))
152       MBB.erase(I);
153     return false;
154   case TargetOpcode::COPY:
155     if (!expandCopy(MBB, I))
156       return false;
157     break;
158   default:
159     return false;
160   }
161 
162   MBB.erase(I);
163   return true;
164 }
165 
166 void ExpandPseudo::expandLoadCCond(MachineBasicBlock &MBB, Iter I) {
167   //  load $vr, FI
168   //  copy ccond, $vr
169 
170   assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
171 
172   const TargetRegisterClass *RC = RegInfo.intRegClass(4);
173   Register VR = MRI.createVirtualRegister(RC);
174   Register Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
175 
176   TII.loadRegFromStack(MBB, I, VR, FI, RC, &RegInfo, 0);
177   BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), Dst)
178     .addReg(VR, RegState::Kill);
179 }
180 
181 void ExpandPseudo::expandStoreCCond(MachineBasicBlock &MBB, Iter I) {
182   //  copy $vr, ccond
183   //  store $vr, FI
184 
185   assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
186 
187   const TargetRegisterClass *RC = RegInfo.intRegClass(4);
188   Register VR = MRI.createVirtualRegister(RC);
189   Register Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
190 
191   BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), VR)
192     .addReg(Src, getKillRegState(I->getOperand(0).isKill()));
193   TII.storeRegToStack(MBB, I, VR, true, FI, RC, &RegInfo, 0);
194 }
195 
196 void ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I,
197                                  unsigned RegSize) {
198   //  load $vr0, FI
199   //  copy lo, $vr0
200   //  load $vr1, FI + 4
201   //  copy hi, $vr1
202 
203   assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
204 
205   const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
206   Register VR0 = MRI.createVirtualRegister(RC);
207   Register VR1 = MRI.createVirtualRegister(RC);
208   Register Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
209   Register Lo = RegInfo.getSubReg(Dst, Mips::sub_lo);
210   Register Hi = RegInfo.getSubReg(Dst, Mips::sub_hi);
211   DebugLoc DL = I->getDebugLoc();
212   const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY);
213 
214   TII.loadRegFromStack(MBB, I, VR0, FI, RC, &RegInfo, 0);
215   BuildMI(MBB, I, DL, Desc, Lo).addReg(VR0, RegState::Kill);
216   TII.loadRegFromStack(MBB, I, VR1, FI, RC, &RegInfo, RegSize);
217   BuildMI(MBB, I, DL, Desc, Hi).addReg(VR1, RegState::Kill);
218 }
219 
220 void ExpandPseudo::expandStoreACC(MachineBasicBlock &MBB, Iter I,
221                                   unsigned MFHiOpc, unsigned MFLoOpc,
222                                   unsigned RegSize) {
223   //  mflo $vr0, src
224   //  store $vr0, FI
225   //  mfhi $vr1, src
226   //  store $vr1, FI + 4
227 
228   assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
229 
230   const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
231   Register VR0 = MRI.createVirtualRegister(RC);
232   Register VR1 = MRI.createVirtualRegister(RC);
233   Register Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
234   unsigned SrcKill = getKillRegState(I->getOperand(0).isKill());
235   DebugLoc DL = I->getDebugLoc();
236 
237   BuildMI(MBB, I, DL, TII.get(MFLoOpc), VR0).addReg(Src);
238   TII.storeRegToStack(MBB, I, VR0, true, FI, RC, &RegInfo, 0);
239   BuildMI(MBB, I, DL, TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);
240   TII.storeRegToStack(MBB, I, VR1, true, FI, RC, &RegInfo, RegSize);
241 }
242 
243 bool ExpandPseudo::expandCopy(MachineBasicBlock &MBB, Iter I) {
244   Register Src = I->getOperand(1).getReg();
245   std::pair<unsigned, unsigned> Opcodes = getMFHiLoOpc(Src);
246 
247   if (!Opcodes.first)
248     return false;
249 
250   return expandCopyACC(MBB, I, Opcodes.first, Opcodes.second);
251 }
252 
253 bool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I,
254                                  unsigned MFHiOpc, unsigned MFLoOpc) {
255   //  mflo $vr0, src
256   //  copy dst_lo, $vr0
257   //  mfhi $vr1, src
258   //  copy dst_hi, $vr1
259 
260   unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg();
261   const TargetRegisterClass *DstRC = RegInfo.getMinimalPhysRegClass(Dst);
262   unsigned VRegSize = RegInfo.getRegSizeInBits(*DstRC) / 16;
263   const TargetRegisterClass *RC = RegInfo.intRegClass(VRegSize);
264   Register VR0 = MRI.createVirtualRegister(RC);
265   Register VR1 = MRI.createVirtualRegister(RC);
266   unsigned SrcKill = getKillRegState(I->getOperand(1).isKill());
267   Register DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo);
268   Register DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi);
269   DebugLoc DL = I->getDebugLoc();
270 
271   BuildMI(MBB, I, DL, TII.get(MFLoOpc), VR0).addReg(Src);
272   BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstLo)
273     .addReg(VR0, RegState::Kill);
274   BuildMI(MBB, I, DL, TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);
275   BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstHi)
276     .addReg(VR1, RegState::Kill);
277   return true;
278 }
279 
280 /// This method expands the same instruction that MipsSEInstrInfo::
281 /// expandBuildPairF64 does, for the case when ABI is fpxx and mthc1 is not
282 /// available and the case where the ABI is FP64A. It is implemented here
283 /// because frame indexes are eliminated before MipsSEInstrInfo::
284 /// expandBuildPairF64 is called.
285 bool ExpandPseudo::expandBuildPairF64(MachineBasicBlock &MBB,
286                                       MachineBasicBlock::iterator I,
287                                       bool FP64) const {
288   // For fpxx and when mthc1 is not available, use:
289   //   spill + reload via ldc1
290   //
291   // The case where dmtc1 is available doesn't need to be handled here
292   // because it never creates a BuildPairF64 node.
293   //
294   // The FP64A ABI (fp64 with nooddspreg) must also use a spill/reload sequence
295   // for odd-numbered double precision values (because the lower 32-bits is
296   // transferred with mtc1 which is redirected to the upper half of the even
297   // register). Unfortunately, we have to make this decision before register
298   // allocation so for now we use a spill/reload sequence for all
299   // double-precision values in regardless of being an odd/even register.
300   //
301   // For the cases that should be covered here MipsSEISelDAGToDAG adds $sp as
302   // implicit operand, so other passes (like ShrinkWrapping) are aware that
303   // stack is used.
304   if (I->getNumOperands() == 4 && I->getOperand(3).isReg()
305       && I->getOperand(3).getReg() == Mips::SP) {
306     Register DstReg = I->getOperand(0).getReg();
307     Register LoReg = I->getOperand(1).getReg();
308     Register HiReg = I->getOperand(2).getReg();
309 
310     // It should be impossible to have FGR64 on MIPS-II or MIPS32r1 (which are
311     // the cases where mthc1 is not available). 64-bit architectures and
312     // MIPS32r2 or later can use FGR64 though.
313     assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||
314            !Subtarget.isFP64bit());
315 
316     const TargetRegisterClass *RC = &Mips::GPR32RegClass;
317     const TargetRegisterClass *RC2 =
318         FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
319 
320     // We re-use the same spill slot each time so that the stack frame doesn't
321     // grow too much in functions with a large number of moves.
322     int FI = MF.getInfo<MipsFunctionInfo>()->getMoveF64ViaSpillFI(MF, RC2);
323     if (!Subtarget.isLittle())
324       std::swap(LoReg, HiReg);
325     TII.storeRegToStack(MBB, I, LoReg, I->getOperand(1).isKill(), FI, RC,
326                         &RegInfo, 0);
327     TII.storeRegToStack(MBB, I, HiReg, I->getOperand(2).isKill(), FI, RC,
328                         &RegInfo, 4);
329     TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, &RegInfo, 0);
330     return true;
331   }
332 
333   return false;
334 }
335 
336 /// This method expands the same instruction that MipsSEInstrInfo::
337 /// expandExtractElementF64 does, for the case when ABI is fpxx and mfhc1 is not
338 /// available and the case where the ABI is FP64A. It is implemented here
339 /// because frame indexes are eliminated before MipsSEInstrInfo::
340 /// expandExtractElementF64 is called.
341 bool ExpandPseudo::expandExtractElementF64(MachineBasicBlock &MBB,
342                                            MachineBasicBlock::iterator I,
343                                            bool FP64) const {
344   const MachineOperand &Op1 = I->getOperand(1);
345   const MachineOperand &Op2 = I->getOperand(2);
346 
347   if ((Op1.isReg() && Op1.isUndef()) || (Op2.isReg() && Op2.isUndef())) {
348     Register DstReg = I->getOperand(0).getReg();
349     BuildMI(MBB, I, I->getDebugLoc(), TII.get(Mips::IMPLICIT_DEF), DstReg);
350     return true;
351   }
352 
353   // For fpxx and when mfhc1 is not available, use:
354   //   spill + reload via ldc1
355   //
356   // The case where dmfc1 is available doesn't need to be handled here
357   // because it never creates a ExtractElementF64 node.
358   //
359   // The FP64A ABI (fp64 with nooddspreg) must also use a spill/reload sequence
360   // for odd-numbered double precision values (because the lower 32-bits is
361   // transferred with mfc1 which is redirected to the upper half of the even
362   // register). Unfortunately, we have to make this decision before register
363   // allocation so for now we use a spill/reload sequence for all
364   // double-precision values in regardless of being an odd/even register.
365   //
366   // For the cases that should be covered here MipsSEISelDAGToDAG adds $sp as
367   // implicit operand, so other passes (like ShrinkWrapping) are aware that
368   // stack is used.
369   if (I->getNumOperands() == 4 && I->getOperand(3).isReg()
370       && I->getOperand(3).getReg() == Mips::SP) {
371     Register DstReg = I->getOperand(0).getReg();
372     Register SrcReg = Op1.getReg();
373     unsigned N = Op2.getImm();
374     int64_t Offset = 4 * (Subtarget.isLittle() ? N : (1 - N));
375 
376     // It should be impossible to have FGR64 on MIPS-II or MIPS32r1 (which are
377     // the cases where mfhc1 is not available). 64-bit architectures and
378     // MIPS32r2 or later can use FGR64 though.
379     assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||
380            !Subtarget.isFP64bit());
381 
382     const TargetRegisterClass *RC =
383         FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
384     const TargetRegisterClass *RC2 = &Mips::GPR32RegClass;
385 
386     // We re-use the same spill slot each time so that the stack frame doesn't
387     // grow too much in functions with a large number of moves.
388     int FI = MF.getInfo<MipsFunctionInfo>()->getMoveF64ViaSpillFI(MF, RC);
389     TII.storeRegToStack(MBB, I, SrcReg, Op1.isKill(), FI, RC, &RegInfo, 0);
390     TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, &RegInfo, Offset);
391     return true;
392   }
393 
394   return false;
395 }
396 
397 MipsSEFrameLowering::MipsSEFrameLowering(const MipsSubtarget &STI)
398     : MipsFrameLowering(STI, STI.getStackAlignment()) {}
399 
400 void MipsSEFrameLowering::emitPrologue(MachineFunction &MF,
401                                        MachineBasicBlock &MBB) const {
402   MachineFrameInfo &MFI    = MF.getFrameInfo();
403   MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
404 
405   const MipsSEInstrInfo &TII =
406       *static_cast<const MipsSEInstrInfo *>(STI.getInstrInfo());
407   const MipsRegisterInfo &RegInfo =
408       *static_cast<const MipsRegisterInfo *>(STI.getRegisterInfo());
409 
410   MachineBasicBlock::iterator MBBI = MBB.begin();
411   DebugLoc dl;
412   MipsABIInfo ABI = STI.getABI();
413   unsigned SP = ABI.GetStackPtr();
414   unsigned FP = ABI.GetFramePtr();
415   unsigned ZERO = ABI.GetNullPtr();
416   unsigned MOVE = ABI.GetGPRMoveOp();
417   unsigned ADDiu = ABI.GetPtrAddiuOp();
418   unsigned AND = ABI.IsN64() ? Mips::AND64 : Mips::AND;
419 
420   const TargetRegisterClass *RC = ABI.ArePtrs64bit() ?
421         &Mips::GPR64RegClass : &Mips::GPR32RegClass;
422 
423   // First, compute final stack size.
424   uint64_t StackSize = MFI.getStackSize();
425 
426   // No need to allocate space on the stack.
427   if (StackSize == 0 && !MFI.adjustsStack()) return;
428 
429   const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();
430 
431   // Adjust stack.
432   TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
433 
434   // emit ".cfi_def_cfa_offset StackSize"
435   unsigned CFIIndex =
436       MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize));
437   BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
438       .addCFIIndex(CFIIndex);
439 
440   if (MF.getFunction().hasFnAttribute("interrupt"))
441     emitInterruptPrologueStub(MF, MBB);
442 
443   const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
444 
445   if (!CSI.empty()) {
446     // Find the instruction past the last instruction that saves a callee-saved
447     // register to the stack.
448     for (unsigned i = 0; i < CSI.size(); ++i)
449       ++MBBI;
450 
451     // Iterate over list of callee-saved registers and emit .cfi_offset
452     // directives.
453     for (const CalleeSavedInfo &I : CSI) {
454       int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());
455       Register Reg = I.getReg();
456 
457       // If Reg is a double precision register, emit two cfa_offsets,
458       // one for each of the paired single precision registers.
459       if (Mips::AFGR64RegClass.contains(Reg)) {
460         unsigned Reg0 =
461             MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_lo), true);
462         unsigned Reg1 =
463             MRI->getDwarfRegNum(RegInfo.getSubReg(Reg, Mips::sub_hi), true);
464 
465         if (!STI.isLittle())
466           std::swap(Reg0, Reg1);
467 
468         unsigned CFIIndex = MF.addFrameInst(
469             MCCFIInstruction::createOffset(nullptr, Reg0, Offset));
470         BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
471             .addCFIIndex(CFIIndex);
472 
473         CFIIndex = MF.addFrameInst(
474             MCCFIInstruction::createOffset(nullptr, Reg1, Offset + 4));
475         BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
476             .addCFIIndex(CFIIndex);
477       } else if (Mips::FGR64RegClass.contains(Reg)) {
478         unsigned Reg0 = MRI->getDwarfRegNum(Reg, true);
479         unsigned Reg1 = MRI->getDwarfRegNum(Reg, true) + 1;
480 
481         if (!STI.isLittle())
482           std::swap(Reg0, Reg1);
483 
484         unsigned CFIIndex = MF.addFrameInst(
485           MCCFIInstruction::createOffset(nullptr, Reg0, Offset));
486         BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
487             .addCFIIndex(CFIIndex);
488 
489         CFIIndex = MF.addFrameInst(
490           MCCFIInstruction::createOffset(nullptr, Reg1, Offset + 4));
491         BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
492             .addCFIIndex(CFIIndex);
493       } else {
494         // Reg is either in GPR32 or FGR32.
495         unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
496             nullptr, MRI->getDwarfRegNum(Reg, true), Offset));
497         BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
498             .addCFIIndex(CFIIndex);
499       }
500     }
501   }
502 
503   if (MipsFI->callsEhReturn()) {
504     // Insert instructions that spill eh data registers.
505     for (int I = 0; I < 4; ++I) {
506       if (!MBB.isLiveIn(ABI.GetEhDataReg(I)))
507         MBB.addLiveIn(ABI.GetEhDataReg(I));
508       TII.storeRegToStackSlot(MBB, MBBI, ABI.GetEhDataReg(I), false,
509                               MipsFI->getEhDataRegFI(I), RC, &RegInfo,
510                               Register());
511     }
512 
513     // Emit .cfi_offset directives for eh data registers.
514     for (int I = 0; I < 4; ++I) {
515       int64_t Offset = MFI.getObjectOffset(MipsFI->getEhDataRegFI(I));
516       unsigned Reg = MRI->getDwarfRegNum(ABI.GetEhDataReg(I), true);
517       unsigned CFIIndex = MF.addFrameInst(
518           MCCFIInstruction::createOffset(nullptr, Reg, Offset));
519       BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
520           .addCFIIndex(CFIIndex);
521     }
522   }
523 
524   // if framepointer enabled, set it to point to the stack pointer.
525   if (hasFP(MF)) {
526     // Insert instruction "move $fp, $sp" at this location.
527     BuildMI(MBB, MBBI, dl, TII.get(MOVE), FP).addReg(SP).addReg(ZERO)
528       .setMIFlag(MachineInstr::FrameSetup);
529 
530     // emit ".cfi_def_cfa_register $fp"
531     unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(
532         nullptr, MRI->getDwarfRegNum(FP, true)));
533     BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
534         .addCFIIndex(CFIIndex);
535 
536     if (RegInfo.hasStackRealignment(MF)) {
537       // addiu $Reg, $zero, -MaxAlignment
538       // andi $sp, $sp, $Reg
539       Register VR = MF.getRegInfo().createVirtualRegister(RC);
540       assert((Log2(MFI.getMaxAlign()) < 16) &&
541              "Function's alignment size requirement is not supported.");
542       int64_t MaxAlign = -(int64_t)MFI.getMaxAlign().value();
543 
544       BuildMI(MBB, MBBI, dl, TII.get(ADDiu), VR).addReg(ZERO).addImm(MaxAlign);
545       BuildMI(MBB, MBBI, dl, TII.get(AND), SP).addReg(SP).addReg(VR);
546 
547       if (hasBP(MF)) {
548         // move $s7, $sp
549         unsigned BP = STI.isABI_N64() ? Mips::S7_64 : Mips::S7;
550         BuildMI(MBB, MBBI, dl, TII.get(MOVE), BP)
551           .addReg(SP)
552           .addReg(ZERO);
553       }
554     }
555   }
556 }
557 
558 void MipsSEFrameLowering::emitInterruptPrologueStub(
559     MachineFunction &MF, MachineBasicBlock &MBB) const {
560   MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
561   MachineBasicBlock::iterator MBBI = MBB.begin();
562   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
563 
564   // Report an error the target doesn't support Mips32r2 or later.
565   // The epilogue relies on the use of the "ehb" to clear execution
566   // hazards. Pre R2 Mips relies on an implementation defined number
567   // of "ssnop"s to clear the execution hazard. Support for ssnop hazard
568   // clearing is not provided so reject that configuration.
569   if (!STI.hasMips32r2())
570     report_fatal_error(
571         "\"interrupt\" attribute is not supported on pre-MIPS32R2 or "
572         "MIPS16 targets.");
573 
574   // The GP register contains the "user" value, so we cannot perform
575   // any gp relative loads until we restore the "kernel" or "system" gp
576   // value. Until support is written we shall only accept the static
577   // relocation model.
578   if ((STI.getRelocationModel() != Reloc::Static))
579     report_fatal_error("\"interrupt\" attribute is only supported for the "
580                        "static relocation model on MIPS at the present time.");
581 
582   if (!STI.isABI_O32() || STI.hasMips64())
583     report_fatal_error("\"interrupt\" attribute is only supported for the "
584                        "O32 ABI on MIPS32R2+ at the present time.");
585 
586   // Perform ISR handling like GCC
587   StringRef IntKind =
588       MF.getFunction().getFnAttribute("interrupt").getValueAsString();
589   const TargetRegisterClass *PtrRC = &Mips::GPR32RegClass;
590 
591   // EIC interrupt handling needs to read the Cause register to disable
592   // interrupts.
593   if (IntKind == "eic") {
594     // Coprocessor registers are always live per se.
595     MBB.addLiveIn(Mips::COP013);
596     BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K0)
597         .addReg(Mips::COP013)
598         .addImm(0)
599         .setMIFlag(MachineInstr::FrameSetup);
600 
601     BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::EXT), Mips::K0)
602         .addReg(Mips::K0)
603         .addImm(10)
604         .addImm(6)
605         .setMIFlag(MachineInstr::FrameSetup);
606   }
607 
608   // Fetch and spill EPC
609   MBB.addLiveIn(Mips::COP014);
610   BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K1)
611       .addReg(Mips::COP014)
612       .addImm(0)
613       .setMIFlag(MachineInstr::FrameSetup);
614 
615   STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::K1, false,
616                                       MipsFI->getISRRegFI(0), PtrRC,
617                                       STI.getRegisterInfo(), 0);
618 
619   // Fetch and Spill Status
620   MBB.addLiveIn(Mips::COP012);
621   BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K1)
622       .addReg(Mips::COP012)
623       .addImm(0)
624       .setMIFlag(MachineInstr::FrameSetup);
625 
626   STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::K1, false,
627                                       MipsFI->getISRRegFI(1), PtrRC,
628                                       STI.getRegisterInfo(), 0);
629 
630   // Build the configuration for disabling lower priority interrupts. Non EIC
631   // interrupts need to be masked off with zero, EIC from the Cause register.
632   unsigned InsPosition = 8;
633   unsigned InsSize = 0;
634   unsigned SrcReg = Mips::ZERO;
635 
636   // If the interrupt we're tied to is the EIC, switch the source for the
637   // masking off interrupts to the cause register.
638   if (IntKind == "eic") {
639     SrcReg = Mips::K0;
640     InsPosition = 10;
641     InsSize = 6;
642   } else
643     InsSize = StringSwitch<unsigned>(IntKind)
644                   .Case("sw0", 1)
645                   .Case("sw1", 2)
646                   .Case("hw0", 3)
647                   .Case("hw1", 4)
648                   .Case("hw2", 5)
649                   .Case("hw3", 6)
650                   .Case("hw4", 7)
651                   .Case("hw5", 8)
652                   .Default(0);
653   assert(InsSize != 0 && "Unknown interrupt type!");
654 
655   BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)
656       .addReg(SrcReg)
657       .addImm(InsPosition)
658       .addImm(InsSize)
659       .addReg(Mips::K1)
660       .setMIFlag(MachineInstr::FrameSetup);
661 
662   // Mask off KSU, ERL, EXL
663   BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)
664       .addReg(Mips::ZERO)
665       .addImm(1)
666       .addImm(4)
667       .addReg(Mips::K1)
668       .setMIFlag(MachineInstr::FrameSetup);
669 
670   // Disable the FPU as we are not spilling those register sets.
671   if (!STI.useSoftFloat())
672     BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)
673         .addReg(Mips::ZERO)
674         .addImm(29)
675         .addImm(1)
676         .addReg(Mips::K1)
677         .setMIFlag(MachineInstr::FrameSetup);
678 
679   // Set the new status
680   BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP012)
681       .addReg(Mips::K1)
682       .addImm(0)
683       .setMIFlag(MachineInstr::FrameSetup);
684 }
685 
686 void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF,
687                                        MachineBasicBlock &MBB) const {
688   MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
689   MachineFrameInfo &MFI            = MF.getFrameInfo();
690   MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
691 
692   const MipsSEInstrInfo &TII =
693       *static_cast<const MipsSEInstrInfo *>(STI.getInstrInfo());
694   const MipsRegisterInfo &RegInfo =
695       *static_cast<const MipsRegisterInfo *>(STI.getRegisterInfo());
696 
697   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
698   MipsABIInfo ABI = STI.getABI();
699   unsigned SP = ABI.GetStackPtr();
700   unsigned FP = ABI.GetFramePtr();
701   unsigned ZERO = ABI.GetNullPtr();
702   unsigned MOVE = ABI.GetGPRMoveOp();
703 
704   // if framepointer enabled, restore the stack pointer.
705   if (hasFP(MF)) {
706     // Find the first instruction that restores a callee-saved register.
707     MachineBasicBlock::iterator I = MBBI;
708 
709     for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i)
710       --I;
711 
712     // Insert instruction "move $sp, $fp" at this location.
713     BuildMI(MBB, I, DL, TII.get(MOVE), SP).addReg(FP).addReg(ZERO);
714   }
715 
716   if (MipsFI->callsEhReturn()) {
717     const TargetRegisterClass *RC =
718         ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
719 
720     // Find first instruction that restores a callee-saved register.
721     MachineBasicBlock::iterator I = MBBI;
722     for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i)
723       --I;
724 
725     // Insert instructions that restore eh data registers.
726     for (int J = 0; J < 4; ++J) {
727       TII.loadRegFromStackSlot(MBB, I, ABI.GetEhDataReg(J),
728                                MipsFI->getEhDataRegFI(J), RC, &RegInfo,
729                                Register());
730     }
731   }
732 
733   if (MF.getFunction().hasFnAttribute("interrupt"))
734     emitInterruptEpilogueStub(MF, MBB);
735 
736   // Get the number of bytes from FrameInfo
737   uint64_t StackSize = MFI.getStackSize();
738 
739   if (!StackSize)
740     return;
741 
742   // Adjust stack.
743   TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
744 }
745 
746 void MipsSEFrameLowering::emitInterruptEpilogueStub(
747     MachineFunction &MF, MachineBasicBlock &MBB) const {
748   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
749   MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
750   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
751 
752   // Perform ISR handling like GCC
753   const TargetRegisterClass *PtrRC = &Mips::GPR32RegClass;
754 
755   // Disable Interrupts.
756   BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::DI), Mips::ZERO);
757   BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::EHB));
758 
759   // Restore EPC
760   STI.getInstrInfo()->loadRegFromStackSlot(MBB, MBBI, Mips::K1,
761                                            MipsFI->getISRRegFI(0), PtrRC,
762                                            STI.getRegisterInfo(), Register());
763   BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP014)
764       .addReg(Mips::K1)
765       .addImm(0);
766 
767   // Restore Status
768   STI.getInstrInfo()->loadRegFromStackSlot(MBB, MBBI, Mips::K1,
769                                            MipsFI->getISRRegFI(1), PtrRC,
770                                            STI.getRegisterInfo(), Register());
771   BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP012)
772       .addReg(Mips::K1)
773       .addImm(0);
774 }
775 
776 StackOffset
777 MipsSEFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
778                                             Register &FrameReg) const {
779   const MachineFrameInfo &MFI = MF.getFrameInfo();
780   MipsABIInfo ABI = STI.getABI();
781 
782   if (MFI.isFixedObjectIndex(FI))
783     FrameReg = hasFP(MF) ? ABI.GetFramePtr() : ABI.GetStackPtr();
784   else
785     FrameReg = hasBP(MF) ? ABI.GetBasePtr() : ABI.GetStackPtr();
786 
787   return StackOffset::getFixed(MFI.getObjectOffset(FI) + MFI.getStackSize() -
788                                getOffsetOfLocalArea() +
789                                MFI.getOffsetAdjustment());
790 }
791 
792 bool MipsSEFrameLowering::spillCalleeSavedRegisters(
793     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
794     ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
795   MachineFunction *MF = MBB.getParent();
796   const TargetInstrInfo &TII = *STI.getInstrInfo();
797 
798   for (const CalleeSavedInfo &I : CSI) {
799     // Add the callee-saved register as live-in. Do not add if the register is
800     // RA and return address is taken, because it has already been added in
801     // method MipsTargetLowering::lowerRETURNADDR.
802     // It's killed at the spill, unless the register is RA and return address
803     // is taken.
804     Register Reg = I.getReg();
805     bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)
806         && MF->getFrameInfo().isReturnAddressTaken();
807     if (!IsRAAndRetAddrIsTaken)
808       MBB.addLiveIn(Reg);
809 
810     // ISRs require HI/LO to be spilled into kernel registers to be then
811     // spilled to the stack frame.
812     bool IsLOHI = (Reg == Mips::LO0 || Reg == Mips::LO0_64 ||
813                    Reg == Mips::HI0 || Reg == Mips::HI0_64);
814     const Function &Func = MBB.getParent()->getFunction();
815     if (IsLOHI && Func.hasFnAttribute("interrupt")) {
816       DebugLoc DL = MI->getDebugLoc();
817 
818       unsigned Op = 0;
819       if (!STI.getABI().ArePtrs64bit()) {
820         Op = (Reg == Mips::HI0) ? Mips::MFHI : Mips::MFLO;
821         Reg = Mips::K0;
822       } else {
823         Op = (Reg == Mips::HI0) ? Mips::MFHI64 : Mips::MFLO64;
824         Reg = Mips::K0_64;
825       }
826       BuildMI(MBB, MI, DL, TII.get(Op), Mips::K0)
827           .setMIFlag(MachineInstr::FrameSetup);
828     }
829 
830     // Insert the spill to the stack frame.
831     bool IsKill = !IsRAAndRetAddrIsTaken;
832     const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
833     TII.storeRegToStackSlot(MBB, MI, Reg, IsKill, I.getFrameIdx(), RC, TRI,
834                             Register());
835   }
836 
837   return true;
838 }
839 
840 bool
841 MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
842   const MachineFrameInfo &MFI = MF.getFrameInfo();
843   // Reserve call frame if the size of the maximum call frame fits into 16-bit
844   // immediate field and there are no variable sized objects on the stack.
845   // Make sure the second register scavenger spill slot can be accessed with one
846   // instruction.
847   return isInt<16>(MFI.getMaxCallFrameSize() + getStackAlignment()) &&
848     !MFI.hasVarSizedObjects();
849 }
850 
851 /// Mark \p Reg and all registers aliasing it in the bitset.
852 static void setAliasRegs(MachineFunction &MF, BitVector &SavedRegs,
853                          unsigned Reg) {
854   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
855   for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
856     SavedRegs.set(*AI);
857 }
858 
859 void MipsSEFrameLowering::determineCalleeSaves(MachineFunction &MF,
860                                                BitVector &SavedRegs,
861                                                RegScavenger *RS) const {
862   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
863   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
864   MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
865   MipsABIInfo ABI = STI.getABI();
866   unsigned RA = ABI.IsN64() ? Mips::RA_64 : Mips::RA;
867   unsigned FP = ABI.GetFramePtr();
868   unsigned BP = ABI.IsN64() ? Mips::S7_64 : Mips::S7;
869 
870   // Mark $ra and $fp as used if function has dedicated frame pointer.
871   if (hasFP(MF)) {
872     setAliasRegs(MF, SavedRegs, RA);
873     setAliasRegs(MF, SavedRegs, FP);
874   }
875   // Mark $s7 as used if function has dedicated base pointer.
876   if (hasBP(MF))
877     setAliasRegs(MF, SavedRegs, BP);
878 
879   // Create spill slots for eh data registers if function calls eh_return.
880   if (MipsFI->callsEhReturn())
881     MipsFI->createEhDataRegsFI(MF);
882 
883   // Create spill slots for Coprocessor 0 registers if function is an ISR.
884   if (MipsFI->isISR())
885     MipsFI->createISRRegFI(MF);
886 
887   // Expand pseudo instructions which load, store or copy accumulators.
888   // Add an emergency spill slot if a pseudo was expanded.
889   if (ExpandPseudo(MF).expand()) {
890     // The spill slot should be half the size of the accumulator. If target have
891     // general-purpose registers 64 bits wide, it should be 64-bit, otherwise
892     // it should be 32-bit.
893     const TargetRegisterClass &RC = STI.isGP64bit() ?
894       Mips::GPR64RegClass : Mips::GPR32RegClass;
895     int FI = MF.getFrameInfo().CreateSpillStackObject(TRI->getSpillSize(RC),
896                                                       TRI->getSpillAlign(RC));
897     RS->addScavengingFrameIndex(FI);
898   }
899 
900   // Set scavenging frame index if necessary.
901   uint64_t MaxSPOffset = estimateStackSize(MF);
902 
903   // MSA has a minimum offset of 10 bits signed. If there is a variable
904   // sized object on the stack, the estimation cannot account for it.
905   if (isIntN(STI.hasMSA() ? 10 : 16, MaxSPOffset) &&
906       !MF.getFrameInfo().hasVarSizedObjects())
907     return;
908 
909   const TargetRegisterClass &RC =
910       ABI.ArePtrs64bit() ? Mips::GPR64RegClass : Mips::GPR32RegClass;
911   int FI = MF.getFrameInfo().CreateSpillStackObject(TRI->getSpillSize(RC),
912                                                     TRI->getSpillAlign(RC));
913   RS->addScavengingFrameIndex(FI);
914 }
915 
916 const MipsFrameLowering *
917 llvm::createMipsSEFrameLowering(const MipsSubtarget &ST) {
918   return new MipsSEFrameLowering(ST);
919 }
920