Line data Source code
1 : //===- 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 :
26 : namespace llvm {
27 :
28 : class MCExpr;
29 : class MCInst;
30 : class MCInstPrinter;
31 : class raw_ostream;
32 :
33 : /// Instances of this class represent operands of the MCInst class.
34 : /// This is a simple discriminated union.
35 : class 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 :
54 : public:
55 5616345 : MCOperand() : FPImmVal(0.0) {}
56 :
57 0 : bool isValid() const { return Kind != kInvalid; }
58 17 : bool isReg() const { return Kind == kRegister; }
59 1 : bool isImm() const { return Kind == kImmediate; }
60 0 : bool isFPImm() const { return Kind == kFPImmediate; }
61 0 : bool isExpr() const { return Kind == kExpr; }
62 0 : bool isInst() const { return Kind == kInst; }
63 :
64 : /// Returns the register number.
65 243 : unsigned getReg() const {
66 : assert(isReg() && "This is not a register operand!");
67 1 : return RegVal;
68 : }
69 :
70 : /// Set the register number.
71 0 : void setReg(unsigned Reg) {
72 : assert(isReg() && "This is not a register operand!");
73 227 : RegVal = Reg;
74 0 : }
75 :
76 206 : int64_t getImm() const {
77 : assert(isImm() && "This is not an immediate");
78 0 : return ImmVal;
79 : }
80 :
81 0 : void setImm(int64_t Val) {
82 : assert(isImm() && "This is not an immediate");
83 23527 : ImmVal = Val;
84 0 : }
85 :
86 0 : double getFPImm() const {
87 : assert(isFPImm() && "This is not an FP immediate");
88 0 : return FPImmVal;
89 : }
90 :
91 : void setFPImm(double Val) {
92 : assert(isFPImm() && "This is not an FP immediate");
93 : FPImmVal = Val;
94 : }
95 :
96 0 : const MCExpr *getExpr() const {
97 : assert(isExpr() && "This is not an expression");
98 0 : return ExprVal;
99 : }
100 :
101 0 : void setExpr(const MCExpr *Val) {
102 : assert(isExpr() && "This is not an expression");
103 8 : ExprVal = Val;
104 0 : }
105 :
106 0 : const MCInst *getInst() const {
107 : assert(isInst() && "This is not a sub-instruction");
108 0 : return InstVal;
109 : }
110 :
111 0 : void setInst(const MCInst *Val) {
112 : assert(isInst() && "This is not a sub-instruction");
113 1591 : InstVal = Val;
114 0 : }
115 :
116 : static MCOperand createReg(unsigned Reg) {
117 : MCOperand Op;
118 : Op.Kind = kRegister;
119 97193743 : Op.RegVal = Reg;
120 97345443 : 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 61724 : Op.ExprVal = Val;
141 : return Op;
142 : }
143 :
144 : static MCOperand createInst(const MCInst *Val) {
145 : MCOperand Op;
146 : Op.Kind = kInst;
147 226132 : Op.InstVal = Val;
148 : return Op;
149 : }
150 :
151 : void print(raw_ostream &OS) const;
152 : void dump() const;
153 : bool isBareSymbolRef() const;
154 : bool evaluateAsConstantImm(int64_t &Imm) const;
155 : };
156 :
157 : template <> struct isPodLike<MCOperand> { static const bool value = true; };
158 :
159 : /// Instances of this class represent a single low-level machine
160 : /// instruction.
161 4725561 : class 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 :
170 : public:
171 595733280 : MCInst() = default;
172 :
173 37749390 : void setOpcode(unsigned Op) { Opcode = Op; }
174 1 : unsigned getOpcode() const { return Opcode; }
175 :
176 2984657 : void setFlags(unsigned F) { Flags = F; }
177 0 : unsigned getFlags() const { return Flags; }
178 :
179 550105 : void setLoc(SMLoc loc) { Loc = loc; }
180 0 : SMLoc getLoc() const { return Loc; }
181 :
182 503258661 : const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
183 273402 : MCOperand &getOperand(unsigned i) { return Operands[i]; }
184 66020197 : unsigned getNumOperands() const { return Operands.size(); }
185 :
186 150184722 : 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 245219 : 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 33168 : return Operands.insert(I, Op);
201 : }
202 :
203 : void print(raw_ostream &OS) const;
204 : void dump() const;
205 :
206 : /// Dump the MCInst as prettily as possible using the additional MC
207 : /// 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 :
213 : inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
214 0 : MO.print(OS);
215 : return OS;
216 : }
217 :
218 : inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
219 0 : MI.print(OS);
220 : return OS;
221 : }
222 :
223 : } // end namespace llvm
224 :
225 : #endif // LLVM_MC_MCINST_H
|