File indexing completed on 2026-05-10 08:44:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_MC_MCINST_H
0016 #define LLVM_MC_MCINST_H
0017
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/ADT/StringRef.h"
0020 #include "llvm/ADT/bit.h"
0021 #include "llvm/MC/MCRegister.h"
0022 #include "llvm/Support/SMLoc.h"
0023 #include <cassert>
0024 #include <cstddef>
0025 #include <cstdint>
0026
0027 namespace llvm {
0028
0029 class MCExpr;
0030 class MCInst;
0031 class MCInstPrinter;
0032 class MCRegisterInfo;
0033 class raw_ostream;
0034
0035
0036
0037 class MCOperand {
0038 enum MachineOperandType : unsigned char {
0039 kInvalid,
0040 kRegister,
0041 kImmediate,
0042 kSFPImmediate,
0043 kDFPImmediate,
0044 kExpr,
0045 kInst
0046 };
0047 MachineOperandType Kind = kInvalid;
0048
0049 union {
0050 unsigned RegVal;
0051 int64_t ImmVal;
0052 uint32_t SFPImmVal;
0053 uint64_t FPImmVal;
0054 const MCExpr *ExprVal;
0055 const MCInst *InstVal;
0056 };
0057
0058 public:
0059 MCOperand() : FPImmVal(0) {}
0060
0061 bool isValid() const { return Kind != kInvalid; }
0062 bool isReg() const { return Kind == kRegister; }
0063 bool isImm() const { return Kind == kImmediate; }
0064 bool isSFPImm() const { return Kind == kSFPImmediate; }
0065 bool isDFPImm() const { return Kind == kDFPImmediate; }
0066 bool isExpr() const { return Kind == kExpr; }
0067 bool isInst() const { return Kind == kInst; }
0068
0069
0070 MCRegister getReg() const {
0071 assert(isReg() && "This is not a register operand!");
0072 return RegVal;
0073 }
0074
0075
0076 void setReg(MCRegister Reg) {
0077 assert(isReg() && "This is not a register operand!");
0078 RegVal = Reg.id();
0079 }
0080
0081 int64_t getImm() const {
0082 assert(isImm() && "This is not an immediate");
0083 return ImmVal;
0084 }
0085
0086 void setImm(int64_t Val) {
0087 assert(isImm() && "This is not an immediate");
0088 ImmVal = Val;
0089 }
0090
0091 uint32_t getSFPImm() const {
0092 assert(isSFPImm() && "This is not an SFP immediate");
0093 return SFPImmVal;
0094 }
0095
0096 void setSFPImm(uint32_t Val) {
0097 assert(isSFPImm() && "This is not an SFP immediate");
0098 SFPImmVal = Val;
0099 }
0100
0101 uint64_t getDFPImm() const {
0102 assert(isDFPImm() && "This is not an FP immediate");
0103 return FPImmVal;
0104 }
0105
0106 void setDFPImm(uint64_t Val) {
0107 assert(isDFPImm() && "This is not an FP immediate");
0108 FPImmVal = Val;
0109 }
0110 void setFPImm(double Val) {
0111 assert(isDFPImm() && "This is not an FP immediate");
0112 FPImmVal = bit_cast<uint64_t>(Val);
0113 }
0114
0115 const MCExpr *getExpr() const {
0116 assert(isExpr() && "This is not an expression");
0117 return ExprVal;
0118 }
0119
0120 void setExpr(const MCExpr *Val) {
0121 assert(isExpr() && "This is not an expression");
0122 ExprVal = Val;
0123 }
0124
0125 const MCInst *getInst() const {
0126 assert(isInst() && "This is not a sub-instruction");
0127 return InstVal;
0128 }
0129
0130 void setInst(const MCInst *Val) {
0131 assert(isInst() && "This is not a sub-instruction");
0132 InstVal = Val;
0133 }
0134
0135 static MCOperand createReg(MCRegister Reg) {
0136 MCOperand Op;
0137 Op.Kind = kRegister;
0138 Op.RegVal = Reg.id();
0139 return Op;
0140 }
0141
0142 static MCOperand createImm(int64_t Val) {
0143 MCOperand Op;
0144 Op.Kind = kImmediate;
0145 Op.ImmVal = Val;
0146 return Op;
0147 }
0148
0149 static MCOperand createSFPImm(uint32_t Val) {
0150 MCOperand Op;
0151 Op.Kind = kSFPImmediate;
0152 Op.SFPImmVal = Val;
0153 return Op;
0154 }
0155
0156 static MCOperand createDFPImm(uint64_t Val) {
0157 MCOperand Op;
0158 Op.Kind = kDFPImmediate;
0159 Op.FPImmVal = Val;
0160 return Op;
0161 }
0162
0163 static MCOperand createExpr(const MCExpr *Val) {
0164 MCOperand Op;
0165 Op.Kind = kExpr;
0166 Op.ExprVal = Val;
0167 return Op;
0168 }
0169
0170 static MCOperand createInst(const MCInst *Val) {
0171 MCOperand Op;
0172 Op.Kind = kInst;
0173 Op.InstVal = Val;
0174 return Op;
0175 }
0176
0177 void print(raw_ostream &OS, const MCRegisterInfo *RegInfo = nullptr) const;
0178 void dump() const;
0179 bool isBareSymbolRef() const;
0180 bool evaluateAsConstantImm(int64_t &Imm) const;
0181 };
0182
0183
0184
0185 class MCInst {
0186 unsigned Opcode = 0;
0187
0188
0189
0190 unsigned Flags = 0;
0191
0192 SMLoc Loc;
0193 SmallVector<MCOperand, 6> Operands;
0194
0195 public:
0196 MCInst() = default;
0197
0198 void setOpcode(unsigned Op) { Opcode = Op; }
0199 unsigned getOpcode() const { return Opcode; }
0200
0201 void setFlags(unsigned F) { Flags = F; }
0202 unsigned getFlags() const { return Flags; }
0203
0204 void setLoc(SMLoc loc) { Loc = loc; }
0205 SMLoc getLoc() const { return Loc; }
0206
0207 const MCOperand &getOperand(unsigned i) const { return Operands[i]; }
0208 MCOperand &getOperand(unsigned i) { return Operands[i]; }
0209 unsigned getNumOperands() const { return Operands.size(); }
0210
0211 void addOperand(const MCOperand Op) { Operands.push_back(Op); }
0212
0213 using iterator = SmallVectorImpl<MCOperand>::iterator;
0214 using const_iterator = SmallVectorImpl<MCOperand>::const_iterator;
0215
0216 void clear() { Operands.clear(); }
0217 void erase(iterator I) { Operands.erase(I); }
0218 void erase(iterator First, iterator Last) { Operands.erase(First, Last); }
0219 size_t size() const { return Operands.size(); }
0220 iterator begin() { return Operands.begin(); }
0221 const_iterator begin() const { return Operands.begin(); }
0222 iterator end() { return Operands.end(); }
0223 const_iterator end() const { return Operands.end(); }
0224
0225 iterator insert(iterator I, const MCOperand &Op) {
0226 return Operands.insert(I, Op);
0227 }
0228
0229 void print(raw_ostream &OS, const MCRegisterInfo *RegInfo = nullptr) const;
0230 void dump() const;
0231
0232
0233
0234
0235 void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer = nullptr,
0236 StringRef Separator = " ",
0237 const MCRegisterInfo *RegInfo = nullptr) const;
0238 void dump_pretty(raw_ostream &OS, StringRef Name, StringRef Separator = " ",
0239 const MCRegisterInfo *RegInfo = nullptr) const;
0240 };
0241
0242 inline raw_ostream& operator<<(raw_ostream &OS, const MCOperand &MO) {
0243 MO.print(OS);
0244 return OS;
0245 }
0246
0247 inline raw_ostream& operator<<(raw_ostream &OS, const MCInst &MI) {
0248 MI.print(OS);
0249 return OS;
0250 }
0251
0252 }
0253
0254 #endif