LLVM 20.0.0git
MipsInstrInfo.cpp
Go to the documentation of this file.
1//===- MipsInstrInfo.cpp - Mips 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 Mips implementation of the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "MipsInstrInfo.h"
16#include "Mips.h"
17#include "MipsSubtarget.h"
28#include "llvm/IR/DebugLoc.h"
29#include "llvm/MC/MCInstrDesc.h"
31#include <cassert>
32
33using namespace llvm;
34
35#define GET_INSTRINFO_CTOR_DTOR
36#include "MipsGenInstrInfo.inc"
37
38// Pin the vtable to this file.
39void MipsInstrInfo::anchor() {}
40
41MipsInstrInfo::MipsInstrInfo(const MipsSubtarget &STI, unsigned UncondBr)
42 : MipsGenInstrInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP),
43 Subtarget(STI), UncondBrOpc(UncondBr) {}
44
46 if (STI.inMips16Mode())
47 return createMips16InstrInfo(STI);
48
49 return createMipsSEInstrInfo(STI);
50}
51
53 return op.isImm() && op.getImm() == 0;
54}
55
56/// insertNoop - If data hazard condition is found insert the target nop
57/// instruction.
60{
62 BuildMI(MBB, MI, DL, get(Mips::NOP));
63}
64
67 DebugLoc DL) const {
69 "insertNop does not support MIPS16e mode at this time");
70 const unsigned MMOpc =
71 Subtarget.hasMips32r6() ? Mips::SLL_MMR6 : Mips::SLL_MM;
72 const unsigned Opc =
73 Subtarget.inMicroMipsMode() ? MMOpc : (unsigned)Mips::SLL;
74 return BuildMI(MBB, MI, DL, get(Opc), Mips::ZERO)
75 .addReg(Mips::ZERO)
76 .addImm(0);
77}
78
81 MachineMemOperand::Flags Flags) const {
84
86 Flags, MFI.getObjectSize(FI),
87 MFI.getObjectAlign(FI));
88}
89
90//===----------------------------------------------------------------------===//
91// Branch Analysis
92//===----------------------------------------------------------------------===//
93
94void MipsInstrInfo::AnalyzeCondBr(const MachineInstr *Inst, unsigned Opc,
97 assert(getAnalyzableBrOpc(Opc) && "Not an analyzable branch");
98 int NumOp = Inst->getNumExplicitOperands();
99
100 // for both int and fp branches, the last explicit operand is the
101 // MBB.
102 BB = Inst->getOperand(NumOp-1).getMBB();
103 Cond.push_back(MachineOperand::CreateImm(Opc));
104
105 for (int i = 0; i < NumOp-1; i++)
106 Cond.push_back(Inst->getOperand(i));
107}
108
111 MachineBasicBlock *&FBB,
113 bool AllowModify) const {
115 BranchType BT = analyzeBranch(MBB, TBB, FBB, Cond, AllowModify, BranchInstrs);
116
117 return (BT == BT_None) || (BT == BT_Indirect);
118}
119
120void MipsInstrInfo::BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
121 const DebugLoc &DL,
123 unsigned Opc = Cond[0].getImm();
124 const MCInstrDesc &MCID = get(Opc);
125 MachineInstrBuilder MIB = BuildMI(&MBB, DL, MCID);
126
127 for (unsigned i = 1; i < Cond.size(); ++i) {
128 assert((Cond[i].isImm() || Cond[i].isReg()) &&
129 "Cannot copy operand for conditional branch!");
130 MIB.add(Cond[i]);
131 }
132 MIB.addMBB(TBB);
133}
134
139 const DebugLoc &DL,
140 int *BytesAdded) const {
141 // Shouldn't be a fall through.
142 assert(TBB && "insertBranch must not be told to insert a fallthrough");
143 assert(!BytesAdded && "code size not handled");
144
145 // # of condition operands:
146 // Unconditional branches: 0
147 // Floating point branches: 1 (opc)
148 // Int BranchZero: 2 (opc, reg)
149 // Int Branch: 3 (opc, reg0, reg1)
150 assert((Cond.size() <= 3) &&
151 "# of Mips branch conditions must be <= 3!");
152
153 // Two-way Conditional branch.
154 if (FBB) {
155 BuildCondBr(MBB, TBB, DL, Cond);
157 return 2;
158 }
159
160 // One way branch.
161 // Unconditional branch.
162 if (Cond.empty())
164 else // Conditional branch.
165 BuildCondBr(MBB, TBB, DL, Cond);
166 return 1;
167}
168
170 int *BytesRemoved) const {
171 assert(!BytesRemoved && "code size not handled");
172
174 unsigned removed = 0;
175
176 // Up to 2 branches are removed.
177 // Note that indirect branches are not removed.
178 while (I != REnd && removed < 2) {
179 // Skip past debug instructions.
180 if (I->isDebugInstr()) {
181 ++I;
182 continue;
183 }
184 if (!getAnalyzableBrOpc(I->getOpcode()))
185 break;
186 // Remove the branch.
187 I->eraseFromParent();
188 I = MBB.rbegin();
189 ++removed;
190 }
191
192 return removed;
193}
194
195/// reverseBranchCondition - Return the inverse opcode of the
196/// specified Branch instruction.
199 assert( (Cond.size() && Cond.size() <= 3) &&
200 "Invalid Mips branch condition!");
201 Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm()));
202 return false;
203}
204
207 SmallVectorImpl<MachineOperand> &Cond, bool AllowModify,
208 SmallVectorImpl<MachineInstr *> &BranchInstrs) const {
210
211 // Skip all the debug instructions.
212 while (I != REnd && I->isDebugInstr())
213 ++I;
214
215 if (I == REnd || !isUnpredicatedTerminator(*I)) {
216 // This block ends with no branches (it just falls through to its succ).
217 // Leave TBB/FBB null.
218 TBB = FBB = nullptr;
219 return BT_NoBranch;
220 }
221
222 MachineInstr *LastInst = &*I;
223 unsigned LastOpc = LastInst->getOpcode();
224 BranchInstrs.push_back(LastInst);
225
226 // Not an analyzable branch (e.g., indirect jump).
227 if (!getAnalyzableBrOpc(LastOpc))
228 return LastInst->isIndirectBranch() ? BT_Indirect : BT_None;
229
230 // Get the second to last instruction in the block.
231 unsigned SecondLastOpc = 0;
232 MachineInstr *SecondLastInst = nullptr;
233
234 // Skip past any debug instruction to see if the second last actual
235 // is a branch.
236 ++I;
237 while (I != REnd && I->isDebugInstr())
238 ++I;
239
240 if (I != REnd) {
241 SecondLastInst = &*I;
242 SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->getOpcode());
243
244 // Not an analyzable branch (must be an indirect jump).
245 if (isUnpredicatedTerminator(*SecondLastInst) && !SecondLastOpc)
246 return BT_None;
247 }
248
249 // If there is only one terminator instruction, process it.
250 if (!SecondLastOpc) {
251 // Unconditional branch.
252 if (LastInst->isUnconditionalBranch()) {
253 TBB = LastInst->getOperand(0).getMBB();
254 return BT_Uncond;
255 }
256
257 // Conditional branch
258 AnalyzeCondBr(LastInst, LastOpc, TBB, Cond);
259 return BT_Cond;
260 }
261
262 // If we reached here, there are two branches.
263 // If there are three terminators, we don't know what sort of block this is.
264 if (++I != REnd && isUnpredicatedTerminator(*I))
265 return BT_None;
266
267 BranchInstrs.insert(BranchInstrs.begin(), SecondLastInst);
268
269 // If second to last instruction is an unconditional branch,
270 // analyze it and remove the last instruction.
271 if (SecondLastInst->isUnconditionalBranch()) {
272 // Return if the last instruction cannot be removed.
273 if (!AllowModify)
274 return BT_None;
275
276 TBB = SecondLastInst->getOperand(0).getMBB();
277 LastInst->eraseFromParent();
278 BranchInstrs.pop_back();
279 return BT_Uncond;
280 }
281
282 // Conditional branch followed by an unconditional branch.
283 // The last one must be unconditional.
284 if (!LastInst->isUnconditionalBranch())
285 return BT_None;
286
287 AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond);
288 FBB = LastInst->getOperand(0).getMBB();
289
290 return BT_CondUncond;
291}
292
294 int64_t BrOffset) const {
295 switch (BranchOpc) {
296 case Mips::B:
297 case Mips::BAL:
298 case Mips::BAL_BR:
299 case Mips::BAL_BR_MM:
300 case Mips::BC1F:
301 case Mips::BC1FL:
302 case Mips::BC1T:
303 case Mips::BC1TL:
304 case Mips::BEQ: case Mips::BEQ64:
305 case Mips::BEQL:
306 case Mips::BGEZ: case Mips::BGEZ64:
307 case Mips::BGEZL:
308 case Mips::BGEZAL:
309 case Mips::BGEZALL:
310 case Mips::BGTZ: case Mips::BGTZ64:
311 case Mips::BGTZL:
312 case Mips::BLEZ: case Mips::BLEZ64:
313 case Mips::BLEZL:
314 case Mips::BLTZ: case Mips::BLTZ64:
315 case Mips::BLTZL:
316 case Mips::BLTZAL:
317 case Mips::BLTZALL:
318 case Mips::BNE: case Mips::BNE64:
319 case Mips::BNEL:
320 return isInt<18>(BrOffset);
321
322 // microMIPSr3 branches
323 case Mips::B_MM:
324 case Mips::BC1F_MM:
325 case Mips::BC1T_MM:
326 case Mips::BEQ_MM:
327 case Mips::BGEZ_MM:
328 case Mips::BGEZAL_MM:
329 case Mips::BGTZ_MM:
330 case Mips::BLEZ_MM:
331 case Mips::BLTZ_MM:
332 case Mips::BLTZAL_MM:
333 case Mips::BNE_MM:
334 case Mips::BEQZC_MM:
335 case Mips::BNEZC_MM:
336 return isInt<17>(BrOffset);
337
338 // microMIPSR3 short branches.
339 case Mips::B16_MM:
340 return isInt<11>(BrOffset);
341
342 case Mips::BEQZ16_MM:
343 case Mips::BNEZ16_MM:
344 return isInt<8>(BrOffset);
345
346 // MIPSR6 branches.
347 case Mips::BALC:
348 case Mips::BC:
349 return isInt<28>(BrOffset);
350
351 case Mips::BC1EQZ:
352 case Mips::BC1NEZ:
353 case Mips::BC2EQZ:
354 case Mips::BC2NEZ:
355 case Mips::BEQC: case Mips::BEQC64:
356 case Mips::BNEC: case Mips::BNEC64:
357 case Mips::BGEC: case Mips::BGEC64:
358 case Mips::BGEUC: case Mips::BGEUC64:
359 case Mips::BGEZC: case Mips::BGEZC64:
360 case Mips::BGTZC: case Mips::BGTZC64:
361 case Mips::BLEZC: case Mips::BLEZC64:
362 case Mips::BLTC: case Mips::BLTC64:
363 case Mips::BLTUC: case Mips::BLTUC64:
364 case Mips::BLTZC: case Mips::BLTZC64:
365 case Mips::BNVC:
366 case Mips::BOVC:
367 case Mips::BGEZALC:
368 case Mips::BEQZALC:
369 case Mips::BGTZALC:
370 case Mips::BLEZALC:
371 case Mips::BLTZALC:
372 case Mips::BNEZALC:
373 return isInt<18>(BrOffset);
374
375 case Mips::BEQZC: case Mips::BEQZC64:
376 case Mips::BNEZC: case Mips::BNEZC64:
377 return isInt<23>(BrOffset);
378
379 // microMIPSR6 branches
380 case Mips::BC16_MMR6:
381 return isInt<11>(BrOffset);
382
383 case Mips::BEQZC16_MMR6:
384 case Mips::BNEZC16_MMR6:
385 return isInt<8>(BrOffset);
386
387 case Mips::BALC_MMR6:
388 case Mips::BC_MMR6:
389 return isInt<27>(BrOffset);
390
391 case Mips::BC1EQZC_MMR6:
392 case Mips::BC1NEZC_MMR6:
393 case Mips::BC2EQZC_MMR6:
394 case Mips::BC2NEZC_MMR6:
395 case Mips::BGEZALC_MMR6:
396 case Mips::BEQZALC_MMR6:
397 case Mips::BGTZALC_MMR6:
398 case Mips::BLEZALC_MMR6:
399 case Mips::BLTZALC_MMR6:
400 case Mips::BNEZALC_MMR6:
401 case Mips::BNVC_MMR6:
402 case Mips::BOVC_MMR6:
403 return isInt<17>(BrOffset);
404
405 case Mips::BEQC_MMR6:
406 case Mips::BNEC_MMR6:
407 case Mips::BGEC_MMR6:
408 case Mips::BGEUC_MMR6:
409 case Mips::BGEZC_MMR6:
410 case Mips::BGTZC_MMR6:
411 case Mips::BLEZC_MMR6:
412 case Mips::BLTC_MMR6:
413 case Mips::BLTUC_MMR6:
414 case Mips::BLTZC_MMR6:
415 return isInt<18>(BrOffset);
416
417 case Mips::BEQZC_MMR6:
418 case Mips::BNEZC_MMR6:
419 return isInt<23>(BrOffset);
420
421 // DSP branches.
422 case Mips::BPOSGE32:
423 return isInt<18>(BrOffset);
424 case Mips::BPOSGE32_MM:
425 case Mips::BPOSGE32C_MMR3:
426 return isInt<17>(BrOffset);
427
428 // cnMIPS branches.
429 case Mips::BBIT0:
430 case Mips::BBIT032:
431 case Mips::BBIT1:
432 case Mips::BBIT132:
433 return isInt<18>(BrOffset);
434
435 // MSA branches.
436 case Mips::BZ_B:
437 case Mips::BZ_H:
438 case Mips::BZ_W:
439 case Mips::BZ_D:
440 case Mips::BZ_V:
441 case Mips::BNZ_B:
442 case Mips::BNZ_H:
443 case Mips::BNZ_W:
444 case Mips::BNZ_D:
445 case Mips::BNZ_V:
446 return isInt<18>(BrOffset);
447 }
448
449 llvm_unreachable("Unknown branch instruction!");
450}
451
452/// Return the corresponding compact (no delay slot) form of a branch.
454 const MachineBasicBlock::iterator I) const {
455 unsigned Opcode = I->getOpcode();
456 bool canUseShortMicroMipsCTI = false;
457
459 switch (Opcode) {
460 case Mips::BNE:
461 case Mips::BNE_MM:
462 case Mips::BEQ:
463 case Mips::BEQ_MM:
464 // microMIPS has NE,EQ branches that do not have delay slots provided one
465 // of the operands is zero.
466 if (I->getOperand(1).getReg() == Subtarget.getABI().GetZeroReg())
467 canUseShortMicroMipsCTI = true;
468 break;
469 // For microMIPS the PseudoReturn and PseudoIndirectBranch are always
470 // expanded to JR_MM, so they can be replaced with JRC16_MM.
471 case Mips::JR:
472 case Mips::PseudoReturn:
473 case Mips::PseudoIndirectBranch:
474 canUseShortMicroMipsCTI = true;
475 break;
476 }
477 }
478
479 // MIPSR6 forbids both operands being the zero register.
480 if (Subtarget.hasMips32r6() && (I->getNumOperands() > 1) &&
481 (I->getOperand(0).isReg() &&
482 (I->getOperand(0).getReg() == Mips::ZERO ||
483 I->getOperand(0).getReg() == Mips::ZERO_64)) &&
484 (I->getOperand(1).isReg() &&
485 (I->getOperand(1).getReg() == Mips::ZERO ||
486 I->getOperand(1).getReg() == Mips::ZERO_64)))
487 return 0;
488
489 if (Subtarget.hasMips32r6() || canUseShortMicroMipsCTI) {
490 switch (Opcode) {
491 case Mips::B:
492 return Mips::BC;
493 case Mips::BAL:
494 return Mips::BALC;
495 case Mips::BEQ:
496 case Mips::BEQ_MM:
497 if (canUseShortMicroMipsCTI)
498 return Mips::BEQZC_MM;
499 else if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
500 return 0;
501 return Mips::BEQC;
502 case Mips::BNE:
503 case Mips::BNE_MM:
504 if (canUseShortMicroMipsCTI)
505 return Mips::BNEZC_MM;
506 else if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
507 return 0;
508 return Mips::BNEC;
509 case Mips::BGE:
510 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
511 return 0;
512 return Mips::BGEC;
513 case Mips::BGEU:
514 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
515 return 0;
516 return Mips::BGEUC;
517 case Mips::BGEZ:
518 return Mips::BGEZC;
519 case Mips::BGTZ:
520 return Mips::BGTZC;
521 case Mips::BLEZ:
522 return Mips::BLEZC;
523 case Mips::BLT:
524 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
525 return 0;
526 return Mips::BLTC;
527 case Mips::BLTU:
528 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
529 return 0;
530 return Mips::BLTUC;
531 case Mips::BLTZ:
532 return Mips::BLTZC;
533 case Mips::BEQ64:
534 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
535 return 0;
536 return Mips::BEQC64;
537 case Mips::BNE64:
538 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
539 return 0;
540 return Mips::BNEC64;
541 case Mips::BGTZ64:
542 return Mips::BGTZC64;
543 case Mips::BGEZ64:
544 return Mips::BGEZC64;
545 case Mips::BLTZ64:
546 return Mips::BLTZC64;
547 case Mips::BLEZ64:
548 return Mips::BLEZC64;
549 // For MIPSR6, the instruction 'jic' can be used for these cases. Some
550 // tools will accept 'jrc reg' as an alias for 'jic 0, $reg'.
551 case Mips::JR:
552 case Mips::PseudoIndirectBranchR6:
553 case Mips::PseudoReturn:
554 case Mips::TAILCALLR6REG:
555 if (canUseShortMicroMipsCTI)
556 return Mips::JRC16_MM;
557 return Mips::JIC;
558 case Mips::JALRPseudo:
559 return Mips::JIALC;
560 case Mips::JR64:
561 case Mips::PseudoIndirectBranch64R6:
562 case Mips::PseudoReturn64:
563 case Mips::TAILCALL64R6REG:
564 return Mips::JIC64;
565 case Mips::JALR64Pseudo:
566 return Mips::JIALC64;
567 default:
568 return 0;
569 }
570 }
571
572 return 0;
573}
574
576 if (IsDIVMULT(MI.getOpcode()))
577 return false;
578
579 return true;
580}
581
582/// Predicate for distingushing between control transfer instructions and all
583/// other instructions for handling forbidden slots. Consider inline assembly
584/// as unsafe as well.
586 if (MI.isInlineAsm())
587 return false;
588
589 return (MI.getDesc().TSFlags & MipsII::IsCTI) == 0;
590}
591
593 const MachineInstr &FPUMI) const {
594 if (MIInSlot.isInlineAsm())
595 return false;
596
597 if (HasFPUDelaySlot(MIInSlot))
598 return false;
599
600 switch (MIInSlot.getOpcode()) {
601 case Mips::BC1F:
602 case Mips::BC1FL:
603 case Mips::BC1T:
604 case Mips::BC1TL:
605 return false;
606 }
607
608 for (const MachineOperand &Op : FPUMI.defs()) {
609 if (!Op.isReg())
610 continue;
611
612 bool Reads, Writes;
613 std::tie(Reads, Writes) = MIInSlot.readsWritesVirtualRegister(Op.getReg());
614
615 if (Reads || Writes)
616 return false;
617 }
618
619 return true;
620}
621
622/// Predicate for distinguishing instructions that are hazardous in a load delay
623/// slot. Consider inline assembly as unsafe as well.
625 const MachineInstr &LoadMI) const {
626 if (MIInSlot.isInlineAsm())
627 return false;
628
629 return !llvm::any_of(LoadMI.defs(), [&](const MachineOperand &Op) {
630 return Op.isReg() && MIInSlot.readsRegister(Op.getReg(), /*TRI=*/nullptr);
631 });
632}
633
635 if (IsMFLOMFHI(MI.getOpcode()))
636 return true;
637
638 return false;
639}
640
641/// Predicate for distingushing instructions that have forbidden slots.
643 return (MI.getDesc().TSFlags & MipsII::HasForbiddenSlot) != 0;
644}
645
646/// Predicate for distingushing instructions that have FPU delay slots.
648 switch (MI.getOpcode()) {
649 case Mips::MTC1:
650 case Mips::MFC1:
651 case Mips::MTC1_D64:
652 case Mips::MFC1_D64:
653 case Mips::DMTC1:
654 case Mips::DMFC1:
655 case Mips::FCMP_S32:
656 case Mips::FCMP_D32:
657 case Mips::FCMP_D64:
658 return true;
659
660 default:
661 return false;
662 }
663}
664
665/// Predicate for distingushing instructions that have load delay slots.
667 switch (MI.getOpcode()) {
668 case Mips::LB:
669 case Mips::LBu:
670 case Mips::LH:
671 case Mips::LHu:
672 case Mips::LW:
673 case Mips::LWR:
674 case Mips::LWL:
675 return true;
676 default:
677 return false;
678 }
679}
680
681/// Return the number of bytes of code the specified instruction may be.
683 switch (MI.getOpcode()) {
684 default:
685 return MI.getDesc().getSize();
686 case TargetOpcode::INLINEASM:
687 case TargetOpcode::INLINEASM_BR: { // Inline Asm: Variable size.
688 const MachineFunction *MF = MI.getParent()->getParent();
689 const char *AsmStr = MI.getOperand(0).getSymbolName();
690 return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
691 }
692 case Mips::CONSTPOOL_ENTRY:
693 // If this machine instr is a constant pool entry, its size is recorded as
694 // operand #2.
695 return MI.getOperand(2).getImm();
696 }
697}
698
703
704 // Certain branches have two forms: e.g beq $1, $zero, dest vs beqz $1, dest
705 // Pick the zero form of the branch for readable assembly and for greater
706 // branch distance in non-microMIPS mode.
707 // Additional MIPSR6 does not permit the use of register $zero for compact
708 // branches.
709 // FIXME: Certain atomic sequences on mips64 generate 32bit references to
710 // Mips::ZERO, which is incorrect. This test should be updated to use
711 // Subtarget.getABI().GetZeroReg() when those atomic sequences and others
712 // are fixed.
713 int ZeroOperandPosition = -1;
714 bool BranchWithZeroOperand = false;
715 if (I->isBranch() && !I->isPseudo()) {
716 auto TRI = I->getParent()->getParent()->getSubtarget().getRegisterInfo();
717 ZeroOperandPosition = I->findRegisterUseOperandIdx(Mips::ZERO, TRI, false);
718 BranchWithZeroOperand = ZeroOperandPosition != -1;
719 }
720
721 if (BranchWithZeroOperand) {
722 switch (NewOpc) {
723 case Mips::BEQC:
724 NewOpc = Mips::BEQZC;
725 break;
726 case Mips::BNEC:
727 NewOpc = Mips::BNEZC;
728 break;
729 case Mips::BGEC:
730 NewOpc = Mips::BGEZC;
731 break;
732 case Mips::BLTC:
733 NewOpc = Mips::BLTZC;
734 break;
735 case Mips::BEQC64:
736 NewOpc = Mips::BEQZC64;
737 break;
738 case Mips::BNEC64:
739 NewOpc = Mips::BNEZC64;
740 break;
741 }
742 }
743
744 MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), get(NewOpc));
745
746 // For MIPSR6 JI*C requires an immediate 0 as an operand, JIALC(64) an
747 // immediate 0 as an operand and requires the removal of it's implicit-def %ra
748 // implicit operand as copying the implicit operations of the instructio we're
749 // looking at will give us the correct flags.
750 if (NewOpc == Mips::JIC || NewOpc == Mips::JIALC || NewOpc == Mips::JIC64 ||
751 NewOpc == Mips::JIALC64) {
752
753 if (NewOpc == Mips::JIALC || NewOpc == Mips::JIALC64)
754 MIB->removeOperand(0);
755
756 for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) {
757 MIB.add(I->getOperand(J));
758 }
759
760 MIB.addImm(0);
761
762 // If I has an MCSymbol operand (used by asm printer, to emit R_MIPS_JALR),
763 // add it to the new instruction.
764 for (unsigned J = I->getDesc().getNumOperands(), E = I->getNumOperands();
765 J < E; ++J) {
766 const MachineOperand &MO = I->getOperand(J);
767 if (MO.isMCSymbol() && (MO.getTargetFlags() & MipsII::MO_JALR))
769 }
770
771
772 } else {
773 for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) {
774 if (BranchWithZeroOperand && (unsigned)ZeroOperandPosition == J)
775 continue;
776
777 MIB.add(I->getOperand(J));
778 }
779 }
780
781 MIB.copyImplicitOps(*I);
782 MIB.cloneMemRefs(*I);
783 return MIB;
784}
785
787 unsigned &SrcOpIdx1,
788 unsigned &SrcOpIdx2) const {
789 assert(!MI.isBundle() &&
790 "TargetInstrInfo::findCommutedOpIndices() can't handle bundles");
791
792 const MCInstrDesc &MCID = MI.getDesc();
793 if (!MCID.isCommutable())
794 return false;
795
796 switch (MI.getOpcode()) {
797 case Mips::DPADD_U_H:
798 case Mips::DPADD_U_W:
799 case Mips::DPADD_U_D:
800 case Mips::DPADD_S_H:
801 case Mips::DPADD_S_W:
802 case Mips::DPADD_S_D:
803 // The first operand is both input and output, so it should not commute
804 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3))
805 return false;
806
807 if (!MI.getOperand(SrcOpIdx1).isReg() || !MI.getOperand(SrcOpIdx2).isReg())
808 return false;
809 return true;
810 }
811 return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);
812}
813
814// ins, ext, dext*, dins have the following constraints:
815// X <= pos < Y
816// X < size <= Y
817// X < pos+size <= Y
818//
819// dinsm and dinsu have the following constraints:
820// X <= pos < Y
821// X <= size <= Y
822// X < pos+size <= Y
823//
824// The callee of verifyInsExtInstruction however gives the bounds of
825// dins[um] like the other (d)ins (d)ext(um) instructions, so that this
826// function doesn't have to vary it's behaviour based on the instruction
827// being checked.
829 const int64_t PosLow, const int64_t PosHigh,
830 const int64_t SizeLow,
831 const int64_t SizeHigh,
832 const int64_t BothLow,
833 const int64_t BothHigh) {
834 MachineOperand MOPos = MI.getOperand(2);
835 if (!MOPos.isImm()) {
836 ErrInfo = "Position is not an immediate!";
837 return false;
838 }
839 int64_t Pos = MOPos.getImm();
840 if (!((PosLow <= Pos) && (Pos < PosHigh))) {
841 ErrInfo = "Position operand is out of range!";
842 return false;
843 }
844
845 MachineOperand MOSize = MI.getOperand(3);
846 if (!MOSize.isImm()) {
847 ErrInfo = "Size operand is not an immediate!";
848 return false;
849 }
850 int64_t Size = MOSize.getImm();
851 if (!((SizeLow < Size) && (Size <= SizeHigh))) {
852 ErrInfo = "Size operand is out of range!";
853 return false;
854 }
855
856 if (!((BothLow < (Pos + Size)) && ((Pos + Size) <= BothHigh))) {
857 ErrInfo = "Position + Size is out of range!";
858 return false;
859 }
860
861 return true;
862}
863
864// Perform target specific instruction verification.
866 StringRef &ErrInfo) const {
867 // Verify that ins and ext instructions are well formed.
868 switch (MI.getOpcode()) {
869 case Mips::EXT:
870 case Mips::EXT_MM:
871 case Mips::INS:
872 case Mips::INS_MM:
873 case Mips::DINS:
874 return verifyInsExtInstruction(MI, ErrInfo, 0, 32, 0, 32, 0, 32);
875 case Mips::DINSM:
876 // The ISA spec has a subtle difference between dinsm and dextm
877 // in that it says:
878 // 2 <= size <= 64 for 'dinsm' but 'dextm' has 32 < size <= 64.
879 // To make the bounds checks similar, the range 1 < size <= 64 is checked
880 // for 'dinsm'.
881 return verifyInsExtInstruction(MI, ErrInfo, 0, 32, 1, 64, 32, 64);
882 case Mips::DINSU:
883 // The ISA spec has a subtle difference between dinsu and dextu in that
884 // the size range of dinsu is specified as 1 <= size <= 32 whereas size
885 // for dextu is 0 < size <= 32. The range checked for dinsu here is
886 // 0 < size <= 32, which is equivalent and similar to dextu.
887 return verifyInsExtInstruction(MI, ErrInfo, 32, 64, 0, 32, 32, 64);
888 case Mips::DEXT:
889 return verifyInsExtInstruction(MI, ErrInfo, 0, 32, 0, 32, 0, 63);
890 case Mips::DEXTM:
891 return verifyInsExtInstruction(MI, ErrInfo, 0, 32, 32, 64, 32, 64);
892 case Mips::DEXTU:
893 return verifyInsExtInstruction(MI, ErrInfo, 32, 64, 0, 32, 32, 64);
894 case Mips::TAILCALLREG:
895 case Mips::PseudoIndirectBranch:
896 case Mips::JR:
897 case Mips::JR64:
898 case Mips::JALR:
899 case Mips::JALR64:
900 case Mips::JALRPseudo:
902 return true;
903
904 ErrInfo = "invalid instruction when using jump guards!";
905 return false;
906 default:
907 return true;
908 }
909
910 return true;
911}
912
913std::pair<unsigned, unsigned>
915 return std::make_pair(TF, 0u);
916}
917
920 using namespace MipsII;
921
922 static const std::pair<unsigned, const char*> Flags[] = {
923 {MO_GOT, "mips-got"},
924 {MO_GOT_CALL, "mips-got-call"},
925 {MO_GPREL, "mips-gprel"},
926 {MO_ABS_HI, "mips-abs-hi"},
927 {MO_ABS_LO, "mips-abs-lo"},
928 {MO_TLSGD, "mips-tlsgd"},
929 {MO_TLSLDM, "mips-tlsldm"},
930 {MO_DTPREL_HI, "mips-dtprel-hi"},
931 {MO_DTPREL_LO, "mips-dtprel-lo"},
932 {MO_GOTTPREL, "mips-gottprel"},
933 {MO_TPREL_HI, "mips-tprel-hi"},
934 {MO_TPREL_LO, "mips-tprel-lo"},
935 {MO_GPOFF_HI, "mips-gpoff-hi"},
936 {MO_GPOFF_LO, "mips-gpoff-lo"},
937 {MO_GOT_DISP, "mips-got-disp"},
938 {MO_GOT_PAGE, "mips-got-page"},
939 {MO_GOT_OFST, "mips-got-ofst"},
940 {MO_HIGHER, "mips-higher"},
941 {MO_HIGHEST, "mips-highest"},
942 {MO_GOT_HI16, "mips-got-hi16"},
943 {MO_GOT_LO16, "mips-got-lo16"},
944 {MO_CALL_HI16, "mips-call-hi16"},
945 {MO_CALL_LO16, "mips-call-lo16"},
946 {MO_JALR, "mips-jalr"}
947 };
948 return ArrayRef(Flags);
949}
950
951std::optional<ParamLoadedValue>
953 DIExpression *Expr =
954 DIExpression::get(MI.getMF()->getFunction().getContext(), {});
955
956 // TODO: Special MIPS instructions that need to be described separately.
957 if (auto RegImm = isAddImmediate(MI, Reg)) {
958 Register SrcReg = RegImm->Reg;
959 int64_t Offset = RegImm->Imm;
960 // When SrcReg is $zero, treat loaded value as immediate only.
961 // Ex. $a2 = ADDiu $zero, 10
962 if (SrcReg == Mips::ZERO || SrcReg == Mips::ZERO_64) {
963 return ParamLoadedValue(MI.getOperand(2), Expr);
964 }
966 return ParamLoadedValue(MachineOperand::CreateReg(SrcReg, false), Expr);
967 } else if (auto DestSrc = isCopyInstr(MI)) {
968 const MachineFunction *MF = MI.getMF();
970 Register DestReg = DestSrc->Destination->getReg();
971 // TODO: Handle cases where the Reg is sub- or super-register of the
972 // DestReg.
973 if (TRI->isSuperRegister(Reg, DestReg) || TRI->isSubRegister(Reg, DestReg))
974 return std::nullopt;
975 }
976
978}
979
980std::optional<RegImmPair> MipsInstrInfo::isAddImmediate(const MachineInstr &MI,
981 Register Reg) const {
982 // TODO: Handle cases where Reg is a super- or sub-register of the
983 // destination register.
984 const MachineOperand &Op0 = MI.getOperand(0);
985 if (!Op0.isReg() || Reg != Op0.getReg())
986 return std::nullopt;
987
988 switch (MI.getOpcode()) {
989 case Mips::ADDiu:
990 case Mips::DADDiu: {
991 const MachineOperand &Dop = MI.getOperand(0);
992 const MachineOperand &Sop1 = MI.getOperand(1);
993 const MachineOperand &Sop2 = MI.getOperand(2);
994 // Value is sum of register and immediate. Immediate value could be
995 // global string address which is not supported.
996 if (Dop.isReg() && Sop1.isReg() && Sop2.isImm())
997 return RegImmPair{Sop1.getReg(), Sop2.getImm()};
998 // TODO: Handle case where Sop1 is a frame-index.
999 }
1000 }
1001 return std::nullopt;
1002}
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
uint64_t Size
SmallVector< uint32_t, 0 > Writes
Definition: ELF_riscv.cpp:497
#define op(i)
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
static bool isReg(const MCInst &MI, unsigned OpNo)
static bool verifyInsExtInstruction(const MachineInstr &MI, StringRef &ErrInfo, const int64_t PosLow, const int64_t PosHigh, const int64_t SizeLow, const int64_t SizeHigh, const int64_t BothLow, const int64_t BothHigh)
#define IsMFLOMFHI(instr)
Definition: Mips.h:20
#define IsDIVMULT(instr)
Definition: Mips.h:23
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
DWARF expression.
static DIExpression * prepend(const DIExpression *Expr, uint8_t Flags, int64_t Offset=0)
Prepend DIExpr with a deref and offset operation and optionally turn it into a stack value or/and an ...
This class represents an Operation in the Expression.
A debug info location.
Definition: DebugLoc.h:33
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
bool isCommutable() const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z,...
Definition: MCInstrDesc.h:481
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1543
reverse_iterator rend()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
reverse_iterator rbegin()
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
Representation of each machine instruction.
Definition: MachineInstr.h:69
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:575
std::pair< bool, bool > readsWritesVirtualRegister(Register Reg, SmallVectorImpl< unsigned > *Ops=nullptr) const
Return a pair of bools (reads, writes) indicating if this instruction reads or writes Reg.
bool isInlineAsm() const
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool isUnconditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which always transfers control flow to some other block.
iterator_range< mop_iterator > defs()
Returns a range over all explicit operands that are register definitions.
Definition: MachineInstr.h:728
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
void removeOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:585
bool isIndirectBranch(QueryType Type=AnyInBundle) const
Return true if this is an indirect branch, such as a branch through a register.
Definition: MachineInstr.h:994
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
MachineOperand class - Representation of each machine instruction operand.
bool isMCSymbol() const
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
unsigned getTargetFlags() const
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
MCSymbol * getMCSymbol() const
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
unsigned GetZeroReg() const
Definition: MipsABIInfo.cpp:93
bool SafeAfterMflo(const MachineInstr &MI) const
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
bool SafeInForbiddenSlot(const MachineInstr &MI) const
Predicate to determine if an instruction can go in a forbidden slot.
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
Return the number of bytes of code the specified instruction may be.
MachineInstrBuilder insertNop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc DL) const
Insert an ISA appropriate nop.
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
Determine if the branch target is in range.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Branch Analysis.
const MipsSubtarget & Subtarget
Definition: MipsInstrInfo.h:45
MipsInstrInfo(const MipsSubtarget &STI, unsigned UncondBrOpc)
MachineMemOperand * GetMemOperand(MachineBasicBlock &MBB, int FI, MachineMemOperand::Flags Flags) const
MachineInstrBuilder genInstrWithNewOpc(unsigned NewOpc, MachineBasicBlock::iterator I) const
Create an instruction which has the same operands and memory operands as MI but has a new opcode.
bool HasForbiddenSlot(const MachineInstr &MI) const
Predicate to determine if an instruction has a forbidden slot.
bool SafeInFPUDelaySlot(const MachineInstr &MIInSlot, const MachineInstr &FPUMI) const
Predicate to determine if an instruction can go in an FPU delay slot.
bool isZeroImm(const MachineOperand &op) const
unsigned getEquivalentCompactForm(const MachineBasicBlock::iterator I) const
Determine the opcode of a non-delay slot form for a branch if one exists.
bool SafeInLoadDelaySlot(const MachineInstr &MIInSlot, const MachineInstr &LoadMI) const
Predicate to determine if an instruction can go in a load delay slot.
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
reverseBranchCondition - Return the inverse opcode of the specified Branch instruction.
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
std::optional< RegImmPair > isAddImmediate(const MachineInstr &MI, Register Reg) const override
bool HasFPUDelaySlot(const MachineInstr &MI) const
Predicate to determine if an instruction has an FPU delay slot.
bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override
Perform target specific instruction verification.
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
static const MipsInstrInfo * create(MipsSubtarget &STI)
bool IsMfloOrMfhi(const MachineInstr &MI) const
bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
std::optional< ParamLoadedValue > describeLoadedValue(const MachineInstr &MI, Register Reg) const override
virtual unsigned getOppositeBranchOpc(unsigned Opc) const =0
bool HasLoadDelaySlot(const MachineInstr &MI) const
Predicate to determine if an instruction has a load delay slot.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
Insert nop instruction when hazard condition is found.
bool hasMips32r6() const
bool inMicroMipsMode() const
bool useIndirectJumpsHazard() const
bool inMips16Mode() const
const MipsABIInfo & getABI() const
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:805
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
virtual bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const
Returns true iff the routine could find two commutable operands in the given machine instruction.
virtual std::optional< ParamLoadedValue > describeLoadedValue(const MachineInstr &MI, Register Reg) const
Produce the expression describing the MI loading a value into the physical register Reg.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ IsCTI
IsCTI - Instruction is a Control Transfer Instruction.
Definition: MipsBaseInfo.h:124
@ HasForbiddenSlot
HasForbiddenSlot - Instruction has a forbidden slot.
Definition: MipsBaseInfo.h:126
@ MO_JALR
Helper operand used to generate R_MIPS_JALR.
Definition: MipsBaseInfo.h:95
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
std::pair< MachineOperand, DIExpression * > ParamLoadedValue
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const MipsInstrInfo * createMipsSEInstrInfo(const MipsSubtarget &STI)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1746
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
const MipsInstrInfo * createMips16InstrInfo(const MipsSubtarget &STI)
Create MipsInstrInfo objects.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Used to describe a register and immediate addition.