Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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/ADT/bit.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 MCRegisterInfo;
32
class raw_ostream;
33
 
34
/// Instances of this class represent operands of the MCInst class.
35
/// This is a simple discriminated union.
36
class MCOperand {
37
  enum MachineOperandType : unsigned char {
38
    kInvalid,      ///< Uninitialized.
39
    kRegister,     ///< Register operand.
40
    kImmediate,    ///< Immediate operand.
41
    kSFPImmediate, ///< Single-floating-point immediate operand.
42
    kDFPImmediate, ///< Double-Floating-point immediate operand.
43
    kExpr,         ///< Relocatable immediate operand.
44
    kInst          ///< Sub-instruction operand.
45
  };
46
  MachineOperandType Kind = kInvalid;
47
 
48
  union {
49
    unsigned RegVal;
50
    int64_t ImmVal;
51
    uint32_t SFPImmVal;
52
    uint64_t FPImmVal;
53
    const MCExpr *ExprVal;
54
    const MCInst *InstVal;
55
  };
56
 
57
public:
58
  MCOperand() : FPImmVal(0) {}
59
 
60
  bool isValid() const { return Kind != kInvalid; }
61
  bool isReg() const { return Kind == kRegister; }
62
  bool isImm() const { return Kind == kImmediate; }
63
  bool isSFPImm() const { return Kind == kSFPImmediate; }
64
  bool isDFPImm() const { return Kind == kDFPImmediate; }
65
  bool isExpr() const { return Kind == kExpr; }
66
  bool isInst() const { return Kind == kInst; }
67
 
68
  /// Returns the register number.
69
  unsigned getReg() const {
70
    assert(isReg() && "This is not a register operand!");
71
    return RegVal;
72
  }
73
 
74
  /// Set the register number.
75
  void setReg(unsigned Reg) {
76
    assert(isReg() && "This is not a register operand!");
77
    RegVal = Reg;
78
  }
79
 
80
  int64_t getImm() const {
81
    assert(isImm() && "This is not an immediate");
82
    return ImmVal;
83
  }
84
 
85
  void setImm(int64_t Val) {
86
    assert(isImm() && "This is not an immediate");
87
    ImmVal = Val;
88
  }
89
 
90
  uint32_t getSFPImm() const {
91
    assert(isSFPImm() && "This is not an SFP immediate");
92
    return SFPImmVal;
93
  }
94
 
95
  void setSFPImm(uint32_t Val) {
96
    assert(isSFPImm() && "This is not an SFP immediate");
97
    SFPImmVal = Val;
98
  }
99
 
100
  uint64_t getDFPImm() const {
101
    assert(isDFPImm() && "This is not an FP immediate");
102
    return FPImmVal;
103
  }
104
 
105
  void setDFPImm(uint64_t Val) {
106
    assert(isDFPImm() && "This is not an FP immediate");
107
    FPImmVal = Val;
108
  }
109
  void setFPImm(double Val) {
110
    assert(isDFPImm() && "This is not an FP immediate");
111
    FPImmVal = bit_cast<uint64_t>(Val);
112
  }
113
 
114
  const MCExpr *getExpr() const {
115
    assert(isExpr() && "This is not an expression");
116
    return ExprVal;
117
  }
118
 
119
  void setExpr(const MCExpr *Val) {
120
    assert(isExpr() && "This is not an expression");
121
    ExprVal = Val;
122
  }
123
 
124
  const MCInst *getInst() const {
125
    assert(isInst() && "This is not a sub-instruction");
126
    return InstVal;
127
  }
128
 
129
  void setInst(const MCInst *Val) {
130
    assert(isInst() && "This is not a sub-instruction");
131
    InstVal = Val;
132
  }
133
 
134
  static MCOperand createReg(unsigned Reg) {
135
    MCOperand Op;
136
    Op.Kind = kRegister;
137
    Op.RegVal = Reg;
138
    return Op;
139
  }
140
 
141
  static MCOperand createImm(int64_t Val) {
142
    MCOperand Op;
143
    Op.Kind = kImmediate;
144
    Op.ImmVal = Val;
145
    return Op;
146
  }
147
 
148
  static MCOperand createSFPImm(uint32_t Val) {
149
    MCOperand Op;
150
    Op.Kind = kSFPImmediate;
151
    Op.SFPImmVal = Val;
152
    return Op;
153
  }
154
 
155
  static MCOperand createDFPImm(uint64_t Val) {
156
    MCOperand Op;
157
    Op.Kind = kDFPImmediate;
158
    Op.FPImmVal = Val;
159
    return Op;
160
  }
161
 
162
  static MCOperand createExpr(const MCExpr *Val) {
163
    MCOperand Op;
164
    Op.Kind = kExpr;
165
    Op.ExprVal = Val;
166
    return Op;
167
  }
168
 
169
  static MCOperand createInst(const MCInst *Val) {
170
    MCOperand Op;
171
    Op.Kind = kInst;
172
    Op.InstVal = Val;
173
    return Op;
174
  }
175
 
176
  void print(raw_ostream &OS, const MCRegisterInfo *RegInfo = nullptr) const;
177
  void dump() const;
178
  bool isBareSymbolRef() const;
179
  bool evaluateAsConstantImm(int64_t &Imm) const;
180
};
181
 
182
/// Instances of this class represent a single low-level machine
183
/// instruction.
184
class MCInst {
185
  unsigned Opcode = 0;
186
  // These flags could be used to pass some info from one target subcomponent
187
  // to another, for example, from disassembler to asm printer. The values of
188
  // the flags have any sense on target level only (e.g. prefixes on x86).
189
  unsigned Flags = 0;
190
 
191
  SMLoc Loc;
192
  SmallVector<MCOperand, 10> Operands;
193
 
194
public:
195
  MCInst() = default;
196
 
197
  void setOpcode(unsigned Op) { Opcode = Op; }
198
  unsigned getOpcode() const { return Opcode; }
199
 
200
  void setFlags(unsigned F) { Flags = F; }
201
  unsigned getFlags() const { return Flags; }
202
 
203
  void setLoc(SMLoc loc) { Loc = loc; }
204
  SMLoc getLoc() const { return Loc; }
205
 
206
  const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
207
  MCOperand &getOperand(unsigned i) { return Operands[i]; }
208
  unsigned getNumOperands() const { return Operands.size(); }
209
 
210
  void addOperand(const MCOperand Op) { Operands.push_back(Op); }
211
 
212
  using iterator = SmallVectorImpl<MCOperand>::iterator;
213
  using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;
214
 
215
  void clear() { Operands.clear(); }
216
  void erase(iterator I) { Operands.erase(I); }
217
  void erase(iterator First, iterator Last) { Operands.erase(First, Last); }
218
  size_t size() const { return Operands.size(); }
219
  iterator begin() { return Operands.begin(); }
220
  const_iterator begin() const { return Operands.begin(); }
221
  iterator end() { return Operands.end(); }
222
  const_iterator end() const { return Operands.end(); }
223
 
224
  iterator insert(iterator I, const MCOperand &Op) {
225
    return Operands.insert(I, Op);
226
  }
227
 
228
  void print(raw_ostream &OS, const MCRegisterInfo *RegInfo = nullptr) const;
229
  void dump() const;
230
 
231
  /// Dump the MCInst as prettily as possible using the additional MC
232
  /// structures, if given. Operators are separated by the \p Separator
233
  /// string.
234
  void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr,
235
                   StringRef Separator = " ",
236
                   const MCRegisterInfo *RegInfo = nullptr) const;
237
  void dump_pretty(raw_ostream &OS, StringRef Name, StringRef Separator = " ",
238
                   const MCRegisterInfo *RegInfo = nullptr) const;
239
};
240
 
241
inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
242
  MO.print(OS);
243
  return OS;
244
}
245
 
246
inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
247
  MI.print(OS);
248
  return OS;
249
}
250
 
251
} // end namespace llvm
252
 
253
#endif // LLVM_MC_MCINST_H