Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===- MCExpr.h - Assembly Level Expressions --------------------*- 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 #ifndef LLVM_MC_MCEXPR_H
0010 #define LLVM_MC_MCEXPR_H
0011 
0012 #include "llvm/ADT/DenseMap.h"
0013 #include "llvm/Support/SMLoc.h"
0014 #include <cstdint>
0015 
0016 namespace llvm {
0017 
0018 class MCAsmInfo;
0019 class MCAssembler;
0020 class MCContext;
0021 class MCFixup;
0022 class MCFragment;
0023 class MCSection;
0024 class MCStreamer;
0025 class MCSymbol;
0026 class MCValue;
0027 class raw_ostream;
0028 class StringRef;
0029 
0030 using SectionAddrMap = DenseMap<const MCSection *, uint64_t>;
0031 
0032 /// Base class for the full range of assembler expressions which are
0033 /// needed for parsing.
0034 class MCExpr {
0035 public:
0036   enum ExprKind : uint8_t {
0037     Binary,    ///< Binary expressions.
0038     Constant,  ///< Constant expressions.
0039     SymbolRef, ///< References to labels and assigned expressions.
0040     Unary,     ///< Unary expressions.
0041     Target     ///< Target specific expression.
0042   };
0043 
0044 private:
0045   static const unsigned NumSubclassDataBits = 24;
0046   static_assert(
0047       NumSubclassDataBits == CHAR_BIT * (sizeof(unsigned) - sizeof(ExprKind)),
0048       "ExprKind and SubclassData together should take up one word");
0049 
0050   ExprKind Kind;
0051   /// Field reserved for use by MCExpr subclasses.
0052   unsigned SubclassData : NumSubclassDataBits;
0053   SMLoc Loc;
0054 
0055   bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
0056                           const SectionAddrMap *Addrs, bool InSet) const;
0057 
0058 protected:
0059   explicit MCExpr(ExprKind Kind, SMLoc Loc, unsigned SubclassData = 0)
0060       : Kind(Kind), SubclassData(SubclassData), Loc(Loc) {
0061     assert(SubclassData < (1 << NumSubclassDataBits) &&
0062            "Subclass data too large");
0063   }
0064 
0065   bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
0066                                  const MCFixup *Fixup,
0067                                  const SectionAddrMap *Addrs, bool InSet) const;
0068 
0069   unsigned getSubclassData() const { return SubclassData; }
0070 
0071 public:
0072   MCExpr(const MCExpr &) = delete;
0073   MCExpr &operator=(const MCExpr &) = delete;
0074 
0075   /// \name Accessors
0076   /// @{
0077 
0078   ExprKind getKind() const { return Kind; }
0079   SMLoc getLoc() const { return Loc; }
0080 
0081   /// @}
0082   /// \name Utility Methods
0083   /// @{
0084 
0085   void print(raw_ostream &OS, const MCAsmInfo *MAI,
0086              bool InParens = false) const;
0087   void dump() const;
0088 
0089   /// Returns whether the given symbol is used anywhere in the expression or
0090   /// subexpressions.
0091   bool isSymbolUsedInExpression(const MCSymbol *Sym) const;
0092 
0093   /// @}
0094   /// \name Expression Evaluation
0095   /// @{
0096 
0097   /// Try to evaluate the expression to an absolute value.
0098   ///
0099   /// \param Res - The absolute value, if evaluation succeeds.
0100   /// \return - True on success.
0101   bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm,
0102                           const SectionAddrMap &Addrs) const;
0103   bool evaluateAsAbsolute(int64_t &Res) const;
0104   bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
0105   bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm) const;
0106 
0107   /// Aggressive variant of evaluateAsRelocatable when relocations are
0108   /// unavailable (e.g. .fill). Expects callers to handle errors when true is
0109   /// returned.
0110   bool evaluateKnownAbsolute(int64_t &Res, const MCAssembler &Asm) const;
0111 
0112   /// Try to evaluate the expression to a relocatable value, i.e. an
0113   /// expression of the fixed form (a - b + constant).
0114   ///
0115   /// \param Res - The relocatable value, if evaluation succeeds.
0116   /// \param Asm - The assembler object to use for evaluating values.
0117   /// \param Fixup - The Fixup object if available.
0118   /// \return - True on success.
0119   bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm,
0120                              const MCFixup *Fixup) const;
0121 
0122   /// Try to evaluate the expression to the form (a - b + constant) where
0123   /// neither a nor b are variables.
0124   ///
0125   /// This is a more aggressive variant of evaluateAsRelocatable. The intended
0126   /// use is for when relocations are not available, like the .size directive.
0127   bool evaluateAsValue(MCValue &Res, const MCAssembler &Asm) const;
0128 
0129   /// Find the "associated section" for this expression, which is
0130   /// currently defined as the absolute section for constants, or
0131   /// otherwise the section associated with the first defined symbol in the
0132   /// expression.
0133   MCFragment *findAssociatedFragment() const;
0134 
0135   /// @}
0136 };
0137 
0138 inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
0139   E.print(OS, nullptr);
0140   return OS;
0141 }
0142 
0143 ////  Represent a constant integer expression.
0144 class MCConstantExpr : public MCExpr {
0145   int64_t Value;
0146 
0147   // Subclass data stores SizeInBytes in bits 0..7 and PrintInHex in bit 8.
0148   static const unsigned SizeInBytesBits = 8;
0149   static const unsigned SizeInBytesMask = (1 << SizeInBytesBits) - 1;
0150   static const unsigned PrintInHexBit = 1 << SizeInBytesBits;
0151 
0152   static unsigned encodeSubclassData(bool PrintInHex, unsigned SizeInBytes) {
0153     assert(SizeInBytes <= sizeof(int64_t) && "Excessive size");
0154     return SizeInBytes | (PrintInHex ? PrintInHexBit : 0);
0155   }
0156 
0157   MCConstantExpr(int64_t Value, bool PrintInHex, unsigned SizeInBytes)
0158       : MCExpr(MCExpr::Constant, SMLoc(),
0159                encodeSubclassData(PrintInHex, SizeInBytes)), Value(Value) {}
0160 
0161 public:
0162   /// \name Construction
0163   /// @{
0164 
0165   static const MCConstantExpr *create(int64_t Value, MCContext &Ctx,
0166                                       bool PrintInHex = false,
0167                                       unsigned SizeInBytes = 0);
0168 
0169   /// @}
0170   /// \name Accessors
0171   /// @{
0172 
0173   int64_t getValue() const { return Value; }
0174   unsigned getSizeInBytes() const {
0175     return getSubclassData() & SizeInBytesMask;
0176   }
0177 
0178   bool useHexFormat() const { return (getSubclassData() & PrintInHexBit) != 0; }
0179 
0180   /// @}
0181 
0182   static bool classof(const MCExpr *E) {
0183     return E->getKind() == MCExpr::Constant;
0184   }
0185 };
0186 
0187 ///  Represent a reference to a symbol from inside an expression.
0188 ///
0189 /// A symbol reference in an expression may be a use of a label, a use of an
0190 /// assembler variable (defined constant), or constitute an implicit definition
0191 /// of the symbol as external.
0192 class MCSymbolRefExpr : public MCExpr {
0193 public:
0194   enum VariantKind : uint16_t {
0195     VK_None,
0196     VK_Invalid,
0197 
0198     VK_GOT,
0199     VK_GOTENT,
0200     VK_GOTOFF,
0201     VK_GOTREL,
0202     VK_PCREL,
0203     VK_GOTPCREL,
0204     VK_GOTPCREL_NORELAX,
0205     VK_GOTTPOFF,
0206     VK_INDNTPOFF,
0207     VK_NTPOFF,
0208     VK_GOTNTPOFF,
0209     VK_PLT,
0210     VK_TLSGD,
0211     VK_TLSLD,
0212     VK_TLSLDM,
0213     VK_TPOFF,
0214     VK_DTPOFF,
0215     VK_TLSCALL, // symbol(tlscall)
0216     VK_TLSDESC, // symbol(tlsdesc)
0217     VK_TLVP,    // Mach-O thread local variable relocations
0218     VK_TLVPPAGE,
0219     VK_TLVPPAGEOFF,
0220     VK_PAGE,
0221     VK_PAGEOFF,
0222     VK_GOTPAGE,
0223     VK_GOTPAGEOFF,
0224     VK_SECREL,
0225     VK_SIZE,    // symbol@SIZE
0226     VK_WEAKREF, // The link between the symbols in .weakref foo, bar
0227     VK_FUNCDESC,
0228     VK_GOTFUNCDESC,
0229     VK_GOTOFFFUNCDESC,
0230     VK_TLSGD_FDPIC,
0231     VK_TLSLDM_FDPIC,
0232     VK_GOTTPOFF_FDPIC,
0233 
0234     VK_X86_ABS8,
0235     VK_X86_PLTOFF,
0236 
0237     VK_ARM_NONE,
0238     VK_ARM_GOT_PREL,
0239     VK_ARM_TARGET1,
0240     VK_ARM_TARGET2,
0241     VK_ARM_PREL31,
0242     VK_ARM_SBREL,  // symbol(sbrel)
0243     VK_ARM_TLSLDO, // symbol(tlsldo)
0244     VK_ARM_TLSDESCSEQ,
0245 
0246     VK_AVR_NONE,
0247     VK_AVR_LO8,
0248     VK_AVR_HI8,
0249     VK_AVR_HLO8,
0250     VK_AVR_DIFF8,
0251     VK_AVR_DIFF16,
0252     VK_AVR_DIFF32,
0253     VK_AVR_PM,
0254 
0255     VK_PPC_LO,              // symbol@l
0256     VK_PPC_HI,              // symbol@h
0257     VK_PPC_HA,              // symbol@ha
0258     VK_PPC_HIGH,            // symbol@high
0259     VK_PPC_HIGHA,           // symbol@higha
0260     VK_PPC_HIGHER,          // symbol@higher
0261     VK_PPC_HIGHERA,         // symbol@highera
0262     VK_PPC_HIGHEST,         // symbol@highest
0263     VK_PPC_HIGHESTA,        // symbol@highesta
0264     VK_PPC_GOT_LO,          // symbol@got@l
0265     VK_PPC_GOT_HI,          // symbol@got@h
0266     VK_PPC_GOT_HA,          // symbol@got@ha
0267     VK_PPC_TOCBASE,         // symbol@tocbase
0268     VK_PPC_TOC,             // symbol@toc
0269     VK_PPC_TOC_LO,          // symbol@toc@l
0270     VK_PPC_TOC_HI,          // symbol@toc@h
0271     VK_PPC_TOC_HA,          // symbol@toc@ha
0272     VK_PPC_U,               // symbol@u
0273     VK_PPC_L,               // symbol@l
0274     VK_PPC_DTPMOD,          // symbol@dtpmod
0275     VK_PPC_TPREL_LO,        // symbol@tprel@l
0276     VK_PPC_TPREL_HI,        // symbol@tprel@h
0277     VK_PPC_TPREL_HA,        // symbol@tprel@ha
0278     VK_PPC_TPREL_HIGH,      // symbol@tprel@high
0279     VK_PPC_TPREL_HIGHA,     // symbol@tprel@higha
0280     VK_PPC_TPREL_HIGHER,    // symbol@tprel@higher
0281     VK_PPC_TPREL_HIGHERA,   // symbol@tprel@highera
0282     VK_PPC_TPREL_HIGHEST,   // symbol@tprel@highest
0283     VK_PPC_TPREL_HIGHESTA,  // symbol@tprel@highesta
0284     VK_PPC_DTPREL_LO,       // symbol@dtprel@l
0285     VK_PPC_DTPREL_HI,       // symbol@dtprel@h
0286     VK_PPC_DTPREL_HA,       // symbol@dtprel@ha
0287     VK_PPC_DTPREL_HIGH,     // symbol@dtprel@high
0288     VK_PPC_DTPREL_HIGHA,    // symbol@dtprel@higha
0289     VK_PPC_DTPREL_HIGHER,   // symbol@dtprel@higher
0290     VK_PPC_DTPREL_HIGHERA,  // symbol@dtprel@highera
0291     VK_PPC_DTPREL_HIGHEST,  // symbol@dtprel@highest
0292     VK_PPC_DTPREL_HIGHESTA, // symbol@dtprel@highesta
0293     VK_PPC_GOT_TPREL,       // symbol@got@tprel
0294     VK_PPC_GOT_TPREL_LO,    // symbol@got@tprel@l
0295     VK_PPC_GOT_TPREL_HI,    // symbol@got@tprel@h
0296     VK_PPC_GOT_TPREL_HA,    // symbol@got@tprel@ha
0297     VK_PPC_GOT_DTPREL,      // symbol@got@dtprel
0298     VK_PPC_GOT_DTPREL_LO,   // symbol@got@dtprel@l
0299     VK_PPC_GOT_DTPREL_HI,   // symbol@got@dtprel@h
0300     VK_PPC_GOT_DTPREL_HA,   // symbol@got@dtprel@ha
0301     VK_PPC_TLS,             // symbol@tls
0302     VK_PPC_GOT_TLSGD,       // symbol@got@tlsgd
0303     VK_PPC_GOT_TLSGD_LO,    // symbol@got@tlsgd@l
0304     VK_PPC_GOT_TLSGD_HI,    // symbol@got@tlsgd@h
0305     VK_PPC_GOT_TLSGD_HA,    // symbol@got@tlsgd@ha
0306     VK_PPC_TLSGD,           // symbol@tlsgd
0307     VK_PPC_AIX_TLSGD,       // symbol@gd
0308     VK_PPC_AIX_TLSGDM,      // symbol@m
0309     VK_PPC_AIX_TLSIE,       // symbol@ie
0310     VK_PPC_AIX_TLSLE,       // symbol@le
0311     VK_PPC_AIX_TLSLD,       // symbol@ld
0312     VK_PPC_AIX_TLSML,       // symbol@ml
0313     VK_PPC_GOT_TLSLD,       // symbol@got@tlsld
0314     VK_PPC_GOT_TLSLD_LO,    // symbol@got@tlsld@l
0315     VK_PPC_GOT_TLSLD_HI,    // symbol@got@tlsld@h
0316     VK_PPC_GOT_TLSLD_HA,    // symbol@got@tlsld@ha
0317     VK_PPC_GOT_PCREL,       // symbol@got@pcrel
0318     VK_PPC_GOT_TLSGD_PCREL, // symbol@got@tlsgd@pcrel
0319     VK_PPC_GOT_TLSLD_PCREL, // symbol@got@tlsld@pcrel
0320     VK_PPC_GOT_TPREL_PCREL, // symbol@got@tprel@pcrel
0321     VK_PPC_TLS_PCREL,       // symbol@tls@pcrel
0322     VK_PPC_TLSLD,           // symbol@tlsld
0323     VK_PPC_LOCAL,           // symbol@local
0324     VK_PPC_NOTOC,           // symbol@notoc
0325     VK_PPC_PCREL_OPT,       // .reloc expr, R_PPC64_PCREL_OPT, expr
0326 
0327     VK_COFF_IMGREL32, // symbol@imgrel (image-relative)
0328 
0329     VK_Hexagon_LO16,
0330     VK_Hexagon_HI16,
0331     VK_Hexagon_GPREL,
0332     VK_Hexagon_GD_GOT,
0333     VK_Hexagon_LD_GOT,
0334     VK_Hexagon_GD_PLT,
0335     VK_Hexagon_LD_PLT,
0336     VK_Hexagon_IE,
0337     VK_Hexagon_IE_GOT,
0338 
0339     VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature)
0340     VK_WASM_TLSREL,    // Memory address relative to __tls_base
0341     VK_WASM_MBREL,     // Memory address relative to __memory_base
0342     VK_WASM_TBREL,     // Table index relative to __table_base
0343     VK_WASM_GOT_TLS,   // Wasm global index of TLS symbol.
0344     VK_WASM_FUNCINDEX, // Wasm function index.
0345 
0346     VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo
0347     VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi
0348     VK_AMDGPU_REL32_LO,      // symbol@rel32@lo
0349     VK_AMDGPU_REL32_HI,      // symbol@rel32@hi
0350     VK_AMDGPU_REL64,         // symbol@rel64
0351     VK_AMDGPU_ABS32_LO,      // symbol@abs32@lo
0352     VK_AMDGPU_ABS32_HI,      // symbol@abs32@hi
0353 
0354     VK_VE_HI32,        // symbol@hi
0355     VK_VE_LO32,        // symbol@lo
0356     VK_VE_PC_HI32,     // symbol@pc_hi
0357     VK_VE_PC_LO32,     // symbol@pc_lo
0358     VK_VE_GOT_HI32,    // symbol@got_hi
0359     VK_VE_GOT_LO32,    // symbol@got_lo
0360     VK_VE_GOTOFF_HI32, // symbol@gotoff_hi
0361     VK_VE_GOTOFF_LO32, // symbol@gotoff_lo
0362     VK_VE_PLT_HI32,    // symbol@plt_hi
0363     VK_VE_PLT_LO32,    // symbol@plt_lo
0364     VK_VE_TLS_GD_HI32, // symbol@tls_gd_hi
0365     VK_VE_TLS_GD_LO32, // symbol@tls_gd_lo
0366     VK_VE_TPOFF_HI32,  // symbol@tpoff_hi
0367     VK_VE_TPOFF_LO32,  // symbol@tpoff_lo
0368 
0369     VK_TPREL,
0370     VK_DTPREL
0371   };
0372 
0373 private:
0374   /// The symbol being referenced.
0375   const MCSymbol *Symbol;
0376 
0377   // Subclass data stores VariantKind in bits 0..15 and HasSubsectionsViaSymbols
0378   // in bit 16.
0379   static const unsigned VariantKindBits = 16;
0380   static const unsigned VariantKindMask = (1 << VariantKindBits) - 1;
0381 
0382   // FIXME: Remove this bit.
0383   static const unsigned HasSubsectionsViaSymbolsBit = 1 << VariantKindBits;
0384 
0385   static unsigned encodeSubclassData(VariantKind Kind,
0386                                      bool HasSubsectionsViaSymbols) {
0387     return (unsigned)Kind |
0388            (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0);
0389   }
0390 
0391   explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
0392                            const MCAsmInfo *MAI, SMLoc Loc = SMLoc());
0393 
0394 public:
0395   /// \name Construction
0396   /// @{
0397 
0398   static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) {
0399     return MCSymbolRefExpr::create(Symbol, VK_None, Ctx);
0400   }
0401 
0402   static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind,
0403                                        MCContext &Ctx, SMLoc Loc = SMLoc());
0404   static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind,
0405                                        MCContext &Ctx);
0406 
0407   /// @}
0408   /// \name Accessors
0409   /// @{
0410 
0411   const MCSymbol &getSymbol() const { return *Symbol; }
0412 
0413   VariantKind getKind() const {
0414     return (VariantKind)(getSubclassData() & VariantKindMask);
0415   }
0416 
0417   bool hasSubsectionsViaSymbols() const {
0418     return (getSubclassData() & HasSubsectionsViaSymbolsBit) != 0;
0419   }
0420 
0421   /// @}
0422   /// \name Static Utility Functions
0423   /// @{
0424 
0425   static StringRef getVariantKindName(VariantKind Kind);
0426 
0427   static VariantKind getVariantKindForName(StringRef Name);
0428 
0429   /// @}
0430 
0431   static bool classof(const MCExpr *E) {
0432     return E->getKind() == MCExpr::SymbolRef;
0433   }
0434 };
0435 
0436 /// Unary assembler expressions.
0437 class MCUnaryExpr : public MCExpr {
0438 public:
0439   enum Opcode {
0440     LNot,  ///< Logical negation.
0441     Minus, ///< Unary minus.
0442     Not,   ///< Bitwise negation.
0443     Plus   ///< Unary plus.
0444   };
0445 
0446 private:
0447   const MCExpr *Expr;
0448 
0449   MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc)
0450       : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {}
0451 
0452 public:
0453   /// \name Construction
0454   /// @{
0455 
0456   static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr,
0457                                    MCContext &Ctx, SMLoc Loc = SMLoc());
0458 
0459   static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
0460     return create(LNot, Expr, Ctx, Loc);
0461   }
0462 
0463   static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
0464     return create(Minus, Expr, Ctx, Loc);
0465   }
0466 
0467   static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
0468     return create(Not, Expr, Ctx, Loc);
0469   }
0470 
0471   static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
0472     return create(Plus, Expr, Ctx, Loc);
0473   }
0474 
0475   /// @}
0476   /// \name Accessors
0477   /// @{
0478 
0479   /// Get the kind of this unary expression.
0480   Opcode getOpcode() const { return (Opcode)getSubclassData(); }
0481 
0482   /// Get the child of this unary expression.
0483   const MCExpr *getSubExpr() const { return Expr; }
0484 
0485   /// @}
0486 
0487   static bool classof(const MCExpr *E) {
0488     return E->getKind() == MCExpr::Unary;
0489   }
0490 };
0491 
0492 /// Binary assembler expressions.
0493 class MCBinaryExpr : public MCExpr {
0494 public:
0495   enum Opcode {
0496     Add,  ///< Addition.
0497     And,  ///< Bitwise and.
0498     Div,  ///< Signed division.
0499     EQ,   ///< Equality comparison.
0500     GT,   ///< Signed greater than comparison (result is either 0 or some
0501           ///< target-specific non-zero value)
0502     GTE,  ///< Signed greater than or equal comparison (result is either 0 or
0503           ///< some target-specific non-zero value).
0504     LAnd, ///< Logical and.
0505     LOr,  ///< Logical or.
0506     LT,   ///< Signed less than comparison (result is either 0 or
0507           ///< some target-specific non-zero value).
0508     LTE,  ///< Signed less than or equal comparison (result is either 0 or
0509           ///< some target-specific non-zero value).
0510     Mod,  ///< Signed remainder.
0511     Mul,  ///< Multiplication.
0512     NE,   ///< Inequality comparison.
0513     Or,   ///< Bitwise or.
0514     OrNot, ///< Bitwise or not.
0515     Shl,  ///< Shift left.
0516     AShr, ///< Arithmetic shift right.
0517     LShr, ///< Logical shift right.
0518     Sub,  ///< Subtraction.
0519     Xor   ///< Bitwise exclusive or.
0520   };
0521 
0522 private:
0523   const MCExpr *LHS, *RHS;
0524 
0525   MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS,
0526                SMLoc Loc = SMLoc())
0527       : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {}
0528 
0529 public:
0530   /// \name Construction
0531   /// @{
0532 
0533   static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS,
0534                                     const MCExpr *RHS, MCContext &Ctx,
0535                                     SMLoc Loc = SMLoc());
0536 
0537   static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS,
0538                                        MCContext &Ctx) {
0539     return create(Add, LHS, RHS, Ctx);
0540   }
0541 
0542   static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS,
0543                                        MCContext &Ctx) {
0544     return create(And, LHS, RHS, Ctx);
0545   }
0546 
0547   static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS,
0548                                        MCContext &Ctx) {
0549     return create(Div, LHS, RHS, Ctx);
0550   }
0551 
0552   static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS,
0553                                       MCContext &Ctx) {
0554     return create(EQ, LHS, RHS, Ctx);
0555   }
0556 
0557   static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS,
0558                                       MCContext &Ctx) {
0559     return create(GT, LHS, RHS, Ctx);
0560   }
0561 
0562   static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS,
0563                                        MCContext &Ctx) {
0564     return create(GTE, LHS, RHS, Ctx);
0565   }
0566 
0567   static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS,
0568                                         MCContext &Ctx) {
0569     return create(LAnd, LHS, RHS, Ctx);
0570   }
0571 
0572   static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS,
0573                                        MCContext &Ctx) {
0574     return create(LOr, LHS, RHS, Ctx);
0575   }
0576 
0577   static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS,
0578                                       MCContext &Ctx) {
0579     return create(LT, LHS, RHS, Ctx);
0580   }
0581 
0582   static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS,
0583                                        MCContext &Ctx) {
0584     return create(LTE, LHS, RHS, Ctx);
0585   }
0586 
0587   static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS,
0588                                        MCContext &Ctx) {
0589     return create(Mod, LHS, RHS, Ctx);
0590   }
0591 
0592   static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS,
0593                                        MCContext &Ctx) {
0594     return create(Mul, LHS, RHS, Ctx);
0595   }
0596 
0597   static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS,
0598                                       MCContext &Ctx) {
0599     return create(NE, LHS, RHS, Ctx);
0600   }
0601 
0602   static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS,
0603                                       MCContext &Ctx) {
0604     return create(Or, LHS, RHS, Ctx);
0605   }
0606 
0607   static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS,
0608                                        MCContext &Ctx) {
0609     return create(Shl, LHS, RHS, Ctx);
0610   }
0611 
0612   static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS,
0613                                        MCContext &Ctx) {
0614     return create(AShr, LHS, RHS, Ctx);
0615   }
0616 
0617   static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS,
0618                                        MCContext &Ctx) {
0619     return create(LShr, LHS, RHS, Ctx);
0620   }
0621 
0622   static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS,
0623                                        MCContext &Ctx) {
0624     return create(Sub, LHS, RHS, Ctx);
0625   }
0626 
0627   static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS,
0628                                        MCContext &Ctx) {
0629     return create(Xor, LHS, RHS, Ctx);
0630   }
0631 
0632   /// @}
0633   /// \name Accessors
0634   /// @{
0635 
0636   /// Get the kind of this binary expression.
0637   Opcode getOpcode() const { return (Opcode)getSubclassData(); }
0638 
0639   /// Get the left-hand side expression of the binary operator.
0640   const MCExpr *getLHS() const { return LHS; }
0641 
0642   /// Get the right-hand side expression of the binary operator.
0643   const MCExpr *getRHS() const { return RHS; }
0644 
0645   /// @}
0646 
0647   static bool classof(const MCExpr *E) {
0648     return E->getKind() == MCExpr::Binary;
0649   }
0650 };
0651 
0652 /// This is an extension point for target-specific MCExpr subclasses to
0653 /// implement.
0654 ///
0655 /// NOTE: All subclasses are required to have trivial destructors because
0656 /// MCExprs are bump pointer allocated and not destructed.
0657 class MCTargetExpr : public MCExpr {
0658   virtual void anchor();
0659 
0660 protected:
0661   MCTargetExpr() : MCExpr(Target, SMLoc()) {}
0662   virtual ~MCTargetExpr() = default;
0663 
0664 public:
0665   virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0;
0666   virtual bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
0667                                          const MCFixup *Fixup) const = 0;
0668   // allow Target Expressions to be checked for equality
0669   virtual bool isEqualTo(const MCExpr *x) const { return false; }
0670   virtual bool isSymbolUsedInExpression(const MCSymbol *Sym) const {
0671     return false;
0672   }
0673   // This should be set when assigned expressions are not valid ".set"
0674   // expressions, e.g. registers, and must be inlined.
0675   virtual bool inlineAssignedExpr() const { return false; }
0676   virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
0677   virtual MCFragment *findAssociatedFragment() const = 0;
0678 
0679   virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
0680 
0681   static bool classof(const MCExpr *E) {
0682     return E->getKind() == MCExpr::Target;
0683   }
0684 };
0685 
0686 } // end namespace llvm
0687 
0688 #endif // LLVM_MC_MCEXPR_H