Home | History | Annotate | Line # | Download | only in MC
      1 //===- MCExpr.h - Assembly Level Expressions --------------------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #ifndef LLVM_MC_MCEXPR_H
     10 #define LLVM_MC_MCEXPR_H
     11 
     12 #include "llvm/ADT/DenseMap.h"
     13 #include "llvm/Support/SMLoc.h"
     14 #include <cstdint>
     15 
     16 namespace llvm {
     17 
     18 class MCAsmInfo;
     19 class MCAsmLayout;
     20 class MCAssembler;
     21 class MCContext;
     22 class MCFixup;
     23 class MCFragment;
     24 class MCSection;
     25 class MCStreamer;
     26 class MCSymbol;
     27 class MCValue;
     28 class raw_ostream;
     29 class StringRef;
     30 
     31 using SectionAddrMap = DenseMap<const MCSection *, uint64_t>;
     32 
     33 /// Base class for the full range of assembler expressions which are
     34 /// needed for parsing.
     35 class MCExpr {
     36 public:
     37   enum ExprKind : uint8_t {
     38     Binary,    ///< Binary expressions.
     39     Constant,  ///< Constant expressions.
     40     SymbolRef, ///< References to labels and assigned expressions.
     41     Unary,     ///< Unary expressions.
     42     Target     ///< Target specific expression.
     43   };
     44 
     45 private:
     46   static const unsigned NumSubclassDataBits = 24;
     47   static_assert(
     48       NumSubclassDataBits == CHAR_BIT * (sizeof(unsigned) - sizeof(ExprKind)),
     49       "ExprKind and SubclassData together should take up one word");
     50 
     51   ExprKind Kind;
     52   /// Field reserved for use by MCExpr subclasses.
     53   unsigned SubclassData : NumSubclassDataBits;
     54   SMLoc Loc;
     55 
     56   bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
     57                           const MCAsmLayout *Layout,
     58                           const SectionAddrMap *Addrs, bool InSet) const;
     59 
     60 protected:
     61   explicit MCExpr(ExprKind Kind, SMLoc Loc, unsigned SubclassData = 0)
     62       : Kind(Kind), SubclassData(SubclassData), Loc(Loc) {
     63     assert(SubclassData < (1 << NumSubclassDataBits) &&
     64            "Subclass data too large");
     65   }
     66 
     67   bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
     68                                  const MCAsmLayout *Layout,
     69                                  const MCFixup *Fixup,
     70                                  const SectionAddrMap *Addrs, bool InSet) const;
     71 
     72   unsigned getSubclassData() const { return SubclassData; }
     73 
     74 public:
     75   MCExpr(const MCExpr &) = delete;
     76   MCExpr &operator=(const MCExpr &) = delete;
     77 
     78   /// \name Accessors
     79   /// @{
     80 
     81   ExprKind getKind() const { return Kind; }
     82   SMLoc getLoc() const { return Loc; }
     83 
     84   /// @}
     85   /// \name Utility Methods
     86   /// @{
     87 
     88   void print(raw_ostream &OS, const MCAsmInfo *MAI,
     89              bool InParens = false) const;
     90   void dump() const;
     91 
     92   /// @}
     93   /// \name Expression Evaluation
     94   /// @{
     95 
     96   /// Try to evaluate the expression to an absolute value.
     97   ///
     98   /// \param Res - The absolute value, if evaluation succeeds.
     99   /// \param Layout - The assembler layout object to use for evaluating symbol
    100   /// values. If not given, then only non-symbolic expressions will be
    101   /// evaluated.
    102   /// \return - True on success.
    103   bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
    104                           const SectionAddrMap &Addrs) const;
    105   bool evaluateAsAbsolute(int64_t &Res) const;
    106   bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
    107   bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm) const;
    108   bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
    109 
    110   bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
    111 
    112   /// Try to evaluate the expression to a relocatable value, i.e. an
    113   /// expression of the fixed form (a - b + constant).
    114   ///
    115   /// \param Res - The relocatable value, if evaluation succeeds.
    116   /// \param Layout - The assembler layout object to use for evaluating values.
    117   /// \param Fixup - The Fixup object if available.
    118   /// \return - True on success.
    119   bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout,
    120                              const MCFixup *Fixup) const;
    121 
    122   /// Try to evaluate the expression to the form (a - b + constant) where
    123   /// neither a nor b are variables.
    124   ///
    125   /// This is a more aggressive variant of evaluateAsRelocatable. The intended
    126   /// use is for when relocations are not available, like the .size directive.
    127   bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const;
    128 
    129   /// Find the "associated section" for this expression, which is
    130   /// currently defined as the absolute section for constants, or
    131   /// otherwise the section associated with the first defined symbol in the
    132   /// expression.
    133   MCFragment *findAssociatedFragment() const;
    134 
    135   /// @}
    136 };
    137 
    138 inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
    139   E.print(OS, nullptr);
    140   return OS;
    141 }
    142 
    143 ////  Represent a constant integer expression.
    144 class MCConstantExpr : public MCExpr {
    145   int64_t Value;
    146 
    147   // Subclass data stores SizeInBytes in bits 0..7 and PrintInHex in bit 8.
    148   static const unsigned SizeInBytesBits = 8;
    149   static const unsigned SizeInBytesMask = (1 << SizeInBytesBits) - 1;
    150   static const unsigned PrintInHexBit = 1 << SizeInBytesBits;
    151 
    152   static unsigned encodeSubclassData(bool PrintInHex, unsigned SizeInBytes) {
    153     assert(SizeInBytes <= sizeof(int64_t) && "Excessive size");
    154     return SizeInBytes | (PrintInHex ? PrintInHexBit : 0);
    155   }
    156 
    157   MCConstantExpr(int64_t Value, bool PrintInHex, unsigned SizeInBytes)
    158       : MCExpr(MCExpr::Constant, SMLoc(),
    159                encodeSubclassData(PrintInHex, SizeInBytes)), Value(Value) {}
    160 
    161 public:
    162   /// \name Construction
    163   /// @{
    164 
    165   static const MCConstantExpr *create(int64_t Value, MCContext &Ctx,
    166                                       bool PrintInHex = false,
    167                                       unsigned SizeInBytes = 0);
    168 
    169   /// @}
    170   /// \name Accessors
    171   /// @{
    172 
    173   int64_t getValue() const { return Value; }
    174   unsigned getSizeInBytes() const {
    175     return getSubclassData() & SizeInBytesMask;
    176   }
    177 
    178   bool useHexFormat() const { return (getSubclassData() & PrintInHexBit) != 0; }
    179 
    180   /// @}
    181 
    182   static bool classof(const MCExpr *E) {
    183     return E->getKind() == MCExpr::Constant;
    184   }
    185 };
    186 
    187 ///  Represent a reference to a symbol from inside an expression.
    188 ///
    189 /// A symbol reference in an expression may be a use of a label, a use of an
    190 /// assembler variable (defined constant), or constitute an implicit definition
    191 /// of the symbol as external.
    192 class MCSymbolRefExpr : public MCExpr {
    193 public:
    194   enum VariantKind : uint16_t {
    195     VK_None,
    196     VK_Invalid,
    197 
    198     VK_GOT,
    199     VK_GOTOFF,
    200     VK_GOTREL,
    201     VK_PCREL,
    202     VK_GOTPCREL,
    203     VK_GOTTPOFF,
    204     VK_INDNTPOFF,
    205     VK_NTPOFF,
    206     VK_GOTNTPOFF,
    207     VK_PLT,
    208     VK_TLSGD,
    209     VK_TLSLD,
    210     VK_TLSLDM,
    211     VK_TPOFF,
    212     VK_DTPOFF,
    213     VK_TLSCALL, // symbol(tlscall)
    214     VK_TLSDESC, // symbol(tlsdesc)
    215     VK_TLVP,    // Mach-O thread local variable relocations
    216     VK_TLVPPAGE,
    217     VK_TLVPPAGEOFF,
    218     VK_PAGE,
    219     VK_PAGEOFF,
    220     VK_GOTPAGE,
    221     VK_GOTPAGEOFF,
    222     VK_SECREL,
    223     VK_SIZE,    // symbol@SIZE
    224     VK_WEAKREF, // The link between the symbols in .weakref foo, bar
    225 
    226     VK_X86_ABS8,
    227     VK_X86_PLTOFF,
    228 
    229     VK_ARM_NONE,
    230     VK_ARM_GOT_PREL,
    231     VK_ARM_TARGET1,
    232     VK_ARM_TARGET2,
    233     VK_ARM_PREL31,
    234     VK_ARM_SBREL,  // symbol(sbrel)
    235     VK_ARM_TLSLDO, // symbol(tlsldo)
    236     VK_ARM_TLSDESCSEQ,
    237 
    238     VK_AVR_NONE,
    239     VK_AVR_LO8,
    240     VK_AVR_HI8,
    241     VK_AVR_HLO8,
    242     VK_AVR_DIFF8,
    243     VK_AVR_DIFF16,
    244     VK_AVR_DIFF32,
    245     VK_AVR_PM,
    246 
    247     VK_PPC_LO,              // symbol@l
    248     VK_PPC_HI,              // symbol@h
    249     VK_PPC_HA,              // symbol@ha
    250     VK_PPC_HIGH,            // symbol@high
    251     VK_PPC_HIGHA,           // symbol@higha
    252     VK_PPC_HIGHER,          // symbol@higher
    253     VK_PPC_HIGHERA,         // symbol@highera
    254     VK_PPC_HIGHEST,         // symbol@highest
    255     VK_PPC_HIGHESTA,        // symbol@highesta
    256     VK_PPC_GOT_LO,          // symbol@got@l
    257     VK_PPC_GOT_HI,          // symbol@got@h
    258     VK_PPC_GOT_HA,          // symbol@got@ha
    259     VK_PPC_TOCBASE,         // symbol@tocbase
    260     VK_PPC_TOC,             // symbol@toc
    261     VK_PPC_TOC_LO,          // symbol@toc@l
    262     VK_PPC_TOC_HI,          // symbol@toc@h
    263     VK_PPC_TOC_HA,          // symbol@toc@ha
    264     VK_PPC_U,               // symbol@u
    265     VK_PPC_L,               // symbol@l
    266     VK_PPC_DTPMOD,          // symbol@dtpmod
    267     VK_PPC_TPREL_LO,        // symbol@tprel@l
    268     VK_PPC_TPREL_HI,        // symbol@tprel@h
    269     VK_PPC_TPREL_HA,        // symbol@tprel@ha
    270     VK_PPC_TPREL_HIGH,      // symbol@tprel@high
    271     VK_PPC_TPREL_HIGHA,     // symbol@tprel@higha
    272     VK_PPC_TPREL_HIGHER,    // symbol@tprel@higher
    273     VK_PPC_TPREL_HIGHERA,   // symbol@tprel@highera
    274     VK_PPC_TPREL_HIGHEST,   // symbol@tprel@highest
    275     VK_PPC_TPREL_HIGHESTA,  // symbol@tprel@highesta
    276     VK_PPC_DTPREL_LO,       // symbol@dtprel@l
    277     VK_PPC_DTPREL_HI,       // symbol@dtprel@h
    278     VK_PPC_DTPREL_HA,       // symbol@dtprel@ha
    279     VK_PPC_DTPREL_HIGH,     // symbol@dtprel@high
    280     VK_PPC_DTPREL_HIGHA,    // symbol@dtprel@higha
    281     VK_PPC_DTPREL_HIGHER,   // symbol@dtprel@higher
    282     VK_PPC_DTPREL_HIGHERA,  // symbol@dtprel@highera
    283     VK_PPC_DTPREL_HIGHEST,  // symbol@dtprel@highest
    284     VK_PPC_DTPREL_HIGHESTA, // symbol@dtprel@highesta
    285     VK_PPC_GOT_TPREL,       // symbol@got@tprel
    286     VK_PPC_GOT_TPREL_LO,    // symbol@got@tprel@l
    287     VK_PPC_GOT_TPREL_HI,    // symbol@got@tprel@h
    288     VK_PPC_GOT_TPREL_HA,    // symbol@got@tprel@ha
    289     VK_PPC_GOT_DTPREL,      // symbol@got@dtprel
    290     VK_PPC_GOT_DTPREL_LO,   // symbol@got@dtprel@l
    291     VK_PPC_GOT_DTPREL_HI,   // symbol@got@dtprel@h
    292     VK_PPC_GOT_DTPREL_HA,   // symbol@got@dtprel@ha
    293     VK_PPC_TLS,             // symbol@tls
    294     VK_PPC_GOT_TLSGD,       // symbol@got@tlsgd
    295     VK_PPC_GOT_TLSGD_LO,    // symbol@got@tlsgd@l
    296     VK_PPC_GOT_TLSGD_HI,    // symbol@got@tlsgd@h
    297     VK_PPC_GOT_TLSGD_HA,    // symbol@got@tlsgd@ha
    298     VK_PPC_TLSGD,           // symbol@tlsgd
    299     VK_PPC_AIX_TLSGD,       // symbol@gd
    300     VK_PPC_AIX_TLSGDM,      // symbol@m
    301     VK_PPC_GOT_TLSLD,       // symbol@got@tlsld
    302     VK_PPC_GOT_TLSLD_LO,    // symbol@got@tlsld@l
    303     VK_PPC_GOT_TLSLD_HI,    // symbol@got@tlsld@h
    304     VK_PPC_GOT_TLSLD_HA,    // symbol@got@tlsld@ha
    305     VK_PPC_GOT_PCREL,       // symbol@got@pcrel
    306     VK_PPC_GOT_TLSGD_PCREL, // symbol@got@tlsgd@pcrel
    307     VK_PPC_GOT_TLSLD_PCREL, // symbol@got@tlsld@pcrel
    308     VK_PPC_GOT_TPREL_PCREL, // symbol@got@tprel@pcrel
    309     VK_PPC_TLS_PCREL,       // symbol@tls@pcrel
    310     VK_PPC_TLSLD,           // symbol@tlsld
    311     VK_PPC_LOCAL,           // symbol@local
    312     VK_PPC_NOTOC,           // symbol@notoc
    313     VK_PPC_PCREL_OPT,       // .reloc expr, R_PPC64_PCREL_OPT, expr
    314 
    315     VK_COFF_IMGREL32, // symbol@imgrel (image-relative)
    316 
    317     VK_Hexagon_LO16,
    318     VK_Hexagon_HI16,
    319     VK_Hexagon_GPREL,
    320     VK_Hexagon_GD_GOT,
    321     VK_Hexagon_LD_GOT,
    322     VK_Hexagon_GD_PLT,
    323     VK_Hexagon_LD_PLT,
    324     VK_Hexagon_IE,
    325     VK_Hexagon_IE_GOT,
    326 
    327     VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature)
    328     VK_WASM_TLSREL,    // Memory address relative to __tls_base
    329     VK_WASM_MBREL,     // Memory address relative to __memory_base
    330     VK_WASM_TBREL,     // Table index relative to __table_base
    331 
    332     VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo
    333     VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi
    334     VK_AMDGPU_REL32_LO,      // symbol@rel32@lo
    335     VK_AMDGPU_REL32_HI,      // symbol@rel32@hi
    336     VK_AMDGPU_REL64,         // symbol@rel64
    337     VK_AMDGPU_ABS32_LO,      // symbol@abs32@lo
    338     VK_AMDGPU_ABS32_HI,      // symbol@abs32@hi
    339 
    340     VK_VE_HI32,        // symbol@hi
    341     VK_VE_LO32,        // symbol@lo
    342     VK_VE_PC_HI32,     // symbol@pc_hi
    343     VK_VE_PC_LO32,     // symbol@pc_lo
    344     VK_VE_GOT_HI32,    // symbol@got_hi
    345     VK_VE_GOT_LO32,    // symbol@got_lo
    346     VK_VE_GOTOFF_HI32, // symbol@gotoff_hi
    347     VK_VE_GOTOFF_LO32, // symbol@gotoff_lo
    348     VK_VE_PLT_HI32,    // symbol@plt_hi
    349     VK_VE_PLT_LO32,    // symbol@plt_lo
    350     VK_VE_TLS_GD_HI32, // symbol@tls_gd_hi
    351     VK_VE_TLS_GD_LO32, // symbol@tls_gd_lo
    352     VK_VE_TPOFF_HI32,  // symbol@tpoff_hi
    353     VK_VE_TPOFF_LO32,  // symbol@tpoff_lo
    354 
    355     VK_TPREL,
    356     VK_DTPREL
    357   };
    358 
    359 private:
    360   /// The symbol being referenced.
    361   const MCSymbol *Symbol;
    362 
    363   // Subclass data stores VariantKind in bits 0..15 and HasSubsectionsViaSymbols
    364   // in bit 16.
    365   static const unsigned VariantKindBits = 16;
    366   static const unsigned VariantKindMask = (1 << VariantKindBits) - 1;
    367 
    368   // FIXME: Remove this bit.
    369   static const unsigned HasSubsectionsViaSymbolsBit = 1 << VariantKindBits;
    370 
    371   static unsigned encodeSubclassData(VariantKind Kind,
    372                                      bool HasSubsectionsViaSymbols) {
    373     return (unsigned)Kind |
    374            (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0);
    375   }
    376 
    377   explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
    378                            const MCAsmInfo *MAI, SMLoc Loc = SMLoc());
    379 
    380 public:
    381   /// \name Construction
    382   /// @{
    383 
    384   static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) {
    385     return MCSymbolRefExpr::create(Symbol, VK_None, Ctx);
    386   }
    387 
    388   static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind,
    389                                        MCContext &Ctx, SMLoc Loc = SMLoc());
    390   static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind,
    391                                        MCContext &Ctx);
    392 
    393   /// @}
    394   /// \name Accessors
    395   /// @{
    396 
    397   const MCSymbol &getSymbol() const { return *Symbol; }
    398 
    399   VariantKind getKind() const {
    400     return (VariantKind)(getSubclassData() & VariantKindMask);
    401   }
    402 
    403   bool hasSubsectionsViaSymbols() const {
    404     return (getSubclassData() & HasSubsectionsViaSymbolsBit) != 0;
    405   }
    406 
    407   /// @}
    408   /// \name Static Utility Functions
    409   /// @{
    410 
    411   static StringRef getVariantKindName(VariantKind Kind);
    412 
    413   static VariantKind getVariantKindForName(StringRef Name);
    414 
    415   /// @}
    416 
    417   static bool classof(const MCExpr *E) {
    418     return E->getKind() == MCExpr::SymbolRef;
    419   }
    420 };
    421 
    422 /// Unary assembler expressions.
    423 class MCUnaryExpr : public MCExpr {
    424 public:
    425   enum Opcode {
    426     LNot,  ///< Logical negation.
    427     Minus, ///< Unary minus.
    428     Not,   ///< Bitwise negation.
    429     Plus   ///< Unary plus.
    430   };
    431 
    432 private:
    433   const MCExpr *Expr;
    434 
    435   MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc)
    436       : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {}
    437 
    438 public:
    439   /// \name Construction
    440   /// @{
    441 
    442   static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr,
    443                                    MCContext &Ctx, SMLoc Loc = SMLoc());
    444 
    445   static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
    446     return create(LNot, Expr, Ctx, Loc);
    447   }
    448 
    449   static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
    450     return create(Minus, Expr, Ctx, Loc);
    451   }
    452 
    453   static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
    454     return create(Not, Expr, Ctx, Loc);
    455   }
    456 
    457   static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) {
    458     return create(Plus, Expr, Ctx, Loc);
    459   }
    460 
    461   /// @}
    462   /// \name Accessors
    463   /// @{
    464 
    465   /// Get the kind of this unary expression.
    466   Opcode getOpcode() const { return (Opcode)getSubclassData(); }
    467 
    468   /// Get the child of this unary expression.
    469   const MCExpr *getSubExpr() const { return Expr; }
    470 
    471   /// @}
    472 
    473   static bool classof(const MCExpr *E) {
    474     return E->getKind() == MCExpr::Unary;
    475   }
    476 };
    477 
    478 /// Binary assembler expressions.
    479 class MCBinaryExpr : public MCExpr {
    480 public:
    481   enum Opcode {
    482     Add,  ///< Addition.
    483     And,  ///< Bitwise and.
    484     Div,  ///< Signed division.
    485     EQ,   ///< Equality comparison.
    486     GT,   ///< Signed greater than comparison (result is either 0 or some
    487           ///< target-specific non-zero value)
    488     GTE,  ///< Signed greater than or equal comparison (result is either 0 or
    489           ///< some target-specific non-zero value).
    490     LAnd, ///< Logical and.
    491     LOr,  ///< Logical or.
    492     LT,   ///< Signed less than comparison (result is either 0 or
    493           ///< some target-specific non-zero value).
    494     LTE,  ///< Signed less than or equal comparison (result is either 0 or
    495           ///< some target-specific non-zero value).
    496     Mod,  ///< Signed remainder.
    497     Mul,  ///< Multiplication.
    498     NE,   ///< Inequality comparison.
    499     Or,   ///< Bitwise or.
    500     OrNot, ///< Bitwise or not.
    501     Shl,  ///< Shift left.
    502     AShr, ///< Arithmetic shift right.
    503     LShr, ///< Logical shift right.
    504     Sub,  ///< Subtraction.
    505     Xor   ///< Bitwise exclusive or.
    506   };
    507 
    508 private:
    509   const MCExpr *LHS, *RHS;
    510 
    511   MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS,
    512                SMLoc Loc = SMLoc())
    513       : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {}
    514 
    515 public:
    516   /// \name Construction
    517   /// @{
    518 
    519   static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS,
    520                                     const MCExpr *RHS, MCContext &Ctx,
    521                                     SMLoc Loc = SMLoc());
    522 
    523   static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS,
    524                                        MCContext &Ctx) {
    525     return create(Add, LHS, RHS, Ctx);
    526   }
    527 
    528   static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS,
    529                                        MCContext &Ctx) {
    530     return create(And, LHS, RHS, Ctx);
    531   }
    532 
    533   static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS,
    534                                        MCContext &Ctx) {
    535     return create(Div, LHS, RHS, Ctx);
    536   }
    537 
    538   static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS,
    539                                       MCContext &Ctx) {
    540     return create(EQ, LHS, RHS, Ctx);
    541   }
    542 
    543   static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS,
    544                                       MCContext &Ctx) {
    545     return create(GT, LHS, RHS, Ctx);
    546   }
    547 
    548   static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS,
    549                                        MCContext &Ctx) {
    550     return create(GTE, LHS, RHS, Ctx);
    551   }
    552 
    553   static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS,
    554                                         MCContext &Ctx) {
    555     return create(LAnd, LHS, RHS, Ctx);
    556   }
    557 
    558   static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS,
    559                                        MCContext &Ctx) {
    560     return create(LOr, LHS, RHS, Ctx);
    561   }
    562 
    563   static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS,
    564                                       MCContext &Ctx) {
    565     return create(LT, LHS, RHS, Ctx);
    566   }
    567 
    568   static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS,
    569                                        MCContext &Ctx) {
    570     return create(LTE, LHS, RHS, Ctx);
    571   }
    572 
    573   static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS,
    574                                        MCContext &Ctx) {
    575     return create(Mod, LHS, RHS, Ctx);
    576   }
    577 
    578   static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS,
    579                                        MCContext &Ctx) {
    580     return create(Mul, LHS, RHS, Ctx);
    581   }
    582 
    583   static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS,
    584                                       MCContext &Ctx) {
    585     return create(NE, LHS, RHS, Ctx);
    586   }
    587 
    588   static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS,
    589                                       MCContext &Ctx) {
    590     return create(Or, LHS, RHS, Ctx);
    591   }
    592 
    593   static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS,
    594                                        MCContext &Ctx) {
    595     return create(Shl, LHS, RHS, Ctx);
    596   }
    597 
    598   static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS,
    599                                        MCContext &Ctx) {
    600     return create(AShr, LHS, RHS, Ctx);
    601   }
    602 
    603   static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS,
    604                                        MCContext &Ctx) {
    605     return create(LShr, LHS, RHS, Ctx);
    606   }
    607 
    608   static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS,
    609                                        MCContext &Ctx) {
    610     return create(Sub, LHS, RHS, Ctx);
    611   }
    612 
    613   static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS,
    614                                        MCContext &Ctx) {
    615     return create(Xor, LHS, RHS, Ctx);
    616   }
    617 
    618   /// @}
    619   /// \name Accessors
    620   /// @{
    621 
    622   /// Get the kind of this binary expression.
    623   Opcode getOpcode() const { return (Opcode)getSubclassData(); }
    624 
    625   /// Get the left-hand side expression of the binary operator.
    626   const MCExpr *getLHS() const { return LHS; }
    627 
    628   /// Get the right-hand side expression of the binary operator.
    629   const MCExpr *getRHS() const { return RHS; }
    630 
    631   /// @}
    632 
    633   static bool classof(const MCExpr *E) {
    634     return E->getKind() == MCExpr::Binary;
    635   }
    636 };
    637 
    638 /// This is an extension point for target-specific MCExpr subclasses to
    639 /// implement.
    640 ///
    641 /// NOTE: All subclasses are required to have trivial destructors because
    642 /// MCExprs are bump pointer allocated and not destructed.
    643 class MCTargetExpr : public MCExpr {
    644   virtual void anchor();
    645 
    646 protected:
    647   MCTargetExpr() : MCExpr(Target, SMLoc()) {}
    648   virtual ~MCTargetExpr() = default;
    649 
    650 public:
    651   virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0;
    652   virtual bool evaluateAsRelocatableImpl(MCValue &Res,
    653                                          const MCAsmLayout *Layout,
    654                                          const MCFixup *Fixup) const = 0;
    655   // allow Target Expressions to be checked for equality
    656   virtual bool isEqualTo(const MCExpr *x) const { return false; }
    657   // This should be set when assigned expressions are not valid ".set"
    658   // expressions, e.g. registers, and must be inlined.
    659   virtual bool inlineAssignedExpr() const { return false; }
    660   virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
    661   virtual MCFragment *findAssociatedFragment() const = 0;
    662 
    663   virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
    664 
    665   static bool classof(const MCExpr *E) {
    666     return E->getKind() == MCExpr::Target;
    667   }
    668 };
    669 
    670 } // end namespace llvm
    671 
    672 #endif // LLVM_MC_MCEXPR_H
    673