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 
    127 /// MCInst - Instances of this class represent a single low-level machine
    128 /// instruction.
    129 class MCInst {
    130   unsigned Opcode;
    131   SmallVector<MCOperand, 8> Operands;
    132 public:
    133   MCInst() : Opcode(0) {}
    134 
    135   void setOpcode(unsigned Op) { Opcode = Op; }
    136 
    137   unsigned getOpcode() const { return Opcode; }
    138 
    139   const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
    140   MCOperand &getOperand(unsigned i) { return Operands[i]; }
    141   unsigned getNumOperands() const { return Operands.size(); }
    142 
    143   void addOperand(const MCOperand &Op) {
    144     Operands.push_back(Op);
    145   }
    146 
    147   void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
    148   void dump() const;
    149 
    150   /// \brief Dump the MCInst as prettily as possible using the additional MC
    151   /// structures, if given. Operators are separated by the \arg Separator
    152   /// string.
    153   void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = 0,
    154                    const MCInstPrinter *Printer = 0,
    155                    StringRef Separator = " ") const;
    156 };
    157 
    158 inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
    159   MO.print(OS, 0);
    160   return OS;
    161 }
    162 
    163 inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
    164   MI.print(OS, 0);
    165   return OS;
    166 }
    167 
    168 } // end namespace llvm
    169 
    170 #endif
    171