diff options
Diffstat (limited to 'include/llvm/MC/MCInstrDesc.h')
-rw-r--r-- | include/llvm/MC/MCInstrDesc.h | 521 |
1 files changed, 211 insertions, 310 deletions
diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index 360989305d3af..de3a1959e05c9 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -15,142 +15,142 @@ #ifndef LLVM_MC_MCINSTRDESC_H #define LLVM_MC_MCINSTRDESC_H -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCRegisterInfo.h" -#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/DataTypes.h" +#include <string> namespace llvm { + class MCInst; + class MCRegisterInfo; + class MCSubtargetInfo; + class FeatureBitset; //===----------------------------------------------------------------------===// // Machine Operand Flags and Description //===----------------------------------------------------------------------===// namespace MCOI { - // Operand constraints - enum OperandConstraint { - TIED_TO = 0, // Must be allocated the same register as. - EARLY_CLOBBER // Operand is an early clobber register operand - }; - - /// OperandFlags - These are flags set on operands, but should be considered - /// private, all access should go through the MCOperandInfo accessors. - /// See the accessors for a description of what these are. - enum OperandFlags { - LookupPtrRegClass = 0, - Predicate, - OptionalDef - }; - - /// Operand Type - Operands are tagged with one of the values of this enum. - enum OperandType { - OPERAND_UNKNOWN = 0, - OPERAND_IMMEDIATE = 1, - OPERAND_REGISTER = 2, - OPERAND_MEMORY = 3, - OPERAND_PCREL = 4, - OPERAND_FIRST_TARGET = 5 - }; +// Operand constraints +enum OperandConstraint { + TIED_TO = 0, // Must be allocated the same register as. + EARLY_CLOBBER // Operand is an early clobber register operand +}; + +/// \brief These are flags set on operands, but should be considered +/// private, all access should go through the MCOperandInfo accessors. +/// See the accessors for a description of what these are. +enum OperandFlags { LookupPtrRegClass = 0, Predicate, OptionalDef }; + +/// \brief Operands are tagged with one of the values of this enum. +enum OperandType { + OPERAND_UNKNOWN = 0, + OPERAND_IMMEDIATE = 1, + OPERAND_REGISTER = 2, + OPERAND_MEMORY = 3, + OPERAND_PCREL = 4, + OPERAND_FIRST_TARGET = 5 +}; } -/// MCOperandInfo - This holds information about one operand of a machine -/// instruction, indicating the register class for register operands, etc. -/// +/// \brief This holds information about one operand of a machine instruction, +/// indicating the register class for register operands, etc. class MCOperandInfo { public: - /// RegClass - This specifies the register class enumeration of the operand + /// \brief This specifies the register class enumeration of the operand /// if the operand is a register. If isLookupPtrRegClass is set, then this is /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to /// get a dynamic register class. int16_t RegClass; - /// Flags - These are flags from the MCOI::OperandFlags enum. + /// \brief These are flags from the MCOI::OperandFlags enum. uint8_t Flags; - /// OperandType - Information about the type of the operand. + /// \brief Information about the type of the operand. uint8_t OperandType; - - /// Lower 16 bits are used to specify which constraints are set. The higher 16 - /// bits are used to specify the value of constraints (4 bits each). + /// \brief The lower 16 bits are used to specify which constraints are set. + /// The higher 16 bits are used to specify the value of constraints (4 bits + /// each). uint32_t Constraints; - /// Currently no other information. - /// isLookupPtrRegClass - Set if this operand is a pointer value and it - /// requires a callback to look up its register class. - bool isLookupPtrRegClass() const {return Flags&(1 <<MCOI::LookupPtrRegClass);} + /// \brief Set if this operand is a pointer value and it requires a callback + /// to look up its register class. + bool isLookupPtrRegClass() const { + return Flags & (1 << MCOI::LookupPtrRegClass); + } - /// isPredicate - Set if this is one of the operands that made up of - /// the predicate operand that controls an isPredicable() instruction. + /// \brief Set if this is one of the operands that made up of the predicate + /// operand that controls an isPredicable() instruction. bool isPredicate() const { return Flags & (1 << MCOI::Predicate); } - /// isOptionalDef - Set if this operand is a optional def. - /// + /// \brief Set if this operand is a optional def. bool isOptionalDef() const { return Flags & (1 << MCOI::OptionalDef); } }; - //===----------------------------------------------------------------------===// // Machine Instruction Flags and Description //===----------------------------------------------------------------------===// -/// MCInstrDesc flags - These should be considered private to the -/// implementation of the MCInstrDesc class. Clients should use the predicate -/// methods on MCInstrDesc, not use these directly. These all correspond to -/// bitfields in the MCInstrDesc::Flags field. namespace MCID { - enum { - Variadic = 0, - HasOptionalDef, - Pseudo, - Return, - Call, - Barrier, - Terminator, - Branch, - IndirectBranch, - Compare, - MoveImm, - Bitcast, - Select, - DelaySlot, - FoldableAsLoad, - MayLoad, - MayStore, - Predicable, - NotDuplicable, - UnmodeledSideEffects, - Commutable, - ConvertibleTo3Addr, - UsesCustomInserter, - HasPostISelHook, - Rematerializable, - CheapAsAMove, - ExtraSrcRegAllocReq, - ExtraDefRegAllocReq, - RegSequence, - ExtractSubreg, - InsertSubreg - }; +/// \brief These should be considered private to the implementation of the +/// MCInstrDesc class. Clients should use the predicate methods on MCInstrDesc, +/// not use these directly. These all correspond to bitfields in the +/// MCInstrDesc::Flags field. +enum Flag { + Variadic = 0, + HasOptionalDef, + Pseudo, + Return, + Call, + Barrier, + Terminator, + Branch, + IndirectBranch, + Compare, + MoveImm, + Bitcast, + Select, + DelaySlot, + FoldableAsLoad, + MayLoad, + MayStore, + Predicable, + NotDuplicable, + UnmodeledSideEffects, + Commutable, + ConvertibleTo3Addr, + UsesCustomInserter, + HasPostISelHook, + Rematerializable, + CheapAsAMove, + ExtraSrcRegAllocReq, + ExtraDefRegAllocReq, + RegSequence, + ExtractSubreg, + InsertSubreg +}; } -/// MCInstrDesc - Describe properties that are true of each instruction in the -/// target description file. This captures information about side effects, -/// register use and many other things. There is one instance of this struct -/// for each target instruction class, and the MachineInstr class points to -/// this struct directly to describe itself. +/// \brief Describe properties that are true of each instruction in the target +/// description file. This captures information about side effects, register +/// use and many other things. There is one instance of this struct for each +/// target instruction class, and the MachineInstr class points to this struct +/// directly to describe itself. class MCInstrDesc { public: - unsigned short Opcode; // The opcode number - unsigned short NumOperands; // Num of args (may be more if variable_ops) - unsigned short NumDefs; // Num of args that are definitions - unsigned short SchedClass; // enum identifying instr sched class - unsigned short Size; // Number of bytes in encoding. - unsigned Flags; // Flags identifying machine instr class - uint64_t TSFlags; // Target Specific Flag values - const uint16_t *ImplicitUses; // Registers implicitly read by this instr - const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr - const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands - uint64_t DeprecatedFeatureMask;// Feature bits that this is deprecated on, if any + unsigned short Opcode; // The opcode number + unsigned short NumOperands; // Num of args (may be more if variable_ops) + unsigned short NumDefs; // Num of args that are definitions + unsigned short SchedClass; // enum identifying instr sched class + unsigned short Size; // Number of bytes in encoding. + unsigned Flags; // Flags identifying machine instr class + uint64_t TSFlags; // Target Specific Flag values + const uint16_t *ImplicitUses; // Registers implicitly read by this instr + const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr + const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands + // Subtarget feature that this is deprecated on, if any + // -1 implies this is not deprecated by any single feature. It may still be + // deprecated due to a "complex" reason, below. + int64_t DeprecatedFeature; + // A complex method to determine is a certain is deprecated or not, and return // the reason for deprecation. bool (*ComplexDeprecationInfo)(MCInst &, MCSubtargetInfo &, std::string &); @@ -170,38 +170,23 @@ 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; - } + unsigned getOpcode() const { return Opcode; } /// \brief Return the number of declared MachineOperands for this /// MachineInstruction. Note that variadic (isVariadic() returns true) /// instructions may have additional operands at the end of the list, and note /// that the machine instruction may include implicit register def/uses as /// well. - unsigned getNumOperands() const { - return NumOperands; - } + unsigned getNumOperands() const { return NumOperands; } /// \brief Return the number of MachineOperands that are register /// definitions. Register definitions always occur at the start of the /// machine operand list. This is the number of "outs" in the .td file, /// and does not include implicit defs. - unsigned getNumDefs() const { - return NumDefs; - } + unsigned getNumDefs() const { return NumDefs; } /// \brief Return flags of this instruction. unsigned getFlags() const { return Flags; } @@ -210,39 +195,26 @@ public: /// operands. In this case, the variable operands will be after the normal /// operands but before the implicit definitions and uses (if any are /// present). - bool isVariadic() const { - return Flags & (1 << MCID::Variadic); - } + bool isVariadic() const { return Flags & (1 << MCID::Variadic); } /// \brief Set if this instruction has an optional definition, e.g. /// ARM instructions which can set condition code if 's' bit is set. - bool hasOptionalDef() const { - return Flags & (1 << MCID::HasOptionalDef); - } + bool hasOptionalDef() const { return Flags & (1 << MCID::HasOptionalDef); } /// \brief Return true if this is a pseudo instruction that doesn't /// correspond to a real machine instruction. - /// - bool isPseudo() const { - return Flags & (1 << MCID::Pseudo); - } + bool isPseudo() const { return Flags & (1 << MCID::Pseudo); } /// \brief Return true if the instruction is a return. - bool isReturn() const { - return Flags & (1 << MCID::Return); - } + bool isReturn() const { return Flags & (1 << MCID::Return); } /// \brief Return true if the instruction is a call. - bool isCall() const { - return Flags & (1 << MCID::Call); - } + bool isCall() const { return Flags & (1 << MCID::Call); } /// \brief Returns true if the specified instruction stops control flow /// from executing the instruction immediately following it. Examples include /// unconditional branches and return instructions. - bool isBarrier() const { - return Flags & (1 << MCID::Barrier); - } + bool isBarrier() const { return Flags & (1 << MCID::Barrier); } /// \brief Returns true if this instruction part of the terminator for /// a basic block. Typically this is things like return and branch @@ -250,23 +222,17 @@ public: /// /// Various passes use this to insert code into the bottom of a basic block, /// but before control flow occurs. - bool isTerminator() const { - return Flags & (1 << MCID::Terminator); - } + bool isTerminator() const { return Flags & (1 << MCID::Terminator); } /// \brief Returns true if this is a conditional, unconditional, or /// indirect branch. Predicates below can be used to discriminate between /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to /// get more information. - bool isBranch() const { - return Flags & (1 << MCID::Branch); - } + bool isBranch() const { return Flags & (1 << MCID::Branch); } /// \brief Return true if this is an indirect branch, such as a /// branch through a register. - bool isIndirectBranch() const { - return Flags & (1 << MCID::IndirectBranch); - } + bool isIndirectBranch() const { return Flags & (1 << MCID::IndirectBranch); } /// \brief Return true if this is a branch which may fall /// through to the next instruction or may transfer control flow to some other @@ -287,79 +253,44 @@ 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 /// values. There are various methods in TargetInstrInfo that can be used to /// control and modify the predicate in this instruction. - bool isPredicable() const { - return Flags & (1 << MCID::Predicable); - } + bool isPredicable() const { return Flags & (1 << MCID::Predicable); } /// \brief Return true if this instruction is a comparison. - bool isCompare() const { - return Flags & (1 << MCID::Compare); - } + bool isCompare() const { return Flags & (1 << MCID::Compare); } /// \brief Return true if this instruction is a move immediate /// (including conditional moves) instruction. - bool isMoveImmediate() const { - return Flags & (1 << MCID::MoveImm); - } + bool isMoveImmediate() const { return Flags & (1 << MCID::MoveImm); } /// \brief Return true if this instruction is a bitcast instruction. - bool isBitcast() const { - return Flags & (1 << MCID::Bitcast); - } + bool isBitcast() const { return Flags & (1 << MCID::Bitcast); } /// \brief Return true if this is a select instruction. - bool isSelect() const { - return Flags & (1 << MCID::Select); - } + bool isSelect() const { return Flags & (1 << MCID::Select); } /// \brief Return true if this instruction cannot be safely /// duplicated. For example, if the instruction has a unique labels attached /// to it, duplicating it would cause multiple definition errors. - bool isNotDuplicable() const { - return Flags & (1 << MCID::NotDuplicable); - } + bool isNotDuplicable() const { return Flags & (1 << MCID::NotDuplicable); } - /// hasDelaySlot - Returns true if the specified instruction has a delay slot - /// which must be filled by the code generator. - bool hasDelaySlot() const { - return Flags & (1 << MCID::DelaySlot); - } + /// \brief Returns true if the specified instruction has a delay slot which + /// must be filled by the code generator. + bool hasDelaySlot() const { return Flags & (1 << MCID::DelaySlot); } - /// canFoldAsLoad - Return true for instructions that can be folded as - /// memory operands in other instructions. The most common use for this - /// is instructions that are simple loads from memory that don't modify - /// the loaded value in any way, but it can also be used for instructions - /// that can be expressed as constant-pool loads, such as V_SETALLONES - /// on x86, to allow them to be folded when it is beneficial. - /// This should only be set on instructions that return a value in their - /// only virtual register definition. - bool canFoldAsLoad() const { - return Flags & (1 << MCID::FoldableAsLoad); - } + /// \brief Return true for instructions that can be folded as memory operands + /// in other instructions. The most common use for this is instructions that + /// are simple loads from memory that don't modify the loaded value in any + /// way, but it can also be used for instructions that can be expressed as + /// constant-pool loads, such as V_SETALLONES on x86, to allow them to be + /// folded when it is beneficial. This should only be set on instructions + /// that return a value in their only virtual register definition. + bool canFoldAsLoad() const { return Flags & (1 << MCID::FoldableAsLoad); } /// \brief Return true if this instruction behaves /// the same way as the generic REG_SEQUENCE instructions. @@ -398,9 +329,7 @@ public: /// Note that for the optimizers to be able to take advantage of /// this property, TargetInstrInfo::getInsertSubregLikeInputs has to be /// override accordingly. - bool isInsertSubregLike() const { - return Flags & (1 << MCID::InsertSubreg); - } + bool isInsertSubregLike() const { return Flags & (1 << MCID::InsertSubreg); } //===--------------------------------------------------------------------===// // Side Effect Analysis @@ -409,20 +338,15 @@ public: /// \brief Return true if this instruction could possibly read memory. /// Instructions with this flag set are not necessarily simple load /// instructions, they may load a value and modify it, for example. - bool mayLoad() const { - return Flags & (1 << MCID::MayLoad); - } - + bool mayLoad() const { return Flags & (1 << MCID::MayLoad); } /// \brief Return true if this instruction could possibly modify memory. /// Instructions with this flag set are not necessarily simple store /// instructions, they may store a modified value based on their operands, or /// may not actually modify anything, for example. - bool mayStore() const { - return Flags & (1 << MCID::MayStore); - } + bool mayStore() const { return Flags & (1 << MCID::MayStore); } - /// hasUnmodeledSideEffects - Return true if this instruction has side + /// \brief Return true if this instruction has side /// effects that are not modeled by other flags. This does not return true /// for instructions whose effects are captured by: /// @@ -434,7 +358,6 @@ public: /// Examples of side effects would be modifying 'invisible' machine state like /// a control register, flushing a cache, modifying a register invisible to /// LLVM, etc. - /// bool hasUnmodeledSideEffects() const { return Flags & (1 << MCID::UnmodeledSideEffects); } @@ -443,9 +366,9 @@ public: // Flags that indicate whether an instruction can be modified by a method. //===--------------------------------------------------------------------===// - /// isCommutable - Return true if this may be a 2- or 3-address - /// instruction (of the form "X = op Y, Z, ..."), which produces the same - /// result if Y and Z are exchanged. If this flag is set, then the + /// \brief Return true if this may be a 2- or 3-address instruction (of the + /// form "X = op Y, Z, ..."), which produces the same result if Y and Z are + /// exchanged. If this flag is set, then the /// TargetInstrInfo::commuteInstruction method may be used to hack on the /// instruction. /// @@ -453,18 +376,16 @@ public: /// sometimes. In these cases, the call to commuteInstruction will fail. /// Also note that some instructions require non-trivial modification to /// commute them. - bool isCommutable() const { - return Flags & (1 << MCID::Commutable); - } - - /// isConvertibleTo3Addr - Return true if this is a 2-address instruction - /// which can be changed into a 3-address instruction if needed. Doing this - /// transformation can be profitable in the register allocator, because it - /// means that the instruction can use a 2-address form if possible, but - /// degrade into a less efficient form if the source and dest register cannot - /// be assigned to the same register. For example, this allows the x86 - /// backend to turn a "shl reg, 3" instruction into an LEA instruction, which - /// is the same speed as the shift but has bigger code size. + bool isCommutable() const { return Flags & (1 << MCID::Commutable); } + + /// \brief Return true if this is a 2-address instruction which can be changed + /// into a 3-address instruction if needed. Doing this transformation can be + /// profitable in the register allocator, because it means that the + /// instruction can use a 2-address form if possible, but degrade into a less + /// efficient form if the source and dest register cannot be assigned to the + /// same register. For example, this allows the x86 backend to turn a "shl + /// reg, 3" instruction into an LEA instruction, which is the same speed as + /// the shift but has bigger code size. /// /// If this returns true, then the target must implement the /// TargetInstrInfo::convertToThreeAddress method for this instruction, which @@ -475,11 +396,11 @@ public: return Flags & (1 << MCID::ConvertibleTo3Addr); } - /// usesCustomInsertionHook - Return true if this instruction requires - /// custom insertion support when the DAG scheduler is inserting it into a - /// machine basic block. If this is true for the instruction, it basically - /// means that it is a pseudo instruction used at SelectionDAG time that is - /// expanded out into magic code by the target when MachineInstrs are formed. + /// \brief Return true if this instruction requires custom insertion support + /// when the DAG scheduler is inserting it into a machine basic block. If + /// this is true for the instruction, it basically means that it is a pseudo + /// instruction used at SelectionDAG time that is expanded out into magic code + /// by the target when MachineInstrs are formed. /// /// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method /// is used to insert this into the MachineBasicBlock. @@ -487,17 +408,14 @@ public: return Flags & (1 << MCID::UsesCustomInserter); } - /// hasPostISelHook - Return true if this instruction requires *adjustment* - /// after instruction selection by calling a target hook. For example, this - /// can be used to fill in ARM 's' optional operand depending on whether - /// the conditional flag register is used. - bool hasPostISelHook() const { - return Flags & (1 << MCID::HasPostISelHook); - } + /// \brief Return true if this instruction requires *adjustment* after + /// instruction selection by calling a target hook. For example, this can be + /// used to fill in ARM 's' optional operand depending on whether the + /// conditional flag register is used. + bool hasPostISelHook() const { return Flags & (1 << MCID::HasPostISelHook); } - /// isRematerializable - Returns true if this instruction is a candidate for - /// remat. This flag is only used in TargetInstrInfo method - /// isTriviallyRematerializable. + /// \brief Returns true if this instruction is a candidate for remat. This + /// flag is only used in TargetInstrInfo method isTriviallyRematerializable. /// /// If this flag is set, the isReallyTriviallyReMaterializable() /// or isReallyTriviallyReMaterializableGeneric methods are called to verify @@ -506,80 +424,76 @@ public: return Flags & (1 << MCID::Rematerializable); } - /// isAsCheapAsAMove - Returns true if this instruction has the same cost (or - /// less) than a move instruction. This is useful during certain types of - /// optimizations (e.g., remat during two-address conversion or machine licm) - /// where we would like to remat or hoist the instruction, but not if it costs - /// more than moving the instruction into the appropriate register. Note, we - /// are not marking copies from and to the same register class with this flag. + /// \brief Returns true if this instruction has the same cost (or less) than a + /// move instruction. This is useful during certain types of optimizations + /// (e.g., remat during two-address conversion or machine licm) where we would + /// like to remat or hoist the instruction, but not if it costs more than + /// moving the instruction into the appropriate register. Note, we are not + /// marking copies from and to the same register class with this flag. /// /// This method could be called by interface TargetInstrInfo::isAsCheapAsAMove /// for different subtargets. - bool isAsCheapAsAMove() const { - return Flags & (1 << MCID::CheapAsAMove); - } - - /// hasExtraSrcRegAllocReq - Returns true if this instruction source operands - /// have special register allocation requirements that are not captured by the - /// operand register classes. e.g. ARM::STRD's two source registers must be an - /// even / odd pair, ARM::STM registers have to be in ascending order. - /// Post-register allocation passes should not attempt to change allocations - /// for sources of instructions with this flag. + bool isAsCheapAsAMove() const { return Flags & (1 << MCID::CheapAsAMove); } + + /// \brief Returns true if this instruction source operands have special + /// register allocation requirements that are not captured by the operand + /// register classes. e.g. ARM::STRD's two source registers must be an even / + /// odd pair, ARM::STM registers have to be in ascending order. Post-register + /// allocation passes should not attempt to change allocations for sources of + /// instructions with this flag. bool hasExtraSrcRegAllocReq() const { return Flags & (1 << MCID::ExtraSrcRegAllocReq); } - /// hasExtraDefRegAllocReq - Returns true if this instruction def operands - /// have special register allocation requirements that are not captured by the - /// operand register classes. e.g. ARM::LDRD's two def registers must be an - /// even / odd pair, ARM::LDM registers have to be in ascending order. - /// Post-register allocation passes should not attempt to change allocations - /// for definitions of instructions with this flag. + /// \brief Returns true if this instruction def operands have special register + /// allocation requirements that are not captured by the operand register + /// classes. e.g. ARM::LDRD's two def registers must be an even / odd pair, + /// ARM::LDM registers have to be in ascending order. Post-register + /// allocation passes should not attempt to change allocations for definitions + /// of instructions with this flag. bool hasExtraDefRegAllocReq() const { return Flags & (1 << MCID::ExtraDefRegAllocReq); } - - /// getImplicitUses - Return a list of registers that are potentially - /// read by any instance of this machine instruction. For example, on X86, - /// the "adc" instruction adds two register operands and adds the carry bit in - /// from the flags register. In this case, the instruction is marked as - /// implicitly reading the flags. Likewise, the variable shift instruction on - /// X86 is marked as implicitly reading the 'CL' register, which it always - /// does. + /// \brief Return a list of registers that are potentially read by any + /// instance of this machine instruction. For example, on X86, the "adc" + /// instruction adds two register operands and adds the carry bit in from the + /// flags register. In this case, the instruction is marked as implicitly + /// reading the flags. Likewise, the variable shift instruction on X86 is + /// marked as implicitly reading the 'CL' register, which it always does. /// /// This method returns null if the instruction has no implicit uses. - const uint16_t *getImplicitUses() const { - return ImplicitUses; - } + const uint16_t *getImplicitUses() const { return ImplicitUses; } /// \brief Return the number of implicit uses this instruction has. unsigned getNumImplicitUses() const { - if (!ImplicitUses) return 0; + if (!ImplicitUses) + return 0; unsigned i = 0; - for (; ImplicitUses[i]; ++i) /*empty*/; + for (; ImplicitUses[i]; ++i) /*empty*/ + ; return i; } - /// getImplicitDefs - Return a list of registers that are potentially - /// written by any instance of this machine instruction. For example, on X86, - /// many instructions implicitly set the flags register. In this case, they - /// are marked as setting the FLAGS. Likewise, many instructions always - /// deposit their result in a physical register. For example, the X86 divide + /// \brief Return a list of registers that are potentially written by any + /// instance of this machine instruction. For example, on X86, many + /// instructions implicitly set the flags register. In this case, they are + /// marked as setting the FLAGS. Likewise, many instructions always deposit + /// their result in a physical register. For example, the X86 divide /// instruction always deposits the quotient and remainder in the EAX/EDX /// registers. For that instruction, this will return a list containing the /// EAX/EDX/EFLAGS registers. /// /// This method returns null if the instruction has no implicit defs. - const uint16_t *getImplicitDefs() const { - return ImplicitDefs; - } + const uint16_t *getImplicitDefs() const { return ImplicitDefs; } /// \brief Return the number of implicit defs this instruct has. unsigned getNumImplicitDefs() const { - if (!ImplicitDefs) return 0; + if (!ImplicitDefs) + return 0; unsigned i = 0; - for (; ImplicitDefs[i]; ++i) /*empty*/; + for (; ImplicitDefs[i]; ++i) /*empty*/ + ; return i; } @@ -588,45 +502,25 @@ public: bool hasImplicitUseOfPhysReg(unsigned Reg) const { if (const uint16_t *ImpUses = ImplicitUses) for (; *ImpUses; ++ImpUses) - if (*ImpUses == Reg) return true; + if (*ImpUses == Reg) + return true; return false; } /// \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 /// returns zero if there is no known scheduling information for the /// instruction. - unsigned getSchedClass() const { - return SchedClass; - } + unsigned getSchedClass() const { return SchedClass; } /// \brief Return the number of bytes in the encoding of this instruction, /// or zero if the encoding size cannot be known from the opcode. - unsigned getSize() const { - return Size; - } + unsigned getSize() const { return Size; } /// \brief Find the index of the first operand in the /// operand list that is used to represent the predicate. It returns -1 if @@ -639,6 +533,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 |