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