MCInst.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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. #ifndef LLVM_MC_MCINST_H
  15. #define LLVM_MC_MCINST_H
  16. #include "llvm/ADT/SmallVector.h"
  17. #include "llvm/ADT/StringRef.h"
  18. #include "llvm/ADT/bit.h"
  19. #include "llvm/Support/SMLoc.h"
  20. #include <cassert>
  21. #include <cstddef>
  22. #include <cstdint>
  23. namespace llvm {
  24. class MCExpr;
  25. class MCInst;
  26. class MCInstPrinter;
  27. class MCRegisterInfo;
  28. class raw_ostream;
  29. /// Instances of this class represent operands of the MCInst class.
  30. /// This is a simple discriminated union.
  31. class MCOperand {
  32. enum MachineOperandType : unsigned char {
  33. kInvalid, ///< Uninitialized.
  34. kRegister, ///< Register operand.
  35. kImmediate, ///< Immediate operand.
  36. kSFPImmediate, ///< Single-floating-point immediate operand.
  37. kDFPImmediate, ///< Double-Floating-point immediate operand.
  38. kExpr, ///< Relocatable immediate operand.
  39. kInst ///< Sub-instruction operand.
  40. };
  41. MachineOperandType Kind = kInvalid;
  42. union {
  43. unsigned RegVal;
  44. int64_t ImmVal;
  45. uint32_t SFPImmVal;
  46. uint64_t FPImmVal;
  47. const MCExpr *ExprVal;
  48. const MCInst *InstVal;
  49. };
  50. public:
  51. MCOperand() : FPImmVal(0) {}
  52. bool isValid() const { return Kind != kInvalid; }
  53. bool isReg() const { return Kind == kRegister; }
  54. bool isImm() const { return Kind == kImmediate; }
  55. bool isSFPImm() const { return Kind == kSFPImmediate; }
  56. bool isDFPImm() const { return Kind == kDFPImmediate; }
  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. uint32_t getSFPImm() const {
  78. assert(isSFPImm() && "This is not an SFP immediate");
  79. return SFPImmVal;
  80. }
  81. void setSFPImm(uint32_t Val) {
  82. assert(isSFPImm() && "This is not an SFP immediate");
  83. SFPImmVal = Val;
  84. }
  85. uint64_t getDFPImm() const {
  86. assert(isDFPImm() && "This is not an FP immediate");
  87. return FPImmVal;
  88. }
  89. void setDFPImm(uint64_t Val) {
  90. assert(isDFPImm() && "This is not an FP immediate");
  91. FPImmVal = Val;
  92. }
  93. void setFPImm(double Val) {
  94. assert(isDFPImm() && "This is not an FP immediate");
  95. FPImmVal = bit_cast<uint64_t>(Val);
  96. }
  97. const MCExpr *getExpr() const {
  98. assert(isExpr() && "This is not an expression");
  99. return ExprVal;
  100. }
  101. void setExpr(const MCExpr *Val) {
  102. assert(isExpr() && "This is not an expression");
  103. ExprVal = Val;
  104. }
  105. const MCInst *getInst() const {
  106. assert(isInst() && "This is not a sub-instruction");
  107. return InstVal;
  108. }
  109. void setInst(const MCInst *Val) {
  110. assert(isInst() && "This is not a sub-instruction");
  111. InstVal = Val;
  112. }
  113. static MCOperand createReg(unsigned Reg) {
  114. MCOperand Op;
  115. Op.Kind = kRegister;
  116. Op.RegVal = Reg;
  117. return Op;
  118. }
  119. static MCOperand createImm(int64_t Val) {
  120. MCOperand Op;
  121. Op.Kind = kImmediate;
  122. Op.ImmVal = Val;
  123. return Op;
  124. }
  125. static MCOperand createSFPImm(uint32_t Val) {
  126. MCOperand Op;
  127. Op.Kind = kSFPImmediate;
  128. Op.SFPImmVal = Val;
  129. return Op;
  130. }
  131. static MCOperand createDFPImm(uint64_t Val) {
  132. MCOperand Op;
  133. Op.Kind = kDFPImmediate;
  134. Op.FPImmVal = Val;
  135. return Op;
  136. }
  137. static MCOperand createExpr(const MCExpr *Val) {
  138. MCOperand Op;
  139. Op.Kind = kExpr;
  140. Op.ExprVal = Val;
  141. return Op;
  142. }
  143. static MCOperand createInst(const MCInst *Val) {
  144. MCOperand Op;
  145. Op.Kind = kInst;
  146. Op.InstVal = Val;
  147. return Op;
  148. }
  149. void print(raw_ostream &OS, const MCRegisterInfo *RegInfo = nullptr) const;
  150. void dump() const;
  151. bool isBareSymbolRef() const;
  152. bool evaluateAsConstantImm(int64_t &Imm) const;
  153. };
  154. /// Instances of this class represent a single low-level machine
  155. /// instruction.
  156. class MCInst {
  157. unsigned Opcode = 0;
  158. // These flags could be used to pass some info from one target subcomponent
  159. // to another, for example, from disassembler to asm printer. The values of
  160. // the flags have any sense on target level only (e.g. prefixes on x86).
  161. unsigned Flags = 0;
  162. SMLoc Loc;
  163. SmallVector<MCOperand, 8> Operands;
  164. public:
  165. MCInst() = default;
  166. void setOpcode(unsigned Op) { Opcode = Op; }
  167. unsigned getOpcode() const { return Opcode; }
  168. void setFlags(unsigned F) { Flags = F; }
  169. unsigned getFlags() const { return Flags; }
  170. void setLoc(SMLoc loc) { Loc = loc; }
  171. SMLoc getLoc() const { return Loc; }
  172. const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
  173. MCOperand &getOperand(unsigned i) { return Operands[i]; }
  174. unsigned getNumOperands() const { return Operands.size(); }
  175. void addOperand(const MCOperand Op) { Operands.push_back(Op); }
  176. using iterator = SmallVectorImpl<MCOperand>::iterator;
  177. using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;
  178. void clear() { Operands.clear(); }
  179. void erase(iterator I) { Operands.erase(I); }
  180. void erase(iterator First, iterator Last) { Operands.erase(First, Last); }
  181. size_t size() const { return Operands.size(); }
  182. iterator begin() { return Operands.begin(); }
  183. const_iterator begin() const { return Operands.begin(); }
  184. iterator end() { return Operands.end(); }
  185. const_iterator end() const { return Operands.end(); }
  186. iterator insert(iterator I, const MCOperand &Op) {
  187. return Operands.insert(I, Op);
  188. }
  189. void print(raw_ostream &OS, const MCRegisterInfo *RegInfo = nullptr) const;
  190. void dump() const;
  191. /// Dump the MCInst as prettily as possible using the additional MC
  192. /// structures, if given. Operators are separated by the \p Separator
  193. /// string.
  194. void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr,
  195. StringRef Separator = " ",
  196. const MCRegisterInfo *RegInfo = nullptr) const;
  197. void dump_pretty(raw_ostream &OS, StringRef Name, StringRef Separator = " ",
  198. const MCRegisterInfo *RegInfo = nullptr) const;
  199. };
  200. inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
  201. MO.print(OS);
  202. return OS;
  203. }
  204. inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
  205. MI.print(OS);
  206. return OS;
  207. }
  208. } // end namespace llvm
  209. #endif // LLVM_MC_MCINST_H