LLVM 24.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
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);
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)
177 .addReg(VR, RegState::Kill);
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);
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);
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);
214 BuildMI(MBB, I, DL, Desc, Lo).addReg(VR0, RegState::Kill);
215 TII.loadRegFromStack(MBB, I, VR1, FI, RC, RegSize);
216 BuildMI(MBB, I, DL, Desc, Hi).addReg(VR1, RegState::Kill);
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);
232 Register Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();
233 RegState 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);
265 RegState 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 FPXX/FP64 when mthc1 is not available and
281/// for 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/FP64 when mthc1 is not available, use:
288 // spill + reload via ldc1
289 //
290 // The case where 64-bit GPRs can be used 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 const TargetRegisterClass *RC = &Mips::GPR32RegClass;
310 const TargetRegisterClass *RC2 =
311 FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
312
313 // We re-use the same spill slot each time so that the stack frame doesn't
314 // grow too much in functions with a large number of moves.
315 int FI = MF.getInfo<MipsFunctionInfo>()->getMoveF64ViaSpillFI(MF, RC2);
316 if (!Subtarget.isLittle())
317 std::swap(LoReg, HiReg);
318 TII.storeRegToStack(MBB, I, LoReg, I->getOperand(1).isKill(), FI, RC, 0);
319 TII.storeRegToStack(MBB, I, HiReg, I->getOperand(2).isKill(), FI, RC, 4);
320 TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, 0);
321 return true;
322 }
323
324 return false;
325}
326
327/// This method expands the same instruction that MipsSEInstrInfo::
328/// expandExtractElementF64 does, for FPXX/FP64 when mfhc1 is not available and
329/// for FP64A. It is implemented here
330/// because frame indexes are eliminated before MipsSEInstrInfo::
331/// expandExtractElementF64 is called.
332bool ExpandPseudo::expandExtractElementF64(MachineBasicBlock &MBB,
334 bool FP64) const {
335 const MachineOperand &Op1 = I->getOperand(1);
336 const MachineOperand &Op2 = I->getOperand(2);
337
338 if ((Op1.isReg() && Op1.isUndef()) || (Op2.isReg() && Op2.isUndef())) {
339 Register DstReg = I->getOperand(0).getReg();
340 BuildMI(MBB, I, I->getDebugLoc(), TII.get(Mips::IMPLICIT_DEF), DstReg);
341 return true;
342 }
343
344 // For FPXX/FP64 when mfhc1 is not available, use:
345 // spill + reload via ldc1
346 //
347 // The case where 64-bit GPRs can be used doesn't need to be handled here
348 // because it never creates a ExtractElementF64 node.
349 //
350 // The FP64A ABI (fp64 with nooddspreg) must also use a spill/reload sequence
351 // for odd-numbered double precision values (because the lower 32-bits is
352 // transferred with mfc1 which is redirected to the upper half of the even
353 // register). Unfortunately, we have to make this decision before register
354 // allocation so for now we use a spill/reload sequence for all
355 // double-precision values in regardless of being an odd/even register.
356 //
357 // For the cases that should be covered here MipsSEISelDAGToDAG adds $sp as
358 // implicit operand, so other passes (like ShrinkWrapping) are aware that
359 // stack is used.
360 if (I->getNumOperands() == 4 && I->getOperand(3).isReg()
361 && I->getOperand(3).getReg() == Mips::SP) {
362 Register DstReg = I->getOperand(0).getReg();
363 Register SrcReg = Op1.getReg();
364 unsigned N = Op2.getImm();
365 int64_t Offset = 4 * (Subtarget.isLittle() ? N : (1 - N));
366
367 const TargetRegisterClass *RC =
368 FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;
369 const TargetRegisterClass *RC2 = &Mips::GPR32RegClass;
370
371 // We re-use the same spill slot each time so that the stack frame doesn't
372 // grow too much in functions with a large number of moves.
373 int FI = MF.getInfo<MipsFunctionInfo>()->getMoveF64ViaSpillFI(MF, RC);
374 TII.storeRegToStack(MBB, I, SrcReg, Op1.isKill(), FI, RC, 0);
375 TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, Offset);
376 return true;
377 }
378
379 return false;
380}
381
384
386 MachineBasicBlock &MBB) const {
387 MachineFrameInfo &MFI = MF.getFrameInfo();
389
390 const MipsSEInstrInfo &TII =
391 *static_cast<const MipsSEInstrInfo *>(STI.getInstrInfo());
392 const MipsRegisterInfo &RegInfo = *STI.getRegisterInfo();
393
395 DebugLoc dl;
396 MipsABIInfo ABI = STI.getABI();
397 unsigned SP = ABI.GetStackPtr();
398 unsigned FP = ABI.GetFramePtr();
399 unsigned ZERO = ABI.GetNullPtr();
400 unsigned MOVE = ABI.GetGPRMoveOp();
401 unsigned ADDiu = ABI.GetPtrAddiuOp();
402 unsigned AND = ABI.IsN64() ? Mips::AND64 : Mips::AND;
403
404 const TargetRegisterClass *RC = ABI.ArePtrs64bit() ?
405 &Mips::GPR64RegClass : &Mips::GPR32RegClass;
406
407 // First, compute final stack size.
408 uint64_t StackSize = MFI.getStackSize();
409
410 // No need to allocate space on the stack.
411 if (StackSize == 0 && !MFI.adjustsStack()) return;
412
414
415 // Adjust stack.
416 TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
417 CFIBuilder.buildDefCFAOffset(StackSize);
418
419 if (MF.getFunction().hasFnAttribute("interrupt"))
420 emitInterruptPrologueStub(MF, MBB);
421
422 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
423
424 // Find the instruction past the last instruction that saves a callee-saved
425 // register to the stack.
426 std::advance(MBBI, CSI.size());
427 CFIBuilder.setInsertPoint(MBBI);
428
429 if (!CSI.empty()) {
430 // Iterate over list of callee-saved registers and emit .cfi_offset
431 // directives.
432 for (const CalleeSavedInfo &I : CSI) {
433 int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());
434 MCRegister Reg = I.getReg();
435
436 // If Reg is a double precision register, emit two cfa_offsets,
437 // one for each of the paired single precision registers.
438 if (Mips::AFGR64RegClass.contains(Reg)) {
439 MCRegister Reg0 = RegInfo.getSubReg(Reg, Mips::sub_lo);
440 MCRegister Reg1 = RegInfo.getSubReg(Reg, Mips::sub_hi);
441
442 if (!STI.isLittle())
443 std::swap(Reg0, Reg1);
444
445 CFIBuilder.buildOffset(Reg0, Offset);
446 CFIBuilder.buildOffset(Reg1, Offset + 4);
447 } else if (Mips::FGR64RegClass.contains(Reg)) {
448 MCRegister Reg0 = Reg;
449 MCRegister Reg1 = Reg + 1;
450
451 if (!STI.isLittle())
452 std::swap(Reg0, Reg1);
453
454 CFIBuilder.buildOffset(Reg0, Offset);
455 CFIBuilder.buildOffset(Reg1, Offset + 4);
456 } else {
457 // Reg is either in GPR32 or FGR32.
458 CFIBuilder.buildOffset(Reg, Offset);
459 }
460 }
461 }
462
463 if (MipsFI->callsEhReturn()) {
464 // Insert instructions that spill eh data registers.
465 for (int I = 0; I < 4; ++I) {
466 if (!MBB.isLiveIn(ABI.GetEhDataReg(I)))
467 MBB.addLiveIn(ABI.GetEhDataReg(I));
468 TII.storeRegToStackSlot(MBB, MBBI, ABI.GetEhDataReg(I), false,
469 MipsFI->getEhDataRegFI(I), RC, Register());
470 }
471
472 // Emit .cfi_offset directives for eh data registers.
473 for (int I = 0; I < 4; ++I) {
474 int64_t Offset = MFI.getObjectOffset(MipsFI->getEhDataRegFI(I));
475 CFIBuilder.buildOffset(ABI.GetEhDataReg(I), Offset);
476 }
477 }
478
479 // if framepointer enabled, set it to point to the stack pointer.
480 if (hasFP(MF)) {
481 // Insert instruction "move $fp, $sp" at this location.
482 BuildMI(MBB, MBBI, dl, TII.get(MOVE), FP).addReg(SP).addReg(ZERO)
484
485 CFIBuilder.buildDefCFARegister(FP);
486
487 if (RegInfo.hasStackRealignment(MF)) {
488 // addiu $Reg, $zero, -MaxAlignment
489 // andi $sp, $sp, $Reg
491 assert((Log2(MFI.getMaxAlign()) < 16) &&
492 "Function's alignment size requirement is not supported.");
493 int64_t MaxAlign = -(int64_t)MFI.getMaxAlign().value();
494
495 BuildMI(MBB, MBBI, dl, TII.get(ADDiu), VR).addReg(ZERO).addImm(MaxAlign);
496 BuildMI(MBB, MBBI, dl, TII.get(AND), SP).addReg(SP).addReg(VR);
497
498 if (hasBP(MF)) {
499 // move $s7, $sp
500 unsigned BP = STI.getABI().GetBasePtr();
501 BuildMI(MBB, MBBI, dl, TII.get(MOVE), BP)
502 .addReg(SP)
503 .addReg(ZERO);
504 }
505 }
506 }
507}
508
509void MipsSEFrameLowering::emitInterruptPrologueStub(
513 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
514
515 // Report an error the target doesn't support Mips32r2 or later.
516 // The epilogue relies on the use of the "ehb" to clear execution
517 // hazards. Pre R2 Mips relies on an implementation defined number
518 // of "ssnop"s to clear the execution hazard. Support for ssnop hazard
519 // clearing is not provided so reject that configuration.
520 if (!STI.hasMips32r2())
522 "\"interrupt\" attribute is not supported on pre-MIPS32R2 or "
523 "MIPS16 targets.");
524
525 // The GP register contains the "user" value, so we cannot perform
526 // any gp relative loads until we restore the "kernel" or "system" gp
527 // value. Until support is written we shall only accept the static
528 // relocation model.
530 report_fatal_error("\"interrupt\" attribute is only supported for the "
531 "static relocation model on MIPS at the present time.");
532
533 if (!STI.isABI_O32() || STI.hasMips64())
534 report_fatal_error("\"interrupt\" attribute is only supported for the "
535 "O32 ABI on MIPS32R2+ at the present time.");
536
537 // Perform ISR handling like GCC
538 StringRef IntKind =
539 MF.getFunction().getFnAttribute("interrupt").getValueAsString();
540 const TargetRegisterClass *PtrRC = &Mips::GPR32RegClass;
541
542 // EIC interrupt handling needs to read the Cause register to disable
543 // interrupts.
544 if (IntKind == "eic") {
545 // Coprocessor registers are always live per se.
546 MBB.addLiveIn(Mips::COP013);
547 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::R26)
548 .addReg(Mips::COP013)
550
551 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::EXT), Mips::R26)
552 .addReg(Mips::R26)
553 .addImm(10)
554 .addImm(6)
556 }
557
558 // Fetch and spill EPC
559 MBB.addLiveIn(Mips::COP014);
560 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::R27)
561 .addReg(Mips::COP014)
563
564 STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::R27, false,
565 MipsFI->getISRRegFI(0), PtrRC, 0);
566
567 // Fetch and Spill Status
568 MBB.addLiveIn(Mips::COP012);
569 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::R27)
570 .addReg(Mips::COP012)
572
573 STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::R27, false,
574 MipsFI->getISRRegFI(1), PtrRC, 0);
575
576 // Build the configuration for disabling lower priority interrupts. Non EIC
577 // interrupts need to be masked off with zero, EIC from the Cause register.
578 unsigned InsPosition = 8;
579 unsigned InsSize = 0;
580 unsigned SrcReg = Mips::R0;
581
582 // If the interrupt we're tied to is the EIC, switch the source for the
583 // masking off interrupts to the cause register.
584 if (IntKind == "eic") {
585 SrcReg = Mips::R26;
586 InsPosition = 10;
587 InsSize = 6;
588 } else
589 InsSize = StringSwitch<unsigned>(IntKind)
590 .Case("sw0", 1)
591 .Case("sw1", 2)
592 .Case("hw0", 3)
593 .Case("hw1", 4)
594 .Case("hw2", 5)
595 .Case("hw3", 6)
596 .Case("hw4", 7)
597 .Case("hw5", 8)
598 .Default(0);
599 assert(InsSize != 0 && "Unknown interrupt type!");
600
601 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::R27)
602 .addReg(SrcReg)
603 .addImm(InsPosition)
604 .addImm(InsSize)
605 .addReg(Mips::R27)
607
608 // Mask off KSU, ERL, EXL
609 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::R27)
610 .addReg(Mips::R0)
611 .addImm(1)
612 .addImm(4)
613 .addReg(Mips::R27)
615
616 // Disable the FPU as we are not spilling those register sets.
617 if (!STI.useSoftFloat())
618 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::R27)
619 .addReg(Mips::R0)
620 .addImm(29)
621 .addImm(1)
622 .addReg(Mips::R27)
624
625 // Set the new status
626 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP012)
627 .addReg(Mips::R27)
629}
630
632 MachineBasicBlock &MBB) const {
633 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
634 MachineFrameInfo &MFI = MF.getFrameInfo();
636
637 const MipsSEInstrInfo &TII =
638 *static_cast<const MipsSEInstrInfo *>(STI.getInstrInfo());
639
640 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
641 MipsABIInfo ABI = STI.getABI();
642 unsigned SP = ABI.GetStackPtr();
643 unsigned FP = ABI.GetFramePtr();
644 unsigned ZERO = ABI.GetNullPtr();
645 unsigned MOVE = ABI.GetGPRMoveOp();
646
647 // if framepointer enabled, restore the stack pointer.
648 if (hasFP(MF)) {
649 // Find the first instruction that restores a callee-saved register.
651
652 for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i)
653 --I;
654
655 // Insert instruction "move $sp, $fp" at this location.
656 BuildMI(MBB, I, DL, TII.get(MOVE), SP).addReg(FP).addReg(ZERO);
657 }
658
659 if (MipsFI->callsEhReturn()) {
660 const TargetRegisterClass *RC =
661 ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
662
663 // Find first instruction that restores a callee-saved register.
665 for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i)
666 --I;
667
668 // Insert instructions that restore eh data registers.
669 for (int J = 0; J < 4; ++J) {
670 TII.loadRegFromStackSlot(MBB, I, ABI.GetEhDataReg(J),
671 MipsFI->getEhDataRegFI(J), RC, Register());
672 }
673 }
674
675 if (MF.getFunction().hasFnAttribute("interrupt"))
676 emitInterruptEpilogueStub(MF, MBB);
677
678 // Get the number of bytes from FrameInfo
679 uint64_t StackSize = MFI.getStackSize();
680
681 if (!StackSize)
682 return;
683
684 // Adjust stack.
685 TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
686}
687
688void MipsSEFrameLowering::emitInterruptEpilogueStub(
690 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
692 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
693
694 // Perform ISR handling like GCC
695 const TargetRegisterClass *PtrRC = &Mips::GPR32RegClass;
696
697 // Disable Interrupts.
698 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::DI), Mips::R0);
699 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::EHB));
700
701 // Restore EPC
703 MBB, MBBI, Mips::R27, MipsFI->getISRRegFI(0), PtrRC, Register());
704 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP014)
705 .addReg(Mips::R27);
706
707 // Restore Status
709 MBB, MBBI, Mips::R27, MipsFI->getISRRegFI(1), PtrRC, Register());
710 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP012)
711 .addReg(Mips::R27);
712}
713
716 Register &FrameReg) const {
717 const MachineFrameInfo &MFI = MF.getFrameInfo();
718 MipsABIInfo ABI = STI.getABI();
719
720 if (MFI.isFixedObjectIndex(FI))
721 FrameReg = hasFP(MF) ? ABI.GetFramePtr() : ABI.GetStackPtr();
722 else
723 FrameReg = hasBP(MF) ? ABI.GetBasePtr() : ABI.GetStackPtr();
724
725 return StackOffset::getFixed(MFI.getObjectOffset(FI) + MFI.getStackSize() -
727 MFI.getOffsetAdjustment());
728}
729
733 MachineFunction *MF = MBB.getParent();
734 const TargetInstrInfo &TII = *STI.getInstrInfo();
735
736 for (const CalleeSavedInfo &I : CSI) {
737 // Add the callee-saved register as live-in. Do not add if the register is
738 // RA and return address is taken, because it has already been added in
739 // method MipsTargetLowering::lowerRETURNADDR.
740 // It's killed at the spill, unless the register is RA and return address
741 // is taken.
742 MCRegister Reg = I.getReg();
743 bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)
745 if (!IsRAAndRetAddrIsTaken)
746 MBB.addLiveIn(Reg);
747
748 // ISRs require HI/LO to be spilled into kernel registers to be then
749 // spilled to the stack frame.
750 bool IsLOHI = (Reg == Mips::LO0 || Reg == Mips::LO0_64 ||
751 Reg == Mips::HI0 || Reg == Mips::HI0_64);
752 const Function &Func = MBB.getParent()->getFunction();
753 if (IsLOHI && Func.hasFnAttribute("interrupt")) {
754 DebugLoc DL = MI->getDebugLoc();
755
756 unsigned Op = 0;
757 if (!STI.getABI().ArePtrs64bit()) {
758 Op = (Reg == Mips::HI0) ? Mips::MFHI : Mips::MFLO;
759 Reg = Mips::R26;
760 } else {
761 Op = (Reg == Mips::HI0) ? Mips::MFHI64 : Mips::MFLO64;
762 Reg = Mips::R26_64;
763 }
764 BuildMI(MBB, MI, DL, TII.get(Op), Mips::R26)
766 }
767
768 // Insert the spill to the stack frame.
769 bool IsKill = !IsRAAndRetAddrIsTaken;
770 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
771 TII.storeRegToStackSlot(MBB, MI, Reg, IsKill, I.getFrameIdx(), RC,
772 Register());
773 }
774
775 return true;
776}
777
778bool
780 const MachineFrameInfo &MFI = MF.getFrameInfo();
781 // Reserve call frame if the size of the maximum call frame fits into 16-bit
782 // immediate field and there are no variable sized objects on the stack.
783 // Make sure the second register scavenger spill slot can be accessed with one
784 // instruction.
786 !MFI.hasVarSizedObjects();
787}
788
789/// Mark \p Reg and all registers aliasing it in the bitset.
790static void setAliasRegs(MachineFunction &MF, BitVector &SavedRegs,
791 unsigned Reg) {
793 for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
794 SavedRegs.set(*AI);
795}
796
798 BitVector &SavedRegs,
799 RegScavenger *RS) const {
803 MipsABIInfo ABI = STI.getABI();
804 unsigned RA = ABI.IsN64() ? Mips::RA_64 : Mips::RA;
805 unsigned FP = ABI.GetFramePtr();
806 unsigned BP = ABI.GetBasePtr();
807
808 // Mark $ra and $fp as used if function has dedicated frame pointer.
809 if (hasFP(MF)) {
810 setAliasRegs(MF, SavedRegs, RA);
811 setAliasRegs(MF, SavedRegs, FP);
812 }
813 // Mark $s7 as used if function has dedicated base pointer.
814 if (hasBP(MF))
815 setAliasRegs(MF, SavedRegs, BP);
816
817 // Create spill slots for eh data registers if function calls eh_return.
818 if (MipsFI->callsEhReturn())
819 MipsFI->createEhDataRegsFI(MF);
820
821 // Create spill slots for Coprocessor 0 registers if function is an ISR.
822 if (MipsFI->isISR())
823 MipsFI->createISRRegFI(MF);
824
825 // Expand pseudo instructions which load, store or copy accumulators.
826 // Add an emergency spill slot if a pseudo was expanded.
827 if (ExpandPseudo(MF).expand()) {
828 // The spill slot should be half the size of the accumulator. If target have
829 // general-purpose registers 64 bits wide, it should be 64-bit, otherwise
830 // it should be 32-bit.
831 const TargetRegisterClass &RC = STI.isGP64bit() ?
832 Mips::GPR64RegClass : Mips::GPR32RegClass;
833 int FI = MF.getFrameInfo().CreateSpillStackObject(TRI->getSpillSize(RC),
834 TRI->getSpillAlign(RC));
835 RS->addScavengingFrameIndex(FI);
836 }
837
838 // Set scavenging frame index if necessary.
839 uint64_t MaxSPOffset = estimateStackSize(MF);
840
841 // MSA has a minimum offset of 10 bits signed. If there is a variable
842 // sized object on the stack, the estimation cannot account for it.
843 if (isIntN(STI.hasMSA() ? 10 : 16, MaxSPOffset) &&
845 return;
846
847 const TargetRegisterClass &RC =
848 ABI.ArePtrs64bit() ? Mips::GPR64RegClass : Mips::GPR32RegClass;
849 int FI = MF.getFrameInfo().CreateSpillStackObject(TRI->getSpillSize(RC),
850 TRI->getSpillAlign(RC));
851 RS->addScavengingFrameIndex(FI);
852}
853
854const MipsFrameLowering *
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.
MachineRegisterInfo & MRI
MachineInstr *& Lo
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...
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()
Set all bits in the bitvector.
Definition BitVector.h:366
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:126
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition Function.cpp:766
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:731
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 alignment of this function's frame.
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, TargetStackID::Value StackID=TargetStackID::Default)
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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate 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, unsigned SubReg=0, 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 isLittle() const
const MipsInstrInfo * getInstrInfo() const override
bool hasMips64() const
bool hasMips32r2() 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:31
int64_t getFixed() const
Returns the fixed component of the stack.
Definition TypeSize.h:47
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
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.
constexpr MCPhysReg RA_64
constexpr MCPhysReg SP
constexpr MCPhysReg RA
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
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:1685
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:166
RegState
Flags to represent properties of register accesses.
constexpr RegState getKillRegState(bool B)
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:163
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:249
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition Alignment.h:202
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:82