MCInst.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- llvm/MC/MCInst.h - MCInst class --------------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file contains the declaration of the MCInst and MCOperand classes, which
  15. // is the basic representation used to represent low-level machine code
  16. // instructions.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_MC_MCINST_H
  20. #define LLVM_MC_MCINST_H
  21. #include "llvm/ADT/SmallVector.h"
  22. #include "llvm/ADT/StringRef.h"
  23. #include "llvm/ADT/bit.h"
  24. #include "llvm/Support/SMLoc.h"
  25. #include <cassert>
  26. #include <cstddef>
  27. #include <cstdint>
  28. namespace llvm {
  29. class MCExpr;
  30. class MCInst;
  31. class MCInstPrinter;
  32. class MCRegisterInfo;
  33. class raw_ostream;
  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. union {
  48. unsigned RegVal;
  49. int64_t ImmVal;
  50. uint32_t SFPImmVal;
  51. uint64_t FPImmVal;
  52. const MCExpr *ExprVal;
  53. const MCInst *InstVal;
  54. };
  55. public:
  56. MCOperand() : FPImmVal(0) {}
  57. bool isValid() const { return Kind != kInvalid; }
  58. bool isReg() const { return Kind == kRegister; }
  59. bool isImm() const { return Kind == kImmediate; }
  60. bool isSFPImm() const { return Kind == kSFPImmediate; }
  61. bool isDFPImm() const { return Kind == kDFPImmediate; }
  62. bool isExpr() const { return Kind == kExpr; }
  63. bool isInst() const { return Kind == kInst; }
  64. /// Returns the register number.
  65. unsigned getReg() const {
  66. assert(isReg() && "This is not a register operand!");
  67. return RegVal;
  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. int64_t getImm() const {
  75. assert(isImm() && "This is not an immediate");
  76. return ImmVal;
  77. }
  78. void setImm(int64_t Val) {
  79. assert(isImm() && "This is not an immediate");
  80. ImmVal = Val;
  81. }
  82. uint32_t getSFPImm() const {
  83. assert(isSFPImm() && "This is not an SFP immediate");
  84. return SFPImmVal;
  85. }
  86. void setSFPImm(uint32_t Val) {
  87. assert(isSFPImm() && "This is not an SFP immediate");
  88. SFPImmVal = Val;
  89. }
  90. uint64_t getDFPImm() const {
  91. assert(isDFPImm() && "This is not an FP immediate");
  92. return FPImmVal;
  93. }
  94. void setDFPImm(uint64_t Val) {
  95. assert(isDFPImm() && "This is not an FP immediate");
  96. FPImmVal = Val;
  97. }
  98. void setFPImm(double Val) {
  99. assert(isDFPImm() && "This is not an FP immediate");
  100. FPImmVal = bit_cast<uint64_t>(Val);
  101. }
  102. const MCExpr *getExpr() const {
  103. assert(isExpr() && "This is not an expression");
  104. return ExprVal;
  105. }
  106. void setExpr(const MCExpr *Val) {
  107. assert(isExpr() && "This is not an expression");
  108. ExprVal = Val;
  109. }
  110. const MCInst *getInst() const {
  111. assert(isInst() && "This is not a sub-instruction");
  112. return InstVal;
  113. }
  114. void setInst(const MCInst *Val) {
  115. assert(isInst() && "This is not a sub-instruction");
  116. InstVal = Val;
  117. }
  118. static MCOperand createReg(unsigned Reg) {
  119. MCOperand Op;
  120. Op.Kind = kRegister;
  121. Op.RegVal = Reg;
  122. return Op;
  123. }
  124. static MCOperand createImm(int64_t Val) {
  125. MCOperand Op;
  126. Op.Kind = kImmediate;
  127. Op.ImmVal = Val;
  128. return Op;
  129. }
  130. static MCOperand createSFPImm(uint32_t Val) {
  131. MCOperand Op;
  132. Op.Kind = kSFPImmediate;
  133. Op.SFPImmVal = Val;
  134. return Op;
  135. }
  136. static MCOperand createDFPImm(uint64_t Val) {
  137. MCOperand Op;
  138. Op.Kind = kDFPImmediate;
  139. Op.FPImmVal = Val;
  140. return Op;
  141. }
  142. static MCOperand createExpr(const MCExpr *Val) {
  143. MCOperand Op;
  144. Op.Kind = kExpr;
  145. Op.ExprVal = Val;
  146. return Op;
  147. }
  148. static MCOperand createInst(const MCInst *Val) {
  149. MCOperand Op;
  150. Op.Kind = kInst;
  151. Op.InstVal = Val;
  152. return Op;
  153. }
  154. void print(raw_ostream &OS, const MCRegisterInfo *RegInfo = nullptr) const;
  155. void dump() const;
  156. bool isBareSymbolRef() const;
  157. bool evaluateAsConstantImm(int64_t &Imm) const;
  158. };
  159. /// Instances of this class represent a single low-level machine
  160. /// instruction.
  161. class MCInst {
  162. unsigned Opcode = 0;
  163. // These flags could be used to pass some info from one target subcomponent
  164. // to another, for example, from disassembler to asm printer. The values of
  165. // the flags have any sense on target level only (e.g. prefixes on x86).
  166. unsigned Flags = 0;
  167. SMLoc Loc;
  168. SmallVector<MCOperand, 8> Operands;
  169. public:
  170. MCInst() = default;
  171. void setOpcode(unsigned Op) { Opcode = Op; }
  172. unsigned getOpcode() const { return Opcode; }
  173. void setFlags(unsigned F) { Flags = F; }
  174. unsigned getFlags() const { return Flags; }
  175. void setLoc(SMLoc loc) { Loc = loc; }
  176. SMLoc getLoc() const { return Loc; }
  177. const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
  178. MCOperand &getOperand(unsigned i) { return Operands[i]; }
  179. unsigned getNumOperands() const { return Operands.size(); }
  180. void addOperand(const MCOperand Op) { Operands.push_back(Op); }
  181. using iterator = SmallVectorImpl<MCOperand>::iterator;
  182. using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;
  183. void clear() { Operands.clear(); }
  184. void erase(iterator I) { Operands.erase(I); }
  185. void erase(iterator First, iterator Last) { Operands.erase(First, Last); }
  186. size_t size() const { return Operands.size(); }
  187. iterator begin() { return Operands.begin(); }
  188. const_iterator begin() const { return Operands.begin(); }
  189. iterator end() { return Operands.end(); }
  190. const_iterator end() const { return Operands.end(); }
  191. iterator insert(iterator I, const MCOperand &Op) {
  192. return Operands.insert(I, Op);
  193. }
  194. void print(raw_ostream &OS, const MCRegisterInfo *RegInfo = nullptr) const;
  195. void dump() const;
  196. /// Dump the MCInst as prettily as possible using the additional MC
  197. /// structures, if given. Operators are separated by the \p Separator
  198. /// string.
  199. void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr,
  200. StringRef Separator = " ",
  201. const MCRegisterInfo *RegInfo = nullptr) const;
  202. void dump_pretty(raw_ostream &OS, StringRef Name, StringRef Separator = " ",
  203. const MCRegisterInfo *RegInfo = nullptr) const;
  204. };
  205. inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
  206. MO.print(OS);
  207. return OS;
  208. }
  209. inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
  210. MI.print(OS);
  211. return OS;
  212. }
  213. } // end namespace llvm
  214. #endif // LLVM_MC_MCINST_H
  215. #ifdef __GNUC__
  216. #pragma GCC diagnostic pop
  217. #endif