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