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