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

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