26 #define GET_INSTRINFO_CTOR_DTOR
27 #include "MipsGenInstrInfo.inc"
30 void MipsInstrInfo::anchor() {}
34 Subtarget(STI), UncondBrOpc(UncondBr) {}
54 BuildMI(MBB, MI, DL,
get(Mips::NOP));
72 void MipsInstrInfo::AnalyzeCondBr(
const MachineInstr *Inst,
unsigned Opc,
75 assert(getAnalyzableBrOpc(Opc) &&
"Not an analyzable branch");
83 for (
int i=0;
i<NumOp-1;
i++)
91 bool AllowModify)
const {
101 unsigned Opc = Cond[0].getImm();
105 for (
unsigned i = 1;
i < Cond.
size(); ++
i) {
108 else if (Cond[
i].isImm())
111 assert(
false &&
"Cannot copy operand");
121 int *BytesAdded)
const {
123 assert(TBB &&
"insertBranch must not be told to insert a fallthrough");
124 assert(!BytesAdded &&
"code size not handled");
132 "# of Mips branch conditions must be <= 3!");
136 BuildCondBr(MBB, TBB, DL, Cond);
146 BuildCondBr(MBB, TBB, DL, Cond);
151 int *BytesRemoved)
const {
152 assert(!BytesRemoved &&
"code size not handled");
158 while (I != REnd && I->isDebugValue())
168 for (removed = 0; I != REnd && removed < 2; ++
I, ++removed)
169 if (!getAnalyzableBrOpc(I->getOpcode()))
172 MBB.
erase((--I).getReverse(), FirstBr);
182 "Invalid Mips branch condition!");
195 while (I != REnd && I->isDebugValue())
198 if (I == REnd || !isUnpredicatedTerminator(*I)) {
206 unsigned LastOpc = LastInst->
getOpcode();
210 if (!getAnalyzableBrOpc(LastOpc))
214 unsigned SecondLastOpc = 0;
218 SecondLastInst = &*
I;
219 SecondLastOpc = getAnalyzableBrOpc(SecondLastInst->
getOpcode());
222 if (isUnpredicatedTerminator(*SecondLastInst) && !SecondLastOpc)
227 if (!SecondLastOpc) {
235 AnalyzeCondBr(LastInst, LastOpc, TBB, Cond);
241 if (++I != REnd && isUnpredicatedTerminator(*I))
244 BranchInstrs.
insert(BranchInstrs.
begin(), SecondLastInst);
264 AnalyzeCondBr(SecondLastInst, SecondLastOpc, TBB, Cond);
273 unsigned Opcode = I->getOpcode();
274 bool canUseShortMicroMipsCTI =
false;
285 canUseShortMicroMipsCTI =
true;
290 case Mips::PseudoReturn:
291 case Mips::PseudoIndirectBranch:
292 case Mips::TAILCALLREG:
293 canUseShortMicroMipsCTI =
true;
300 (I->getOperand(0).isReg() &&
301 (I->getOperand(0).getReg() == Mips::ZERO ||
302 I->getOperand(0).getReg() == Mips::ZERO_64)) &&
303 (I->getOperand(1).isReg() &&
304 (I->getOperand(1).getReg() == Mips::ZERO ||
305 I->getOperand(1).getReg() == Mips::ZERO_64)))
316 if (canUseShortMicroMipsCTI)
317 return Mips::BEQZC_MM;
318 else if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
323 if (canUseShortMicroMipsCTI)
324 return Mips::BNEZC_MM;
325 else if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
329 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
333 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
343 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
347 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
353 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
357 if (I->getOperand(0).getReg() == I->getOperand(1).getReg())
361 return Mips::BGTZC64;
363 return Mips::BGEZC64;
365 return Mips::BLTZC64;
367 return Mips::BLEZC64;
371 case Mips::PseudoReturn:
372 case Mips::PseudoIndirectBranch:
373 case Mips::TAILCALLREG:
374 if (canUseShortMicroMipsCTI)
375 return Mips::JRC16_MM;
377 case Mips::JALRPseudo:
380 case Mips::PseudoReturn64:
381 case Mips::PseudoIndirectBranch64:
382 case Mips::TAILCALLREG64:
384 case Mips::JALR64Pseudo:
385 return Mips::JIALC64;
420 case Mips::CONSTPOOL_ENTRY:
441 int ZeroOperandPosition = -1;
442 bool BranchWithZeroOperand =
false;
443 if (I->isBranch() && !I->isPseudo()) {
444 auto TRI = I->getParent()->getParent()->getSubtarget().getRegisterInfo();
445 ZeroOperandPosition = I->findRegisterUseOperandIdx(Mips::ZERO,
false, TRI);
446 BranchWithZeroOperand = ZeroOperandPosition != -1;
449 if (BranchWithZeroOperand) {
452 NewOpc = Mips::BEQZC;
455 NewOpc = Mips::BNEZC;
458 NewOpc = Mips::BGEZC;
461 NewOpc = Mips::BLTZC;
464 NewOpc = Mips::BEQZC64;
467 NewOpc = Mips::BNEZC64;
472 MIB =
BuildMI(*I->getParent(),
I, I->getDebugLoc(),
get(NewOpc));
478 if (NewOpc == Mips::JIC || NewOpc == Mips::JIALC || NewOpc == Mips::JIC64 ||
479 NewOpc == Mips::JIALC64) {
481 if (NewOpc == Mips::JIALC || NewOpc == Mips::JIALC64)
484 for (
unsigned J = 0,
E = I->getDesc().getNumOperands(); J <
E; ++J) {
491 for (
unsigned J = 0,
E = I->getDesc().getNumOperands(); J <
E; ++J) {
492 if (BranchWithZeroOperand && (
unsigned)ZeroOperandPosition == J)
501 MIB.
setMemRefs(I->memoperands_begin(), I->memoperands_end());
static bool isReg(const MCInst &MI, unsigned OpNo)
bool isZeroImm(const MachineOperand &op) const
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
Return the number of bytes of code the specified instruction may be.
void push_back(const T &Elt)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
bool HasForbiddenSlot(const MachineInstr &MI) const
Predicate to determine if an instruction has a forbidden slot.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
const MipsABIInfo & getABI() const
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Branch Analysis.
MachineBasicBlock * getMBB() const
Describe properties that are true of each instruction in the target description file.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
const char * getSymbolName() const
virtual unsigned getOppositeBranchOpc(unsigned Opc) const =0
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
reverseBranchCondition - Return the inverse opcode of the specified Branch instruction.
void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
Insert nop instruction when hazard condition is found.
A description of a memory reference used in the backend.
MipsInstrInfo(const MipsSubtarget &STI, unsigned UncondBrOpc)
struct fuzzer::@269 Flags
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
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...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
INLINEASM - Represents an inline asm block.
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
size_t size() const
size - Get the array size.
reverse_iterator rbegin()
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const MachineInstrBuilder & setMemRefs(MachineInstr::mmo_iterator b, MachineInstr::mmo_iterator e) const
const MipsInstrInfo * createMips16InstrInfo(const MipsSubtarget &STI)
Create MipsInstrInfo objects.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
const MachineOperand & getOperand(unsigned i) const
HasForbiddenSlot - Instruction has a forbidden slot.
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
bool isIndirectBranch(QueryType Type=AnyInBundle) const
Return true if this is an indirect branch, such as a branch through a register.
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool SafeInForbiddenSlot(const MachineInstr &MI) const
Predicate to determine if an instruction can go in a forbidden slot.
bool empty() const
empty - Check if the array is empty.
bool inMicroMipsMode() const
bool inMips16Mode() const
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
unsigned getEquivalentCompactForm(const MachineBasicBlock::iterator I) const
Determine the opcode of a non-delay slot form for a branch if one exists.
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...
MachineMemOperand * GetMemOperand(MachineBasicBlock &MBB, int FI, MachineMemOperand::Flags Flags) const
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SynchronizationScope SynchScope=CrossThread, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
iterator insert(iterator I, T &&Elt)
Flags
Flags values. These may be or'd together.
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.
unsigned GetZeroReg() const
static MachineOperand CreateImm(int64_t Val)
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
const MipsInstrInfo * createMipsSEInstrInfo(const MipsSubtarget &STI)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IsCTI - Instruction is a Control Transfer Instruction.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
static const MipsInstrInfo * create(MipsSubtarget &STI)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
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...
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool isUnconditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which always transfers control flow to some other block...