1 //===- llvm/MC/MCInst.h - MCInst class --------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_MC_MCINST_H
16 #define LLVM_MC_MCINST_H
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Support/SMLoc.h"
32 /// Instances of this class represent operands of the MCInst class.
33 /// This is a simple discriminated union.
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.
43 MachineOperandType Kind
= kInvalid
;
49 const MCExpr
*ExprVal
;
50 const MCInst
*InstVal
;
54 MCOperand() : FPImmVal(0.0) {}
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
; }
63 /// Returns the register number.
64 unsigned getReg() const {
65 assert(isReg() && "This is not a register operand!");
69 /// Set the register number.
70 void setReg(unsigned Reg
) {
71 assert(isReg() && "This is not a register operand!");
75 int64_t getImm() const {
76 assert(isImm() && "This is not an immediate");
80 void setImm(int64_t Val
) {
81 assert(isImm() && "This is not an immediate");
85 double getFPImm() const {
86 assert(isFPImm() && "This is not an FP immediate");
90 void setFPImm(double Val
) {
91 assert(isFPImm() && "This is not an FP immediate");
95 const MCExpr
*getExpr() const {
96 assert(isExpr() && "This is not an expression");
100 void setExpr(const MCExpr
*Val
) {
101 assert(isExpr() && "This is not an expression");
105 const MCInst
*getInst() const {
106 assert(isInst() && "This is not a sub-instruction");
110 void setInst(const MCInst
*Val
) {
111 assert(isInst() && "This is not a sub-instruction");
115 static MCOperand
createReg(unsigned Reg
) {
122 static MCOperand
createImm(int64_t Val
) {
124 Op
.Kind
= kImmediate
;
129 static MCOperand
createFPImm(double Val
) {
131 Op
.Kind
= kFPImmediate
;
136 static MCOperand
createExpr(const MCExpr
*Val
) {
143 static MCOperand
createInst(const MCInst
*Val
) {
150 void print(raw_ostream
&OS
) const;
152 bool isBareSymbolRef() const;
153 bool evaluateAsConstantImm(int64_t &Imm
) const;
156 /// Instances of this class represent a single low-level machine
161 SmallVector
<MCOperand
, 8> Operands
;
162 // These flags could be used to pass some info from one target subcomponent
163 // to another, for example, from disassembler to asm printer. The values of
164 // the flags have any sense on target level only (e.g. prefixes on x86).
170 void setOpcode(unsigned Op
) { Opcode
= Op
; }
171 unsigned getOpcode() const { return Opcode
; }
173 void setFlags(unsigned F
) { Flags
= F
; }
174 unsigned getFlags() const { return Flags
; }
176 void setLoc(SMLoc loc
) { Loc
= loc
; }
177 SMLoc
getLoc() const { return Loc
; }
179 const MCOperand
&getOperand(unsigned i
) const { return Operands
[i
]; }
180 MCOperand
&getOperand(unsigned i
) { return Operands
[i
]; }
181 unsigned getNumOperands() const { return Operands
.size(); }
183 void addOperand(const MCOperand
&Op
) { Operands
.push_back(Op
); }
185 using iterator
= SmallVectorImpl
<MCOperand
>::iterator
;
186 using const_iterator
= SmallVectorImpl
<MCOperand
>::const_iterator
;
188 void clear() { Operands
.clear(); }
189 void erase(iterator I
) { Operands
.erase(I
); }
190 void erase(iterator First
, iterator Last
) { Operands
.erase(First
, Last
); }
191 size_t size() const { return Operands
.size(); }
192 iterator
begin() { return Operands
.begin(); }
193 const_iterator
begin() const { return Operands
.begin(); }
194 iterator
end() { return Operands
.end(); }
195 const_iterator
end() const { return Operands
.end(); }
197 iterator
insert(iterator I
, const MCOperand
&Op
) {
198 return Operands
.insert(I
, Op
);
201 void print(raw_ostream
&OS
) const;
204 /// Dump the MCInst as prettily as possible using the additional MC
205 /// structures, if given. Operators are separated by the \p Separator
207 void dump_pretty(raw_ostream
&OS
, const MCInstPrinter
*Printer
= nullptr,
208 StringRef Separator
= " ") const;
209 void dump_pretty(raw_ostream
&OS
, StringRef Name
,
210 StringRef Separator
= " ") const;
213 inline raw_ostream
& operator<<(raw_ostream
&OS
, const MCOperand
&MO
) {
218 inline raw_ostream
& operator<<(raw_ostream
&OS
, const MCInst
&MI
) {
223 } // end namespace llvm
225 #endif // LLVM_MC_MCINST_H