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