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 /// MCOperand - 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 public:
52 
MCOperand()53   MCOperand() : Kind(kInvalid), FPImmVal(0.0) {}
54 
isValid()55   bool isValid() const { return Kind != kInvalid; }
isReg()56   bool isReg() const { return Kind == kRegister; }
isImm()57   bool isImm() const { return Kind == kImmediate; }
isFPImm()58   bool isFPImm() const { return Kind == kFPImmediate; }
isExpr()59   bool isExpr() const { return Kind == kExpr; }
isInst()60   bool isInst() const { return Kind == kInst; }
61 
62   /// getReg - Returns the register number.
getReg()63   unsigned getReg() const {
64     assert(isReg() && "This is not a register operand!");
65     return RegVal;
66   }
67 
68   /// setReg - Set the register number.
setReg(unsigned Reg)69   void setReg(unsigned Reg) {
70     assert(isReg() && "This is not a register operand!");
71     RegVal = Reg;
72   }
73 
getImm()74   int64_t getImm() const {
75     assert(isImm() && "This is not an immediate");
76     return ImmVal;
77   }
setImm(int64_t Val)78   void setImm(int64_t Val) {
79     assert(isImm() && "This is not an immediate");
80     ImmVal = Val;
81   }
82 
getFPImm()83   double getFPImm() const {
84     assert(isFPImm() && "This is not an FP immediate");
85     return FPImmVal;
86   }
87 
setFPImm(double Val)88   void setFPImm(double Val) {
89     assert(isFPImm() && "This is not an FP immediate");
90     FPImmVal = Val;
91   }
92 
getExpr()93   const MCExpr *getExpr() const {
94     assert(isExpr() && "This is not an expression");
95     return ExprVal;
96   }
setExpr(const MCExpr * Val)97   void setExpr(const MCExpr *Val) {
98     assert(isExpr() && "This is not an expression");
99     ExprVal = Val;
100   }
101 
getInst()102   const MCInst *getInst() const {
103     assert(isInst() && "This is not a sub-instruction");
104     return InstVal;
105   }
setInst(const MCInst * Val)106   void setInst(const MCInst *Val) {
107     assert(isInst() && "This is not a sub-instruction");
108     InstVal = Val;
109   }
110 
CreateReg(unsigned Reg)111   static MCOperand CreateReg(unsigned Reg) {
112     MCOperand Op;
113     Op.Kind = kRegister;
114     Op.RegVal = Reg;
115     return Op;
116   }
CreateImm(int64_t Val)117   static MCOperand CreateImm(int64_t Val) {
118     MCOperand Op;
119     Op.Kind = kImmediate;
120     Op.ImmVal = Val;
121     return Op;
122   }
CreateFPImm(double Val)123   static MCOperand CreateFPImm(double Val) {
124     MCOperand Op;
125     Op.Kind = kFPImmediate;
126     Op.FPImmVal = Val;
127     return Op;
128   }
CreateExpr(const MCExpr * Val)129   static MCOperand CreateExpr(const MCExpr *Val) {
130     MCOperand Op;
131     Op.Kind = kExpr;
132     Op.ExprVal = Val;
133     return Op;
134   }
CreateInst(const MCInst * Val)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 /// MCInst - 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 public:
155   MCInst() : Opcode(0) {}
156 
157   void setOpcode(unsigned Op) { Opcode = Op; }
158   unsigned getOpcode() const { return Opcode; }
159 
160   void setLoc(SMLoc loc) { Loc = loc; }
161   SMLoc getLoc() const { return Loc; }
162 
163   const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
164   MCOperand &getOperand(unsigned i) { return Operands[i]; }
165   unsigned getNumOperands() const { return Operands.size(); }
166 
167   void addOperand(const MCOperand &Op) {
168     Operands.push_back(Op);
169   }
170 
171   void clear() { Operands.clear(); }
172   size_t size() const { return Operands.size(); }
173 
174   typedef SmallVectorImpl<MCOperand>::iterator iterator;
175   typedef SmallVectorImpl<MCOperand>::const_iterator const_iterator;
176   iterator begin() { return Operands.begin(); }
177   const_iterator begin() const { return Operands.begin(); }
178   iterator end()   { return Operands.end(); }
179   const_iterator end() const { return Operands.end(); }
180   iterator insert(iterator I, const MCOperand &Op) {
181     return Operands.insert(I, Op);
182   }
183 
184   void print(raw_ostream &OS) const;
185   void dump() const;
186 
187   /// \brief Dump the MCInst as prettily as possible using the additional MC
188   /// structures, if given. Operators are separated by the \p Separator
189   /// string.
190   void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr,
191                    StringRef Separator = " ") const;
192 };
193 
194 inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
195   MO.print(OS);
196   return OS;
197 }
198 
199 inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
200   MI.print(OS);
201   return OS;
202 }
203 
204 } // end namespace llvm
205 
206 #endif
207