1//===- llvm/MC/MCInst.h - MCInst class --------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the declaration of the MCInst and MCOperand classes, which 11// is the basic representation used to represent low-level machine code 12// instructions. 13// 14//===----------------------------------------------------------------------===// 15 16#ifndef LLVM_MC_MCINST_H 17#define LLVM_MC_MCINST_H 18 19#include "llvm/ADT/SmallVector.h" 20#include "llvm/ADT/StringRef.h" 21#include "llvm/Support/SMLoc.h" 22#include <cassert> 23#include <cstddef> 24#include <cstdint> 25 26namespace llvm { 27 28class MCExpr; 29class MCInst; 30class MCInstPrinter; 31class raw_ostream; 32 33/// \brief Instances of this class represent operands of the MCInst class. 34/// This is a simple discriminated union. 35class MCOperand { 36 enum MachineOperandType : unsigned char { 37 kInvalid, ///< Uninitialized. 38 kRegister, ///< Register operand. 39 kImmediate, ///< Immediate operand. 40 kFPImmediate, ///< Floating-point immediate operand. 41 kExpr, ///< Relocatable immediate operand. 42 kInst ///< Sub-instruction operand. 43 }; 44 MachineOperandType Kind = kInvalid; 45 46 union { 47 unsigned RegVal; 48 int64_t ImmVal; 49 double FPImmVal; 50 const MCExpr *ExprVal; 51 const MCInst *InstVal; 52 }; 53 54public: 55 MCOperand() : FPImmVal(0.0) {} 56 57 bool isValid() const { return Kind != kInvalid; } 58 bool isReg() const { return Kind == kRegister; } 59 bool isImm() const { return Kind == kImmediate; } 60 bool isFPImm() const { return Kind == kFPImmediate; } 61 bool isExpr() const { return Kind == kExpr; } 62 bool isInst() const { return Kind == kInst; } 63 64 /// \brief Returns the register number. 65 unsigned getReg() const { 66 assert(isReg() && "This is not a register operand!"); 67 return RegVal; 68 } 69 70 /// \brief Set the register number. 71 void setReg(unsigned Reg) { 72 assert(isReg() && "This is not a register operand!"); 73 RegVal = Reg; 74 } 75 76 int64_t getImm() const { 77 assert(isImm() && "This is not an immediate"); 78 return ImmVal; 79 } 80 81 void setImm(int64_t Val) { 82 assert(isImm() && "This is not an immediate"); 83 ImmVal = Val; 84 } 85 86 double getFPImm() const { 87 assert(isFPImm() && "This is not an FP immediate"); 88 return FPImmVal; 89 } 90 91 void setFPImm(double Val) { 92 assert(isFPImm() && "This is not an FP immediate"); 93 FPImmVal = Val; 94 } 95 96 const MCExpr *getExpr() const { 97 assert(isExpr() && "This is not an expression"); 98 return ExprVal; 99 } 100 101 void setExpr(const MCExpr *Val) { 102 assert(isExpr() && "This is not an expression"); 103 ExprVal = Val; 104 } 105 106 const MCInst *getInst() const { 107 assert(isInst() && "This is not a sub-instruction"); 108 return InstVal; 109 } 110 111 void setInst(const MCInst *Val) { 112 assert(isInst() && "This is not a sub-instruction"); 113 InstVal = Val; 114 } 115 116 static MCOperand createReg(unsigned Reg) { 117 MCOperand Op; 118 Op.Kind = kRegister; 119 Op.RegVal = Reg; 120 return Op; 121 } 122 123 static MCOperand createImm(int64_t Val) { 124 MCOperand Op; 125 Op.Kind = kImmediate; 126 Op.ImmVal = Val; 127 return Op; 128 } 129 130 static MCOperand createFPImm(double Val) { 131 MCOperand Op; 132 Op.Kind = kFPImmediate; 133 Op.FPImmVal = Val; 134 return Op; 135 } 136 137 static MCOperand createExpr(const MCExpr *Val) { 138 MCOperand Op; 139 Op.Kind = kExpr; 140 Op.ExprVal = Val; 141 return Op; 142 } 143 144 static MCOperand createInst(const MCInst *Val) { 145 MCOperand Op; 146 Op.Kind = kInst; 147 Op.InstVal = Val; 148 return Op; 149 } 150 151 void print(raw_ostream &OS) const; 152 void dump() const; 153}; 154 155template <> struct isPodLike<MCOperand> { static const bool value = true; }; 156 157/// \brief Instances of this class represent a single low-level machine 158/// instruction. 159class MCInst { 160 unsigned Opcode = 0; 161 SMLoc Loc; 162 SmallVector<MCOperand, 8> Operands; 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 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 size_t size() const { return Operands.size(); } 192 iterator begin() { return Operands.begin(); } 193 const_iterator begin() const { return Operands.begin(); } 194 iterator end() { return Operands.end(); } 195 const_iterator end() const { return Operands.end(); } 196 197 iterator insert(iterator I, const MCOperand &Op) { 198 return Operands.insert(I, Op); 199 } 200 201 void print(raw_ostream &OS) const; 202 void dump() const; 203 204 /// \brief Dump the MCInst as prettily as possible using the additional MC 205 /// structures, if given. Operators are separated by the \p Separator 206 /// string. 207 void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr, 208 StringRef Separator = " ") const; 209}; 210 211inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) { 212 MO.print(OS); 213 return OS; 214} 215 216inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) { 217 MI.print(OS); 218 return OS; 219} 220 221} // end namespace llvm 222 223#endif // LLVM_MC_MCINST_H 224