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