1 //===- llvm/MC/MCInst.h - MCInst class --------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_MC_MCINST_H
17 #define LLVM_MC_MCINST_H
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/SMLoc.h"
33 /// Instances of this class represent operands of the MCInst class.
34 /// This is a simple discriminated union.
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.
44 MachineOperandType Kind = kInvalid;
50 const MCExpr *ExprVal;
51 const MCInst *InstVal;
55 MCOperand() : FPImmVal(0.0) {}
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; }
64 /// Returns the register number.
65 unsigned getReg() const {
66 assert(isReg() && "This is not a register operand!");
70 /// Set the register number.
71 void setReg(unsigned Reg) {
72 assert(isReg() && "This is not a register operand!");
76 int64_t getImm() const {
77 assert(isImm() && "This is not an immediate");
81 void setImm(int64_t Val) {
82 assert(isImm() && "This is not an immediate");
86 double getFPImm() const {
87 assert(isFPImm() && "This is not an FP immediate");
91 void setFPImm(double Val) {
92 assert(isFPImm() && "This is not an FP immediate");
96 const MCExpr *getExpr() const {
97 assert(isExpr() && "This is not an expression");
101 void setExpr(const MCExpr *Val) {
102 assert(isExpr() && "This is not an expression");
106 const MCInst *getInst() const {
107 assert(isInst() && "This is not a sub-instruction");
111 void setInst(const MCInst *Val) {
112 assert(isInst() && "This is not a sub-instruction");
116 static MCOperand createReg(unsigned Reg) {
123 static MCOperand createImm(int64_t Val) {
125 Op.Kind = kImmediate;
130 static MCOperand createFPImm(double Val) {
132 Op.Kind = kFPImmediate;
137 static MCOperand createExpr(const MCExpr *Val) {
144 static MCOperand createInst(const MCInst *Val) {
151 void print(raw_ostream &OS) const;
153 bool isBareSymbolRef() const;
154 bool evaluateAsConstantImm(int64_t &Imm) const;
157 template <> struct isPodLike<MCOperand> { static const bool value = true; };
159 /// Instances of this class represent a single low-level machine
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).
173 void setOpcode(unsigned Op) { Opcode = Op; }
174 unsigned getOpcode() const { return Opcode; }
176 void setFlags(unsigned F) { Flags = F; }
177 unsigned getFlags() const { return Flags; }
179 void setLoc(SMLoc loc) { Loc = loc; }
180 SMLoc getLoc() const { return Loc; }
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(); }
186 void addOperand(const MCOperand &Op) { Operands.push_back(Op); }
188 using iterator = SmallVectorImpl<MCOperand>::iterator;
189 using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;
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(); }
199 iterator insert(iterator I, const MCOperand &Op) {
200 return Operands.insert(I, Op);
203 void print(raw_ostream &OS) const;
206 /// Dump the MCInst as prettily as possible using the additional MC
207 /// structures, if given. Operators are separated by the \p Separator
209 void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr,
210 StringRef Separator = " ") const;
211 void dump_pretty(raw_ostream &OS, StringRef Name,
212 StringRef Separator = " ") const;
215 inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
220 inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
225 } // end namespace llvm
227 #endif // LLVM_MC_MCINST_H