Home | History | Annotate | Line # | Download | only in MC
      1 //===- llvm/MC/MCInst.h - MCInst class --------------------------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file contains the declaration of the MCInst and MCOperand classes, which
     10 // is the basic representation used to represent low-level machine code
     11 // instructions.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_MC_MCINST_H
     16 #define LLVM_MC_MCINST_H
     17 
     18 #include "llvm/ADT/SmallVector.h"
     19 #include "llvm/ADT/StringRef.h"
     20 #include "llvm/ADT/bit.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 MCRegisterInfo;
     32 class raw_ostream;
     33 
     34 /// Instances of this class represent operands of the MCInst class.
     35 /// This is a simple discriminated union.
     36 class MCOperand {
     37   enum MachineOperandType : unsigned char {
     38     kInvalid,      ///< Uninitialized.
     39     kRegister,     ///< Register operand.
     40     kImmediate,    ///< Immediate operand.
     41     kSFPImmediate, ///< Single-floating-point immediate operand.
     42     kDFPImmediate, ///< Double-Floating-point immediate operand.
     43     kExpr,         ///< Relocatable immediate operand.
     44     kInst          ///< Sub-instruction operand.
     45   };
     46   MachineOperandType Kind = kInvalid;
     47 
     48   union {
     49     unsigned RegVal;
     50     int64_t ImmVal;
     51     uint32_t SFPImmVal;
     52     uint64_t FPImmVal;
     53     const MCExpr *ExprVal;
     54     const MCInst *InstVal;
     55   };
     56 
     57 public:
     58   MCOperand() : FPImmVal(0) {}
     59 
     60   bool isValid() const { return Kind != kInvalid; }
     61   bool isReg() const { return Kind == kRegister; }
     62   bool isImm() const { return Kind == kImmediate; }
     63   bool isSFPImm() const { return Kind == kSFPImmediate; }
     64   bool isDFPImm() const { return Kind == kDFPImmediate; }
     65   bool isExpr() const { return Kind == kExpr; }
     66   bool isInst() const { return Kind == kInst; }
     67 
     68   /// Returns the register number.
     69   unsigned getReg() const {
     70     assert(isReg() && "This is not a register operand!");
     71     return RegVal;
     72   }
     73 
     74   /// Set the register number.
     75   void setReg(unsigned Reg) {
     76     assert(isReg() && "This is not a register operand!");
     77     RegVal = Reg;
     78   }
     79 
     80   int64_t getImm() const {
     81     assert(isImm() && "This is not an immediate");
     82     return ImmVal;
     83   }
     84 
     85   void setImm(int64_t Val) {
     86     assert(isImm() && "This is not an immediate");
     87     ImmVal = Val;
     88   }
     89 
     90   uint32_t getSFPImm() const {
     91     assert(isSFPImm() && "This is not an SFP immediate");
     92     return SFPImmVal;
     93   }
     94 
     95   void setSFPImm(uint32_t Val) {
     96     assert(isSFPImm() && "This is not an SFP immediate");
     97     SFPImmVal = Val;
     98   }
     99 
    100   uint64_t getDFPImm() const {
    101     assert(isDFPImm() && "This is not an FP immediate");
    102     return FPImmVal;
    103   }
    104 
    105   void setDFPImm(uint64_t Val) {
    106     assert(isDFPImm() && "This is not an FP immediate");
    107     FPImmVal = Val;
    108   }
    109   void setFPImm(double Val) {
    110     assert(isDFPImm() && "This is not an FP immediate");
    111     FPImmVal = bit_cast<uint64_t>(Val);
    112   }
    113 
    114   const MCExpr *getExpr() const {
    115     assert(isExpr() && "This is not an expression");
    116     return ExprVal;
    117   }
    118 
    119   void setExpr(const MCExpr *Val) {
    120     assert(isExpr() && "This is not an expression");
    121     ExprVal = Val;
    122   }
    123 
    124   const MCInst *getInst() const {
    125     assert(isInst() && "This is not a sub-instruction");
    126     return InstVal;
    127   }
    128 
    129   void setInst(const MCInst *Val) {
    130     assert(isInst() && "This is not a sub-instruction");
    131     InstVal = Val;
    132   }
    133 
    134   static MCOperand createReg(unsigned Reg) {
    135     MCOperand Op;
    136     Op.Kind = kRegister;
    137     Op.RegVal = Reg;
    138     return Op;
    139   }
    140 
    141   static MCOperand createImm(int64_t Val) {
    142     MCOperand Op;
    143     Op.Kind = kImmediate;
    144     Op.ImmVal = Val;
    145     return Op;
    146   }
    147 
    148   static MCOperand createSFPImm(uint32_t Val) {
    149     MCOperand Op;
    150     Op.Kind = kSFPImmediate;
    151     Op.SFPImmVal = Val;
    152     return Op;
    153   }
    154 
    155   static MCOperand createDFPImm(uint64_t Val) {
    156     MCOperand Op;
    157     Op.Kind = kDFPImmediate;
    158     Op.FPImmVal = Val;
    159     return Op;
    160   }
    161 
    162   static MCOperand createExpr(const MCExpr *Val) {
    163     MCOperand Op;
    164     Op.Kind = kExpr;
    165     Op.ExprVal = Val;
    166     return Op;
    167   }
    168 
    169   static MCOperand createInst(const MCInst *Val) {
    170     MCOperand Op;
    171     Op.Kind = kInst;
    172     Op.InstVal = Val;
    173     return Op;
    174   }
    175 
    176   void print(raw_ostream &OS, const MCRegisterInfo *RegInfo = nullptr) const;
    177   void dump() const;
    178   bool isBareSymbolRef() const;
    179   bool evaluateAsConstantImm(int64_t &Imm) const;
    180 };
    181 
    182 /// Instances of this class represent a single low-level machine
    183 /// instruction.
    184 class MCInst {
    185   unsigned Opcode = 0;
    186   // These flags could be used to pass some info from one target subcomponent
    187   // to another, for example, from disassembler to asm printer. The values of
    188   // the flags have any sense on target level only (e.g. prefixes on x86).
    189   unsigned Flags = 0;
    190 
    191   SMLoc Loc;
    192   SmallVector<MCOperand, 8> Operands;
    193 
    194 public:
    195   MCInst() = default;
    196 
    197   void setOpcode(unsigned Op) { Opcode = Op; }
    198   unsigned getOpcode() const { return Opcode; }
    199 
    200   void setFlags(unsigned F) { Flags = F; }
    201   unsigned getFlags() const { return Flags; }
    202 
    203   void setLoc(SMLoc loc) { Loc = loc; }
    204   SMLoc getLoc() const { return Loc; }
    205 
    206   const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
    207   MCOperand &getOperand(unsigned i) { return Operands[i]; }
    208   unsigned getNumOperands() const { return Operands.size(); }
    209 
    210   void addOperand(const MCOperand Op) { Operands.push_back(Op); }
    211 
    212   using iterator = SmallVectorImpl<MCOperand>::iterator;
    213   using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;
    214 
    215   void clear() { Operands.clear(); }
    216   void erase(iterator I) { Operands.erase(I); }
    217   void erase(iterator First, iterator Last) { Operands.erase(First, Last); }
    218   size_t size() const { return Operands.size(); }
    219   iterator begin() { return Operands.begin(); }
    220   const_iterator begin() const { return Operands.begin(); }
    221   iterator end() { return Operands.end(); }
    222   const_iterator end() const { return Operands.end(); }
    223 
    224   iterator insert(iterator I, const MCOperand &Op) {
    225     return Operands.insert(I, Op);
    226   }
    227 
    228   void print(raw_ostream &OS, const MCRegisterInfo *RegInfo = nullptr) const;
    229   void dump() const;
    230 
    231   /// Dump the MCInst as prettily as possible using the additional MC
    232   /// structures, if given. Operators are separated by the \p Separator
    233   /// string.
    234   void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr,
    235                    StringRef Separator = " ",
    236                    const MCRegisterInfo *RegInfo = nullptr) const;
    237   void dump_pretty(raw_ostream &OS, StringRef Name, StringRef Separator = " ",
    238                    const MCRegisterInfo *RegInfo = nullptr) const;
    239 };
    240 
    241 inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
    242   MO.print(OS);
    243   return OS;
    244 }
    245 
    246 inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
    247   MI.print(OS);
    248   return OS;
    249 }
    250 
    251 } // end namespace llvm
    252 
    253 #endif // LLVM_MC_MCINST_H
    254