blob: 67bb11a703872731d4eeb9693bb321ab0f9558ed [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- 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
26namespace llvm {
27
28class MCExpr;
29class MCInst;
30class MCInstPrinter;
31class raw_ostream;
32
Andrew Scullcdfcccc2018-10-05 20:58:37 +010033/// Instances of this class represent operands of the MCInst class.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010034/// This is a simple discriminated union.
35class 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
54public:
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
Andrew Scullcdfcccc2018-10-05 20:58:37 +010064 /// Returns the register number.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010065 unsigned getReg() const {
66 assert(isReg() && "This is not a register operand!");
67 return RegVal;
68 }
69
Andrew Scullcdfcccc2018-10-05 20:58:37 +010070 /// Set the register number.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010071 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;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100153 bool isBareSymbolRef() const;
154 bool evaluateAsConstantImm(int64_t &Imm) const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100155};
156
157template <> struct isPodLike<MCOperand> { static const bool value = true; };
158
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100159/// Instances of this class represent a single low-level machine
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100160/// instruction.
161class 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
170public:
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
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100206 /// Dump the MCInst as prettily as possible using the additional MC
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100207 /// 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
213inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
214 MO.print(OS);
215 return OS;
216}
217
218inline 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