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/ArrayRef.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/ADT/bit.h"
22#include "llvm/MC/MCRegister.h"
23#include "llvm/Support/Compiler.h"
24#include "llvm/Support/SMLoc.h"
25#include <cassert>
26#include <cstddef>
27#include <cstdint>
28
29namespace llvm {
30
31class MCContext;
32class MCExpr;
33class MCInst;
34class MCInstPrinter;
35class MCRegisterInfo;
36class raw_ostream;
37
38/// Instances of this class represent operands of the MCInst class.
39/// This is a simple discriminated union.
40class MCOperand {
41 enum MachineOperandType : unsigned char {
42 kInvalid, ///< Uninitialized.
43 kRegister, ///< Register operand.
44 kImmediate, ///< Immediate operand.
45 kSFPImmediate, ///< Single-floating-point immediate operand.
46 kDFPImmediate, ///< Double-Floating-point immediate operand.
47 kExpr, ///< Relocatable immediate operand.
48 kInst ///< Sub-instruction operand.
49 };
50 MachineOperandType Kind = kInvalid;
51
52 union {
53 unsigned RegVal;
54 int64_t ImmVal;
55 uint32_t SFPImmVal;
56 uint64_t FPImmVal;
57 const MCExpr *ExprVal;
58 const MCInst *InstVal;
59 };
60
61public:
62 MCOperand() : FPImmVal(0) {}
63
64 bool isValid() const { return Kind != kInvalid; }
65 bool isReg() const { return Kind == kRegister; }
66 bool isImm() const { return Kind == kImmediate; }
67 bool isSFPImm() const { return Kind == kSFPImmediate; }
68 bool isDFPImm() const { return Kind == kDFPImmediate; }
69 bool isExpr() const { return Kind == kExpr; }
70 bool isInst() const { return Kind == kInst; }
71
72 /// Returns the register number.
73 MCRegister getReg() const {
74 assert(isReg() && "This is not a register operand!");
75 return RegVal;
76 }
77
78 /// Set the register number.
79 void setReg(MCRegister Reg) {
80 assert(isReg() && "This is not a register operand!");
81 RegVal = Reg.id();
82 }
83
84 int64_t getImm() const {
85 assert(isImm() && "This is not an immediate");
86 return ImmVal;
87 }
88
89 void setImm(int64_t Val) {
90 assert(isImm() && "This is not an immediate");
91 ImmVal = Val;
92 }
93
94 uint32_t getSFPImm() const {
95 assert(isSFPImm() && "This is not an SFP immediate");
96 return SFPImmVal;
97 }
98
99 void setSFPImm(uint32_t Val) {
100 assert(isSFPImm() && "This is not an SFP immediate");
101 SFPImmVal = Val;
102 }
103
104 uint64_t getDFPImm() const {
105 assert(isDFPImm() && "This is not an FP immediate");
106 return FPImmVal;
107 }
108
109 void setDFPImm(uint64_t Val) {
110 assert(isDFPImm() && "This is not an FP immediate");
111 FPImmVal = Val;
112 }
113 void setFPImm(double Val) {
114 assert(isDFPImm() && "This is not an FP immediate");
115 FPImmVal = bit_cast<uint64_t>(from: Val);
116 }
117
118 const MCExpr *getExpr() const {
119 assert(isExpr() && "This is not an expression");
120 return ExprVal;
121 }
122
123 void setExpr(const MCExpr *Val) {
124 assert(isExpr() && "This is not an expression");
125 ExprVal = Val;
126 }
127
128 const MCInst *getInst() const {
129 assert(isInst() && "This is not a sub-instruction");
130 return InstVal;
131 }
132
133 void setInst(const MCInst *Val) {
134 assert(isInst() && "This is not a sub-instruction");
135 InstVal = Val;
136 }
137
138 static MCOperand createReg(MCRegister Reg) {
139 MCOperand Op;
140 Op.Kind = kRegister;
141 Op.RegVal = Reg.id();
142 return Op;
143 }
144
145 static MCOperand createImm(int64_t Val) {
146 MCOperand Op;
147 Op.Kind = kImmediate;
148 Op.ImmVal = Val;
149 return Op;
150 }
151
152 static MCOperand createSFPImm(uint32_t Val) {
153 MCOperand Op;
154 Op.Kind = kSFPImmediate;
155 Op.SFPImmVal = Val;
156 return Op;
157 }
158
159 static MCOperand createDFPImm(uint64_t Val) {
160 MCOperand Op;
161 Op.Kind = kDFPImmediate;
162 Op.FPImmVal = Val;
163 return Op;
164 }
165
166 static MCOperand createExpr(const MCExpr *Val) {
167 MCOperand Op;
168 Op.Kind = kExpr;
169 Op.ExprVal = Val;
170 return Op;
171 }
172
173 static MCOperand createInst(const MCInst *Val) {
174 MCOperand Op;
175 Op.Kind = kInst;
176 Op.InstVal = Val;
177 return Op;
178 }
179
180 LLVM_ABI void print(raw_ostream &OS, const MCContext *Ctx = nullptr) const;
181 LLVM_ABI void dump() const;
182 LLVM_ABI bool isBareSymbolRef() const;
183 LLVM_ABI bool evaluateAsConstantImm(int64_t &Imm) const;
184};
185
186/// Instances of this class represent a single low-level machine
187/// instruction.
188class MCInst {
189 unsigned Opcode = 0;
190 // These flags could be used to pass some info from one target subcomponent
191 // to another, for example, from disassembler to asm printer. The values of
192 // the flags have any sense on target level only (e.g. prefixes on x86).
193 unsigned Flags = 0;
194
195 SMLoc Loc;
196 SmallVector<MCOperand, 6> Operands;
197
198public:
199 MCInst() = default;
200
201 void setOpcode(unsigned Op) { Opcode = Op; }
202 unsigned getOpcode() const { return Opcode; }
203
204 void setFlags(unsigned F) { Flags = F; }
205 unsigned getFlags() const { return Flags; }
206
207 void setLoc(SMLoc loc) { Loc = loc; }
208 SMLoc getLoc() const { return Loc; }
209
210 const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
211 MCOperand &getOperand(unsigned i) { return Operands[i]; }
212 unsigned getNumOperands() const { return Operands.size(); }
213
214 ArrayRef<MCOperand> getOperands() const { return Operands; }
215 void addOperand(const MCOperand Op) { Operands.push_back(Elt: Op); }
216 void setOperands(ArrayRef<MCOperand> Ops) {
217 Operands.assign(in_start: Ops.begin(), in_end: Ops.end());
218 }
219
220 using iterator = SmallVectorImpl<MCOperand>::iterator;
221 using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;
222
223 void clear() { Operands.clear(); }
224 void erase(iterator I) { Operands.erase(CI: I); }
225 void erase(iterator First, iterator Last) { Operands.erase(CS: First, CE: Last); }
226 size_t size() const { return Operands.size(); }
227 iterator begin() { return Operands.begin(); }
228 const_iterator begin() const { return Operands.begin(); }
229 iterator end() { return Operands.end(); }
230 const_iterator end() const { return Operands.end(); }
231
232 iterator insert(iterator I, const MCOperand &Op) {
233 return Operands.insert(I, Elt: Op);
234 }
235
236 LLVM_ABI void print(raw_ostream &OS, const MCContext *Ctx = nullptr) const;
237 LLVM_ABI void dump() const;
238
239 /// Dump the MCInst as prettily as possible using the additional MC
240 /// structures, if given. Operators are separated by the \p Separator
241 /// string.
242 LLVM_ABI void dump_pretty(raw_ostream &OS,
243 const MCInstPrinter *Printer = nullptr,
244 StringRef Separator = " ",
245 const MCContext *Ctx = nullptr) const;
246 LLVM_ABI void dump_pretty(raw_ostream &OS, StringRef Name,
247 StringRef Separator = " ",
248 const MCContext *Ctx = nullptr) const;
249};
250
251inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
252 MO.print(OS);
253 return OS;
254}
255
256inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
257 MI.print(OS);
258 return OS;
259}
260
261} // end namespace llvm
262
263#endif // LLVM_MC_MCINST_H
264

source code of llvm/include/llvm/MC/MCInst.h