LLVM 22.0.0git
MipsSEFrameLowering.cpp
Go to the documentation of this file.
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"
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"
35#include "llvm/IR/DebugLoc.h"
36#include "llvm/IR/Function.h"
40#include <cassert>
41#include <cstdint>
42#include <utility>
43#include <vector>
44
45using namespace llvm;
46
47static std::pair<unsigned, unsigned> getMFHiLoOpc(unsigned Src) {
48 if (Mips::ACC64RegClass.contains(Src))
49 return std::make_pair((unsigned)Mips::PseudoMFHI,
50 (unsigned)Mips::PseudoMFLO);
51
52 if (Mips::ACC64DSPRegClass.contains(Src))
53 return std::make_pair((unsigned)Mips::MFHI_DSP, (unsigned)Mips::MFLO_DSP);
54
55 if (Mips::ACC128RegClass.contains(Src))
56 return std::make_pair((unsigned)Mips::PseudoMFHI64,
57 (unsigned)Mips::PseudoMFLO64);
58
59 return std::make_pair(0, 0);
60}
61
62namespace {
63
64/// Helper class to expand pseudos.
65class ExpandPseudo {
66public:
67 ExpandPseudo(MachineFunction &MF);
68 bool expand();
69
70private:
71 using Iter = MachineBasicBlock::iterator;
72
73 bool expandInstr(MachineBasicBlock &MBB, Iter I);
74 void expandLoadCCond(MachineBasicBlock &MBB, Iter I);
75 void expandStoreCCond(MachineBasicBlock &MBB, Iter I);
76 void expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize);
77 void expandStoreACC(MachineBasicBlock &MBB, Iter I, unsigned MFHiOpc,
78 unsigned MFLoOpc, unsigned RegSize);
79 bool expandCopy(MachineBasicBlock &MBB, Iter I);
80 bool expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned MFHiOpc,
81 unsigned MFLoOpc);
82 bool expandBuildPairF64(MachineBasicBlock &MBB,
83 MachineBasicBlock::iterator I, bool FP64) const;
84 bool expandExtractElementF64(MachineBasicBlock &MBB,
85 MachineBasicBlock::iterator I, bool FP64) const;
86
87 MachineFunction &MF;
88 MachineRegisterInfo &MRI;
89 const MipsSubtarget &Subtarget;
90 const MipsSEInstrInfo &TII;
91 const MipsRegisterInfo &RegInfo;
92};
93
94} // end anonymous namespace
95
96ExpandPseudo::ExpandPseudo(MachineFunction &MF_)
97 : MF(MF_), MRI(MF.getRegInfo()),
98 Subtarget(MF.getSubtarget<MipsSubtarget>()),
99 TII(*static_cast<const MipsSEInstrInfo *>(Subtarget.getInstrInfo())),
100 RegInfo(*Subtarget.getRegisterInfo()) {}
101
102bool ExpandPseudo::expand() {
103 bool Expanded = false;
104
105 for (auto &MBB : MF) {
106 for (Iter I = MBB.begin(), End = MBB.end(); I != End;)
107 Expanded |= expandInstr(MBB, I++);
108 }
109
110 return Expanded;
111}
112
113bool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) {
114 switch(I->getOpcode()) {
115 case Mips::LOAD_CCOND_DSP:
116 expandLoadCCond(MBB, I);
117 break;
118 case Mips::STORE_CCOND_DSP:
119 expandStoreCCond(MBB, I);
120 break;
121 case Mips::LOAD_ACC64:
122 case Mips::LOAD_ACC64DSP:
123 expandLoadACC(MBB, I, 4);
124 break;
125 case Mips::LOAD_ACC128:
126 expandLoadACC(MBB, I, 8);
127 break;
128 case Mips::STORE_ACC64:
129 expandStoreACC(MBB, I, Mips::PseudoMFHI, Mips::PseudoMFLO, 4);
130 break;
131 case Mips::STORE_ACC64DSP:
132 expandStoreACC(MBB, I, Mips::MFHI_DSP, Mips::MFLO_DSP, 4);
133 break;
134 case Mips::STORE_ACC128:
135 expandStoreACC(MBB, I, Mips::PseudoMFHI64, Mips::PseudoMFLO64, 8);
136 break;
137 case Mips::BuildPairF64:
138 if (expandBuildPairF64(MBB, I, false))
139 MBB.erase(I);
140 return false;
141 case Mips::BuildPairF64_64:
142 if (expandBuildPairF64(MBB, I, true))
143 MBB.erase(I);
144 return false;
145 case Mips::ExtractElementF64:
146 if (expandExtractElementF64(MBB, I, false))
147 MBB.erase(I);
148 return false;
149 case Mips::ExtractElementF64_64:
150 if (expandExtractElementF64(MBB, I, true))
151 MBB.erase(I);
152 return false;
153 case TargetOpcode::COPY:
154 if (!expandCopy(MBB, I))
155 return false;
156 break;
157 default:
158 return false;
159 }
160
161 MBB.erase(I);
162 return true;
163}
164
165void ExpandPseudo::expandLoadCCond(MachineBasicBlock &MBB, Iter I) {
166 // load $vr, FI
167 // copy ccond, $vr
168
169 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
170
171 const TargetRegisterClass *RC = RegInfo.intRegClass(4);
172 Register VR = MRI.createVirtualRegister(RC);
173 Register Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
174
175 TII.loadRegFromStack(MBB, I, VR, FI, RC, 0);
176 BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), Dst)
178}
179
180void ExpandPseudo::expandStoreCCond(MachineBasicBlock &MBB, Iter I) {
181 // copy $vr, ccond
182 // store $vr, FI
183
184 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
185
186 const TargetRegisterClass *RC = RegInfo.intRegClass(4);
187 Register VR = MRI.createVirtualRegister(RC);
188 Register Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
189
190 BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), VR)
191 .addReg(Src, getKillRegState(I->getOperand(0).isKill()));
192 TII.storeRegToStack(MBB, I, VR, true, FI, RC, 0);
193}
194
195void ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I,
196 unsigned RegSize) {
197 // load $vr0, FI
198 // copy lo, $vr0
199 // load $vr1, FI + 4
200 // copy hi, $vr1
201
202 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
203
204 const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
205 Register VR0 = MRI.createVirtualRegister(RC);
206 Register VR1 = MRI.createVirtualRegister(RC);
207 Register Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
208 Register Lo = RegInfo.getSubReg(Dst, Mips::sub_lo);
209 Register Hi = RegInfo.getSubReg(Dst, Mips::sub_hi);
210 DebugLoc DL = I->getDebugLoc();
211 const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY);
212
213 TII.loadRegFromStack(MBB, I, VR0, FI, RC, 0);
215 TII.loadRegFromStack(MBB, I, VR1, FI, RC, RegSize);
217}
218
219void ExpandPseudo::expandStoreACC(MachineBasicBlock &MBB, Iter I,
220 unsigned MFHiOpc, unsigned MFLoOpc,
221 unsigned RegSize) {
222 // mflo $vr0, src
223 // store $vr0, FI
224 // mfhi $vr1, src
225 // store $vr1, FI + 4
226
227 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());
228
229 const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);
230 Register VR0 = MRI.createVirtualRegister(RC);
231 Register VR1 = MRI.createVirtualRegister(RC);
232 Register Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
233 unsigned SrcKill = getKillRegState(I->getOperand(0).isKill());
234 DebugLoc DL = I->getDebugLoc();
235
236 BuildMI(MBB, I, DL, TII.get(MFLoOpc), VR0).addReg(Src);
237 TII.storeRegToStack(MBB, I, VR0, true, FI, RC, 0);
238 BuildMI(MBB, I, DL, TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);
239 TII.storeRegToStack(MBB, I, VR1, true, FI, RC, RegSize);
240}
241
242bool ExpandPseudo::expandCopy(MachineBasicBlock &MBB, Iter I) {
243 Register Src = I->getOperand(1).getReg();
244 std::pair<unsigned, unsigned> Opcodes = getMFHiLoOpc(Src);
245
246 if (!Opcodes.first)
247 return false;
248
249 return expandCopyACC(MBB, I, Opcodes.first, Opcodes.second);
250}
251
252bool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I,
253 unsigned MFHiOpc, unsigned MFLoOpc) {
254 // mflo $vr0, src
255 // copy dst_lo, $vr0
256 // mfhi $vr1, src
257 // copy dst_hi, $vr1
258
259 unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg();
260 const TargetRegisterClass *DstRC = RegInfo.getMinimalPhysRegClass(Dst);
261 unsigned VRegSize = RegInfo.getRegSizeInBits(*DstRC) / 16;
262 const TargetRegisterClass *RC = RegInfo.intRegClass(VRegSize);
263 Register VR0 = MRI.createVirtualRegister(RC);
264 Register VR1 = MRI.createVirtualRegister(RC);
265 unsigned SrcKill = getKillRegState(I->getOperand(1).isKill());
266 Register DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo);
267 Register DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi);
268 DebugLoc DL = I->getDebugLoc();
269
270 BuildMI(MBB, I, DL, TII.get(MFLoOpc), VR0).addReg(Src);
271 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstLo)
272 .addReg(VR0, RegState::Kill);
273 BuildMI(MBB, I, DL, TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);
274 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstHi)
275 .addReg(VR1, RegState::Kill);
276 return true;
277}
278
279/// This method expands the same instruction that MipsSEInstrInfo::
280/// expandBuildPairF64 does, for the case when ABI is fpxx and mthc1 is not
281/// available and the case where the ABI is FP64A. It is implemented here
282/// because frame indexes are eliminated before MipsSEInstrInfo::
283/// expandBuildPairF64 is called.
284bool ExpandPseudo::expandBuildPairF64(MachineBasicBlock &MBB,
286 bool FP64) const {
287 // For fpxx and when mthc1 is not available, use:
288 // spill + reload via ldc1
289 //
290 // The case where dmtc1 is available doesn't need to be handled here
291 // because it never creates a BuildPairF64 node.
292 //
293 // The FP64A ABI (fp64 with nooddspreg) must also use a spill/reload sequence
294 // for odd-numbered double precision values (because the lower 32-bits is
295 // transferred with mtc1 which is redirected to the upper half of the even
296 // register). Unfortunately, we have to make this decision before register
297 // allocation so for now we use a spill/reload sequence for all
298 // double-precision values in regardless of being an odd/even register.
299 //
300 // For the cases that should be covered here MipsSEISelDAGToDAG adds $sp as
301 // implicit operand, so other passes (like ShrinkWrapping) are aware that
302 // stack is used.
303 if (I->getNumOperands() == 4 && I->getOperand(3).isReg()
304 && I->getOperand(3).getReg() == Mips::SP) {
305 Register DstReg = I->getOperand(0).getReg();
306 Register LoReg = I->getOperand(1).getReg();
307 Register HiReg = I->getOperand(2).getReg();
308
309 // It should be impossible to have FGR64 on MIPS-II or MIPS32r1 (which are
310 // the cases where mthc1 is not available). 64-bit architectures and
311 // MIPS32r2 or later can use FGR64 though.
312 assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||
313 !Subtarget.isFP64bit());
314
315 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
316 const TargetRegisterClass *RC2 =
317 FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
318
319 // We re-use the same spill slot each time so that the stack frame doesn't
320 // grow too much in functions with a large number of moves.
321 int FI = MF.getInfo<MipsFunctionInfo>()->getMoveF64ViaSpillFI(MF, RC2);
322 if (!Subtarget.isLittle())
323 std::swap(LoReg, HiReg);
324 TII.storeRegToStack(MBB, I, LoReg, I->getOperand(1).isKill(), FI, RC, 0);
325 TII.storeRegToStack(MBB, I, HiReg, I->getOperand(2).isKill(), FI, RC, 4);
326 TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, 0);
327 return true;
328 }
329
330 return false;
331}
332
333/// This method expands the same instruction that MipsSEInstrInfo::
334/// expandExtractElementF64 does, for the case when ABI is fpxx and mfhc1 is not
335/// available and the case where the ABI is FP64A. It is implemented here
336/// because frame indexes are eliminated before MipsSEInstrInfo::
337/// expandExtractElementF64 is called.
338bool ExpandPseudo::expandExtractElementF64(MachineBasicBlock &MBB,
340 bool FP64) const {
341 const MachineOperand &Op1 = I->getOperand(1);
342 const MachineOperand &Op2 = I->getOperand(2);
343
344 if ((Op1.isReg() && Op1.isUndef()) || (Op2.isReg() && Op2.isUndef())) {
345 Register DstReg = I->getOperand(0).getReg();
346 BuildMI(MBB, I, I->getDebugLoc(), TII.get(Mips::IMPLICIT_DEF), DstReg);
347 return true;
348 }
349
350 // For fpxx and when mfhc1 is not available, use:
351 // spill + reload via ldc1
352 //
353 // The case where dmfc1 is available doesn't need to be handled here
354 // because it never creates a ExtractElementF64 node.
355 //
356 // The FP64A ABI (fp64 with nooddspreg) must also use a spill/reload sequence
357 // for odd-numbered double precision values (because the lower 32-bits is
358 // transferred with mfc1 which is redirected to the upper half of the even
359 // register). Unfortunately, we have to make this decision before register
360 // allocation so for now we use a spill/reload sequence for all
361 // double-precision values in regardless of being an odd/even register.
362 //
363 // For the cases that should be covered here MipsSEISelDAGToDAG adds $sp as
364 // implicit operand, so other passes (like ShrinkWrapping) are aware that
365 // stack is used.
366 if (I->getNumOperands() == 4 && I->getOperand(3).isReg()
367 && I->getOperand(3).getReg() == Mips::SP) {
368 Register DstReg = I->getOperand(0).getReg();
369 Register SrcReg = Op1.getReg();
370 unsigned N = Op2.getImm();
371 int64_t Offset = 4 * (Subtarget.isLittle() ? N : (1 - N));
372
373 // It should be impossible to have FGR64 on MIPS-II or MIPS32r1 (which are
374 // the cases where mfhc1 is not available). 64-bit architectures and
375 // MIPS32r2 or later can use FGR64 though.
376 assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||
377 !Subtarget.isFP64bit());
378
379 const TargetRegisterClass *RC =
380 FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
381 const TargetRegisterClass *RC2 = &Mips::GPR32RegClass;
382
383 // We re-use the same spill slot each time so that the stack frame doesn't
384 // grow too much in functions with a large number of moves.
385 int FI = MF.getInfo<MipsFunctionInfo>()->getMoveF64ViaSpillFI(MF, RC);
386 TII.storeRegToStack(MBB, I, SrcReg, Op1.isKill(), FI, RC, 0);
387 TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, Offset);
388 return true;
389 }
390
391 return false;
392}
393
396
398 MachineBasicBlock &MBB) const {
399 MachineFrameInfo &MFI = MF.getFrameInfo();
401
402 const MipsSEInstrInfo &TII =
403 *static_cast<const MipsSEInstrInfo *>(STI.getInstrInfo());
404 const MipsRegisterInfo &RegInfo = *STI.getRegisterInfo();
405
407 DebugLoc dl;
408 MipsABIInfo ABI = STI.getABI();
409 unsigned SP = ABI.GetStackPtr();
410 unsigned FP = ABI.GetFramePtr();
411 unsigned ZERO = ABI.GetNullPtr();
412 unsigned MOVE = ABI.GetGPRMoveOp();
413 unsigned ADDiu = ABI.GetPtrAddiuOp();
414 unsigned AND = ABI.IsN64() ? Mips::AND64 : Mips::AND;
415
416 const TargetRegisterClass *RC = ABI.ArePtrs64bit() ?
417 &Mips::GPR64RegClass : &Mips::GPR32RegClass;
418
419 // First, compute final stack size.
420 uint64_t StackSize = MFI.getStackSize();
421
422 // No need to allocate space on the stack.
423 if (StackSize == 0 && !MFI.adjustsStack()) return;
424
426
427 // Adjust stack.
428 TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
429 CFIBuilder.buildDefCFAOffset(StackSize);
430
431 if (MF.getFunction().hasFnAttribute("interrupt"))
432 emitInterruptPrologueStub(MF, MBB);
433
434 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
435
436 // Find the instruction past the last instruction that saves a callee-saved
437 // register to the stack.
438 std::advance(MBBI, CSI.size());
439 CFIBuilder.setInsertPoint(MBBI);
440
441 if (!CSI.empty()) {
442 // Iterate over list of callee-saved registers and emit .cfi_offset
443 // directives.
444 for (const CalleeSavedInfo &I : CSI) {
445 int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());
446 MCRegister Reg = I.getReg();
447
448 // If Reg is a double precision register, emit two cfa_offsets,
449 // one for each of the paired single precision registers.
450 if (Mips::AFGR64RegClass.contains(Reg)) {
451 MCRegister Reg0 = RegInfo.getSubReg(Reg, Mips::sub_lo);
452 MCRegister Reg1 = RegInfo.getSubReg(Reg, Mips::sub_hi);
453
454 if (!STI.isLittle())
455 std::swap(Reg0, Reg1);
456
457 CFIBuilder.buildOffset(Reg0, Offset);
458 CFIBuilder.buildOffset(Reg1, Offset + 4);
459 } else if (Mips::FGR64RegClass.contains(Reg)) {
460 MCRegister Reg0 = Reg;
461 MCRegister Reg1 = Reg + 1;
462
463 if (!STI.isLittle())
464 std::swap(Reg0, Reg1);
465
466 CFIBuilder.buildOffset(Reg0, Offset);
467 CFIBuilder.buildOffset(Reg1, Offset + 4);
468 } else {
469 // Reg is either in GPR32 or FGR32.
470 CFIBuilder.buildOffset(Reg, Offset);
471 }
472 }
473 }
474
475 if (MipsFI->callsEhReturn()) {
476 // Insert instructions that spill eh data registers.
477 for (int I = 0; I < 4; ++I) {
478 if (!MBB.isLiveIn(ABI.GetEhDataReg(I)))
479 MBB.addLiveIn(ABI.GetEhDataReg(I));
480 TII.storeRegToStackSlot(MBB, MBBI, ABI.GetEhDataReg(I), false,
481 MipsFI->getEhDataRegFI(I), RC, Register());
482 }
483
484 // Emit .cfi_offset directives for eh data registers.
485 for (int I = 0; I < 4; ++I) {
486 int64_t Offset = MFI.getObjectOffset(MipsFI->getEhDataRegFI(I));
487 CFIBuilder.buildOffset(ABI.GetEhDataReg(I), Offset);
488 }
489 }
490
491 // if framepointer enabled, set it to point to the stack pointer.
492 if (hasFP(MF)) {
493 // Insert instruction "move $fp, $sp" at this location.
494 BuildMI(MBB, MBBI, dl, TII.get(MOVE), FP).addReg(SP).addReg(ZERO)
496
497 CFIBuilder.buildDefCFARegister(FP);
498
499 if (RegInfo.hasStackRealignment(MF)) {
500 // addiu $Reg, $zero, -MaxAlignment
501 // andi $sp, $sp, $Reg
503 assert((Log2(MFI.getMaxAlign()) < 16) &&
504 "Function's alignment size requirement is not supported.");
505 int64_t MaxAlign = -(int64_t)MFI.getMaxAlign().value();
506
507 BuildMI(MBB, MBBI, dl, TII.get(ADDiu), VR).addReg(ZERO).addImm(MaxAlign);
508 BuildMI(MBB, MBBI, dl, TII.get(AND), SP).addReg(SP).addReg(VR);
509
510 if (hasBP(MF)) {
511 // move $s7, $sp
512 unsigned BP = STI.isABI_N64() ? Mips::S7_64 : Mips::S7;
513 BuildMI(MBB, MBBI, dl, TII.get(MOVE), BP)
514 .addReg(SP)
515 .addReg(ZERO);
516 }
517 }
518 }
519}
520
521void MipsSEFrameLowering::emitInterruptPrologueStub(
525 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
526
527 // Report an error the target doesn't support Mips32r2 or later.
528 // The epilogue relies on the use of the "ehb" to clear execution
529 // hazards. Pre R2 Mips relies on an implementation defined number
530 // of "ssnop"s to clear the execution hazard. Support for ssnop hazard
531 // clearing is not provided so reject that configuration.
532 if (!STI.hasMips32r2())
534 "\"interrupt\" attribute is not supported on pre-MIPS32R2 or "
535 "MIPS16 targets.");
536
537 // The GP register contains the "user" value, so we cannot perform
538 // any gp relative loads until we restore the "kernel" or "system" gp
539 // value. Until support is written we shall only accept the static
540 // relocation model.
542 report_fatal_error("\"interrupt\" attribute is only supported for the "
543 "static relocation model on MIPS at the present time.");
544
545 if (!STI.isABI_O32() || STI.hasMips64())
546 report_fatal_error("\"interrupt\" attribute is only supported for the "
547 "O32 ABI on MIPS32R2+ at the present time.");
548
549 // Perform ISR handling like GCC
550 StringRef IntKind =
551 MF.getFunction().getFnAttribute("interrupt").getValueAsString();
552 const TargetRegisterClass *PtrRC = &Mips::GPR32RegClass;
553
554 // EIC interrupt handling needs to read the Cause register to disable
555 // interrupts.
556 if (IntKind == "eic") {
557 // Coprocessor registers are always live per se.
558 MBB.addLiveIn(Mips::COP013);
559 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K0)
560 .addReg(Mips::COP013)
561 .addImm(0)
563
564 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::EXT), Mips::K0)
565 .addReg(Mips::K0)
566 .addImm(10)
567 .addImm(6)
569 }
570
571 // Fetch and spill EPC
572 MBB.addLiveIn(Mips::COP014);
573 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K1)
574 .addReg(Mips::COP014)
575 .addImm(0)
577
578 STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::K1, false,
579 MipsFI->getISRRegFI(0), PtrRC, 0);
580
581 // Fetch and Spill Status
582 MBB.addLiveIn(Mips::COP012);
583 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K1)
584 .addReg(Mips::COP012)
585 .addImm(0)
587
588 STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::K1, false,
589 MipsFI->getISRRegFI(1), PtrRC, 0);
590
591 // Build the configuration for disabling lower priority interrupts. Non EIC
592 // interrupts need to be masked off with zero, EIC from the Cause register.
593 unsigned InsPosition = 8;
594 unsigned InsSize = 0;
595 unsigned SrcReg = Mips::ZERO;
596
597 // If the interrupt we're tied to is the EIC, switch the source for the
598 // masking off interrupts to the cause register.
599 if (IntKind == "eic") {
600 SrcReg = Mips::K0;
601 InsPosition = 10;
602 InsSize = 6;
603 } else
604 InsSize = StringSwitch<unsigned>(IntKind)
605 .Case("sw0", 1)
606 .Case("sw1", 2)
607 .Case("hw0", 3)
608 .Case("hw1", 4)
609 .Case("hw2", 5)
610 .Case("hw3", 6)
611 .Case("hw4", 7)
612 .Case("hw5", 8)
613 .Default(0);
614 assert(InsSize != 0 && "Unknown interrupt type!");
615
616 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)
617 .addReg(SrcReg)
618 .addImm(InsPosition)
619 .addImm(InsSize)
620 .addReg(Mips::K1)
622
623 // Mask off KSU, ERL, EXL
624 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)
625 .addReg(Mips::ZERO)
626 .addImm(1)
627 .addImm(4)
628 .addReg(Mips::K1)
630
631 // Disable the FPU as we are not spilling those register sets.
632 if (!STI.useSoftFloat())
633 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)
634 .addReg(Mips::ZERO)
635 .addImm(29)
636 .addImm(1)
637 .addReg(Mips::K1)
639
640 // Set the new status
641 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP012)
642 .addReg(Mips::K1)
643 .addImm(0)
645}
646
648 MachineBasicBlock &MBB) const {
649 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
650 MachineFrameInfo &MFI = MF.getFrameInfo();
652
653 const MipsSEInstrInfo &TII =
654 *static_cast<const MipsSEInstrInfo *>(STI.getInstrInfo());
655
656 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
657 MipsABIInfo ABI = STI.getABI();
658 unsigned SP = ABI.GetStackPtr();
659 unsigned FP = ABI.GetFramePtr();
660 unsigned ZERO = ABI.GetNullPtr();
661 unsigned MOVE = ABI.GetGPRMoveOp();
662
663 // if framepointer enabled, restore the stack pointer.
664 if (hasFP(MF)) {
665 // Find the first instruction that restores a callee-saved register.
667
668 for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i)
669 --I;
670
671 // Insert instruction "move $sp, $fp" at this location.
672 BuildMI(MBB, I, DL, TII.get(MOVE), SP).addReg(FP).addReg(ZERO);
673 }
674
675 if (MipsFI->callsEhReturn()) {
676 const TargetRegisterClass *RC =
677 ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
678
679 // Find first instruction that restores a callee-saved register.
681 for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i)
682 --I;
683
684 // Insert instructions that restore eh data registers.
685 for (int J = 0; J < 4; ++J) {
686 TII.loadRegFromStackSlot(MBB, I, ABI.GetEhDataReg(J),
687 MipsFI->getEhDataRegFI(J), RC, Register());
688 }
689 }
690
691 if (MF.getFunction().hasFnAttribute("interrupt"))
692 emitInterruptEpilogueStub(MF, MBB);
693
694 // Get the number of bytes from FrameInfo
695 uint64_t StackSize = MFI.getStackSize();
696
697 if (!StackSize)
698 return;
699
700 // Adjust stack.
701 TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
702}
703
704void MipsSEFrameLowering::emitInterruptEpilogueStub(
706 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
708 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
709
710 // Perform ISR handling like GCC
711 const TargetRegisterClass *PtrRC = &Mips::GPR32RegClass;
712
713 // Disable Interrupts.
714 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::DI), Mips::ZERO);
715 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::EHB));
716
717 // Restore EPC
719 MBB, MBBI, Mips::K1, MipsFI->getISRRegFI(0), PtrRC, Register());
720 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP014)
721 .addReg(Mips::K1)
722 .addImm(0);
723
724 // Restore Status
726 MBB, MBBI, Mips::K1, MipsFI->getISRRegFI(1), PtrRC, Register());
727 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP012)
728 .addReg(Mips::K1)
729 .addImm(0);
730}
731
734 Register &FrameReg) const {
735 const MachineFrameInfo &MFI = MF.getFrameInfo();
736 MipsABIInfo ABI = STI.getABI();
737
738 if (MFI.isFixedObjectIndex(FI))
739 FrameReg = hasFP(MF) ? ABI.GetFramePtr() : ABI.GetStackPtr();
740 else
741 FrameReg = hasBP(MF) ? ABI.GetBasePtr() : ABI.GetStackPtr();
742
743 return StackOffset::getFixed(MFI.getObjectOffset(FI) + MFI.getStackSize() -
745 MFI.getOffsetAdjustment());
746}
747
751 MachineFunction *MF = MBB.getParent();
752 const TargetInstrInfo &TII = *STI.getInstrInfo();
753
754 for (const CalleeSavedInfo &I : CSI) {
755 // Add the callee-saved register as live-in. Do not add if the register is
756 // RA and return address is taken, because it has already been added in
757 // method MipsTargetLowering::lowerRETURNADDR.
758 // It's killed at the spill, unless the register is RA and return address
759 // is taken.
760 MCRegister Reg = I.getReg();
761 bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)
763 if (!IsRAAndRetAddrIsTaken)
764 MBB.addLiveIn(Reg);
765
766 // ISRs require HI/LO to be spilled into kernel registers to be then
767 // spilled to the stack frame.
768 bool IsLOHI = (Reg == Mips::LO0 || Reg == Mips::LO0_64 ||
769 Reg == Mips::HI0 || Reg == Mips::HI0_64);
770 const Function &Func = MBB.getParent()->getFunction();
771 if (IsLOHI && Func.hasFnAttribute("interrupt")) {
772 DebugLoc DL = MI->getDebugLoc();
773
774 unsigned Op = 0;
775 if (!STI.getABI().ArePtrs64bit()) {
776 Op = (Reg == Mips::HI0) ? Mips::MFHI : Mips::MFLO;
777 Reg = Mips::K0;
778 } else {
779 Op = (Reg == Mips::HI0) ? Mips::MFHI64 : Mips::MFLO64;
780 Reg = Mips::K0_64;
781 }
782 BuildMI(MBB, MI, DL, TII.get(Op), Mips::K0)
784 }
785
786 // Insert the spill to the stack frame.
787 bool IsKill = !IsRAAndRetAddrIsTaken;
788 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
789 TII.storeRegToStackSlot(MBB, MI, Reg, IsKill, I.getFrameIdx(), RC,
790 Register());
791 }
792
793 return true;
794}
795
796bool
798 const MachineFrameInfo &MFI = MF.getFrameInfo();
799 // Reserve call frame if the size of the maximum call frame fits into 16-bit
800 // immediate field and there are no variable sized objects on the stack.
801 // Make sure the second register scavenger spill slot can be accessed with one
802 // instruction.
804 !MFI.hasVarSizedObjects();
805}
806
807/// Mark \p Reg and all registers aliasing it in the bitset.
808static void setAliasRegs(MachineFunction &MF, BitVector &SavedRegs,
809 unsigned Reg) {
811 for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
812 SavedRegs.set(*AI);
813}
814
816 BitVector &SavedRegs,
817 RegScavenger *RS) const {
821 MipsABIInfo ABI = STI.getABI();
822 unsigned RA = ABI.IsN64() ? Mips::RA_64 : Mips::RA;
823 unsigned FP = ABI.GetFramePtr();
824 unsigned BP = ABI.IsN64() ? Mips::S7_64 : Mips::S7;
825
826 // Mark $ra and $fp as used if function has dedicated frame pointer.
827 if (hasFP(MF)) {
828 setAliasRegs(MF, SavedRegs, RA);
829 setAliasRegs(MF, SavedRegs, FP);
830 }
831 // Mark $s7 as used if function has dedicated base pointer.
832 if (hasBP(MF))
833 setAliasRegs(MF, SavedRegs, BP);
834
835 // Create spill slots for eh data registers if function calls eh_return.
836 if (MipsFI->callsEhReturn())
837 MipsFI->createEhDataRegsFI(MF);
838
839 // Create spill slots for Coprocessor 0 registers if function is an ISR.
840 if (MipsFI->isISR())
841 MipsFI->createISRRegFI(MF);
842
843 // Expand pseudo instructions which load, store or copy accumulators.
844 // Add an emergency spill slot if a pseudo was expanded.
845 if (ExpandPseudo(MF).expand()) {
846 // The spill slot should be half the size of the accumulator. If target have
847 // general-purpose registers 64 bits wide, it should be 64-bit, otherwise
848 // it should be 32-bit.
849 const TargetRegisterClass &RC = STI.isGP64bit() ?
850 Mips::GPR64RegClass : Mips::GPR32RegClass;
851 int FI = MF.getFrameInfo().CreateSpillStackObject(TRI->getSpillSize(RC),
852 TRI->getSpillAlign(RC));
853 RS->addScavengingFrameIndex(FI);
854 }
855
856 // Set scavenging frame index if necessary.
857 uint64_t MaxSPOffset = estimateStackSize(MF);
858
859 // MSA has a minimum offset of 10 bits signed. If there is a variable
860 // sized object on the stack, the estimation cannot account for it.
861 if (isIntN(STI.hasMSA() ? 10 : 16, MaxSPOffset) &&
863 return;
864
865 const TargetRegisterClass &RC =
866 ABI.ArePtrs64bit() ? Mips::GPR64RegClass : Mips::GPR32RegClass;
867 int FI = MF.getFrameInfo().CreateSpillStackObject(TRI->getSpillSize(RC),
868 TRI->getSpillAlign(RC));
869 RS->addScavengingFrameIndex(FI);
870}
871
872const MipsFrameLowering *
unsigned const MachineRegisterInfo * MRI
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file implements the BitVector class.
@ ZERO
Special weight used for cases with exact zero probability.
static Expected< BitVector > expand(StringRef S, StringRef Original)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static std::pair< unsigned, unsigned > getMFHiLoOpc(unsigned Src)
static void setAliasRegs(MachineFunction &MF, BitVector &SavedRegs, unsigned Reg)
Mark Reg and all registers aliasing it in the bitset.
This file declares the machine register scavenger class.
SI optimize exec mask operations pre RA
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:480
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
BitVector & set()
Definition BitVector.h:370
Helper class for creating CFI instructions and inserting them into MIR.
void buildDefCFAOffset(int64_t Offset, MCSymbol *Label=nullptr) const
void buildDefCFARegister(MCRegister Reg) const
void buildOffset(MCRegister Reg, int64_t Offset) const
void setInsertPoint(MachineBasicBlock::iterator IP)
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
A debug info location.
Definition DebugLoc.h:124
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition Function.cpp:765
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:730
MCRegAliasIterator enumerates all registers aliasing Reg.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
bool isReturnAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int64_t getOffsetAdjustment() const
Return the correction for frame offsets.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineOperand & getOperand(unsigned i) const
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
MipsFrameLowering(const MipsSubtarget &sti, Align Alignment)
bool hasBP(const MachineFunction &MF) const
uint64_t estimateStackSize(const MachineFunction &MF) const
const MipsSubtarget & STI
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
int getEhDataRegFI(unsigned Reg) const
int getISRRegFI(Register Reg) const
void createEhDataRegsFI(MachineFunction &MF)
void createISRRegFI(MachineFunction &MF)
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
virtual void storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, int64_t Offset, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const =0
virtual const TargetRegisterClass * intRegClass(unsigned Size) const =0
Return GPR register class.
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
MipsSEFrameLowering(const MipsSubtarget &STI)
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
bool isFP64bit() const
bool isLittle() const
const MipsInstrInfo * getInstrInfo() const override
bool hasMips64() const
bool isGP64bit() const
bool hasMips32r2() const
bool hasMTHC1() const
Reloc::Model getRelocationModel() const
Wrapper class representing virtual and physical registers.
Definition Register.h:20
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:30
int64_t getFixed() const
Returns the fixed component of the stack.
Definition TypeSize.h:46
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1655
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:165
const MipsFrameLowering * createMipsSEFrameLowering(const MipsSubtarget &ST)
Op::Description Desc
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:167
unsigned getKillRegState(bool B)
DWARFExpression::Operation Op
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition MathExtras.h:248
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition Alignment.h:197
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:869
#define N
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77