diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index c74d1c3fd86..82c924253ec 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -165,16 +165,7 @@ public: /// \brief Returns true if a certain instruction is deprecated and if so /// returns the reason in \p Info. bool getDeprecatedInfo(MCInst &MI, MCSubtargetInfo &STI, - std::string &Info) const { - if (ComplexDeprecationInfo) - return ComplexDeprecationInfo(MI, STI, Info); - if ((DeprecatedFeatureMask & STI.getFeatureBits()) != 0) { - // FIXME: it would be nice to include the subtarget feature here. - Info = "deprecated"; - return true; - } - return false; - } + std::string &Info) const; /// \brief Return the opcode number for this descriptor. unsigned getOpcode() const { return Opcode; } @@ -257,25 +248,7 @@ public: /// \brief Return true if this is a branch or an instruction which directly /// writes to the program counter. Considered 'may' affect rather than /// 'does' affect as things like predication are not taken into account. - bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const { - if (isBranch() || isCall() || isReturn() || isIndirectBranch()) - return true; - unsigned PC = RI.getProgramCounter(); - if (PC == 0) - return false; - if (hasDefOfPhysReg(MI, PC, RI)) - return true; - // A variadic instruction may define PC in the variable operand list. - // There's currently no indication of which entries in a variable - // list are defs and which are uses. While that's the case, this function - // needs to assume they're defs in order to be conservatively correct. - for (int i = NumOperands, e = MI.getNumOperands(); i != e; ++i) { - if (MI.getOperand(i).isReg() && - RI.isSubRegisterEq(PC, MI.getOperand(i).getReg())) - return true; - } - return false; - } + bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const; /// \brief Return true if this instruction has a predicate operand /// that controls execution. It may be set to 'always', or may be set to other @@ -532,24 +505,7 @@ public: /// \brief Return true if this instruction implicitly /// defines the specified physical register. bool hasImplicitDefOfPhysReg(unsigned Reg, - const MCRegisterInfo *MRI = nullptr) const { - if (const uint16_t *ImpDefs = ImplicitDefs) - for (; *ImpDefs; ++ImpDefs) - if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs))) - return true; - return false; - } - - /// \brief Return true if this instruction defines the specified physical - /// register, either explicitly or implicitly. - bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg, - const MCRegisterInfo &RI) const { - for (int i = 0, e = NumDefs; i != e; ++i) - if (MI.getOperand(i).isReg() && - RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg())) - return true; - return hasImplicitDefOfPhysReg(Reg, &RI); - } + const MCRegisterInfo *MRI = nullptr) const; /// \brief Return the scheduling class for this instruction. The /// scheduling class is an index into the InstrItineraryData table. This @@ -572,6 +528,13 @@ public: } return -1; } + +private: + + /// \brief Return true if this instruction defines the specified physical + /// register, either explicitly or implicitly. + bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg, + const MCRegisterInfo &RI) const; }; } // end namespace llvm diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt index ddddd49d90e..3cee0c43494 100644 --- a/lib/MC/CMakeLists.txt +++ b/lib/MC/CMakeLists.txt @@ -19,6 +19,7 @@ add_llvm_library(LLVMMC MCInst.cpp MCInstPrinter.cpp MCInstrAnalysis.cpp + MCInstrDesc.cpp MCLabel.cpp MCLinkerOptimizationHint.cpp MCMachOStreamer.cpp diff --git a/lib/MC/MCInstrDesc.cpp b/lib/MC/MCInstrDesc.cpp new file mode 100644 index 00000000000..95e8325b9db --- /dev/null +++ b/lib/MC/MCInstrDesc.cpp @@ -0,0 +1,68 @@ +//===------ llvm/MC/MCInstrDesc.cpp- Instruction Descriptors --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines methods on the MCOperandInfo and MCInstrDesc classes, which +// are used to describe target instructions and their operands. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCInst.h" + +using namespace llvm; + +bool MCInstrDesc::getDeprecatedInfo(MCInst &MI, MCSubtargetInfo &STI, + std::string &Info) const { + if (ComplexDeprecationInfo) + return ComplexDeprecationInfo(MI, STI, Info); + if ((DeprecatedFeatureMask & STI.getFeatureBits()) != 0) { + // FIXME: it would be nice to include the subtarget feature here. + Info = "deprecated"; + return true; + } + return false; +} +bool MCInstrDesc::mayAffectControlFlow(const MCInst &MI, + const MCRegisterInfo &RI) const { + if (isBranch() || isCall() || isReturn() || isIndirectBranch()) + return true; + unsigned PC = RI.getProgramCounter(); + if (PC == 0) + return false; + if (hasDefOfPhysReg(MI, PC, RI)) + return true; + // A variadic instruction may define PC in the variable operand list. + // There's currently no indication of which entries in a variable + // list are defs and which are uses. While that's the case, this function + // needs to assume they're defs in order to be conservatively correct. + for (int i = NumOperands, e = MI.getNumOperands(); i != e; ++i) { + if (MI.getOperand(i).isReg() && + RI.isSubRegisterEq(PC, MI.getOperand(i).getReg())) + return true; + } + return false; +} + +bool MCInstrDesc::hasImplicitDefOfPhysReg(unsigned Reg, + const MCRegisterInfo *MRI) const { + if (const uint16_t *ImpDefs = ImplicitDefs) + for (; *ImpDefs; ++ImpDefs) + if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs))) + return true; + return false; +} + +bool MCInstrDesc::hasDefOfPhysReg(const MCInst &MI, unsigned Reg, + const MCRegisterInfo &RI) const { + for (int i = 0, e = NumDefs; i != e; ++i) + if (MI.getOperand(i).isReg() && + RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg())) + return true; + return hasImplicitDefOfPhysReg(Reg, &RI); +}