LLVM 23.0.0git
MipsSEInstrInfo.cpp
Go to the documentation of this file.
1//===-- MipsSEInstrInfo.cpp - Mips32/64 Instruction 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 the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "MipsSEInstrInfo.h"
15#include "MipsTargetMachine.h"
21
22using namespace llvm;
23
24static unsigned getUnconditionalBranch(const MipsSubtarget &STI) {
25 if (STI.inMicroMipsMode())
26 return STI.isPositionIndependent() ? Mips::B_MM : Mips::J_MM;
27 return STI.isPositionIndependent() ? Mips::B : Mips::J;
28}
29
32
33/// isLoadFromStackSlot - If the specified machine instruction is a direct
34/// load from a stack slot, return the virtual or physical register number of
35/// the destination along with the FrameIndex of the loaded stack slot. If
36/// not, return 0. This predicate must return 0 if the instruction has
37/// any side effects other than loading from the stack slot.
39 int &FrameIndex) const {
40 unsigned Opc = MI.getOpcode();
41
42 if ((Opc == Mips::LW) || (Opc == Mips::LD) ||
43 (Opc == Mips::LWC1) || (Opc == Mips::LDC1) || (Opc == Mips::LDC164)) {
44 if ((MI.getOperand(1).isFI()) && // is a stack slot
45 (MI.getOperand(2).isImm()) && // the imm is zero
46 (isZeroImm(MI.getOperand(2)))) {
47 FrameIndex = MI.getOperand(1).getIndex();
48 return MI.getOperand(0).getReg();
49 }
50 }
51
52 return 0;
53}
54
55/// isStoreToStackSlot - If the specified machine instruction is a direct
56/// store to a stack slot, return the virtual or physical register number of
57/// the source reg along with the FrameIndex of the loaded stack slot. If
58/// not, return 0. This predicate must return 0 if the instruction has
59/// any side effects other than storing to the stack slot.
61 int &FrameIndex) const {
62 unsigned Opc = MI.getOpcode();
63
64 if ((Opc == Mips::SW) || (Opc == Mips::SD) ||
65 (Opc == Mips::SWC1) || (Opc == Mips::SDC1) || (Opc == Mips::SDC164)) {
66 if ((MI.getOperand(1).isFI()) && // is a stack slot
67 (MI.getOperand(2).isImm()) && // the imm is zero
68 (isZeroImm(MI.getOperand(2)))) {
69 FrameIndex = MI.getOperand(1).getIndex();
70 return MI.getOperand(0).getReg();
71 }
72 }
73 return 0;
74}
75
76static std::pair<bool, bool> readsWritesFloatRegister(MachineInstr &MI,
77 Register Reg) {
78 bool Reads = false;
79 bool Writes = false;
80 int Idx = -1;
82 assert(RegF32 != Mips::NoRegister && "Reg is not a Float Register");
83 for (llvm::MachineOperand &MO : MI.operands()) {
84 Idx++;
85 if (!MO.isReg())
86 continue;
87 Register MORegF32 = getFloatRegFromFReg(MO.getReg());
88 if (MORegF32 == Mips::NoRegister)
89 continue;
90 if (MORegF32 == RegF32) {
91 if (Idx == 0)
92 Writes = true;
93 else
94 Reads = true;
95 }
96 }
97 return std::make_pair(Reads, Writes);
98}
99
101 MachineBasicBlock *MBB = I->getParent();
102 if (I == MBB->begin())
103 return false;
104 MachineBasicBlock::reverse_iterator RevI = std::prev(I)->getReverseIterator();
105 for (; RevI != MBB->rend(); RevI++) {
106 bool Reads, Writes;
107 std::tie(Reads, Writes) = readsWritesFloatRegister(*RevI, Reg);
108 unsigned Opcode = RevI->getOpcode();
109 if (Writes) {
110 if (Opcode >= Mips::CMP_AF_D_MMR6 && Opcode <= Mips::CMP_UN_S_MMR6)
111 return true;
112 return false;
113 }
114 }
115 return false;
116}
117
119 MachineBasicBlock *MBB = I->getParent();
120 MachineBasicBlock::iterator NextI = std::next(I);
121 bool MaybeOK = false;
122 for (; NextI != MBB->end(); NextI++) {
123 bool Reads, Writes;
124 std::tie(Reads, Writes) = readsWritesFloatRegister(*NextI, Reg);
125 unsigned Opcode = NextI->getOpcode();
126 if (Reads) {
127 if (Opcode < Mips::SEL_D || Opcode > Mips::SEL_S_MMR6)
128 return false;
129 else if (I->getOperand(1).isKill())
130 return true;
131 else
132 MaybeOK = true;
133 }
134 if (Writes)
135 return MaybeOK;
136 }
137 return false;
138}
139
142 const DebugLoc &DL, Register DestReg,
143 Register SrcReg, bool KillSrc,
144 bool RenamableDest, bool RenamableSrc) const {
145 unsigned Opc = 0, ZeroReg = 0;
146 bool isMicroMips = Subtarget.inMicroMipsMode();
147
148 if (Mips::GPR32RegClass.contains(DestReg)) { // Copy to CPU Reg.
149 if (Mips::GPR32RegClass.contains(SrcReg)) {
150 if (isMicroMips)
151 Opc = Mips::MOVE16_MM;
152 else
153 Opc = Mips::OR, ZeroReg = Mips::ZERO;
154 } else if (Mips::CCRRegClass.contains(SrcReg))
155 Opc = Mips::CFC1;
156 else if (Mips::FGR32RegClass.contains(SrcReg))
157 Opc = Mips::MFC1;
158 else if (Mips::HI32RegClass.contains(SrcReg)) {
159 Opc = isMicroMips ? Mips::MFHI16_MM : Mips::MFHI;
160 SrcReg = 0;
161 } else if (Mips::LO32RegClass.contains(SrcReg)) {
162 Opc = isMicroMips ? Mips::MFLO16_MM : Mips::MFLO;
163 SrcReg = 0;
164 } else if (Mips::HI32DSPRegClass.contains(SrcReg))
165 Opc = Mips::MFHI_DSP;
166 else if (Mips::LO32DSPRegClass.contains(SrcReg))
167 Opc = Mips::MFLO_DSP;
168 else if (Mips::DSPCCRegClass.contains(SrcReg)) {
169 BuildMI(MBB, I, DL, get(Mips::RDDSP), DestReg).addImm(1 << 4)
170 .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc));
171 return;
172 } else if (Mips::MSACtrlRegClass.contains(SrcReg)) {
173 Opc = Mips::CFCMSA;
174 } else if (Mips::FGR64RegClass.contains(SrcReg) &&
175 (I->getFlag(MachineInstr::MIFlag::NoSWrap) ||
176 isWritedByFCMP(I, SrcReg))) {
177 Opc = Mips::MFC1_D64;
178 }
179 }
180 else if (Mips::GPR32RegClass.contains(SrcReg)) { // Copy from CPU Reg.
181 if (Mips::CCRRegClass.contains(DestReg))
182 Opc = Mips::CTC1;
183 else if (Mips::FGR32RegClass.contains(DestReg))
184 Opc = Mips::MTC1;
185 else if (Mips::HI32RegClass.contains(DestReg))
186 Opc = Mips::MTHI, DestReg = 0;
187 else if (Mips::LO32RegClass.contains(DestReg))
188 Opc = Mips::MTLO, DestReg = 0;
189 else if (Mips::HI32DSPRegClass.contains(DestReg))
190 Opc = Mips::MTHI_DSP;
191 else if (Mips::LO32DSPRegClass.contains(DestReg))
192 Opc = Mips::MTLO_DSP;
193 else if (Mips::DSPCCRegClass.contains(DestReg)) {
194 BuildMI(MBB, I, DL, get(Mips::WRDSP))
195 .addReg(SrcReg, getKillRegState(KillSrc)).addImm(1 << 4)
197 return;
198 } else if (Mips::MSACtrlRegClass.contains(DestReg)) {
199 BuildMI(MBB, I, DL, get(Mips::CTCMSA))
200 .addReg(DestReg)
201 .addReg(SrcReg, getKillRegState(KillSrc));
202 return;
203 } else if (Mips::FGR64RegClass.contains(DestReg) &&
204 isOnlyReadsBySEL(I, DestReg)) {
205 Opc = Mips::MTC1_D64;
206 }
207 }
208 else if (Mips::FGR32RegClass.contains(DestReg, SrcReg))
209 Opc = Mips::FMOV_S;
210 else if (Mips::AFGR64RegClass.contains(DestReg, SrcReg))
211 Opc = Mips::FMOV_D32;
212 else if (Mips::FGR64RegClass.contains(DestReg, SrcReg))
213 Opc = Mips::FMOV_D64;
214 else if (Mips::GPR64RegClass.contains(DestReg)) { // Copy to CPU64 Reg.
215 if (Mips::GPR64RegClass.contains(SrcReg))
216 Opc = Mips::OR64, ZeroReg = Mips::ZERO_64;
217 else if (Mips::HI64RegClass.contains(SrcReg))
218 Opc = Mips::MFHI64, SrcReg = 0;
219 else if (Mips::LO64RegClass.contains(SrcReg))
220 Opc = Mips::MFLO64, SrcReg = 0;
221 else if (Mips::FGR64RegClass.contains(SrcReg))
222 Opc = Mips::DMFC1;
223 }
224 else if (Mips::GPR64RegClass.contains(SrcReg)) { // Copy from CPU64 Reg.
225 if (Mips::HI64RegClass.contains(DestReg))
226 Opc = Mips::MTHI64, DestReg = 0;
227 else if (Mips::LO64RegClass.contains(DestReg))
228 Opc = Mips::MTLO64, DestReg = 0;
229 else if (Mips::FGR64RegClass.contains(DestReg))
230 Opc = Mips::DMTC1;
231 } else if (Mips::MSA128BRegClass.contains(DestReg)) { // Copy to MSA reg
232 if (Mips::MSA128BRegClass.contains(SrcReg))
233 Opc = Mips::MOVE_V;
234 }
235
236 // FCMP + FSEL for MIPSr6 may emit
237 // $d0_64 = COPY killed renamable $f0
238 if (Opc == 0 && Mips::FGR32RegClass.contains(SrcReg) &&
239 Mips::FGR64RegClass.contains(DestReg) && I != MBB.begin()) {
240 // Who produces SrcReg? If SrcReg is produced by CMP_*, then it's OK.
241 // Who uses DestReg? If DestReg is only used by SEL_*, then it's OK.
242 if (isWritedByFCMP(I, SrcReg) || isOnlyReadsBySEL(I, DestReg)) {
243 Opc = Mips::FMOV_D64;
244 unsigned DestRegOff = DestReg.id() - Mips::D0_64;
245 unsigned SrcRegOff = SrcReg.id() - Mips::F0;
246 if (SrcRegOff == DestRegOff && SrcRegOff <= 31)
247 return;
248 }
249 } else if (Opc == 0 && Mips::FGR32RegClass.contains(DestReg) &&
250 Mips::FGR64RegClass.contains(SrcReg) && I != MBB.begin()) {
251 // Who produces SrcReg? If SrcReg is produced by CMP_*, then it's OK.
252 // Who uses DestReg? If DestReg is only used by SEL_*, then it's OK.
253 if (isWritedByFCMP(I, SrcReg) || isOnlyReadsBySEL(I, DestReg)) {
254 Opc = Mips::FMOV_D32;
255 unsigned DestRegOff = DestReg.id() - Mips::F0;
256 unsigned SrcRegOff = SrcReg.id() - Mips::D0_64;
257 if (SrcRegOff == DestRegOff && SrcRegOff <= 31)
258 return;
259 }
260 }
261 assert(Opc && "Cannot copy registers");
262
264
265 if (DestReg)
266 MIB.addReg(DestReg, RegState::Define);
267
268 if (SrcReg)
269 MIB.addReg(SrcReg, getKillRegState(KillSrc));
270
271 if (ZeroReg)
272 MIB.addReg(ZeroReg);
273}
274
275static bool isORCopyInst(const MachineInstr &MI) {
276 switch (MI.getOpcode()) {
277 default:
278 break;
279 case Mips::OR_MM:
280 case Mips::OR:
281 if (MI.getOperand(2).getReg() == Mips::ZERO)
282 return true;
283 break;
284 case Mips::OR64:
285 if (MI.getOperand(2).getReg() == Mips::ZERO_64)
286 return true;
287 break;
288 }
289 return false;
290}
291
292/// We check for the common case of 'or', as it's MIPS' preferred instruction
293/// for GPRs but we have to check the operands to ensure that is the case.
294/// Other move instructions for MIPS are directly identifiable.
295std::optional<DestSourcePair>
297 if (MI.isMoveReg() || isORCopyInst(MI))
298 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
299
300 return std::nullopt;
301}
302
305 Register SrcReg, bool isKill, int FI,
306 const TargetRegisterClass *RC,
307 int64_t Offset,
308 MachineInstr::MIFlag Flags) const {
309 DebugLoc DL;
311
312 unsigned Opc = 0;
313
314 if (Mips::GPR32RegClass.hasSubClassEq(RC))
315 Opc = Mips::SW;
316 else if (Mips::GPR64RegClass.hasSubClassEq(RC))
317 Opc = Mips::SD;
318 else if (Mips::ACC64RegClass.hasSubClassEq(RC))
319 Opc = Mips::STORE_ACC64;
320 else if (Mips::ACC64DSPRegClass.hasSubClassEq(RC))
321 Opc = Mips::STORE_ACC64DSP;
322 else if (Mips::ACC128RegClass.hasSubClassEq(RC))
323 Opc = Mips::STORE_ACC128;
324 else if (Mips::DSPCCRegClass.hasSubClassEq(RC))
325 Opc = Mips::STORE_CCOND_DSP;
326 else if (Mips::FGR32RegClass.hasSubClassEq(RC))
327 Opc = Mips::SWC1;
328 else if (Mips::AFGR64RegClass.hasSubClassEq(RC))
329 Opc = Mips::SDC1;
330 else if (Mips::FGR64RegClass.hasSubClassEq(RC))
331 Opc = Mips::SDC164;
332 else if (RI.isTypeLegalForClass(*RC, MVT::v16i8))
333 Opc = Mips::ST_B;
334 else if (RI.isTypeLegalForClass(*RC, MVT::v8i16) ||
335 RI.isTypeLegalForClass(*RC, MVT::v8f16))
336 Opc = Mips::ST_H;
337 else if (RI.isTypeLegalForClass(*RC, MVT::v4i32) ||
338 RI.isTypeLegalForClass(*RC, MVT::v4f32))
339 Opc = Mips::ST_W;
340 else if (RI.isTypeLegalForClass(*RC, MVT::v2i64) ||
341 RI.isTypeLegalForClass(*RC, MVT::v2f64))
342 Opc = Mips::ST_D;
343 else if (Mips::LO32RegClass.hasSubClassEq(RC))
344 Opc = Mips::SW;
345 else if (Mips::LO64RegClass.hasSubClassEq(RC))
346 Opc = Mips::SD;
347 else if (Mips::HI32RegClass.hasSubClassEq(RC))
348 Opc = Mips::SW;
349 else if (Mips::HI64RegClass.hasSubClassEq(RC))
350 Opc = Mips::SD;
351 else if (Mips::DSPRRegClass.hasSubClassEq(RC))
352 Opc = Mips::SWDSP;
353
354 // Hi, Lo are normally caller save but they are callee save
355 // for interrupt handling.
356 const Function &Func = MBB.getParent()->getFunction();
357 if (Func.hasFnAttribute("interrupt")) {
358 if (Mips::HI32RegClass.hasSubClassEq(RC)) {
359 BuildMI(MBB, I, DL, get(Mips::MFHI), Mips::K0);
360 SrcReg = Mips::K0;
361 } else if (Mips::HI64RegClass.hasSubClassEq(RC)) {
362 BuildMI(MBB, I, DL, get(Mips::MFHI64), Mips::K0_64);
363 SrcReg = Mips::K0_64;
364 } else if (Mips::LO32RegClass.hasSubClassEq(RC)) {
365 BuildMI(MBB, I, DL, get(Mips::MFLO), Mips::K0);
366 SrcReg = Mips::K0;
367 } else if (Mips::LO64RegClass.hasSubClassEq(RC)) {
368 BuildMI(MBB, I, DL, get(Mips::MFLO64), Mips::K0_64);
369 SrcReg = Mips::K0_64;
370 }
371 }
372
373 assert(Opc && "Register class not handled!");
374 BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill))
376}
377
380 Register DestReg, int FI,
381 const TargetRegisterClass *RC,
382 int64_t Offset,
383 MachineInstr::MIFlag Flags) const {
384 DebugLoc DL;
385 if (I != MBB.end()) DL = I->getDebugLoc();
387 unsigned Opc = 0;
388
389 const Function &Func = MBB.getParent()->getFunction();
390 bool ReqIndirectLoad = Func.hasFnAttribute("interrupt") &&
391 (DestReg == Mips::LO0 || DestReg == Mips::LO0_64 ||
392 DestReg == Mips::HI0 || DestReg == Mips::HI0_64);
393
394 if (Mips::GPR32RegClass.hasSubClassEq(RC))
395 Opc = Mips::LW;
396 else if (Mips::GPR64RegClass.hasSubClassEq(RC))
397 Opc = Mips::LD;
398 else if (Mips::ACC64RegClass.hasSubClassEq(RC))
399 Opc = Mips::LOAD_ACC64;
400 else if (Mips::ACC64DSPRegClass.hasSubClassEq(RC))
401 Opc = Mips::LOAD_ACC64DSP;
402 else if (Mips::ACC128RegClass.hasSubClassEq(RC))
403 Opc = Mips::LOAD_ACC128;
404 else if (Mips::DSPCCRegClass.hasSubClassEq(RC))
405 Opc = Mips::LOAD_CCOND_DSP;
406 else if (Mips::FGR32RegClass.hasSubClassEq(RC))
407 Opc = Mips::LWC1;
408 else if (Mips::AFGR64RegClass.hasSubClassEq(RC))
409 Opc = Mips::LDC1;
410 else if (Mips::FGR64RegClass.hasSubClassEq(RC))
411 Opc = Mips::LDC164;
412 else if (RI.isTypeLegalForClass(*RC, MVT::v16i8))
413 Opc = Mips::LD_B;
414 else if (RI.isTypeLegalForClass(*RC, MVT::v8i16) ||
415 RI.isTypeLegalForClass(*RC, MVT::v8f16))
416 Opc = Mips::LD_H;
417 else if (RI.isTypeLegalForClass(*RC, MVT::v4i32) ||
418 RI.isTypeLegalForClass(*RC, MVT::v4f32))
419 Opc = Mips::LD_W;
420 else if (RI.isTypeLegalForClass(*RC, MVT::v2i64) ||
421 RI.isTypeLegalForClass(*RC, MVT::v2f64))
422 Opc = Mips::LD_D;
423 else if (Mips::HI32RegClass.hasSubClassEq(RC))
424 Opc = Mips::LW;
425 else if (Mips::HI64RegClass.hasSubClassEq(RC))
426 Opc = Mips::LD;
427 else if (Mips::LO32RegClass.hasSubClassEq(RC))
428 Opc = Mips::LW;
429 else if (Mips::LO64RegClass.hasSubClassEq(RC))
430 Opc = Mips::LD;
431 else if (Mips::DSPRRegClass.hasSubClassEq(RC))
432 Opc = Mips::LWDSP;
433
434 assert(Opc && "Register class not handled!");
435
436 if (!ReqIndirectLoad)
437 BuildMI(MBB, I, DL, get(Opc), DestReg)
438 .addFrameIndex(FI)
439 .addImm(Offset)
440 .addMemOperand(MMO);
441 else {
442 // Load HI/LO through K0. Notably the DestReg is encoded into the
443 // instruction itself.
444 unsigned Reg = Mips::K0;
445 unsigned LdOp = Mips::MTLO;
446 if (DestReg == Mips::HI0)
447 LdOp = Mips::MTHI;
448
449 if (Subtarget.getABI().ArePtrs64bit()) {
450 Reg = Mips::K0_64;
451 if (DestReg == Mips::HI0_64)
452 LdOp = Mips::MTHI64;
453 else
454 LdOp = Mips::MTLO64;
455 }
456
457 BuildMI(MBB, I, DL, get(Opc), Reg)
458 .addFrameIndex(FI)
459 .addImm(Offset)
460 .addMemOperand(MMO);
461 BuildMI(MBB, I, DL, get(LdOp)).addReg(Reg);
462 }
463}
464
466 MachineBasicBlock &MBB = *MI.getParent();
467 bool isMicroMips = Subtarget.inMicroMipsMode();
468 unsigned Opc;
469
470 switch (MI.getDesc().getOpcode()) {
471 default:
472 return false;
473 case Mips::RetRA:
474 expandRetRA(MBB, MI);
475 break;
476 case Mips::ERet:
477 expandERet(MBB, MI);
478 break;
479 case Mips::PseudoMFHI:
480 expandPseudoMFHiLo(MBB, MI, Mips::MFHI);
481 break;
482 case Mips::PseudoMFHI_MM:
483 expandPseudoMFHiLo(MBB, MI, Mips::MFHI16_MM);
484 break;
485 case Mips::PseudoMFLO:
486 expandPseudoMFHiLo(MBB, MI, Mips::MFLO);
487 break;
488 case Mips::PseudoMFLO_MM:
489 expandPseudoMFHiLo(MBB, MI, Mips::MFLO16_MM);
490 break;
491 case Mips::PseudoMFHI64:
492 expandPseudoMFHiLo(MBB, MI, Mips::MFHI64);
493 break;
494 case Mips::PseudoMFLO64:
495 expandPseudoMFHiLo(MBB, MI, Mips::MFLO64);
496 break;
497 case Mips::PseudoMTLOHI:
498 expandPseudoMTLoHi(MBB, MI, Mips::MTLO, Mips::MTHI, false);
499 break;
500 case Mips::PseudoMTLOHI64:
501 expandPseudoMTLoHi(MBB, MI, Mips::MTLO64, Mips::MTHI64, false);
502 break;
503 case Mips::PseudoMTLOHI_DSP:
504 expandPseudoMTLoHi(MBB, MI, Mips::MTLO_DSP, Mips::MTHI_DSP, true);
505 break;
506 case Mips::PseudoMTLOHI_MM:
507 expandPseudoMTLoHi(MBB, MI, Mips::MTLO_MM, Mips::MTHI_MM, false);
508 break;
509 case Mips::PseudoCVT_S_W:
510 expandCvtFPInt(MBB, MI, Mips::CVT_S_W, Mips::MTC1, false);
511 break;
512 case Mips::PseudoCVT_D32_W:
513 Opc = isMicroMips ? Mips::CVT_D32_W_MM : Mips::CVT_D32_W;
514 expandCvtFPInt(MBB, MI, Opc, Mips::MTC1, false);
515 break;
516 case Mips::PseudoCVT_S_L:
517 expandCvtFPInt(MBB, MI, Mips::CVT_S_L, Mips::DMTC1, true);
518 break;
519 case Mips::PseudoCVT_D64_W:
520 Opc = isMicroMips ? Mips::CVT_D64_W_MM : Mips::CVT_D64_W;
521 expandCvtFPInt(MBB, MI, Opc, Mips::MTC1, true);
522 break;
523 case Mips::PseudoCVT_D64_L:
524 expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, true);
525 break;
526 case Mips::BuildPairF64:
527 expandBuildPairF64(MBB, MI, isMicroMips, false);
528 break;
529 case Mips::BuildPairF64_64:
530 expandBuildPairF64(MBB, MI, isMicroMips, true);
531 break;
532 case Mips::ExtractElementF64:
533 expandExtractElementF64(MBB, MI, isMicroMips, false);
534 break;
535 case Mips::ExtractElementF64_64:
536 expandExtractElementF64(MBB, MI, isMicroMips, true);
537 break;
538 case Mips::MIPSeh_return32:
539 case Mips::MIPSeh_return64:
540 expandEhReturn(MBB, MI);
541 break;
542 }
543
544 MBB.erase(MI);
545 return true;
546}
547
548/// isBranchWithImm - Return true if the branch contains an immediate
549/// operand (\see lib/Target/Mips/MipsBranchExpansion.cpp).
551 switch (Opc) {
552 default:
553 return false;
554 case Mips::BBIT0:
555 case Mips::BBIT1:
556 case Mips::BBIT032:
557 case Mips::BBIT132:
558 return true;
559 }
560}
561
562/// getOppositeBranchOpc - Return the inverse of the specified
563/// opcode, e.g. turning BEQ to BNE.
565 switch (Opc) {
566 default: llvm_unreachable("Illegal opcode!");
567 case Mips::BEQ: return Mips::BNE;
568 case Mips::BEQ_MM: return Mips::BNE_MM;
569 case Mips::BNE: return Mips::BEQ;
570 case Mips::BNE_MM: return Mips::BEQ_MM;
571 case Mips::BGTZ: return Mips::BLEZ;
572 case Mips::BGEZ: return Mips::BLTZ;
573 case Mips::BLTZ: return Mips::BGEZ;
574 case Mips::BLEZ: return Mips::BGTZ;
575 case Mips::BGTZ_MM: return Mips::BLEZ_MM;
576 case Mips::BGEZ_MM: return Mips::BLTZ_MM;
577 case Mips::BLTZ_MM: return Mips::BGEZ_MM;
578 case Mips::BLEZ_MM: return Mips::BGTZ_MM;
579 case Mips::BEQ64: return Mips::BNE64;
580 case Mips::BNE64: return Mips::BEQ64;
581 case Mips::BGTZ64: return Mips::BLEZ64;
582 case Mips::BGEZ64: return Mips::BLTZ64;
583 case Mips::BLTZ64: return Mips::BGEZ64;
584 case Mips::BLEZ64: return Mips::BGTZ64;
585 case Mips::BC1T: return Mips::BC1F;
586 case Mips::BC1F: return Mips::BC1T;
587 case Mips::BC1T_MM: return Mips::BC1F_MM;
588 case Mips::BC1F_MM: return Mips::BC1T_MM;
589 case Mips::BEQZ16_MM: return Mips::BNEZ16_MM;
590 case Mips::BNEZ16_MM: return Mips::BEQZ16_MM;
591 case Mips::BEQZC_MM: return Mips::BNEZC_MM;
592 case Mips::BNEZC_MM: return Mips::BEQZC_MM;
593 case Mips::BEQZC: return Mips::BNEZC;
594 case Mips::BNEZC: return Mips::BEQZC;
595 case Mips::BLEZC: return Mips::BGTZC;
596 case Mips::BGEZC: return Mips::BLTZC;
597 case Mips::BGEC: return Mips::BLTC;
598 case Mips::BGTZC: return Mips::BLEZC;
599 case Mips::BLTZC: return Mips::BGEZC;
600 case Mips::BLTC: return Mips::BGEC;
601 case Mips::BGEUC: return Mips::BLTUC;
602 case Mips::BLTUC: return Mips::BGEUC;
603 case Mips::BEQC: return Mips::BNEC;
604 case Mips::BNEC: return Mips::BEQC;
605 case Mips::BC1EQZ: return Mips::BC1NEZ;
606 case Mips::BC1NEZ: return Mips::BC1EQZ;
607 case Mips::BEQZC_MMR6: return Mips::BNEZC_MMR6;
608 case Mips::BNEZC_MMR6: return Mips::BEQZC_MMR6;
609 case Mips::BLEZC_MMR6: return Mips::BGTZC_MMR6;
610 case Mips::BGEZC_MMR6: return Mips::BLTZC_MMR6;
611 case Mips::BGEC_MMR6: return Mips::BLTC_MMR6;
612 case Mips::BGTZC_MMR6: return Mips::BLEZC_MMR6;
613 case Mips::BLTZC_MMR6: return Mips::BGEZC_MMR6;
614 case Mips::BLTC_MMR6: return Mips::BGEC_MMR6;
615 case Mips::BGEUC_MMR6: return Mips::BLTUC_MMR6;
616 case Mips::BLTUC_MMR6: return Mips::BGEUC_MMR6;
617 case Mips::BEQC_MMR6: return Mips::BNEC_MMR6;
618 case Mips::BNEC_MMR6: return Mips::BEQC_MMR6;
619 case Mips::BC1EQZC_MMR6: return Mips::BC1NEZC_MMR6;
620 case Mips::BC1NEZC_MMR6: return Mips::BC1EQZC_MMR6;
621 case Mips::BEQZC64: return Mips::BNEZC64;
622 case Mips::BNEZC64: return Mips::BEQZC64;
623 case Mips::BEQC64: return Mips::BNEC64;
624 case Mips::BNEC64: return Mips::BEQC64;
625 case Mips::BGEC64: return Mips::BLTC64;
626 case Mips::BGEUC64: return Mips::BLTUC64;
627 case Mips::BLTC64: return Mips::BGEC64;
628 case Mips::BLTUC64: return Mips::BGEUC64;
629 case Mips::BGTZC64: return Mips::BLEZC64;
630 case Mips::BGEZC64: return Mips::BLTZC64;
631 case Mips::BLTZC64: return Mips::BGEZC64;
632 case Mips::BLEZC64: return Mips::BGTZC64;
633 case Mips::BBIT0: return Mips::BBIT1;
634 case Mips::BBIT1: return Mips::BBIT0;
635 case Mips::BBIT032: return Mips::BBIT132;
636 case Mips::BBIT132: return Mips::BBIT032;
637 case Mips::BZ_B: return Mips::BNZ_B;
638 case Mips::BZ_H: return Mips::BNZ_H;
639 case Mips::BZ_W: return Mips::BNZ_W;
640 case Mips::BZ_D: return Mips::BNZ_D;
641 case Mips::BZ_V: return Mips::BNZ_V;
642 case Mips::BNZ_B: return Mips::BZ_B;
643 case Mips::BNZ_H: return Mips::BZ_H;
644 case Mips::BNZ_W: return Mips::BZ_W;
645 case Mips::BNZ_D: return Mips::BZ_D;
646 case Mips::BNZ_V: return Mips::BZ_V;
647 }
648}
649
650/// Adjust SP by Amount bytes.
651void MipsSEInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
654 MipsABIInfo ABI = Subtarget.getABI();
655 DebugLoc DL;
656 unsigned ADDiu = ABI.GetPtrAddiuOp();
657
658 if (Amount == 0)
659 return;
660
661 if (isInt<16>(Amount)) {
662 // addi sp, sp, amount
663 BuildMI(MBB, I, DL, get(ADDiu), SP).addReg(SP).addImm(Amount);
664 } else {
665 // For numbers which are not 16bit integers we synthesize Amount inline
666 // then add or subtract it from sp.
667 unsigned Opc = ABI.GetPtrAdduOp();
668 if (Amount < 0) {
669 Opc = ABI.GetPtrSubuOp();
670 Amount = -Amount;
671 }
672 unsigned Reg = loadImmediate(Amount, MBB, I, DL, nullptr);
673 BuildMI(MBB, I, DL, get(Opc), SP).addReg(SP).addReg(Reg, RegState::Kill);
674 }
675}
676
677/// This function generates the sequence of instructions needed to get the
678/// result of adding register REG and immediate IMM.
681 const DebugLoc &DL,
682 unsigned *NewImm) const {
683 MipsAnalyzeImmediate AnalyzeImm;
684 const MipsSubtarget &STI = Subtarget;
685 MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
686 unsigned Size = STI.isABI_N64() ? 64 : 32;
687 unsigned LUi = STI.isABI_N64() ? Mips::LUi64 : Mips::LUi;
688 unsigned ZEROReg = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
689 const TargetRegisterClass *RC = STI.isABI_N64() ?
690 &Mips::GPR64RegClass : &Mips::GPR32RegClass;
691 bool LastInstrIsADDiu = NewImm;
692
694 AnalyzeImm.Analyze(Imm, Size, LastInstrIsADDiu);
696
697 assert(Seq.size() && (!LastInstrIsADDiu || (Seq.size() > 1)));
698
699 // The first instruction can be a LUi, which is different from other
700 // instructions (ADDiu, ORI and SLL) in that it does not have a register
701 // operand.
702 Register Reg = RegInfo.createVirtualRegister(RC);
703
704 if (Inst->Opc == LUi)
705 BuildMI(MBB, II, DL, get(LUi), Reg).addImm(SignExtend64<16>(Inst->ImmOpnd));
706 else
707 BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(ZEROReg)
708 .addImm(SignExtend64<16>(Inst->ImmOpnd));
709
710 // Build the remaining instructions in Seq.
711 for (++Inst; Inst != Seq.end() - LastInstrIsADDiu; ++Inst)
712 BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(Reg, RegState::Kill)
713 .addImm(SignExtend64<16>(Inst->ImmOpnd));
714
715 if (LastInstrIsADDiu)
716 *NewImm = Inst->ImmOpnd;
717
718 return Reg;
719}
720
721unsigned MipsSEInstrInfo::getAnalyzableBrOpc(unsigned Opc) const {
722 return (Opc == Mips::BEQ || Opc == Mips::BEQ_MM || Opc == Mips::BNE ||
723 Opc == Mips::BNE_MM || Opc == Mips::BGTZ || Opc == Mips::BGEZ ||
724 Opc == Mips::BLTZ || Opc == Mips::BLEZ || Opc == Mips::BEQ64 ||
725 Opc == Mips::BNE64 || Opc == Mips::BGTZ64 || Opc == Mips::BGEZ64 ||
726 Opc == Mips::BLTZ64 || Opc == Mips::BLEZ64 || Opc == Mips::BC1T ||
727 Opc == Mips::BC1F || Opc == Mips::B || Opc == Mips::J ||
728 Opc == Mips::J_MM || Opc == Mips::B_MM || Opc == Mips::BEQZC_MM ||
729 Opc == Mips::BNEZC_MM || Opc == Mips::BEQC || Opc == Mips::BNEC ||
730 Opc == Mips::BLTC || Opc == Mips::BGEC || Opc == Mips::BLTUC ||
731 Opc == Mips::BGEUC || Opc == Mips::BGTZC || Opc == Mips::BLEZC ||
732 Opc == Mips::BGEZC || Opc == Mips::BLTZC || Opc == Mips::BEQZC ||
733 Opc == Mips::BNEZC || Opc == Mips::BEQZC64 || Opc == Mips::BNEZC64 ||
734 Opc == Mips::BEQC64 || Opc == Mips::BNEC64 || Opc == Mips::BGEC64 ||
735 Opc == Mips::BGEUC64 || Opc == Mips::BLTC64 || Opc == Mips::BLTUC64 ||
736 Opc == Mips::BGTZC64 || Opc == Mips::BGEZC64 ||
737 Opc == Mips::BLTZC64 || Opc == Mips::BLEZC64 || Opc == Mips::BC ||
738 Opc == Mips::BBIT0 || Opc == Mips::BBIT1 || Opc == Mips::BBIT032 ||
739 Opc == Mips::BBIT132 || Opc == Mips::BC_MMR6 ||
740 Opc == Mips::BEQC_MMR6 || Opc == Mips::BNEC_MMR6 ||
741 Opc == Mips::BLTC_MMR6 || Opc == Mips::BGEC_MMR6 ||
742 Opc == Mips::BLTUC_MMR6 || Opc == Mips::BGEUC_MMR6 ||
743 Opc == Mips::BGTZC_MMR6 || Opc == Mips::BLEZC_MMR6 ||
744 Opc == Mips::BGEZC_MMR6 || Opc == Mips::BLTZC_MMR6 ||
745 Opc == Mips::BEQZC_MMR6 || Opc == Mips::BNEZC_MMR6) ? Opc : 0;
746}
747
748void MipsSEInstrInfo::expandRetRA(MachineBasicBlock &MBB,
750
752 if (Subtarget.isGP64bit())
753 MIB = BuildMI(MBB, I, I->getDebugLoc(), get(Mips::PseudoReturn64))
754 .addReg(Mips::RA_64, RegState::Undef);
755 else
756 MIB = BuildMI(MBB, I, I->getDebugLoc(), get(Mips::PseudoReturn))
757 .addReg(Mips::RA, RegState::Undef);
758
759 // Retain any imp-use flags.
760 for (auto & MO : I->operands()) {
761 if (MO.isImplicit())
762 MIB.add(MO);
763 }
764}
765
766void MipsSEInstrInfo::expandERet(MachineBasicBlock &MBB,
768 BuildMI(MBB, I, I->getDebugLoc(), get(Mips::ERET));
769}
770
771std::pair<bool, bool>
772MipsSEInstrInfo::compareOpndSize(unsigned Opc,
773 const MachineFunction &MF) const {
774 const MCInstrDesc &Desc = get(Opc);
775 assert(Desc.NumOperands == 2 && "Unary instruction expected.");
776 const MipsRegisterInfo *RI = &getRegisterInfo();
777 unsigned DstRegSize = RI->getRegSizeInBits(*getRegClass(Desc, 0));
778 unsigned SrcRegSize = RI->getRegSizeInBits(*getRegClass(Desc, 1));
779
780 return std::make_pair(DstRegSize > SrcRegSize, DstRegSize < SrcRegSize);
781}
782
783void MipsSEInstrInfo::expandPseudoMFHiLo(MachineBasicBlock &MBB,
785 unsigned NewOpc) const {
786 BuildMI(MBB, I, I->getDebugLoc(), get(NewOpc), I->getOperand(0).getReg());
787}
788
789void MipsSEInstrInfo::expandPseudoMTLoHi(MachineBasicBlock &MBB,
791 unsigned LoOpc,
792 unsigned HiOpc,
793 bool HasExplicitDef) const {
794 // Expand
795 // lo_hi pseudomtlohi $gpr0, $gpr1
796 // to these two instructions:
797 // mtlo $gpr0
798 // mthi $gpr1
799
800 DebugLoc DL = I->getDebugLoc();
801 const MachineOperand &SrcLo = I->getOperand(1), &SrcHi = I->getOperand(2);
802 MachineInstrBuilder LoInst = BuildMI(MBB, I, DL, get(LoOpc));
803 MachineInstrBuilder HiInst = BuildMI(MBB, I, DL, get(HiOpc));
804
805 // Add lo/hi registers if the mtlo/hi instructions created have explicit
806 // def registers.
807 if (HasExplicitDef) {
808 Register DstReg = I->getOperand(0).getReg();
809 Register DstLo = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);
810 Register DstHi = getRegisterInfo().getSubReg(DstReg, Mips::sub_hi);
811 LoInst.addReg(DstLo, RegState::Define);
812 HiInst.addReg(DstHi, RegState::Define);
813 }
814
815 LoInst.addReg(SrcLo.getReg(), getKillRegState(SrcLo.isKill()));
816 HiInst.addReg(SrcHi.getReg(), getKillRegState(SrcHi.isKill()));
817}
818
819void MipsSEInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB,
821 unsigned CvtOpc, unsigned MovOpc,
822 bool IsI64) const {
823 const MCInstrDesc &CvtDesc = get(CvtOpc), &MovDesc = get(MovOpc);
824 const MachineOperand &Dst = I->getOperand(0), &Src = I->getOperand(1);
825 unsigned DstReg = Dst.getReg(), SrcReg = Src.getReg(), TmpReg = DstReg;
826 RegState KillSrc = getKillRegState(Src.isKill());
827 DebugLoc DL = I->getDebugLoc();
828 bool DstIsLarger, SrcIsLarger;
829
830 std::tie(DstIsLarger, SrcIsLarger) =
831 compareOpndSize(CvtOpc, *MBB.getParent());
832
833 if (DstIsLarger)
834 TmpReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);
835
836 if (SrcIsLarger)
837 DstReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);
838
839 BuildMI(MBB, I, DL, MovDesc, TmpReg).addReg(SrcReg, KillSrc);
840 BuildMI(MBB, I, DL, CvtDesc, DstReg).addReg(TmpReg, RegState::Kill);
841}
842
843void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB,
845 bool isMicroMips,
846 bool FP64) const {
847 Register DstReg = I->getOperand(0).getReg();
848 Register SrcReg = I->getOperand(1).getReg();
849 unsigned N = I->getOperand(2).getImm();
850 DebugLoc dl = I->getDebugLoc();
851
852 assert(N < 2 && "Invalid immediate");
853 unsigned SubIdx = N ? Mips::sub_hi : Mips::sub_lo;
854 Register SubReg = getRegisterInfo().getSubReg(SrcReg, SubIdx);
855
856 // FPXX on MIPS-II or MIPS32r1 should have been handled with a spill/reload
857 // in MipsSEFrameLowering.cpp.
858 assert(!(Subtarget.isABI_FPXX() && !Subtarget.hasMips32r2()));
859
860 // FP64A (FP64 with nooddspreg) should have been handled with a spill/reload
861 // in MipsSEFrameLowering.cpp.
862 assert(!(Subtarget.isFP64bit() && !Subtarget.useOddSPReg()));
863
864 if (SubIdx == Mips::sub_hi && Subtarget.hasMTHC1()) {
865 // FIXME: Strictly speaking MFHC1 only reads the top 32-bits however, we
866 // claim to read the whole 64-bits as part of a white lie used to
867 // temporarily work around a widespread bug in the -mfp64 support.
868 // The problem is that none of the 32-bit fpu ops mention the fact
869 // that they clobber the upper 32-bits of the 64-bit FPR. Fixing that
870 // requires a major overhaul of the FPU implementation which can't
871 // be done right now due to time constraints.
872 // MFHC1 is one of two instructions that are affected since they are
873 // the only instructions that don't read the lower 32-bits.
874 // We therefore pretend that it reads the bottom 32-bits to
875 // artificially create a dependency and prevent the scheduler
876 // changing the behaviour of the code.
877 BuildMI(MBB, I, dl,
878 get(isMicroMips ? (FP64 ? Mips::MFHC1_D64_MM : Mips::MFHC1_D32_MM)
879 : (FP64 ? Mips::MFHC1_D64 : Mips::MFHC1_D32)),
880 DstReg)
881 .addReg(SrcReg);
882 } else
883 BuildMI(MBB, I, dl, get(Mips::MFC1), DstReg).addReg(SubReg);
884}
885
886void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB,
888 bool isMicroMips, bool FP64) const {
889 Register DstReg = I->getOperand(0).getReg();
890 unsigned LoReg = I->getOperand(1).getReg(), HiReg = I->getOperand(2).getReg();
891 const MCInstrDesc& Mtc1Tdd = get(Mips::MTC1);
892 DebugLoc dl = I->getDebugLoc();
893 const TargetRegisterInfo &TRI = getRegisterInfo();
894
895 // When mthc1 is available, use:
896 // mtc1 Lo, $fp
897 // mthc1 Hi, $fp
898 //
899 // Otherwise, for O32 FPXX ABI:
900 // spill + reload via ldc1
901 // This case is handled by the frame lowering code.
902 //
903 // Otherwise, for FP32:
904 // mtc1 Lo, $fp
905 // mtc1 Hi, $fp + 1
906 //
907 // The case where dmtc1 is available doesn't need to be handled here
908 // because it never creates a BuildPairF64 node.
909
910 // FPXX on MIPS-II or MIPS32r1 should have been handled with a spill/reload
911 // in MipsSEFrameLowering.cpp.
912 assert(!(Subtarget.isABI_FPXX() && !Subtarget.hasMips32r2()));
913
914 // FP64A (FP64 with nooddspreg) should have been handled with a spill/reload
915 // in MipsSEFrameLowering.cpp.
916 assert(!(Subtarget.isFP64bit() && !Subtarget.useOddSPReg()));
917
918 BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_lo))
919 .addReg(LoReg);
920
921 if (Subtarget.hasMTHC1()) {
922 // FIXME: The .addReg(DstReg) is a white lie used to temporarily work
923 // around a widespread bug in the -mfp64 support.
924 // The problem is that none of the 32-bit fpu ops mention the fact
925 // that they clobber the upper 32-bits of the 64-bit FPR. Fixing that
926 // requires a major overhaul of the FPU implementation which can't
927 // be done right now due to time constraints.
928 // MTHC1 is one of two instructions that are affected since they are
929 // the only instructions that don't read the lower 32-bits.
930 // We therefore pretend that it reads the bottom 32-bits to
931 // artificially create a dependency and prevent the scheduler
932 // changing the behaviour of the code.
933 BuildMI(MBB, I, dl,
934 get(isMicroMips ? (FP64 ? Mips::MTHC1_D64_MM : Mips::MTHC1_D32_MM)
935 : (FP64 ? Mips::MTHC1_D64 : Mips::MTHC1_D32)),
936 DstReg)
937 .addReg(DstReg)
938 .addReg(HiReg);
939 } else if (Subtarget.isABI_FPXX())
940 llvm_unreachable("BuildPairF64 not expanded in frame lowering code!");
941 else
942 BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_hi))
943 .addReg(HiReg);
944}
945
946void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB,
948 // This pseudo instruction is generated as part of the lowering of
949 // ISD::EH_RETURN. We convert it to a stack increment by OffsetReg, and
950 // indirect jump to TargetReg
951 MipsABIInfo ABI = Subtarget.getABI();
952 unsigned ADDU = ABI.GetPtrAdduOp();
953 unsigned SP = Subtarget.isGP64bit() ? Mips::SP_64 : Mips::SP;
954 unsigned RA = Subtarget.isGP64bit() ? Mips::RA_64 : Mips::RA;
955 unsigned T9 = Subtarget.isGP64bit() ? Mips::T9_64 : Mips::T9;
956 unsigned ZERO = Subtarget.isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
957 Register OffsetReg = I->getOperand(0).getReg();
958 Register TargetReg = I->getOperand(1).getReg();
959
960 // addu $ra, $v0, $zero
961 // addu $sp, $sp, $v1
962 // jr $ra (via RetRA)
963 const TargetMachine &TM = MBB.getParent()->getTarget();
964 if (TM.isPositionIndependent())
965 BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), T9)
966 .addReg(TargetReg)
967 .addReg(ZERO);
968 BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), RA)
969 .addReg(TargetReg)
970 .addReg(ZERO);
971 BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), SP).addReg(SP).addReg(OffsetReg);
972 expandRetRA(MBB, I);
973}
974
976 return new MipsSEInstrInfo(STI);
977}
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
@ ZERO
Special weight used for cases with exact zero probability.
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 bool isORCopyInst(const MachineInstr &MI)
static std::pair< bool, bool > readsWritesFloatRegister(MachineInstr &MI, Register Reg)
static unsigned getUnconditionalBranch(const MipsSubtarget &STI)
static bool isOnlyReadsBySEL(MachineBasicBlock::iterator I, Register Reg)
static bool isWritedByFCMP(MachineBasicBlock::iterator I, Register Reg)
static bool isMicroMips(const MCSubtargetInfo *STI)
uint64_t IntrinsicInst * II
SI optimize exec mask operations pre RA
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:487
A debug info location.
Definition DebugLoc.h:123
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const InstSeq & Analyze(uint64_t Imm, unsigned Size, bool LastInstrIsADDiu)
Analyze - Get an instruction sequence to load immediate Imm.
SmallVector< Inst, 7 > InstSeq
const MipsSubtarget & Subtarget
MachineMemOperand * GetMemOperand(MachineBasicBlock &MBB, int FI, MachineMemOperand::Flags Flags) const
bool isZeroImm(const MachineOperand &op) const
MipsInstrInfo(const MipsSubtarget &STI, const MipsRegisterInfo &RI, unsigned UncondBrOpc)
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
isLoadFromStackSlot - If the specified machine instruction is a direct load from a stack slot,...
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot,...
void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
Adjust SP by Amount bytes.
std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const override
If the specific machine instruction is a instruction that moves/copies value from one register to ano...
unsigned loadImmediate(int64_t Imm, MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, unsigned *NewImm) const
Emit a series of instructions to load an immediate.
bool isBranchWithImm(unsigned Opc) const override
isBranchWithImm - Return true if the branch contains an immediate operand (
MipsSEInstrInfo(const MipsSubtarget &STI)
bool expandPostRAPseudo(MachineInstr &MI) const override
void loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, int64_t Offset, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
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 override
unsigned getOppositeBranchOpc(unsigned Opc) const override
getOppositeBranchOpc - Return the inverse of the specified opcode, e.g.
const MipsSERegisterInfo & getRegisterInfo() const
bool inMicroMipsMode() const
bool isPositionIndependent() const
bool isGP64bit() const
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr unsigned id() const
Definition Register.h:100
bool isPositionIndependent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
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 MipsInstrInfo * createMipsSEInstrInfo(const MipsSubtarget &STI)
RegState
Flags to represent properties of register accesses.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
@ Define
Register definition.
constexpr RegState getKillRegState(bool B)
Op::Description Desc
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
static MCRegister getFloatRegFromFReg(MCRegister Reg)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition MathExtras.h:572
#define N