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