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);
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)
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);
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);
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);
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 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);
263 Register VR0 = MRI.createVirtualRegister(RC);
264 Register VR1 = MRI.createVirtualRegister(RC);
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.isABI_N64() ? Mips::S7_64 : Mips::S7;
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::K0)
548 .addReg(Mips::COP013)
549 .addImm(0)
551
552 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::EXT), Mips::K0)
553 .addReg(Mips::K0)
554 .addImm(10)
555 .addImm(6)
557 }
558
559 // Fetch and spill EPC
560 MBB.addLiveIn(Mips::COP014);
561 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K1)
562 .addReg(Mips::COP014)
563 .addImm(0)
565
566 STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::K1, false,
567 MipsFI->getISRRegFI(0), PtrRC, 0);
568
569 // Fetch and Spill Status
570 MBB.addLiveIn(Mips::COP012);
571 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K1)
572 .addReg(Mips::COP012)
573 .addImm(0)
575
576 STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::K1, false,
577 MipsFI->getISRRegFI(1), PtrRC, 0);
578
579 // Build the configuration for disabling lower priority interrupts. Non EIC
580 // interrupts need to be masked off with zero, EIC from the Cause register.
581 unsigned InsPosition = 8;
582 unsigned InsSize = 0;
583 unsigned SrcReg = Mips::ZERO;
584
585 // If the interrupt we're tied to is the EIC, switch the source for the
586 // masking off interrupts to the cause register.
587 if (IntKind == "eic") {
588 SrcReg = Mips::K0;
589 InsPosition = 10;
590 InsSize = 6;
591 } else
592 InsSize = StringSwitch<unsigned>(IntKind)
593 .Case("sw0", 1)
594 .Case("sw1", 2)
595 .Case("hw0", 3)
596 .Case("hw1", 4)
597 .Case("hw2", 5)
598 .Case("hw3", 6)
599 .Case("hw4", 7)
600 .Case("hw5", 8)
601 .Default(0);
602 assert(InsSize != 0 && "Unknown interrupt type!");
603
604 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)
605 .addReg(SrcReg)
606 .addImm(InsPosition)
607 .addImm(InsSize)
608 .addReg(Mips::K1)
610
611 // Mask off KSU, ERL, EXL
612 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)
613 .addReg(Mips::ZERO)
614 .addImm(1)
615 .addImm(4)
616 .addReg(Mips::K1)
618
619 // Disable the FPU as we are not spilling those register sets.
620 if (!STI.useSoftFloat())
621 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)
622 .addReg(Mips::ZERO)
623 .addImm(29)
624 .addImm(1)
625 .addReg(Mips::K1)
627
628 // Set the new status
629 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP012)
630 .addReg(Mips::K1)
631 .addImm(0)
633}
634
636 MachineBasicBlock &MBB) const {
637 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
638 MachineFrameInfo &MFI = MF.getFrameInfo();
640
641 const MipsSEInstrInfo &TII =
642 *static_cast<const MipsSEInstrInfo *>(STI.getInstrInfo());
643
644 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
645 MipsABIInfo ABI = STI.getABI();
646 unsigned SP = ABI.GetStackPtr();
647 unsigned FP = ABI.GetFramePtr();
648 unsigned ZERO = ABI.GetNullPtr();
649 unsigned MOVE = ABI.GetGPRMoveOp();
650
651 // if framepointer enabled, restore the stack pointer.
652 if (hasFP(MF)) {
653 // Find the first instruction that restores a callee-saved register.
655
656 for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i)
657 --I;
658
659 // Insert instruction "move $sp, $fp" at this location.
660 BuildMI(MBB, I, DL, TII.get(MOVE), SP).addReg(FP).addReg(ZERO);
661 }
662
663 if (MipsFI->callsEhReturn()) {
664 const TargetRegisterClass *RC =
665 ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
666
667 // Find first instruction that restores a callee-saved register.
669 for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i)
670 --I;
671
672 // Insert instructions that restore eh data registers.
673 for (int J = 0; J < 4; ++J) {
674 TII.loadRegFromStackSlot(MBB, I, ABI.GetEhDataReg(J),
675 MipsFI->getEhDataRegFI(J), RC, Register());
676 }
677 }
678
679 if (MF.getFunction().hasFnAttribute("interrupt"))
680 emitInterruptEpilogueStub(MF, MBB);
681
682 // Get the number of bytes from FrameInfo
683 uint64_t StackSize = MFI.getStackSize();
684
685 if (!StackSize)
686 return;
687
688 // Adjust stack.
689 TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
690}
691
692void MipsSEFrameLowering::emitInterruptEpilogueStub(
694 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
696 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
697
698 // Perform ISR handling like GCC
699 const TargetRegisterClass *PtrRC = &Mips::GPR32RegClass;
700
701 // Disable Interrupts.
702 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::DI), Mips::ZERO);
703 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::EHB));
704
705 // Restore EPC
707 MBB, MBBI, Mips::K1, MipsFI->getISRRegFI(0), PtrRC, Register());
708 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP014)
709 .addReg(Mips::K1)
710 .addImm(0);
711
712 // Restore Status
714 MBB, MBBI, Mips::K1, MipsFI->getISRRegFI(1), PtrRC, Register());
715 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP012)
716 .addReg(Mips::K1)
717 .addImm(0);
718}
719
722 Register &FrameReg) const {
723 const MachineFrameInfo &MFI = MF.getFrameInfo();
724 MipsABIInfo ABI = STI.getABI();
725
726 if (MFI.isFixedObjectIndex(FI))
727 FrameReg = hasFP(MF) ? ABI.GetFramePtr() : ABI.GetStackPtr();
728 else
729 FrameReg = hasBP(MF) ? ABI.GetBasePtr() : ABI.GetStackPtr();
730
731 return StackOffset::getFixed(MFI.getObjectOffset(FI) + MFI.getStackSize() -
733 MFI.getOffsetAdjustment());
734}
735
739 MachineFunction *MF = MBB.getParent();
740 const TargetInstrInfo &TII = *STI.getInstrInfo();
741
742 for (const CalleeSavedInfo &I : CSI) {
743 // Add the callee-saved register as live-in. Do not add if the register is
744 // RA and return address is taken, because it has already been added in
745 // method MipsTargetLowering::lowerRETURNADDR.
746 // It's killed at the spill, unless the register is RA and return address
747 // is taken.
748 MCRegister Reg = I.getReg();
749 bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)
751 if (!IsRAAndRetAddrIsTaken)
752 MBB.addLiveIn(Reg);
753
754 // ISRs require HI/LO to be spilled into kernel registers to be then
755 // spilled to the stack frame.
756 bool IsLOHI = (Reg == Mips::LO0 || Reg == Mips::LO0_64 ||
757 Reg == Mips::HI0 || Reg == Mips::HI0_64);
758 const Function &Func = MBB.getParent()->getFunction();
759 if (IsLOHI && Func.hasFnAttribute("interrupt")) {
760 DebugLoc DL = MI->getDebugLoc();
761
762 unsigned Op = 0;
763 if (!STI.getABI().ArePtrs64bit()) {
764 Op = (Reg == Mips::HI0) ? Mips::MFHI : Mips::MFLO;
765 Reg = Mips::K0;
766 } else {
767 Op = (Reg == Mips::HI0) ? Mips::MFHI64 : Mips::MFLO64;
768 Reg = Mips::K0_64;
769 }
770 BuildMI(MBB, MI, DL, TII.get(Op), Mips::K0)
772 }
773
774 // Insert the spill to the stack frame.
775 bool IsKill = !IsRAAndRetAddrIsTaken;
776 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
777 TII.storeRegToStackSlot(MBB, MI, Reg, IsKill, I.getFrameIdx(), RC,
778 Register());
779 }
780
781 return true;
782}
783
784bool
786 const MachineFrameInfo &MFI = MF.getFrameInfo();
787 // Reserve call frame if the size of the maximum call frame fits into 16-bit
788 // immediate field and there are no variable sized objects on the stack.
789 // Make sure the second register scavenger spill slot can be accessed with one
790 // instruction.
792 !MFI.hasVarSizedObjects();
793}
794
795/// Mark \p Reg and all registers aliasing it in the bitset.
796static void setAliasRegs(MachineFunction &MF, BitVector &SavedRegs,
797 unsigned Reg) {
799 for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
800 SavedRegs.set(*AI);
801}
802
804 BitVector &SavedRegs,
805 RegScavenger *RS) const {
809 MipsABIInfo ABI = STI.getABI();
810 unsigned RA = ABI.IsN64() ? Mips::RA_64 : Mips::RA;
811 unsigned FP = ABI.GetFramePtr();
812 unsigned BP = ABI.IsN64() ? Mips::S7_64 : Mips::S7;
813
814 // Mark $ra and $fp as used if function has dedicated frame pointer.
815 if (hasFP(MF)) {
816 setAliasRegs(MF, SavedRegs, RA);
817 setAliasRegs(MF, SavedRegs, FP);
818 }
819 // Mark $s7 as used if function has dedicated base pointer.
820 if (hasBP(MF))
821 setAliasRegs(MF, SavedRegs, BP);
822
823 // Create spill slots for eh data registers if function calls eh_return.
824 if (MipsFI->callsEhReturn())
825 MipsFI->createEhDataRegsFI(MF);
826
827 // Create spill slots for Coprocessor 0 registers if function is an ISR.
828 if (MipsFI->isISR())
829 MipsFI->createISRRegFI(MF);
830
831 // Expand pseudo instructions which load, store or copy accumulators.
832 // Add an emergency spill slot if a pseudo was expanded.
833 if (ExpandPseudo(MF).expand()) {
834 // The spill slot should be half the size of the accumulator. If target have
835 // general-purpose registers 64 bits wide, it should be 64-bit, otherwise
836 // it should be 32-bit.
837 const TargetRegisterClass &RC = STI.isGP64bit() ?
838 Mips::GPR64RegClass : Mips::GPR32RegClass;
839 int FI = MF.getFrameInfo().CreateSpillStackObject(TRI->getSpillSize(RC),
840 TRI->getSpillAlign(RC));
841 RS->addScavengingFrameIndex(FI);
842 }
843
844 // Set scavenging frame index if necessary.
845 uint64_t MaxSPOffset = estimateStackSize(MF);
846
847 // MSA has a minimum offset of 10 bits signed. If there is a variable
848 // sized object on the stack, the estimation cannot account for it.
849 if (isIntN(STI.hasMSA() ? 10 : 16, MaxSPOffset) &&
851 return;
852
853 const TargetRegisterClass &RC =
854 ABI.ArePtrs64bit() ? Mips::GPR64RegClass : Mips::GPR32RegClass;
855 int FI = MF.getFrameInfo().CreateSpillStackObject(TRI->getSpillSize(RC),
856 TRI->getSpillAlign(RC));
857 RS->addScavengingFrameIndex(FI);
858}
859
860const 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.
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:484
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: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 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:30
int64_t getFixed() const
Returns the fixed component of the stack.
Definition TypeSize.h:46
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.
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:197
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:77