MCInst.h revision 360784
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 25namespace llvm { 26 27class MCExpr; 28class MCInst; 29class MCInstPrinter; 30class raw_ostream; 31 32/// Instances of this class represent operands of the MCInst class. 33/// This is a simple discriminated union. 34class 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 53public: 54 MCOperand() : FPImmVal(0.0) {} 55 56 bool isValid() const { return Kind != kInvalid; } 57 bool isReg() const { return Kind == kRegister; } 58 bool isImm() const { return Kind == kImmediate; } 59 bool isFPImm() const { return Kind == kFPImmediate; } 60 bool isExpr() const { return Kind == kExpr; } 61 bool isInst() const { return Kind == kInst; } 62 63 /// Returns the register number. 64 unsigned getReg() const { 65 assert(isReg() && "This is not a register operand!"); 66 return RegVal; 67 } 68 69 /// Set the register number. 70 void setReg(unsigned Reg) { 71 assert(isReg() && "This is not a register operand!"); 72 RegVal = Reg; 73 } 74 75 int64_t getImm() const { 76 assert(isImm() && "This is not an immediate"); 77 return ImmVal; 78 } 79 80 void setImm(int64_t Val) { 81 assert(isImm() && "This is not an immediate"); 82 ImmVal = Val; 83 } 84 85 double getFPImm() const { 86 assert(isFPImm() && "This is not an FP immediate"); 87 return FPImmVal; 88 } 89 90 void setFPImm(double Val) { 91 assert(isFPImm() && "This is not an FP immediate"); 92 FPImmVal = Val; 93 } 94 95 const MCExpr *getExpr() const { 96 assert(isExpr() && "This is not an expression"); 97 return ExprVal; 98 } 99 100 void setExpr(const MCExpr *Val) { 101 assert(isExpr() && "This is not an expression"); 102 ExprVal = Val; 103 } 104 105 const MCInst *getInst() const { 106 assert(isInst() && "This is not a sub-instruction"); 107 return InstVal; 108 } 109 110 void setInst(const MCInst *Val) { 111 assert(isInst() && "This is not a sub-instruction"); 112 InstVal = Val; 113 } 114 115 static MCOperand createReg(unsigned Reg) { 116 MCOperand Op; 117 Op.Kind = kRegister; 118 Op.RegVal = Reg; 119 return Op; 120 } 121 122 static MCOperand createImm(int64_t Val) { 123 MCOperand Op; 124 Op.Kind = kImmediate; 125 Op.ImmVal = Val; 126 return Op; 127 } 128 129 static MCOperand createFPImm(double Val) { 130 MCOperand Op; 131 Op.Kind = kFPImmediate; 132 Op.FPImmVal = Val; 133 return Op; 134 } 135 136 static MCOperand createExpr(const MCExpr *Val) { 137 MCOperand Op; 138 Op.Kind = kExpr; 139 Op.ExprVal = Val; 140 return Op; 141 } 142 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. 158class 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 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 void erase(iterator First, iterator Last) { Operands.erase(First, Last); } 192 size_t size() const { return Operands.size(); } 193 iterator begin() { return Operands.begin(); } 194 const_iterator begin() const { return Operands.begin(); } 195 iterator end() { return Operands.end(); } 196 const_iterator end() const { return Operands.end(); } 197 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 214inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) { 215 MO.print(OS); 216 return OS; 217} 218 219inline 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