• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /// \brief 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 
52 public:
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   /// \brief Returns the register number.
getReg()63   unsigned getReg() const {
64     assert(isReg() && "This is not a register operand!");
65     return RegVal;
66   }
67 
68   /// \brief 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 /// \brief 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 
155 public:
156   MCInst() : Opcode(0) {}
157 
158   void setOpcode(unsigned Op) { Opcode = Op; }
159   unsigned getOpcode() const { return Opcode; }
160 
161   void setLoc(SMLoc loc) { Loc = loc; }
162   SMLoc getLoc() const { return Loc; }
163 
164   const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
165   MCOperand &getOperand(unsigned i) { return Operands[i]; }
166   unsigned getNumOperands() const { return Operands.size(); }
167 
168   void addOperand(const MCOperand &Op) { Operands.push_back(Op); }
169 
170   typedef SmallVectorImpl<MCOperand>::iterator iterator;
171   typedef SmallVectorImpl<MCOperand>::const_iterator const_iterator;
172   void clear() { Operands.clear(); }
173   void erase(iterator I) { Operands.erase(I); }
174   size_t size() const { return Operands.size(); }
175   iterator begin() { return Operands.begin(); }
176   const_iterator begin() const { return Operands.begin(); }
177   iterator end() { return Operands.end(); }
178   const_iterator end() const { return Operands.end(); }
179   iterator insert(iterator I, const MCOperand &Op) {
180     return Operands.insert(I, Op);
181   }
182 
183   void print(raw_ostream &OS) const;
184   void dump() const;
185 
186   /// \brief Dump the MCInst as prettily as possible using the additional MC
187   /// structures, if given. Operators are separated by the \p Separator
188   /// string.
189   void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr,
190                    StringRef Separator = " ") const;
191 };
192 
193 inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
194   MO.print(OS);
195   return OS;
196 }
197 
198 inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
199   MI.print(OS);
200   return OS;
201 }
202 
203 } // end namespace llvm
204 
205 #endif
206