34 #define GET_INSTRINFO_CTOR_DTOR 35 #include "MipsGenInstrInfo.inc" 38 void MipsInstrInfo::anchor() {}
62 BuildMI(MBB, MI, DL,
get(Mips::NOP));
80 void MipsInstrInfo::AnalyzeCondBr(
const MachineInstr *Inst,
unsigned Opc,
83 assert(getAnalyzableBrOpc(Opc) &&
"Not an analyzable branch");
91 for (
int i = 0; i < NumOp-1; i++)
99 bool AllowModify)
const {
109 unsigned Opc = Cond[0].getImm();
113 for (
unsigned i = 1; i < Cond.
size(); ++i) {
115 "Cannot copy operand for conditional branch!");
126 int *BytesAdded)
const {
128 assert(TBB &&
"insertBranch must not be told to insert a fallthrough");
129 assert(!BytesAdded &&
"code size not handled");
137 "# of Mips branch conditions must be <= 3!");
141 BuildCondBr(MBB, TBB, DL, Cond);
151 BuildCondBr(MBB, TBB, DL, Cond);
156 int *BytesRemoved)
const {
157 assert(!BytesRemoved &&
"code size not handled");
160 unsigned removed = 0;
164 while (I != REnd && removed < 2) {
166 if (I->isDebugInstr()) {
170 if (!getAnalyzableBrOpc(I->getOpcode()))
173 I->eraseFromParent();
186 "Invalid Mips branch condition!");
198 while (I != REnd && I->isDebugInstr())
201 if (I == REnd || !isUnpredicatedTerminator(*I)) {
209 unsigned LastOpc = LastInst->
getOpcode();
213 if (!getAnalyzableBrOpc(LastOpc))
217 unsigned SecondLastOpc = 0;
223 while (I != REnd && I->isDebugInstr())
227 SecondLastInst = &*
I;
228 SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->
getOpcode());
231 if (isUnpredicatedTerminator(*SecondLastInst) && !SecondLastOpc)
236 if (!SecondLastOpc) {
244 AnalyzeCondBr(LastInst, LastOpc, TBB, Cond);
250 if (++I != REnd && isUnpredicatedTerminator(*I))
253 BranchInstrs.
insert(BranchInstrs.
begin(), SecondLastInst);
273 AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond);
284 case Mips::BAL_BR_MM:
289 case Mips::BEQ:
case Mips::BEQ64:
291 case Mips::BGEZ:
case Mips::BGEZ64:
295 case Mips::BGTZ:
case Mips::BGTZ64:
297 case Mips::BLEZ:
case Mips::BLEZ64:
299 case Mips::BLTZ:
case Mips::BLTZ64:
303 case Mips::BNE:
case Mips::BNE64:
305 return isInt<18>(BrOffset);
313 case Mips::BGEZAL_MM:
317 case Mips::BLTZAL_MM:
321 return isInt<17>(BrOffset);
325 return isInt<11>(BrOffset);
327 case Mips::BEQZ16_MM:
328 case Mips::BNEZ16_MM:
334 return isInt<28>(BrOffset);
340 case Mips::BEQC:
case Mips::BEQC64:
341 case Mips::BNEC:
case Mips::BNEC64:
342 case Mips::BGEC:
case Mips::BGEC64:
343 case Mips::BGEUC:
case Mips::BGEUC64:
344 case Mips::BGEZC:
case Mips::BGEZC64:
345 case Mips::BGTZC:
case Mips::BGTZC64:
346 case Mips::BLEZC:
case Mips::BLEZC64:
347 case Mips::BLTC:
case Mips::BLTC64:
348 case Mips::BLTUC:
case Mips::BLTUC64:
349 case Mips::BLTZC:
case Mips::BLTZC64:
358 return isInt<18>(BrOffset);
360 case Mips::BEQZC:
case Mips::BEQZC64:
361 case Mips::BNEZC:
case Mips::BNEZC64:
362 return isInt<23>(BrOffset);
365 case Mips::BC16_MMR6:
366 return isInt<11>(BrOffset);
368 case Mips::BEQZC16_MMR6:
369 case Mips::BNEZC16_MMR6:
372 case Mips::BALC_MMR6:
374 return isInt<27>(BrOffset);
376 case Mips::BC1EQZC_MMR6:
377 case Mips::BC1NEZC_MMR6:
378 case Mips::BC2EQZC_MMR6:
379 case Mips::BC2NEZC_MMR6:
380 case Mips::BGEZALC_MMR6:
381 case Mips::BEQZALC_MMR6:
382 case Mips::BGTZALC_MMR6:
383 case Mips::BLEZALC_MMR6:
384 case Mips::BLTZALC_MMR6:
385 case Mips::BNEZALC_MMR6:
386 case Mips::BNVC_MMR6:
387 case Mips::BOVC_MMR6:
388 return isInt<17>(BrOffset);
390 case Mips::BEQC_MMR6:
391 case Mips::BNEC_MMR6:
392 case Mips::BGEC_MMR6:
393 case Mips::BGEUC_MMR6:
394 case Mips::BGEZC_MMR6:
395 case Mips::BGTZC_MMR6:
396 case Mips::BLEZC_MMR6:
397 case Mips::BLTC_MMR6:
398 case Mips::BLTUC_MMR6:
399 case Mips::BLTZC_MMR6:
400 return isInt<18>(BrOffset);
402 case Mips::BEQZC_MMR6:
403 case Mips::BNEZC_MMR6:
404 return isInt<23>(BrOffset);
408 return isInt<18>(BrOffset);
409 case Mips::BPOSGE32_MM:
410 case Mips::BPOSGE32C_MMR3:
411 return isInt<17>(BrOffset);
418 return isInt<18>(BrOffset);
431 return isInt<18>(BrOffset);
441 unsigned Opcode = I->getOpcode();
442 bool canUseShortMicroMipsCTI =
false;
453 canUseShortMicroMipsCTI =
true;
458 case Mips::PseudoReturn:
459 case Mips::PseudoIndirectBranch:
460 canUseShortMicroMipsCTI =
true;
467 (I->getOperand(0).isReg() &&
468 (I->getOperand(0).getReg() == Mips::ZERO ||
469 I->getOperand(0).getReg() == Mips::ZERO_64)) &&
470 (I->getOperand(1).isReg() &&
471 (I->getOperand(1).getReg() == Mips::ZERO ||
472 I->getOperand(1).getReg() == Mips::ZERO_64)))
483 if (canUseShortMicroMipsCTI)
484 return Mips::BEQZC_MM;
485 else if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
490 if (canUseShortMicroMipsCTI)
491 return Mips::BNEZC_MM;
492 else if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
496 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
500 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
510 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
514 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
520 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
524 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
528 return Mips::BGTZC64;
530 return Mips::BGEZC64;
532 return Mips::BLTZC64;
534 return Mips::BLEZC64;
538 case Mips::PseudoIndirectBranchR6:
539 case Mips::PseudoReturn:
540 case Mips::TAILCALLR6REG:
541 if (canUseShortMicroMipsCTI)
542 return Mips::JRC16_MM;
544 case Mips::JALRPseudo:
547 case Mips::PseudoIndirectBranch64R6:
548 case Mips::PseudoReturn64:
549 case Mips::TAILCALL64R6REG:
551 case Mips::JALR64Pseudo:
552 return Mips::JIALC64;
586 case Mips::CONSTPOOL_ENTRY:
607 int ZeroOperandPosition = -1;
608 bool BranchWithZeroOperand =
false;
609 if (I->isBranch() && !I->isPseudo()) {
610 auto TRI = I->getParent()->getParent()->getSubtarget().getRegisterInfo();
611 ZeroOperandPosition = I->findRegisterUseOperandIdx(Mips::ZERO,
false,
TRI);
612 BranchWithZeroOperand = ZeroOperandPosition != -1;
615 if (BranchWithZeroOperand) {
618 NewOpc = Mips::BEQZC;
621 NewOpc = Mips::BNEZC;
624 NewOpc = Mips::BGEZC;
627 NewOpc = Mips::BLTZC;
630 NewOpc = Mips::BEQZC64;
633 NewOpc = Mips::BNEZC64;
638 MIB =
BuildMI(*I->getParent(),
I, I->getDebugLoc(),
get(NewOpc));
644 if (NewOpc == Mips::JIC || NewOpc == Mips::JIALC || NewOpc == Mips::JIC64 ||
645 NewOpc == Mips::JIALC64) {
647 if (NewOpc == Mips::JIALC || NewOpc == Mips::JIALC64)
650 for (
unsigned J = 0,
E = I->getDesc().getNumOperands(); J <
E; ++J) {
651 MIB.
add(I->getOperand(J));
658 for (
unsigned J = I->getDesc().getNumOperands(), E = I->getNumOperands();
667 for (
unsigned J = 0,
E = I->getDesc().getNumOperands(); J <
E; ++J) {
668 if (BranchWithZeroOperand && (
unsigned)ZeroOperandPosition == J)
671 MIB.
add(I->getOperand(J));
681 unsigned &SrcOpIdx2)
const {
683 "TargetInstrInfo::findCommutedOpIndices() can't handle bundles");
686 if (!MCID.isCommutable())
690 case Mips::DPADD_U_H:
691 case Mips::DPADD_U_W:
692 case Mips::DPADD_U_D:
693 case Mips::DPADD_S_H:
694 case Mips::DPADD_S_W:
695 case Mips::DPADD_S_D:
697 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3))
722 const int64_t PosLow,
const int64_t PosHigh,
723 const int64_t SizeLow,
724 const int64_t SizeHigh,
725 const int64_t BothLow,
726 const int64_t BothHigh) {
728 if (!MOPos.
isImm()) {
729 ErrInfo =
"Position is not an immediate!";
732 int64_t Pos = MOPos.
getImm();
733 if (!((PosLow <= Pos) && (Pos < PosHigh))) {
734 ErrInfo =
"Position operand is out of range!";
739 if (!MOSize.
isImm()) {
740 ErrInfo =
"Size operand is not an immediate!";
744 if (!((SizeLow < Size) && (Size <= SizeHigh))) {
745 ErrInfo =
"Size operand is out of range!";
749 if (!((BothLow < (Pos + Size)) && ((Pos + Size) <= BothHigh))) {
750 ErrInfo =
"Position + Size is out of range!";
787 case Mips::TAILCALLREG:
788 case Mips::PseudoIndirectBranch:
793 case Mips::JALRPseudo:
797 ErrInfo =
"invalid instruction when using jump guards!";
806 std::pair<unsigned, unsigned>
808 return std::make_pair(TF, 0u);
813 using namespace MipsII;
815 static const std::pair<unsigned, const char*> Flags[] = {
static bool isReg(const MCInst &MI, unsigned OpNo)
unsigned getTargetFlags() const
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
Return the number of bytes of code the specified instruction may be.
const MachineInstrBuilder & add(const MachineOperand &MO) const
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
Determine if the branch target is in range.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
MachineBasicBlock * getMBB() const
This class represents lattice values for constants.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Branch Analysis.
MO_TLSLDM - Represents the offset into the global offset table at which.
bool inMips16Mode() const
MO_HIGHER/HIGHEST - Represents the highest or higher half word of a 64-bit symbol address...
MO_GOT_HI16/LO16, MO_CALL_HI16/LO16 - Relocations used for large GOTs.
void push_back(const T &Elt)
MO_TLSGD - Represents the offset into the global offset table at which.
Describe properties that are true of each instruction in the target description file.
constexpr bool isInt< 8 >(int64_t x)
bool SafeInForbiddenSlot(const MachineInstr &MI) const
Predicate to determine if an instruction can go in a forbidden slot.
MachineMemOperand * GetMemOperand(MachineBasicBlock &MBB, int FI, MachineMemOperand::Flags Flags) const
unsigned const TargetRegisterInfo * TRI
virtual unsigned getOppositeBranchOpc(unsigned Opc) const =0
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
reverseBranchCondition - Return the inverse opcode of the specified Branch instruction.
bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override
Perform target specific instruction verification.
bool HasForbiddenSlot(const MachineInstr &MI) const
Predicate to determine if an instruction has a forbidden slot.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
Insert nop instruction when hazard condition is found.
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)
A description of a memory reference used in the backend.
MipsInstrInfo(const MipsSubtarget &STI, unsigned UncondBrOpc)
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
bool inMicroMipsMode() const
bool useIndirectJumpsHazard() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MipsSubtarget & Subtarget
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const char * getSymbolName() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned 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.
INLINEASM - Represents an inline asm block.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
bool isIndirectBranch(QueryType Type=AnyInBundle) const
Return true if this is an indirect branch, such as a branch through a register.
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
reverse_iterator rbegin()
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
MO_GOT_CALL - Represents the offset into the global offset table at which the address of a call site ...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const MipsInstrInfo * createMips16InstrInfo(const MipsSubtarget &STI)
Create MipsInstrInfo objects.
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...
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
unsigned getEquivalentCompactForm(const MachineBasicBlock::iterator I) const
Determine the opcode of a non-delay slot form for a branch if one exists.
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
bool isZeroImm(const MachineOperand &op) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MipsABIInfo & getABI() const
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
MO_GOTTPREL - Represents the offset from the thread pointer (Initial.
bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
HasForbiddenSlot - Instruction has a forbidden slot.
IsCTI - Instruction is a Control Transfer Instruction.
virtual bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const
Returns true iff the routine could find two commutable operands in the given machine instruction...
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
bool isUnconditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which always transfers control flow to some other block...
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
iterator insert(iterator I, T &&Elt)
Flags
Flags values. These may be or'd together.
MO_TPREL_HI/LO - Represents the hi and low part of the offset from.
const MachineBasicBlock * getParent() const
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
static MachineOperand CreateImm(int64_t Val)
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MipsInstrInfo * createMipsSEInstrInfo(const MipsSubtarget &STI)
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
unsigned GetZeroReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCSymbol * getMCSymbol() const
StringRef - Represent a constant reference to a string, i.e.
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineOperand & getOperand(unsigned i) const
static const MipsInstrInfo * create(MipsSubtarget &STI)
bool empty() const
empty - Check if the array is empty.
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
Helper operand used to generate R_MIPS_JALR.