Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:13

0001 //===- llvm/MC/MCInst.h - MCInst class --------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file contains the declaration of the MCInst and MCOperand classes, which
0010 // is the basic representation used to represent low-level machine code
0011 // instructions.
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 /// Instances of this class represent operands of the MCInst class.
0036 /// This is a simple discriminated union.
0037 class MCOperand {
0038   enum MachineOperandType : unsigned char {
0039     kInvalid,      ///< Uninitialized.
0040     kRegister,     ///< Register operand.
0041     kImmediate,    ///< Immediate operand.
0042     kSFPImmediate, ///< Single-floating-point immediate operand.
0043     kDFPImmediate, ///< Double-Floating-point immediate operand.
0044     kExpr,         ///< Relocatable immediate operand.
0045     kInst          ///< Sub-instruction operand.
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   /// Returns the register number.
0070   MCRegister getReg() const {
0071     assert(isReg() && "This is not a register operand!");
0072     return RegVal;
0073   }
0074 
0075   /// Set the register number.
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 /// Instances of this class represent a single low-level machine
0184 /// instruction.
0185 class MCInst {
0186   unsigned Opcode = 0;
0187   // These flags could be used to pass some info from one target subcomponent
0188   // to another, for example, from disassembler to asm printer. The values of
0189   // the flags have any sense on target level only (e.g. prefixes on x86).
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   /// Dump the MCInst as prettily as possible using the additional MC
0233   /// structures, if given. Operators are separated by the \p Separator
0234   /// string.
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 } // end namespace llvm
0253 
0254 #endif // LLVM_MC_MCINST_H