Home | History | Annotate | Download | only in MC
      1 //===-- llvm/MC/MCInst.h - MCInst class -------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains the declaration of the MCInst and MCOperand classes, which
     11 // is the basic representation used to represent low-level machine code
     12 // instructions.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #ifndef LLVM_MC_MCINST_H
     17 #define LLVM_MC_MCINST_H
     18 
     19 #include "llvm/ADT/SmallVector.h"
     20 #include "llvm/ADT/StringRef.h"
     21 #include "llvm/Support/DataTypes.h"
     22 #include "llvm/Support/SMLoc.h"
     23 
     24 namespace llvm {
     25 class raw_ostream;
     26 class MCAsmInfo;
     27 class MCInstPrinter;
     28 class MCExpr;
     29 class MCInst;
     30 
     31 /// \brief Instances of this class represent operands of the MCInst class.
     32 /// This is a simple discriminated union.
     33 class MCOperand {
     34   enum MachineOperandType : unsigned char {
     35     kInvalid,     ///< Uninitialized.
     36     kRegister,    ///< Register operand.
     37     kImmediate,   ///< Immediate operand.
     38     kFPImmediate, ///< Floating-point immediate operand.
     39     kExpr,        ///< Relocatable immediate operand.
     40     kInst         ///< Sub-instruction operand.
     41   };
     42   MachineOperandType Kind;
     43 
     44   union {
     45     unsigned RegVal;
     46     int64_t ImmVal;
     47     double FPImmVal;
     48     const MCExpr *ExprVal;
     49     const MCInst *InstVal;
     50   };
     51 
     52 public:
     53   MCOperand() : Kind(kInvalid), FPImmVal(0.0) {}
     54 
     55   bool isValid() const { return Kind != kInvalid; }
     56   bool isReg() const { return Kind == kRegister; }
     57   bool isImm() const { return Kind == kImmediate; }
     58   bool isFPImm() const { return Kind == kFPImmediate; }
     59   bool isExpr() const { return Kind == kExpr; }
     60   bool isInst() const { return Kind == kInst; }
     61 
     62   /// \brief Returns the register number.
     63   unsigned getReg() const {
     64     assert(isReg() && "This is not a register operand!");
     65     return RegVal;
     66   }
     67 
     68   /// \brief Set the register number.
     69   void setReg(unsigned Reg) {
     70     assert(isReg() && "This is not a register operand!");
     71     RegVal = Reg;
     72   }
     73 
     74   int64_t getImm() const {
     75     assert(isImm() && "This is not an immediate");
     76     return ImmVal;
     77   }
     78   void setImm(int64_t Val) {
     79     assert(isImm() && "This is not an immediate");
     80     ImmVal = Val;
     81   }
     82 
     83   double getFPImm() const {
     84     assert(isFPImm() && "This is not an FP immediate");
     85     return FPImmVal;
     86   }
     87 
     88   void setFPImm(double Val) {
     89     assert(isFPImm() && "This is not an FP immediate");
     90     FPImmVal = Val;
     91   }
     92 
     93   const MCExpr *getExpr() const {
     94     assert(isExpr() && "This is not an expression");
     95     return ExprVal;
     96   }
     97   void setExpr(const MCExpr *Val) {
     98     assert(isExpr() && "This is not an expression");
     99     ExprVal = Val;
    100   }
    101 
    102   const MCInst *getInst() const {
    103     assert(isInst() && "This is not a sub-instruction");
    104     return InstVal;
    105   }
    106   void setInst(const MCInst *Val) {
    107     assert(isInst() && "This is not a sub-instruction");
    108     InstVal = Val;
    109   }
    110 
    111   static MCOperand createReg(unsigned Reg) {
    112     MCOperand Op;
    113     Op.Kind = kRegister;
    114     Op.RegVal = Reg;
    115     return Op;
    116   }
    117   static MCOperand createImm(int64_t Val) {
    118     MCOperand Op;
    119     Op.Kind = kImmediate;
    120     Op.ImmVal = Val;
    121     return Op;
    122   }
    123   static MCOperand createFPImm(double Val) {
    124     MCOperand Op;
    125     Op.Kind = kFPImmediate;
    126     Op.FPImmVal = Val;
    127     return Op;
    128   }
    129   static MCOperand createExpr(const MCExpr *Val) {
    130     MCOperand Op;
    131     Op.Kind = kExpr;
    132     Op.ExprVal = Val;
    133     return Op;
    134   }
    135   static MCOperand createInst(const MCInst *Val) {
    136     MCOperand Op;
    137     Op.Kind = kInst;
    138     Op.InstVal = Val;
    139     return Op;
    140   }
    141 
    142   void print(raw_ostream &OS) const;
    143   void dump() const;
    144 };
    145 
    146 template <> struct isPodLike<MCOperand> { static const bool value = true; };
    147 
    148 /// \brief Instances of this class represent a single low-level machine
    149 /// instruction.
    150 class MCInst {
    151   unsigned Opcode;
    152   SMLoc Loc;
    153   SmallVector<MCOperand, 8> Operands;
    154 
    155 public:
    156   MCInst() : Opcode(0) {}
    157 
    158   void setOpcode(unsigned Op) { Opcode = Op; }
    159   unsigned getOpcode() const { return Opcode; }
    160 
    161   void setLoc(SMLoc loc) { Loc = loc; }
    162   SMLoc getLoc() const { return Loc; }
    163 
    164   const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
    165   MCOperand &getOperand(unsigned i) { return Operands[i]; }
    166   unsigned getNumOperands() const { return Operands.size(); }
    167 
    168   void addOperand(const MCOperand &Op) { Operands.push_back(Op); }
    169 
    170   typedef SmallVectorImpl<MCOperand>::iterator iterator;
    171   typedef SmallVectorImpl<MCOperand>::const_iterator const_iterator;
    172   void clear() { Operands.clear(); }
    173   void erase(iterator I) { Operands.erase(I); }
    174   size_t size() const { return Operands.size(); }
    175   iterator begin() { return Operands.begin(); }
    176   const_iterator begin() const { return Operands.begin(); }
    177   iterator end() { return Operands.end(); }
    178   const_iterator end() const { return Operands.end(); }
    179   iterator insert(iterator I, const MCOperand &Op) {
    180     return Operands.insert(I, Op);
    181   }
    182 
    183   void print(raw_ostream &OS) const;
    184   void dump() const;
    185 
    186   /// \brief Dump the MCInst as prettily as possible using the additional MC
    187   /// structures, if given. Operators are separated by the \p Separator
    188   /// string.
    189   void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr,
    190                    StringRef Separator = " ") const;
    191 };
    192 
    193 inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
    194   MO.print(OS);
    195   return OS;
    196 }
    197 
    198 inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
    199   MI.print(OS);
    200   return OS;
    201 }
    202 
    203 } // end namespace llvm
    204 
    205 #endif
    206