1320013Sdim//===- llvm/MC/MCInst.h - MCInst class --------------------------*- C++ -*-===// 2320013Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6320013Sdim// 7320013Sdim//===----------------------------------------------------------------------===// 8320013Sdim// 9320013Sdim// This file contains the declaration of the MCInst and MCOperand classes, which 10320013Sdim// is the basic representation used to represent low-level machine code 11320013Sdim// instructions. 12320013Sdim// 13320013Sdim//===----------------------------------------------------------------------===// 14320013Sdim 15320013Sdim#ifndef LLVM_MC_MCINST_H 16320013Sdim#define LLVM_MC_MCINST_H 17320013Sdim 18320013Sdim#include "llvm/ADT/SmallVector.h" 19320013Sdim#include "llvm/ADT/StringRef.h" 20320013Sdim#include "llvm/Support/SMLoc.h" 21341825Sdim#include <cassert> 22320013Sdim#include <cstddef> 23320013Sdim#include <cstdint> 24320013Sdim 25320013Sdimnamespace llvm { 26327952Sdim 27320013Sdimclass MCExpr; 28327952Sdimclass MCInst; 29341825Sdimclass MCInstPrinter; 30341825Sdimclass raw_ostream; 31341825Sdim 32341825Sdim/// Instances of this class represent operands of the MCInst class. 33341825Sdim/// This is a simple discriminated union. 34341825Sdimclass MCOperand { 35320013Sdim enum MachineOperandType : unsigned char { 36320013Sdim kInvalid, ///< Uninitialized. 37320572Sdim kRegister, ///< Register operand. 38320013Sdim kImmediate, ///< Immediate operand. 39320013Sdim kFPImmediate, ///< Floating-point immediate operand. 40341825Sdim kExpr, ///< Relocatable immediate operand. 41341825Sdim kInst ///< Sub-instruction operand. 42320013Sdim }; 43320013Sdim MachineOperandType Kind = kInvalid; 44320013Sdim 45320013Sdim union { 46320013Sdim unsigned RegVal; 47320013Sdim int64_t ImmVal; 48320013Sdim double FPImmVal; 49327952Sdim const MCExpr *ExprVal; 50327952Sdim const MCInst *InstVal; 51320013Sdim }; 52327952Sdim 53320013Sdimpublic: 54320013Sdim MCOperand() : FPImmVal(0.0) {} 55344779Sdim 56344779Sdim bool isValid() const { return Kind != kInvalid; } 57344779Sdim bool isReg() const { return Kind == kRegister; } 58344779Sdim bool isImm() const { return Kind == kImmediate; } 59344779Sdim bool isFPImm() const { return Kind == kFPImmediate; } 60327952Sdim bool isExpr() const { return Kind == kExpr; } 61341825Sdim bool isInst() const { return Kind == kInst; } 62327952Sdim 63320013Sdim /// Returns the register number. 64320013Sdim unsigned getReg() const { 65320013Sdim assert(isReg() && "This is not a register operand!"); 66320013Sdim return RegVal; 67320013Sdim } 68344779Sdim 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