- //===- llvm/MC/MCInst.h - MCInst class --------------------------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- // This file contains the declaration of the MCInst and MCOperand classes, which 
- // is the basic representation used to represent low-level machine code 
- // instructions. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_MC_MCINST_H 
- #define LLVM_MC_MCINST_H 
-   
- #include "llvm/ADT/SmallVector.h" 
- #include "llvm/ADT/StringRef.h" 
- #include "llvm/ADT/bit.h" 
- #include "llvm/Support/SMLoc.h" 
- #include <cassert> 
- #include <cstddef> 
- #include <cstdint> 
-   
- namespace llvm { 
-   
- class MCExpr; 
- class MCInst; 
- class MCInstPrinter; 
- class MCRegisterInfo; 
- class raw_ostream; 
-   
- /// Instances of this class represent operands of the MCInst class. 
- /// This is a simple discriminated union. 
- class MCOperand { 
-   enum MachineOperandType : unsigned char { 
-     kInvalid,      ///< Uninitialized. 
-     kRegister,     ///< Register operand. 
-     kImmediate,    ///< Immediate operand. 
-     kSFPImmediate, ///< Single-floating-point immediate operand. 
-     kDFPImmediate, ///< Double-Floating-point immediate operand. 
-     kExpr,         ///< Relocatable immediate operand. 
-     kInst          ///< Sub-instruction operand. 
-   }; 
-   MachineOperandType Kind = kInvalid; 
-   
-   union { 
-     unsigned RegVal; 
-     int64_t ImmVal; 
-     uint32_t SFPImmVal; 
-     uint64_t FPImmVal; 
-     const MCExpr *ExprVal; 
-     const MCInst *InstVal; 
-   }; 
-   
- public: 
-   MCOperand() : FPImmVal(0) {} 
-   
-   bool isValid() const { return Kind != kInvalid; } 
-   bool isReg() const { return Kind == kRegister; } 
-   bool isImm() const { return Kind == kImmediate; } 
-   bool isSFPImm() const { return Kind == kSFPImmediate; } 
-   bool isDFPImm() const { return Kind == kDFPImmediate; } 
-   bool isExpr() const { return Kind == kExpr; } 
-   bool isInst() const { return Kind == kInst; } 
-   
-   /// Returns the register number. 
-   unsigned getReg() const { 
-     assert(isReg() && "This is not a register operand!"); 
-     return RegVal; 
-   } 
-   
-   /// Set the register number. 
-   void setReg(unsigned Reg) { 
-     assert(isReg() && "This is not a register operand!"); 
-     RegVal = Reg; 
-   } 
-   
-   int64_t getImm() const { 
-     assert(isImm() && "This is not an immediate"); 
-     return ImmVal; 
-   } 
-   
-   void setImm(int64_t Val) { 
-     assert(isImm() && "This is not an immediate"); 
-     ImmVal = Val; 
-   } 
-   
-   uint32_t getSFPImm() const { 
-     assert(isSFPImm() && "This is not an SFP immediate"); 
-     return SFPImmVal; 
-   } 
-   
-   void setSFPImm(uint32_t Val) { 
-     assert(isSFPImm() && "This is not an SFP immediate"); 
-     SFPImmVal = Val; 
-   } 
-   
-   uint64_t getDFPImm() const { 
-     assert(isDFPImm() && "This is not an FP immediate"); 
-     return FPImmVal; 
-   } 
-   
-   void setDFPImm(uint64_t Val) { 
-     assert(isDFPImm() && "This is not an FP immediate"); 
-     FPImmVal = Val; 
-   } 
-   void setFPImm(double Val) { 
-     assert(isDFPImm() && "This is not an FP immediate"); 
-     FPImmVal = bit_cast<uint64_t>(Val); 
-   } 
-   
-   const MCExpr *getExpr() const { 
-     assert(isExpr() && "This is not an expression"); 
-     return ExprVal; 
-   } 
-   
-   void setExpr(const MCExpr *Val) { 
-     assert(isExpr() && "This is not an expression"); 
-     ExprVal = Val; 
-   } 
-   
-   const MCInst *getInst() const { 
-     assert(isInst() && "This is not a sub-instruction"); 
-     return InstVal; 
-   } 
-   
-   void setInst(const MCInst *Val) { 
-     assert(isInst() && "This is not a sub-instruction"); 
-     InstVal = Val; 
-   } 
-   
-   static MCOperand createReg(unsigned Reg) { 
-     MCOperand Op; 
-     Op.Kind = kRegister; 
-     Op.RegVal = Reg; 
-     return Op; 
-   } 
-   
-   static MCOperand createImm(int64_t Val) { 
-     MCOperand Op; 
-     Op.Kind = kImmediate; 
-     Op.ImmVal = Val; 
-     return Op; 
-   } 
-   
-   static MCOperand createSFPImm(uint32_t Val) { 
-     MCOperand Op; 
-     Op.Kind = kSFPImmediate; 
-     Op.SFPImmVal = Val; 
-     return Op; 
-   } 
-   
-   static MCOperand createDFPImm(uint64_t Val) { 
-     MCOperand Op; 
-     Op.Kind = kDFPImmediate; 
-     Op.FPImmVal = Val; 
-     return Op; 
-   } 
-   
-   static MCOperand createExpr(const MCExpr *Val) { 
-     MCOperand Op; 
-     Op.Kind = kExpr; 
-     Op.ExprVal = Val; 
-     return Op; 
-   } 
-   
-   static MCOperand createInst(const MCInst *Val) { 
-     MCOperand Op; 
-     Op.Kind = kInst; 
-     Op.InstVal = Val; 
-     return Op; 
-   } 
-   
-   void print(raw_ostream &OS, const MCRegisterInfo *RegInfo = nullptr) const; 
-   void dump() const; 
-   bool isBareSymbolRef() const; 
-   bool evaluateAsConstantImm(int64_t &Imm) const; 
- }; 
-   
- /// Instances of this class represent a single low-level machine 
- /// instruction. 
- class MCInst { 
-   unsigned Opcode = 0; 
-   // These flags could be used to pass some info from one target subcomponent 
-   // to another, for example, from disassembler to asm printer. The values of 
-   // the flags have any sense on target level only (e.g. prefixes on x86). 
-   unsigned Flags = 0; 
-   
-   SMLoc Loc; 
-   SmallVector<MCOperand, 10> Operands; 
-   
- public: 
-   MCInst() = default; 
-   
-   void setOpcode(unsigned Op) { Opcode = Op; } 
-   unsigned getOpcode() const { return Opcode; } 
-   
-   void setFlags(unsigned F) { Flags = F; } 
-   unsigned getFlags() const { return Flags; } 
-   
-   void setLoc(SMLoc loc) { Loc = loc; } 
-   SMLoc getLoc() const { return Loc; } 
-   
-   const MCOperand &getOperand(unsigned i) const { return Operands[i]; } 
-   MCOperand &getOperand(unsigned i) { return Operands[i]; } 
-   unsigned getNumOperands() const { return Operands.size(); } 
-   
-   void addOperand(const MCOperand Op) { Operands.push_back(Op); } 
-   
-   using iterator = SmallVectorImpl<MCOperand>::iterator; 
-   using const_iterator = SmallVectorImpl<MCOperand>::const_iterator; 
-   
-   void clear() { Operands.clear(); } 
-   void erase(iterator I) { Operands.erase(I); } 
-   void erase(iterator First, iterator Last) { Operands.erase(First, Last); } 
-   size_t size() const { return Operands.size(); } 
-   iterator begin() { return Operands.begin(); } 
-   const_iterator begin() const { return Operands.begin(); } 
-   iterator end() { return Operands.end(); } 
-   const_iterator end() const { return Operands.end(); } 
-   
-   iterator insert(iterator I, const MCOperand &Op) { 
-     return Operands.insert(I, Op); 
-   } 
-   
-   void print(raw_ostream &OS, const MCRegisterInfo *RegInfo = nullptr) const; 
-   void dump() const; 
-   
-   /// Dump the MCInst as prettily as possible using the additional MC 
-   /// structures, if given. Operators are separated by the \p Separator 
-   /// string. 
-   void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr, 
-                    StringRef Separator = " ", 
-                    const MCRegisterInfo *RegInfo = nullptr) const; 
-   void dump_pretty(raw_ostream &OS, StringRef Name, StringRef Separator = " ", 
-                    const MCRegisterInfo *RegInfo = nullptr) const; 
- }; 
-   
- inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) { 
-   MO.print(OS); 
-   return OS; 
- } 
-   
- inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) { 
-   MI.print(OS); 
-   return OS; 
- } 
-   
- } // end namespace llvm 
-   
- #endif // LLVM_MC_MCINST_H 
-