return get(Opcode).Flags & M_TERMINATOR_FLAG;
}
+ //
+ // Return true if the instruction is a register to register move and
+ // leave the source and dest operands in the passed parameters.
+ //
+ virtual bool isMoveInstr(const MachineInstr& MI,
+ unsigned& sourceReg,
+ unsigned& destReg) const {
+ return false;
+ }
+
// Check if an instruction can be issued before its operands are ready,
// or if a subsequent instruction that uses its result can be issued
// before the results are ready.
return false;
}
+bool X86InstrInfo::isMoveInstr(const MachineInstr& MI,
+ unsigned& sourceReg,
+ unsigned& destReg) const {
+ MachineOpCode oc = MI.getOpcode();
+ if (oc == X86::MOVrr8 || oc == X86::MOVrr16 || oc == X86::MOVrr32) {
+ assert(MI.getNumOperands() == 2 &&
+ MI.getOperand(0).isRegister() &&
+ MI.getOperand(1).isRegister() &&
+ "invalid register-register move instruction");
+ sourceReg = MI.getOperand(1).getAllocatedRegNum();
+ destReg = MI.getOperand(0).getAllocatedRegNum();
+ return true;
+ }
+ return false;
+}
///
MachineInstr* createNOPinstr() const;
+ //
+ // Return true if the instruction is a register to register move and
+ // leave the source and dest operands in the passed parameters.
+ //
+ virtual bool isMoveInstr(const MachineInstr& MI,
+ unsigned& sourceReg,
+ unsigned& destReg) const;
+
/// isNOPinstr - not having a special NOP opcode, we need to know if a given
/// instruction is interpreted as an `official' NOP instr, i.e., there may be
/// more than one way to `do nothing' but only one canonical way to slack off.