106f32e7eSjoerg //===- MCExpr.h - Assembly Level Expressions --------------------*- C++ -*-===// 206f32e7eSjoerg // 306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information. 506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606f32e7eSjoerg // 706f32e7eSjoerg //===----------------------------------------------------------------------===// 806f32e7eSjoerg 906f32e7eSjoerg #ifndef LLVM_MC_MCEXPR_H 1006f32e7eSjoerg #define LLVM_MC_MCEXPR_H 1106f32e7eSjoerg 1206f32e7eSjoerg #include "llvm/ADT/DenseMap.h" 1306f32e7eSjoerg #include "llvm/Support/SMLoc.h" 1406f32e7eSjoerg #include <cstdint> 1506f32e7eSjoerg 1606f32e7eSjoerg namespace llvm { 1706f32e7eSjoerg 1806f32e7eSjoerg class MCAsmInfo; 1906f32e7eSjoerg class MCAsmLayout; 2006f32e7eSjoerg class MCAssembler; 2106f32e7eSjoerg class MCContext; 2206f32e7eSjoerg class MCFixup; 2306f32e7eSjoerg class MCFragment; 2406f32e7eSjoerg class MCSection; 2506f32e7eSjoerg class MCStreamer; 2606f32e7eSjoerg class MCSymbol; 2706f32e7eSjoerg class MCValue; 2806f32e7eSjoerg class raw_ostream; 2906f32e7eSjoerg class StringRef; 3006f32e7eSjoerg 3106f32e7eSjoerg using SectionAddrMap = DenseMap<const MCSection *, uint64_t>; 3206f32e7eSjoerg 3306f32e7eSjoerg /// Base class for the full range of assembler expressions which are 3406f32e7eSjoerg /// needed for parsing. 3506f32e7eSjoerg class MCExpr { 3606f32e7eSjoerg public: 37*da58b97aSjoerg enum ExprKind : uint8_t { 3806f32e7eSjoerg Binary, ///< Binary expressions. 3906f32e7eSjoerg Constant, ///< Constant expressions. 4006f32e7eSjoerg SymbolRef, ///< References to labels and assigned expressions. 4106f32e7eSjoerg Unary, ///< Unary expressions. 4206f32e7eSjoerg Target ///< Target specific expression. 4306f32e7eSjoerg }; 4406f32e7eSjoerg 4506f32e7eSjoerg private: 46*da58b97aSjoerg static const unsigned NumSubclassDataBits = 24; 47*da58b97aSjoerg static_assert( 48*da58b97aSjoerg NumSubclassDataBits == CHAR_BIT * (sizeof(unsigned) - sizeof(ExprKind)), 49*da58b97aSjoerg "ExprKind and SubclassData together should take up one word"); 50*da58b97aSjoerg 5106f32e7eSjoerg ExprKind Kind; 52*da58b97aSjoerg /// Field reserved for use by MCExpr subclasses. 53*da58b97aSjoerg unsigned SubclassData : NumSubclassDataBits; 5406f32e7eSjoerg SMLoc Loc; 5506f32e7eSjoerg 5606f32e7eSjoerg bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, 5706f32e7eSjoerg const MCAsmLayout *Layout, 5806f32e7eSjoerg const SectionAddrMap *Addrs, bool InSet) const; 5906f32e7eSjoerg 6006f32e7eSjoerg protected: 61*da58b97aSjoerg explicit MCExpr(ExprKind Kind, SMLoc Loc, unsigned SubclassData = 0) Kind(Kind)62*da58b97aSjoerg : Kind(Kind), SubclassData(SubclassData), Loc(Loc) { 63*da58b97aSjoerg assert(SubclassData < (1 << NumSubclassDataBits) && 64*da58b97aSjoerg "Subclass data too large"); 65*da58b97aSjoerg } 6606f32e7eSjoerg 6706f32e7eSjoerg bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, 6806f32e7eSjoerg const MCAsmLayout *Layout, 6906f32e7eSjoerg const MCFixup *Fixup, 7006f32e7eSjoerg const SectionAddrMap *Addrs, bool InSet) const; 7106f32e7eSjoerg getSubclassData()72*da58b97aSjoerg unsigned getSubclassData() const { return SubclassData; } 73*da58b97aSjoerg 7406f32e7eSjoerg public: 7506f32e7eSjoerg MCExpr(const MCExpr &) = delete; 7606f32e7eSjoerg MCExpr &operator=(const MCExpr &) = delete; 7706f32e7eSjoerg 7806f32e7eSjoerg /// \name Accessors 7906f32e7eSjoerg /// @{ 8006f32e7eSjoerg getKind()8106f32e7eSjoerg ExprKind getKind() const { return Kind; } getLoc()8206f32e7eSjoerg SMLoc getLoc() const { return Loc; } 8306f32e7eSjoerg 8406f32e7eSjoerg /// @} 8506f32e7eSjoerg /// \name Utility Methods 8606f32e7eSjoerg /// @{ 8706f32e7eSjoerg 8806f32e7eSjoerg void print(raw_ostream &OS, const MCAsmInfo *MAI, 8906f32e7eSjoerg bool InParens = false) const; 9006f32e7eSjoerg void dump() const; 9106f32e7eSjoerg 9206f32e7eSjoerg /// @} 9306f32e7eSjoerg /// \name Expression Evaluation 9406f32e7eSjoerg /// @{ 9506f32e7eSjoerg 9606f32e7eSjoerg /// Try to evaluate the expression to an absolute value. 9706f32e7eSjoerg /// 9806f32e7eSjoerg /// \param Res - The absolute value, if evaluation succeeds. 9906f32e7eSjoerg /// \param Layout - The assembler layout object to use for evaluating symbol 10006f32e7eSjoerg /// values. If not given, then only non-symbolic expressions will be 10106f32e7eSjoerg /// evaluated. 10206f32e7eSjoerg /// \return - True on success. 10306f32e7eSjoerg bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, 10406f32e7eSjoerg const SectionAddrMap &Addrs) const; 10506f32e7eSjoerg bool evaluateAsAbsolute(int64_t &Res) const; 10606f32e7eSjoerg bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; 10706f32e7eSjoerg bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm) const; 10806f32e7eSjoerg bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; 10906f32e7eSjoerg 11006f32e7eSjoerg bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; 11106f32e7eSjoerg 11206f32e7eSjoerg /// Try to evaluate the expression to a relocatable value, i.e. an 11306f32e7eSjoerg /// expression of the fixed form (a - b + constant). 11406f32e7eSjoerg /// 11506f32e7eSjoerg /// \param Res - The relocatable value, if evaluation succeeds. 11606f32e7eSjoerg /// \param Layout - The assembler layout object to use for evaluating values. 11706f32e7eSjoerg /// \param Fixup - The Fixup object if available. 11806f32e7eSjoerg /// \return - True on success. 11906f32e7eSjoerg bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, 12006f32e7eSjoerg const MCFixup *Fixup) const; 12106f32e7eSjoerg 12206f32e7eSjoerg /// Try to evaluate the expression to the form (a - b + constant) where 12306f32e7eSjoerg /// neither a nor b are variables. 12406f32e7eSjoerg /// 12506f32e7eSjoerg /// This is a more aggressive variant of evaluateAsRelocatable. The intended 12606f32e7eSjoerg /// use is for when relocations are not available, like the .size directive. 12706f32e7eSjoerg bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const; 12806f32e7eSjoerg 12906f32e7eSjoerg /// Find the "associated section" for this expression, which is 13006f32e7eSjoerg /// currently defined as the absolute section for constants, or 13106f32e7eSjoerg /// otherwise the section associated with the first defined symbol in the 13206f32e7eSjoerg /// expression. 13306f32e7eSjoerg MCFragment *findAssociatedFragment() const; 13406f32e7eSjoerg 13506f32e7eSjoerg /// @} 13606f32e7eSjoerg }; 13706f32e7eSjoerg 13806f32e7eSjoerg inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { 13906f32e7eSjoerg E.print(OS, nullptr); 14006f32e7eSjoerg return OS; 14106f32e7eSjoerg } 14206f32e7eSjoerg 14306f32e7eSjoerg //// Represent a constant integer expression. 14406f32e7eSjoerg class MCConstantExpr : public MCExpr { 14506f32e7eSjoerg int64_t Value; 14606f32e7eSjoerg 147*da58b97aSjoerg // Subclass data stores SizeInBytes in bits 0..7 and PrintInHex in bit 8. 148*da58b97aSjoerg static const unsigned SizeInBytesBits = 8; 149*da58b97aSjoerg static const unsigned SizeInBytesMask = (1 << SizeInBytesBits) - 1; 150*da58b97aSjoerg static const unsigned PrintInHexBit = 1 << SizeInBytesBits; 15106f32e7eSjoerg encodeSubclassData(bool PrintInHex,unsigned SizeInBytes)152*da58b97aSjoerg static unsigned encodeSubclassData(bool PrintInHex, unsigned SizeInBytes) { 153*da58b97aSjoerg assert(SizeInBytes <= sizeof(int64_t) && "Excessive size"); 154*da58b97aSjoerg return SizeInBytes | (PrintInHex ? PrintInHexBit : 0); 155*da58b97aSjoerg } 156*da58b97aSjoerg MCConstantExpr(int64_t Value,bool PrintInHex,unsigned SizeInBytes)157*da58b97aSjoerg MCConstantExpr(int64_t Value, bool PrintInHex, unsigned SizeInBytes) 158*da58b97aSjoerg : MCExpr(MCExpr::Constant, SMLoc(), 159*da58b97aSjoerg encodeSubclassData(PrintInHex, SizeInBytes)), Value(Value) {} 16006f32e7eSjoerg 16106f32e7eSjoerg public: 16206f32e7eSjoerg /// \name Construction 16306f32e7eSjoerg /// @{ 16406f32e7eSjoerg 16506f32e7eSjoerg static const MCConstantExpr *create(int64_t Value, MCContext &Ctx, 166*da58b97aSjoerg bool PrintInHex = false, 167*da58b97aSjoerg unsigned SizeInBytes = 0); 16806f32e7eSjoerg 16906f32e7eSjoerg /// @} 17006f32e7eSjoerg /// \name Accessors 17106f32e7eSjoerg /// @{ 17206f32e7eSjoerg getValue()17306f32e7eSjoerg int64_t getValue() const { return Value; } getSizeInBytes()174*da58b97aSjoerg unsigned getSizeInBytes() const { 175*da58b97aSjoerg return getSubclassData() & SizeInBytesMask; 176*da58b97aSjoerg } 17706f32e7eSjoerg useHexFormat()178*da58b97aSjoerg bool useHexFormat() const { return (getSubclassData() & PrintInHexBit) != 0; } 17906f32e7eSjoerg 18006f32e7eSjoerg /// @} 18106f32e7eSjoerg classof(const MCExpr * E)18206f32e7eSjoerg static bool classof(const MCExpr *E) { 18306f32e7eSjoerg return E->getKind() == MCExpr::Constant; 18406f32e7eSjoerg } 18506f32e7eSjoerg }; 18606f32e7eSjoerg 18706f32e7eSjoerg /// Represent a reference to a symbol from inside an expression. 18806f32e7eSjoerg /// 18906f32e7eSjoerg /// A symbol reference in an expression may be a use of a label, a use of an 19006f32e7eSjoerg /// assembler variable (defined constant), or constitute an implicit definition 19106f32e7eSjoerg /// of the symbol as external. 19206f32e7eSjoerg class MCSymbolRefExpr : public MCExpr { 19306f32e7eSjoerg public: 19406f32e7eSjoerg enum VariantKind : uint16_t { 19506f32e7eSjoerg VK_None, 19606f32e7eSjoerg VK_Invalid, 19706f32e7eSjoerg 19806f32e7eSjoerg VK_GOT, 19906f32e7eSjoerg VK_GOTOFF, 20006f32e7eSjoerg VK_GOTREL, 201*da58b97aSjoerg VK_PCREL, 20206f32e7eSjoerg VK_GOTPCREL, 20306f32e7eSjoerg VK_GOTTPOFF, 20406f32e7eSjoerg VK_INDNTPOFF, 20506f32e7eSjoerg VK_NTPOFF, 20606f32e7eSjoerg VK_GOTNTPOFF, 20706f32e7eSjoerg VK_PLT, 20806f32e7eSjoerg VK_TLSGD, 20906f32e7eSjoerg VK_TLSLD, 21006f32e7eSjoerg VK_TLSLDM, 21106f32e7eSjoerg VK_TPOFF, 21206f32e7eSjoerg VK_DTPOFF, 21306f32e7eSjoerg VK_TLSCALL, // symbol(tlscall) 21406f32e7eSjoerg VK_TLSDESC, // symbol(tlsdesc) 21506f32e7eSjoerg VK_TLVP, // Mach-O thread local variable relocations 21606f32e7eSjoerg VK_TLVPPAGE, 21706f32e7eSjoerg VK_TLVPPAGEOFF, 21806f32e7eSjoerg VK_PAGE, 21906f32e7eSjoerg VK_PAGEOFF, 22006f32e7eSjoerg VK_GOTPAGE, 22106f32e7eSjoerg VK_GOTPAGEOFF, 22206f32e7eSjoerg VK_SECREL, 22306f32e7eSjoerg VK_SIZE, // symbol@SIZE 22406f32e7eSjoerg VK_WEAKREF, // The link between the symbols in .weakref foo, bar 22506f32e7eSjoerg 22606f32e7eSjoerg VK_X86_ABS8, 227*da58b97aSjoerg VK_X86_PLTOFF, 22806f32e7eSjoerg 22906f32e7eSjoerg VK_ARM_NONE, 23006f32e7eSjoerg VK_ARM_GOT_PREL, 23106f32e7eSjoerg VK_ARM_TARGET1, 23206f32e7eSjoerg VK_ARM_TARGET2, 23306f32e7eSjoerg VK_ARM_PREL31, 23406f32e7eSjoerg VK_ARM_SBREL, // symbol(sbrel) 23506f32e7eSjoerg VK_ARM_TLSLDO, // symbol(tlsldo) 23606f32e7eSjoerg VK_ARM_TLSDESCSEQ, 23706f32e7eSjoerg 23806f32e7eSjoerg VK_AVR_NONE, 23906f32e7eSjoerg VK_AVR_LO8, 24006f32e7eSjoerg VK_AVR_HI8, 24106f32e7eSjoerg VK_AVR_HLO8, 24206f32e7eSjoerg VK_AVR_DIFF8, 24306f32e7eSjoerg VK_AVR_DIFF16, 24406f32e7eSjoerg VK_AVR_DIFF32, 245*da58b97aSjoerg VK_AVR_PM, 24606f32e7eSjoerg 24706f32e7eSjoerg VK_PPC_LO, // symbol@l 24806f32e7eSjoerg VK_PPC_HI, // symbol@h 24906f32e7eSjoerg VK_PPC_HA, // symbol@ha 25006f32e7eSjoerg VK_PPC_HIGH, // symbol@high 25106f32e7eSjoerg VK_PPC_HIGHA, // symbol@higha 25206f32e7eSjoerg VK_PPC_HIGHER, // symbol@higher 25306f32e7eSjoerg VK_PPC_HIGHERA, // symbol@highera 25406f32e7eSjoerg VK_PPC_HIGHEST, // symbol@highest 25506f32e7eSjoerg VK_PPC_HIGHESTA, // symbol@highesta 25606f32e7eSjoerg VK_PPC_GOT_LO, // symbol@got@l 25706f32e7eSjoerg VK_PPC_GOT_HI, // symbol@got@h 25806f32e7eSjoerg VK_PPC_GOT_HA, // symbol@got@ha 25906f32e7eSjoerg VK_PPC_TOCBASE, // symbol@tocbase 26006f32e7eSjoerg VK_PPC_TOC, // symbol@toc 26106f32e7eSjoerg VK_PPC_TOC_LO, // symbol@toc@l 26206f32e7eSjoerg VK_PPC_TOC_HI, // symbol@toc@h 26306f32e7eSjoerg VK_PPC_TOC_HA, // symbol@toc@ha 26406f32e7eSjoerg VK_PPC_U, // symbol@u 26506f32e7eSjoerg VK_PPC_L, // symbol@l 26606f32e7eSjoerg VK_PPC_DTPMOD, // symbol@dtpmod 26706f32e7eSjoerg VK_PPC_TPREL_LO, // symbol@tprel@l 26806f32e7eSjoerg VK_PPC_TPREL_HI, // symbol@tprel@h 26906f32e7eSjoerg VK_PPC_TPREL_HA, // symbol@tprel@ha 27006f32e7eSjoerg VK_PPC_TPREL_HIGH, // symbol@tprel@high 27106f32e7eSjoerg VK_PPC_TPREL_HIGHA, // symbol@tprel@higha 27206f32e7eSjoerg VK_PPC_TPREL_HIGHER, // symbol@tprel@higher 27306f32e7eSjoerg VK_PPC_TPREL_HIGHERA, // symbol@tprel@highera 27406f32e7eSjoerg VK_PPC_TPREL_HIGHEST, // symbol@tprel@highest 27506f32e7eSjoerg VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta 27606f32e7eSjoerg VK_PPC_DTPREL_LO, // symbol@dtprel@l 27706f32e7eSjoerg VK_PPC_DTPREL_HI, // symbol@dtprel@h 27806f32e7eSjoerg VK_PPC_DTPREL_HA, // symbol@dtprel@ha 27906f32e7eSjoerg VK_PPC_DTPREL_HIGH, // symbol@dtprel@high 28006f32e7eSjoerg VK_PPC_DTPREL_HIGHA, // symbol@dtprel@higha 28106f32e7eSjoerg VK_PPC_DTPREL_HIGHER, // symbol@dtprel@higher 28206f32e7eSjoerg VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera 28306f32e7eSjoerg VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest 28406f32e7eSjoerg VK_PPC_DTPREL_HIGHESTA, // symbol@dtprel@highesta 28506f32e7eSjoerg VK_PPC_GOT_TPREL, // symbol@got@tprel 28606f32e7eSjoerg VK_PPC_GOT_TPREL_LO, // symbol@got@tprel@l 28706f32e7eSjoerg VK_PPC_GOT_TPREL_HI, // symbol@got@tprel@h 28806f32e7eSjoerg VK_PPC_GOT_TPREL_HA, // symbol@got@tprel@ha 28906f32e7eSjoerg VK_PPC_GOT_DTPREL, // symbol@got@dtprel 29006f32e7eSjoerg VK_PPC_GOT_DTPREL_LO, // symbol@got@dtprel@l 29106f32e7eSjoerg VK_PPC_GOT_DTPREL_HI, // symbol@got@dtprel@h 29206f32e7eSjoerg VK_PPC_GOT_DTPREL_HA, // symbol@got@dtprel@ha 29306f32e7eSjoerg VK_PPC_TLS, // symbol@tls 29406f32e7eSjoerg VK_PPC_GOT_TLSGD, // symbol@got@tlsgd 29506f32e7eSjoerg VK_PPC_GOT_TLSGD_LO, // symbol@got@tlsgd@l 29606f32e7eSjoerg VK_PPC_GOT_TLSGD_HI, // symbol@got@tlsgd@h 29706f32e7eSjoerg VK_PPC_GOT_TLSGD_HA, // symbol@got@tlsgd@ha 29806f32e7eSjoerg VK_PPC_TLSGD, // symbol@tlsgd 299*da58b97aSjoerg VK_PPC_AIX_TLSGD, // symbol@gd 300*da58b97aSjoerg VK_PPC_AIX_TLSGDM, // symbol@m 30106f32e7eSjoerg VK_PPC_GOT_TLSLD, // symbol@got@tlsld 30206f32e7eSjoerg VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l 30306f32e7eSjoerg VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h 30406f32e7eSjoerg VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha 305*da58b97aSjoerg VK_PPC_GOT_PCREL, // symbol@got@pcrel 306*da58b97aSjoerg VK_PPC_GOT_TLSGD_PCREL, // symbol@got@tlsgd@pcrel 307*da58b97aSjoerg VK_PPC_GOT_TLSLD_PCREL, // symbol@got@tlsld@pcrel 308*da58b97aSjoerg VK_PPC_GOT_TPREL_PCREL, // symbol@got@tprel@pcrel 309*da58b97aSjoerg VK_PPC_TLS_PCREL, // symbol@tls@pcrel 31006f32e7eSjoerg VK_PPC_TLSLD, // symbol@tlsld 31106f32e7eSjoerg VK_PPC_LOCAL, // symbol@local 312*da58b97aSjoerg VK_PPC_NOTOC, // symbol@notoc 313*da58b97aSjoerg VK_PPC_PCREL_OPT, // .reloc expr, R_PPC64_PCREL_OPT, expr 31406f32e7eSjoerg 31506f32e7eSjoerg VK_COFF_IMGREL32, // symbol@imgrel (image-relative) 31606f32e7eSjoerg 31706f32e7eSjoerg VK_Hexagon_LO16, 31806f32e7eSjoerg VK_Hexagon_HI16, 31906f32e7eSjoerg VK_Hexagon_GPREL, 32006f32e7eSjoerg VK_Hexagon_GD_GOT, 32106f32e7eSjoerg VK_Hexagon_LD_GOT, 32206f32e7eSjoerg VK_Hexagon_GD_PLT, 32306f32e7eSjoerg VK_Hexagon_LD_PLT, 32406f32e7eSjoerg VK_Hexagon_IE, 32506f32e7eSjoerg VK_Hexagon_IE_GOT, 32606f32e7eSjoerg 32706f32e7eSjoerg VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature) 328*da58b97aSjoerg VK_WASM_TLSREL, // Memory address relative to __tls_base 329*da58b97aSjoerg VK_WASM_MBREL, // Memory address relative to __memory_base 330*da58b97aSjoerg VK_WASM_TBREL, // Table index relative to __table_base 33106f32e7eSjoerg 33206f32e7eSjoerg VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo 33306f32e7eSjoerg VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi 33406f32e7eSjoerg VK_AMDGPU_REL32_LO, // symbol@rel32@lo 33506f32e7eSjoerg VK_AMDGPU_REL32_HI, // symbol@rel32@hi 33606f32e7eSjoerg VK_AMDGPU_REL64, // symbol@rel64 33706f32e7eSjoerg VK_AMDGPU_ABS32_LO, // symbol@abs32@lo 33806f32e7eSjoerg VK_AMDGPU_ABS32_HI, // symbol@abs32@hi 33906f32e7eSjoerg 340*da58b97aSjoerg VK_VE_HI32, // symbol@hi 341*da58b97aSjoerg VK_VE_LO32, // symbol@lo 342*da58b97aSjoerg VK_VE_PC_HI32, // symbol@pc_hi 343*da58b97aSjoerg VK_VE_PC_LO32, // symbol@pc_lo 344*da58b97aSjoerg VK_VE_GOT_HI32, // symbol@got_hi 345*da58b97aSjoerg VK_VE_GOT_LO32, // symbol@got_lo 346*da58b97aSjoerg VK_VE_GOTOFF_HI32, // symbol@gotoff_hi 347*da58b97aSjoerg VK_VE_GOTOFF_LO32, // symbol@gotoff_lo 348*da58b97aSjoerg VK_VE_PLT_HI32, // symbol@plt_hi 349*da58b97aSjoerg VK_VE_PLT_LO32, // symbol@plt_lo 350*da58b97aSjoerg VK_VE_TLS_GD_HI32, // symbol@tls_gd_hi 351*da58b97aSjoerg VK_VE_TLS_GD_LO32, // symbol@tls_gd_lo 352*da58b97aSjoerg VK_VE_TPOFF_HI32, // symbol@tpoff_hi 353*da58b97aSjoerg VK_VE_TPOFF_LO32, // symbol@tpoff_lo 354*da58b97aSjoerg 35506f32e7eSjoerg VK_TPREL, 35606f32e7eSjoerg VK_DTPREL 35706f32e7eSjoerg }; 35806f32e7eSjoerg 35906f32e7eSjoerg private: 36006f32e7eSjoerg /// The symbol being referenced. 36106f32e7eSjoerg const MCSymbol *Symbol; 36206f32e7eSjoerg 363*da58b97aSjoerg // Subclass data stores VariantKind in bits 0..15 and HasSubsectionsViaSymbols 364*da58b97aSjoerg // in bit 16. 365*da58b97aSjoerg static const unsigned VariantKindBits = 16; 366*da58b97aSjoerg static const unsigned VariantKindMask = (1 << VariantKindBits) - 1; 367*da58b97aSjoerg 368*da58b97aSjoerg // FIXME: Remove this bit. 369*da58b97aSjoerg static const unsigned HasSubsectionsViaSymbolsBit = 1 << VariantKindBits; 370*da58b97aSjoerg encodeSubclassData(VariantKind Kind,bool HasSubsectionsViaSymbols)371*da58b97aSjoerg static unsigned encodeSubclassData(VariantKind Kind, 372*da58b97aSjoerg bool HasSubsectionsViaSymbols) { 373*da58b97aSjoerg return (unsigned)Kind | 374*da58b97aSjoerg (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0); 375*da58b97aSjoerg } 376*da58b97aSjoerg 37706f32e7eSjoerg explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind, 37806f32e7eSjoerg const MCAsmInfo *MAI, SMLoc Loc = SMLoc()); 37906f32e7eSjoerg 38006f32e7eSjoerg public: 38106f32e7eSjoerg /// \name Construction 38206f32e7eSjoerg /// @{ 38306f32e7eSjoerg create(const MCSymbol * Symbol,MCContext & Ctx)38406f32e7eSjoerg static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) { 38506f32e7eSjoerg return MCSymbolRefExpr::create(Symbol, VK_None, Ctx); 38606f32e7eSjoerg } 38706f32e7eSjoerg 38806f32e7eSjoerg static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind, 38906f32e7eSjoerg MCContext &Ctx, SMLoc Loc = SMLoc()); 39006f32e7eSjoerg static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind, 39106f32e7eSjoerg MCContext &Ctx); 39206f32e7eSjoerg 39306f32e7eSjoerg /// @} 39406f32e7eSjoerg /// \name Accessors 39506f32e7eSjoerg /// @{ 39606f32e7eSjoerg getSymbol()39706f32e7eSjoerg const MCSymbol &getSymbol() const { return *Symbol; } 39806f32e7eSjoerg getKind()399*da58b97aSjoerg VariantKind getKind() const { 400*da58b97aSjoerg return (VariantKind)(getSubclassData() & VariantKindMask); 401*da58b97aSjoerg } 40206f32e7eSjoerg hasSubsectionsViaSymbols()403*da58b97aSjoerg bool hasSubsectionsViaSymbols() const { 404*da58b97aSjoerg return (getSubclassData() & HasSubsectionsViaSymbolsBit) != 0; 405*da58b97aSjoerg } 40606f32e7eSjoerg 40706f32e7eSjoerg /// @} 40806f32e7eSjoerg /// \name Static Utility Functions 40906f32e7eSjoerg /// @{ 41006f32e7eSjoerg 41106f32e7eSjoerg static StringRef getVariantKindName(VariantKind Kind); 41206f32e7eSjoerg 41306f32e7eSjoerg static VariantKind getVariantKindForName(StringRef Name); 41406f32e7eSjoerg 41506f32e7eSjoerg /// @} 41606f32e7eSjoerg classof(const MCExpr * E)41706f32e7eSjoerg static bool classof(const MCExpr *E) { 41806f32e7eSjoerg return E->getKind() == MCExpr::SymbolRef; 41906f32e7eSjoerg } 42006f32e7eSjoerg }; 42106f32e7eSjoerg 42206f32e7eSjoerg /// Unary assembler expressions. 42306f32e7eSjoerg class MCUnaryExpr : public MCExpr { 42406f32e7eSjoerg public: 42506f32e7eSjoerg enum Opcode { 42606f32e7eSjoerg LNot, ///< Logical negation. 42706f32e7eSjoerg Minus, ///< Unary minus. 42806f32e7eSjoerg Not, ///< Bitwise negation. 42906f32e7eSjoerg Plus ///< Unary plus. 43006f32e7eSjoerg }; 43106f32e7eSjoerg 43206f32e7eSjoerg private: 43306f32e7eSjoerg const MCExpr *Expr; 43406f32e7eSjoerg MCUnaryExpr(Opcode Op,const MCExpr * Expr,SMLoc Loc)43506f32e7eSjoerg MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc) 436*da58b97aSjoerg : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {} 43706f32e7eSjoerg 43806f32e7eSjoerg public: 43906f32e7eSjoerg /// \name Construction 44006f32e7eSjoerg /// @{ 44106f32e7eSjoerg 44206f32e7eSjoerg static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr, 44306f32e7eSjoerg MCContext &Ctx, SMLoc Loc = SMLoc()); 44406f32e7eSjoerg 44506f32e7eSjoerg static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { 44606f32e7eSjoerg return create(LNot, Expr, Ctx, Loc); 44706f32e7eSjoerg } 44806f32e7eSjoerg 44906f32e7eSjoerg static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { 45006f32e7eSjoerg return create(Minus, Expr, Ctx, Loc); 45106f32e7eSjoerg } 45206f32e7eSjoerg 45306f32e7eSjoerg static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { 45406f32e7eSjoerg return create(Not, Expr, Ctx, Loc); 45506f32e7eSjoerg } 45606f32e7eSjoerg 45706f32e7eSjoerg static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { 45806f32e7eSjoerg return create(Plus, Expr, Ctx, Loc); 45906f32e7eSjoerg } 46006f32e7eSjoerg 46106f32e7eSjoerg /// @} 46206f32e7eSjoerg /// \name Accessors 46306f32e7eSjoerg /// @{ 46406f32e7eSjoerg 46506f32e7eSjoerg /// Get the kind of this unary expression. getOpcode()466*da58b97aSjoerg Opcode getOpcode() const { return (Opcode)getSubclassData(); } 46706f32e7eSjoerg 46806f32e7eSjoerg /// Get the child of this unary expression. getSubExpr()46906f32e7eSjoerg const MCExpr *getSubExpr() const { return Expr; } 47006f32e7eSjoerg 47106f32e7eSjoerg /// @} 47206f32e7eSjoerg classof(const MCExpr * E)47306f32e7eSjoerg static bool classof(const MCExpr *E) { 47406f32e7eSjoerg return E->getKind() == MCExpr::Unary; 47506f32e7eSjoerg } 47606f32e7eSjoerg }; 47706f32e7eSjoerg 47806f32e7eSjoerg /// Binary assembler expressions. 47906f32e7eSjoerg class MCBinaryExpr : public MCExpr { 48006f32e7eSjoerg public: 48106f32e7eSjoerg enum Opcode { 48206f32e7eSjoerg Add, ///< Addition. 48306f32e7eSjoerg And, ///< Bitwise and. 48406f32e7eSjoerg Div, ///< Signed division. 48506f32e7eSjoerg EQ, ///< Equality comparison. 48606f32e7eSjoerg GT, ///< Signed greater than comparison (result is either 0 or some 48706f32e7eSjoerg ///< target-specific non-zero value) 48806f32e7eSjoerg GTE, ///< Signed greater than or equal comparison (result is either 0 or 48906f32e7eSjoerg ///< some target-specific non-zero value). 49006f32e7eSjoerg LAnd, ///< Logical and. 49106f32e7eSjoerg LOr, ///< Logical or. 49206f32e7eSjoerg LT, ///< Signed less than comparison (result is either 0 or 49306f32e7eSjoerg ///< some target-specific non-zero value). 49406f32e7eSjoerg LTE, ///< Signed less than or equal comparison (result is either 0 or 49506f32e7eSjoerg ///< some target-specific non-zero value). 49606f32e7eSjoerg Mod, ///< Signed remainder. 49706f32e7eSjoerg Mul, ///< Multiplication. 49806f32e7eSjoerg NE, ///< Inequality comparison. 49906f32e7eSjoerg Or, ///< Bitwise or. 500*da58b97aSjoerg OrNot, ///< Bitwise or not. 50106f32e7eSjoerg Shl, ///< Shift left. 50206f32e7eSjoerg AShr, ///< Arithmetic shift right. 50306f32e7eSjoerg LShr, ///< Logical shift right. 50406f32e7eSjoerg Sub, ///< Subtraction. 50506f32e7eSjoerg Xor ///< Bitwise exclusive or. 50606f32e7eSjoerg }; 50706f32e7eSjoerg 50806f32e7eSjoerg private: 50906f32e7eSjoerg const MCExpr *LHS, *RHS; 51006f32e7eSjoerg 51106f32e7eSjoerg MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, 51206f32e7eSjoerg SMLoc Loc = SMLoc()) MCExpr(MCExpr::Binary,Loc,Op)513*da58b97aSjoerg : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {} 51406f32e7eSjoerg 51506f32e7eSjoerg public: 51606f32e7eSjoerg /// \name Construction 51706f32e7eSjoerg /// @{ 51806f32e7eSjoerg 51906f32e7eSjoerg static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS, 52006f32e7eSjoerg const MCExpr *RHS, MCContext &Ctx, 52106f32e7eSjoerg SMLoc Loc = SMLoc()); 52206f32e7eSjoerg createAdd(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)52306f32e7eSjoerg static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS, 52406f32e7eSjoerg MCContext &Ctx) { 52506f32e7eSjoerg return create(Add, LHS, RHS, Ctx); 52606f32e7eSjoerg } 52706f32e7eSjoerg createAnd(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)52806f32e7eSjoerg static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS, 52906f32e7eSjoerg MCContext &Ctx) { 53006f32e7eSjoerg return create(And, LHS, RHS, Ctx); 53106f32e7eSjoerg } 53206f32e7eSjoerg createDiv(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)53306f32e7eSjoerg static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS, 53406f32e7eSjoerg MCContext &Ctx) { 53506f32e7eSjoerg return create(Div, LHS, RHS, Ctx); 53606f32e7eSjoerg } 53706f32e7eSjoerg createEQ(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)53806f32e7eSjoerg static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS, 53906f32e7eSjoerg MCContext &Ctx) { 54006f32e7eSjoerg return create(EQ, LHS, RHS, Ctx); 54106f32e7eSjoerg } 54206f32e7eSjoerg createGT(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)54306f32e7eSjoerg static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS, 54406f32e7eSjoerg MCContext &Ctx) { 54506f32e7eSjoerg return create(GT, LHS, RHS, Ctx); 54606f32e7eSjoerg } 54706f32e7eSjoerg createGTE(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)54806f32e7eSjoerg static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS, 54906f32e7eSjoerg MCContext &Ctx) { 55006f32e7eSjoerg return create(GTE, LHS, RHS, Ctx); 55106f32e7eSjoerg } 55206f32e7eSjoerg createLAnd(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)55306f32e7eSjoerg static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS, 55406f32e7eSjoerg MCContext &Ctx) { 55506f32e7eSjoerg return create(LAnd, LHS, RHS, Ctx); 55606f32e7eSjoerg } 55706f32e7eSjoerg createLOr(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)55806f32e7eSjoerg static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS, 55906f32e7eSjoerg MCContext &Ctx) { 56006f32e7eSjoerg return create(LOr, LHS, RHS, Ctx); 56106f32e7eSjoerg } 56206f32e7eSjoerg createLT(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)56306f32e7eSjoerg static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS, 56406f32e7eSjoerg MCContext &Ctx) { 56506f32e7eSjoerg return create(LT, LHS, RHS, Ctx); 56606f32e7eSjoerg } 56706f32e7eSjoerg createLTE(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)56806f32e7eSjoerg static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS, 56906f32e7eSjoerg MCContext &Ctx) { 57006f32e7eSjoerg return create(LTE, LHS, RHS, Ctx); 57106f32e7eSjoerg } 57206f32e7eSjoerg createMod(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)57306f32e7eSjoerg static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS, 57406f32e7eSjoerg MCContext &Ctx) { 57506f32e7eSjoerg return create(Mod, LHS, RHS, Ctx); 57606f32e7eSjoerg } 57706f32e7eSjoerg createMul(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)57806f32e7eSjoerg static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS, 57906f32e7eSjoerg MCContext &Ctx) { 58006f32e7eSjoerg return create(Mul, LHS, RHS, Ctx); 58106f32e7eSjoerg } 58206f32e7eSjoerg createNE(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)58306f32e7eSjoerg static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS, 58406f32e7eSjoerg MCContext &Ctx) { 58506f32e7eSjoerg return create(NE, LHS, RHS, Ctx); 58606f32e7eSjoerg } 58706f32e7eSjoerg createOr(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)58806f32e7eSjoerg static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS, 58906f32e7eSjoerg MCContext &Ctx) { 59006f32e7eSjoerg return create(Or, LHS, RHS, Ctx); 59106f32e7eSjoerg } 59206f32e7eSjoerg createShl(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)59306f32e7eSjoerg static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS, 59406f32e7eSjoerg MCContext &Ctx) { 59506f32e7eSjoerg return create(Shl, LHS, RHS, Ctx); 59606f32e7eSjoerg } 59706f32e7eSjoerg createAShr(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)59806f32e7eSjoerg static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS, 59906f32e7eSjoerg MCContext &Ctx) { 60006f32e7eSjoerg return create(AShr, LHS, RHS, Ctx); 60106f32e7eSjoerg } 60206f32e7eSjoerg createLShr(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)60306f32e7eSjoerg static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS, 60406f32e7eSjoerg MCContext &Ctx) { 60506f32e7eSjoerg return create(LShr, LHS, RHS, Ctx); 60606f32e7eSjoerg } 60706f32e7eSjoerg createSub(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)60806f32e7eSjoerg static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS, 60906f32e7eSjoerg MCContext &Ctx) { 61006f32e7eSjoerg return create(Sub, LHS, RHS, Ctx); 61106f32e7eSjoerg } 61206f32e7eSjoerg createXor(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)61306f32e7eSjoerg static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS, 61406f32e7eSjoerg MCContext &Ctx) { 61506f32e7eSjoerg return create(Xor, LHS, RHS, Ctx); 61606f32e7eSjoerg } 61706f32e7eSjoerg 61806f32e7eSjoerg /// @} 61906f32e7eSjoerg /// \name Accessors 62006f32e7eSjoerg /// @{ 62106f32e7eSjoerg 62206f32e7eSjoerg /// Get the kind of this binary expression. getOpcode()623*da58b97aSjoerg Opcode getOpcode() const { return (Opcode)getSubclassData(); } 62406f32e7eSjoerg 62506f32e7eSjoerg /// Get the left-hand side expression of the binary operator. getLHS()62606f32e7eSjoerg const MCExpr *getLHS() const { return LHS; } 62706f32e7eSjoerg 62806f32e7eSjoerg /// Get the right-hand side expression of the binary operator. getRHS()62906f32e7eSjoerg const MCExpr *getRHS() const { return RHS; } 63006f32e7eSjoerg 63106f32e7eSjoerg /// @} 63206f32e7eSjoerg classof(const MCExpr * E)63306f32e7eSjoerg static bool classof(const MCExpr *E) { 63406f32e7eSjoerg return E->getKind() == MCExpr::Binary; 63506f32e7eSjoerg } 63606f32e7eSjoerg }; 63706f32e7eSjoerg 63806f32e7eSjoerg /// This is an extension point for target-specific MCExpr subclasses to 63906f32e7eSjoerg /// implement. 64006f32e7eSjoerg /// 64106f32e7eSjoerg /// NOTE: All subclasses are required to have trivial destructors because 64206f32e7eSjoerg /// MCExprs are bump pointer allocated and not destructed. 64306f32e7eSjoerg class MCTargetExpr : public MCExpr { 64406f32e7eSjoerg virtual void anchor(); 64506f32e7eSjoerg 64606f32e7eSjoerg protected: MCTargetExpr()64706f32e7eSjoerg MCTargetExpr() : MCExpr(Target, SMLoc()) {} 64806f32e7eSjoerg virtual ~MCTargetExpr() = default; 64906f32e7eSjoerg 65006f32e7eSjoerg public: 65106f32e7eSjoerg virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0; 65206f32e7eSjoerg virtual bool evaluateAsRelocatableImpl(MCValue &Res, 65306f32e7eSjoerg const MCAsmLayout *Layout, 65406f32e7eSjoerg const MCFixup *Fixup) const = 0; 65506f32e7eSjoerg // allow Target Expressions to be checked for equality isEqualTo(const MCExpr * x)65606f32e7eSjoerg virtual bool isEqualTo(const MCExpr *x) const { return false; } 65706f32e7eSjoerg // This should be set when assigned expressions are not valid ".set" 65806f32e7eSjoerg // expressions, e.g. registers, and must be inlined. inlineAssignedExpr()65906f32e7eSjoerg virtual bool inlineAssignedExpr() const { return false; } 66006f32e7eSjoerg virtual void visitUsedExpr(MCStreamer& Streamer) const = 0; 66106f32e7eSjoerg virtual MCFragment *findAssociatedFragment() const = 0; 66206f32e7eSjoerg 66306f32e7eSjoerg virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0; 66406f32e7eSjoerg classof(const MCExpr * E)66506f32e7eSjoerg static bool classof(const MCExpr *E) { 66606f32e7eSjoerg return E->getKind() == MCExpr::Target; 66706f32e7eSjoerg } 66806f32e7eSjoerg }; 66906f32e7eSjoerg 67006f32e7eSjoerg } // end namespace llvm 67106f32e7eSjoerg 67206f32e7eSjoerg #endif // LLVM_MC_MCEXPR_H 673