]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/MC/MCInst.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / MC / MCInst.h
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/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 raw_ostream;
32
33 /// Instances of this class represent operands of the MCInst class.
34 /// This is a simple discriminated union.
35 class MCOperand {
36   enum MachineOperandType : unsigned char {
37     kInvalid,     ///< Uninitialized.
38     kRegister,    ///< Register operand.
39     kImmediate,   ///< Immediate operand.
40     kFPImmediate, ///< Floating-point immediate operand.
41     kExpr,        ///< Relocatable immediate operand.
42     kInst         ///< Sub-instruction operand.
43   };
44   MachineOperandType Kind = kInvalid;
45
46   union {
47     unsigned RegVal;
48     int64_t ImmVal;
49     double FPImmVal;
50     const MCExpr *ExprVal;
51     const MCInst *InstVal;
52   };
53
54 public:
55   MCOperand() : FPImmVal(0.0) {}
56
57   bool isValid() const { return Kind != kInvalid; }
58   bool isReg() const { return Kind == kRegister; }
59   bool isImm() const { return Kind == kImmediate; }
60   bool isFPImm() const { return Kind == kFPImmediate; }
61   bool isExpr() const { return Kind == kExpr; }
62   bool isInst() const { return Kind == kInst; }
63
64   /// Returns the register number.
65   unsigned getReg() const {
66     assert(isReg() && "This is not a register operand!");
67     return RegVal;
68   }
69
70   /// Set the register number.
71   void setReg(unsigned Reg) {
72     assert(isReg() && "This is not a register operand!");
73     RegVal = Reg;
74   }
75
76   int64_t getImm() const {
77     assert(isImm() && "This is not an immediate");
78     return ImmVal;
79   }
80
81   void setImm(int64_t Val) {
82     assert(isImm() && "This is not an immediate");
83     ImmVal = Val;
84   }
85
86   double getFPImm() const {
87     assert(isFPImm() && "This is not an FP immediate");
88     return FPImmVal;
89   }
90
91   void setFPImm(double Val) {
92     assert(isFPImm() && "This is not an FP immediate");
93     FPImmVal = Val;
94   }
95
96   const MCExpr *getExpr() const {
97     assert(isExpr() && "This is not an expression");
98     return ExprVal;
99   }
100
101   void setExpr(const MCExpr *Val) {
102     assert(isExpr() && "This is not an expression");
103     ExprVal = Val;
104   }
105
106   const MCInst *getInst() const {
107     assert(isInst() && "This is not a sub-instruction");
108     return InstVal;
109   }
110
111   void setInst(const MCInst *Val) {
112     assert(isInst() && "This is not a sub-instruction");
113     InstVal = Val;
114   }
115
116   static MCOperand createReg(unsigned Reg) {
117     MCOperand Op;
118     Op.Kind = kRegister;
119     Op.RegVal = Reg;
120     return Op;
121   }
122
123   static MCOperand createImm(int64_t Val) {
124     MCOperand Op;
125     Op.Kind = kImmediate;
126     Op.ImmVal = Val;
127     return Op;
128   }
129
130   static MCOperand createFPImm(double Val) {
131     MCOperand Op;
132     Op.Kind = kFPImmediate;
133     Op.FPImmVal = Val;
134     return Op;
135   }
136
137   static MCOperand createExpr(const MCExpr *Val) {
138     MCOperand Op;
139     Op.Kind = kExpr;
140     Op.ExprVal = Val;
141     return Op;
142   }
143
144   static MCOperand createInst(const MCInst *Val) {
145     MCOperand Op;
146     Op.Kind = kInst;
147     Op.InstVal = Val;
148     return Op;
149   }
150
151   void print(raw_ostream &OS) const;
152   void dump() const;
153   bool isBareSymbolRef() const;
154   bool evaluateAsConstantImm(int64_t &Imm) const;
155 };
156
157 template <> struct isPodLike<MCOperand> { static const bool value = true; };
158
159 /// Instances of this class represent a single low-level machine
160 /// instruction.
161 class MCInst {
162   unsigned Opcode = 0;
163   SMLoc Loc;
164   SmallVector<MCOperand, 8> Operands;
165   // These flags could be used to pass some info from one target subcomponent
166   // to another, for example, from disassembler to asm printer. The values of
167   // the flags have any sense on target level only (e.g. prefixes on x86).
168   unsigned Flags = 0;
169
170 public:
171   MCInst() = default;
172
173   void setOpcode(unsigned Op) { Opcode = Op; }
174   unsigned getOpcode() const { return Opcode; }
175
176   void setFlags(unsigned F) { Flags = F; }
177   unsigned getFlags() const { return Flags; }
178
179   void setLoc(SMLoc loc) { Loc = loc; }
180   SMLoc getLoc() const { return Loc; }
181
182   const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
183   MCOperand &getOperand(unsigned i) { return Operands[i]; }
184   unsigned getNumOperands() const { return Operands.size(); }
185
186   void addOperand(const MCOperand &Op) { Operands.push_back(Op); }
187
188   using iterator = SmallVectorImpl<MCOperand>::iterator;
189   using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;
190
191   void clear() { Operands.clear(); }
192   void erase(iterator I) { Operands.erase(I); }
193   size_t size() const { return Operands.size(); }
194   iterator begin() { return Operands.begin(); }
195   const_iterator begin() const { return Operands.begin(); }
196   iterator end() { return Operands.end(); }
197   const_iterator end() const { return Operands.end(); }
198
199   iterator insert(iterator I, const MCOperand &Op) {
200     return Operands.insert(I, Op);
201   }
202
203   void print(raw_ostream &OS) const;
204   void dump() const;
205
206   /// Dump the MCInst as prettily as possible using the additional MC
207   /// structures, if given. Operators are separated by the \p Separator
208   /// string.
209   void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr,
210                    StringRef Separator = " ") const;
211 };
212
213 inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
214   MO.print(OS);
215   return OS;
216 }
217
218 inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
219   MI.print(OS);
220   return OS;
221 }
222
223 } // end namespace llvm
224
225 #endif // LLVM_MC_MCINST_H