MCInst.h 6.2 KB

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