LLVM API Documentation
00001 //===-- llvm/MC/MCInst.h - MCInst class -------------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the declaration of the MCInst and MCOperand classes, which 00011 // is the basic representation used to represent low-level machine code 00012 // instructions. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #ifndef LLVM_MC_MCINST_H 00017 #define LLVM_MC_MCINST_H 00018 00019 #include "llvm/ADT/SmallVector.h" 00020 #include "llvm/ADT/StringRef.h" 00021 #include "llvm/Support/DataTypes.h" 00022 #include "llvm/Support/SMLoc.h" 00023 00024 namespace llvm { 00025 class raw_ostream; 00026 class MCAsmInfo; 00027 class MCInstPrinter; 00028 class MCExpr; 00029 class MCInst; 00030 00031 /// MCOperand - Instances of this class represent operands of the MCInst class. 00032 /// This is a simple discriminated union. 00033 class MCOperand { 00034 enum MachineOperandType { 00035 kInvalid, ///< Uninitialized. 00036 kRegister, ///< Register operand. 00037 kImmediate, ///< Immediate operand. 00038 kFPImmediate, ///< Floating-point immediate operand. 00039 kExpr, ///< Relocatable immediate operand. 00040 kInst ///< Sub-instruction operand. 00041 }; 00042 unsigned char Kind; 00043 00044 union { 00045 unsigned RegVal; 00046 int64_t ImmVal; 00047 double FPImmVal; 00048 const MCExpr *ExprVal; 00049 const MCInst *InstVal; 00050 }; 00051 public: 00052 00053 MCOperand() : Kind(kInvalid), FPImmVal(0.0) {} 00054 00055 bool isValid() const { return Kind != kInvalid; } 00056 bool isReg() const { return Kind == kRegister; } 00057 bool isImm() const { return Kind == kImmediate; } 00058 bool isFPImm() const { return Kind == kFPImmediate; } 00059 bool isExpr() const { return Kind == kExpr; } 00060 bool isInst() const { return Kind == kInst; } 00061 00062 /// getReg - Returns the register number. 00063 unsigned getReg() const { 00064 assert(isReg() && "This is not a register operand!"); 00065 return RegVal; 00066 } 00067 00068 /// setReg - Set the register number. 00069 void setReg(unsigned Reg) { 00070 assert(isReg() && "This is not a register operand!"); 00071 RegVal = Reg; 00072 } 00073 00074 int64_t getImm() const { 00075 assert(isImm() && "This is not an immediate"); 00076 return ImmVal; 00077 } 00078 void setImm(int64_t Val) { 00079 assert(isImm() && "This is not an immediate"); 00080 ImmVal = Val; 00081 } 00082 00083 double getFPImm() const { 00084 assert(isFPImm() && "This is not an FP immediate"); 00085 return FPImmVal; 00086 } 00087 00088 void setFPImm(double Val) { 00089 assert(isFPImm() && "This is not an FP immediate"); 00090 FPImmVal = Val; 00091 } 00092 00093 const MCExpr *getExpr() const { 00094 assert(isExpr() && "This is not an expression"); 00095 return ExprVal; 00096 } 00097 void setExpr(const MCExpr *Val) { 00098 assert(isExpr() && "This is not an expression"); 00099 ExprVal = Val; 00100 } 00101 00102 const MCInst *getInst() const { 00103 assert(isInst() && "This is not a sub-instruction"); 00104 return InstVal; 00105 } 00106 void setInst(const MCInst *Val) { 00107 assert(isInst() && "This is not a sub-instruction"); 00108 InstVal = Val; 00109 } 00110 00111 static MCOperand CreateReg(unsigned Reg) { 00112 MCOperand Op; 00113 Op.Kind = kRegister; 00114 Op.RegVal = Reg; 00115 return Op; 00116 } 00117 static MCOperand CreateImm(int64_t Val) { 00118 MCOperand Op; 00119 Op.Kind = kImmediate; 00120 Op.ImmVal = Val; 00121 return Op; 00122 } 00123 static MCOperand CreateFPImm(double Val) { 00124 MCOperand Op; 00125 Op.Kind = kFPImmediate; 00126 Op.FPImmVal = Val; 00127 return Op; 00128 } 00129 static MCOperand CreateExpr(const MCExpr *Val) { 00130 MCOperand Op; 00131 Op.Kind = kExpr; 00132 Op.ExprVal = Val; 00133 return Op; 00134 } 00135 static MCOperand CreateInst(const MCInst *Val) { 00136 MCOperand Op; 00137 Op.Kind = kInst; 00138 Op.InstVal = Val; 00139 return Op; 00140 } 00141 00142 void print(raw_ostream &OS, const MCAsmInfo *MAI) const; 00143 void dump() const; 00144 }; 00145 00146 template <> struct isPodLike<MCOperand> { static const bool value = true; }; 00147 00148 /// MCInst - Instances of this class represent a single low-level machine 00149 /// instruction. 00150 class MCInst { 00151 unsigned Opcode; 00152 SMLoc Loc; 00153 SmallVector<MCOperand, 8> Operands; 00154 public: 00155 MCInst() : Opcode(0) {} 00156 00157 void setOpcode(unsigned Op) { Opcode = Op; } 00158 unsigned getOpcode() const { return Opcode; } 00159 00160 void setLoc(SMLoc loc) { Loc = loc; } 00161 SMLoc getLoc() const { return Loc; } 00162 00163 const MCOperand &getOperand(unsigned i) const { return Operands[i]; } 00164 MCOperand &getOperand(unsigned i) { return Operands[i]; } 00165 unsigned getNumOperands() const { return Operands.size(); } 00166 00167 void addOperand(const MCOperand &Op) { 00168 Operands.push_back(Op); 00169 } 00170 00171 void clear() { Operands.clear(); } 00172 size_t size() { return Operands.size(); } 00173 00174 typedef SmallVectorImpl<MCOperand>::iterator iterator; 00175 iterator begin() { return Operands.begin(); } 00176 iterator end() { return Operands.end(); } 00177 iterator insert(iterator I, const MCOperand &Op) { 00178 return Operands.insert(I, Op); 00179 } 00180 00181 void print(raw_ostream &OS, const MCAsmInfo *MAI) const; 00182 void dump() const; 00183 00184 /// \brief Dump the MCInst as prettily as possible using the additional MC 00185 /// structures, if given. Operators are separated by the \p Separator 00186 /// string. 00187 void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = nullptr, 00188 const MCInstPrinter *Printer = nullptr, 00189 StringRef Separator = " ") const; 00190 }; 00191 00192 inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) { 00193 MO.print(OS, nullptr); 00194 return OS; 00195 } 00196 00197 inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) { 00198 MI.print(OS, nullptr); 00199 return OS; 00200 } 00201 00202 } // end namespace llvm 00203 00204 #endif