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/DataTypes.h" 22 #include "llvm/Support/SMLoc.h" 23 24 namespace llvm { 25 class raw_ostream; 26 class MCAsmInfo; 27 class MCInstPrinter; 28 class MCExpr; 29 class MCInst; 30 31 /// \brief Instances of this class represent operands of the MCInst class. 32 /// This is a simple discriminated union. 33 class MCOperand { 34 enum MachineOperandType : unsigned char { 35 kInvalid, ///< Uninitialized. 36 kRegister, ///< Register operand. 37 kImmediate, ///< Immediate operand. 38 kFPImmediate, ///< Floating-point immediate operand. 39 kExpr, ///< Relocatable immediate operand. 40 kInst ///< Sub-instruction operand. 41 }; 42 MachineOperandType Kind; 43 44 union { 45 unsigned RegVal; 46 int64_t ImmVal; 47 double FPImmVal; 48 const MCExpr *ExprVal; 49 const MCInst *InstVal; 50 }; 51 52 public: MCOperand()53 MCOperand() : Kind(kInvalid), FPImmVal(0.0) {} 54 isValid()55 bool isValid() const { return Kind != kInvalid; } isReg()56 bool isReg() const { return Kind == kRegister; } isImm()57 bool isImm() const { return Kind == kImmediate; } isFPImm()58 bool isFPImm() const { return Kind == kFPImmediate; } isExpr()59 bool isExpr() const { return Kind == kExpr; } isInst()60 bool isInst() const { return Kind == kInst; } 61 62 /// \brief Returns the register number. getReg()63 unsigned getReg() const { 64 assert(isReg() && "This is not a register operand!"); 65 return RegVal; 66 } 67 68 /// \brief Set the register number. setReg(unsigned Reg)69 void setReg(unsigned Reg) { 70 assert(isReg() && "This is not a register operand!"); 71 RegVal = Reg; 72 } 73 getImm()74 int64_t getImm() const { 75 assert(isImm() && "This is not an immediate"); 76 return ImmVal; 77 } setImm(int64_t Val)78 void setImm(int64_t Val) { 79 assert(isImm() && "This is not an immediate"); 80 ImmVal = Val; 81 } 82 getFPImm()83 double getFPImm() const { 84 assert(isFPImm() && "This is not an FP immediate"); 85 return FPImmVal; 86 } 87 setFPImm(double Val)88 void setFPImm(double Val) { 89 assert(isFPImm() && "This is not an FP immediate"); 90 FPImmVal = Val; 91 } 92 getExpr()93 const MCExpr *getExpr() const { 94 assert(isExpr() && "This is not an expression"); 95 return ExprVal; 96 } setExpr(const MCExpr * Val)97 void setExpr(const MCExpr *Val) { 98 assert(isExpr() && "This is not an expression"); 99 ExprVal = Val; 100 } 101 getInst()102 const MCInst *getInst() const { 103 assert(isInst() && "This is not a sub-instruction"); 104 return InstVal; 105 } setInst(const MCInst * Val)106 void setInst(const MCInst *Val) { 107 assert(isInst() && "This is not a sub-instruction"); 108 InstVal = Val; 109 } 110 createReg(unsigned Reg)111 static MCOperand createReg(unsigned Reg) { 112 MCOperand Op; 113 Op.Kind = kRegister; 114 Op.RegVal = Reg; 115 return Op; 116 } createImm(int64_t Val)117 static MCOperand createImm(int64_t Val) { 118 MCOperand Op; 119 Op.Kind = kImmediate; 120 Op.ImmVal = Val; 121 return Op; 122 } createFPImm(double Val)123 static MCOperand createFPImm(double Val) { 124 MCOperand Op; 125 Op.Kind = kFPImmediate; 126 Op.FPImmVal = Val; 127 return Op; 128 } createExpr(const MCExpr * Val)129 static MCOperand createExpr(const MCExpr *Val) { 130 MCOperand Op; 131 Op.Kind = kExpr; 132 Op.ExprVal = Val; 133 return Op; 134 } createInst(const MCInst * Val)135 static MCOperand createInst(const MCInst *Val) { 136 MCOperand Op; 137 Op.Kind = kInst; 138 Op.InstVal = Val; 139 return Op; 140 } 141 142 void print(raw_ostream &OS) const; 143 void dump() const; 144 }; 145 146 template <> struct isPodLike<MCOperand> { static const bool value = true; }; 147 148 /// \brief Instances of this class represent a single low-level machine 149 /// instruction. 150 class MCInst { 151 unsigned Opcode; 152 SMLoc Loc; 153 SmallVector<MCOperand, 8> Operands; 154 155 public: 156 MCInst() : Opcode(0) {} 157 158 void setOpcode(unsigned Op) { Opcode = Op; } 159 unsigned getOpcode() const { return Opcode; } 160 161 void setLoc(SMLoc loc) { Loc = loc; } 162 SMLoc getLoc() const { return Loc; } 163 164 const MCOperand &getOperand(unsigned i) const { return Operands[i]; } 165 MCOperand &getOperand(unsigned i) { return Operands[i]; } 166 unsigned getNumOperands() const { return Operands.size(); } 167 168 void addOperand(const MCOperand &Op) { Operands.push_back(Op); } 169 170 typedef SmallVectorImpl<MCOperand>::iterator iterator; 171 typedef SmallVectorImpl<MCOperand>::const_iterator const_iterator; 172 void clear() { Operands.clear(); } 173 void erase(iterator I) { Operands.erase(I); } 174 size_t size() const { return Operands.size(); } 175 iterator begin() { return Operands.begin(); } 176 const_iterator begin() const { return Operands.begin(); } 177 iterator end() { return Operands.end(); } 178 const_iterator end() const { return Operands.end(); } 179 iterator insert(iterator I, const MCOperand &Op) { 180 return Operands.insert(I, Op); 181 } 182 183 void print(raw_ostream &OS) const; 184 void dump() const; 185 186 /// \brief Dump the MCInst as prettily as possible using the additional MC 187 /// structures, if given. Operators are separated by the \p Separator 188 /// string. 189 void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr, 190 StringRef Separator = " ") const; 191 }; 192 193 inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) { 194 MO.print(OS); 195 return OS; 196 } 197 198 inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) { 199 MI.print(OS); 200 return OS; 201 } 202 203 } // end namespace llvm 204 205 #endif 206