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