10b57cec5SDimitry Andric //===- MCExpr.h - Assembly Level Expressions --------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLVM_MC_MCEXPR_H 100b57cec5SDimitry Andric #define LLVM_MC_MCEXPR_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 130b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h" 140b57cec5SDimitry Andric #include <cstdint> 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric namespace llvm { 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric class MCAsmInfo; 190b57cec5SDimitry Andric class MCAsmLayout; 200b57cec5SDimitry Andric class MCAssembler; 210b57cec5SDimitry Andric class MCContext; 220b57cec5SDimitry Andric class MCFixup; 230b57cec5SDimitry Andric class MCFragment; 240b57cec5SDimitry Andric class MCSection; 250b57cec5SDimitry Andric class MCStreamer; 260b57cec5SDimitry Andric class MCSymbol; 270b57cec5SDimitry Andric class MCValue; 280b57cec5SDimitry Andric class raw_ostream; 290b57cec5SDimitry Andric class StringRef; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric using SectionAddrMap = DenseMap<const MCSection *, uint64_t>; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric /// Base class for the full range of assembler expressions which are 340b57cec5SDimitry Andric /// needed for parsing. 350b57cec5SDimitry Andric class MCExpr { 360b57cec5SDimitry Andric public: 375ffd83dbSDimitry Andric enum ExprKind : uint8_t { 380b57cec5SDimitry Andric Binary, ///< Binary expressions. 390b57cec5SDimitry Andric Constant, ///< Constant expressions. 400b57cec5SDimitry Andric SymbolRef, ///< References to labels and assigned expressions. 410b57cec5SDimitry Andric Unary, ///< Unary expressions. 420b57cec5SDimitry Andric Target ///< Target specific expression. 430b57cec5SDimitry Andric }; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric private: 465ffd83dbSDimitry Andric static const unsigned NumSubclassDataBits = 24; 475ffd83dbSDimitry Andric static_assert( 485ffd83dbSDimitry Andric NumSubclassDataBits == CHAR_BIT * (sizeof(unsigned) - sizeof(ExprKind)), 495ffd83dbSDimitry Andric "ExprKind and SubclassData together should take up one word"); 505ffd83dbSDimitry Andric 510b57cec5SDimitry Andric ExprKind Kind; 525ffd83dbSDimitry Andric /// Field reserved for use by MCExpr subclasses. 535ffd83dbSDimitry Andric unsigned SubclassData : NumSubclassDataBits; 540b57cec5SDimitry Andric SMLoc Loc; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, 570b57cec5SDimitry Andric const MCAsmLayout *Layout, 580b57cec5SDimitry Andric const SectionAddrMap *Addrs, bool InSet) const; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric protected: 615ffd83dbSDimitry Andric explicit MCExpr(ExprKind Kind, SMLoc Loc, unsigned SubclassData = 0) Kind(Kind)625ffd83dbSDimitry Andric : Kind(Kind), SubclassData(SubclassData), Loc(Loc) { 635ffd83dbSDimitry Andric assert(SubclassData < (1 << NumSubclassDataBits) && 645ffd83dbSDimitry Andric "Subclass data too large"); 655ffd83dbSDimitry Andric } 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, 680b57cec5SDimitry Andric const MCAsmLayout *Layout, 690b57cec5SDimitry Andric const MCFixup *Fixup, 700b57cec5SDimitry Andric const SectionAddrMap *Addrs, bool InSet) const; 710b57cec5SDimitry Andric getSubclassData()725ffd83dbSDimitry Andric unsigned getSubclassData() const { return SubclassData; } 735ffd83dbSDimitry Andric 740b57cec5SDimitry Andric public: 750b57cec5SDimitry Andric MCExpr(const MCExpr &) = delete; 760b57cec5SDimitry Andric MCExpr &operator=(const MCExpr &) = delete; 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric /// \name Accessors 790b57cec5SDimitry Andric /// @{ 800b57cec5SDimitry Andric getKind()810b57cec5SDimitry Andric ExprKind getKind() const { return Kind; } getLoc()820b57cec5SDimitry Andric SMLoc getLoc() const { return Loc; } 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric /// @} 850b57cec5SDimitry Andric /// \name Utility Methods 860b57cec5SDimitry Andric /// @{ 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric void print(raw_ostream &OS, const MCAsmInfo *MAI, 890b57cec5SDimitry Andric bool InParens = false) const; 900b57cec5SDimitry Andric void dump() const; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric /// @} 930b57cec5SDimitry Andric /// \name Expression Evaluation 940b57cec5SDimitry Andric /// @{ 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric /// Try to evaluate the expression to an absolute value. 970b57cec5SDimitry Andric /// 980b57cec5SDimitry Andric /// \param Res - The absolute value, if evaluation succeeds. 990b57cec5SDimitry Andric /// \param Layout - The assembler layout object to use for evaluating symbol 1000b57cec5SDimitry Andric /// values. If not given, then only non-symbolic expressions will be 1010b57cec5SDimitry Andric /// evaluated. 1020b57cec5SDimitry Andric /// \return - True on success. 1030b57cec5SDimitry Andric bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, 1040b57cec5SDimitry Andric const SectionAddrMap &Addrs) const; 1050b57cec5SDimitry Andric bool evaluateAsAbsolute(int64_t &Res) const; 1060b57cec5SDimitry Andric bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; 1070b57cec5SDimitry Andric bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm) const; 1080b57cec5SDimitry Andric bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric /// Try to evaluate the expression to a relocatable value, i.e. an 1130b57cec5SDimitry Andric /// expression of the fixed form (a - b + constant). 1140b57cec5SDimitry Andric /// 1150b57cec5SDimitry Andric /// \param Res - The relocatable value, if evaluation succeeds. 1160b57cec5SDimitry Andric /// \param Layout - The assembler layout object to use for evaluating values. 1170b57cec5SDimitry Andric /// \param Fixup - The Fixup object if available. 1180b57cec5SDimitry Andric /// \return - True on success. 1190b57cec5SDimitry Andric bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, 1200b57cec5SDimitry Andric const MCFixup *Fixup) const; 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric /// Try to evaluate the expression to the form (a - b + constant) where 1230b57cec5SDimitry Andric /// neither a nor b are variables. 1240b57cec5SDimitry Andric /// 1250b57cec5SDimitry Andric /// This is a more aggressive variant of evaluateAsRelocatable. The intended 1260b57cec5SDimitry Andric /// use is for when relocations are not available, like the .size directive. 1270b57cec5SDimitry Andric bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const; 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric /// Find the "associated section" for this expression, which is 1300b57cec5SDimitry Andric /// currently defined as the absolute section for constants, or 1310b57cec5SDimitry Andric /// otherwise the section associated with the first defined symbol in the 1320b57cec5SDimitry Andric /// expression. 1330b57cec5SDimitry Andric MCFragment *findAssociatedFragment() const; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric /// @} 1360b57cec5SDimitry Andric }; 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { 1390b57cec5SDimitry Andric E.print(OS, nullptr); 1400b57cec5SDimitry Andric return OS; 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric //// Represent a constant integer expression. 1440b57cec5SDimitry Andric class MCConstantExpr : public MCExpr { 1450b57cec5SDimitry Andric int64_t Value; 1460b57cec5SDimitry Andric 1475ffd83dbSDimitry Andric // Subclass data stores SizeInBytes in bits 0..7 and PrintInHex in bit 8. 1485ffd83dbSDimitry Andric static const unsigned SizeInBytesBits = 8; 1495ffd83dbSDimitry Andric static const unsigned SizeInBytesMask = (1 << SizeInBytesBits) - 1; 1505ffd83dbSDimitry Andric static const unsigned PrintInHexBit = 1 << SizeInBytesBits; 1510b57cec5SDimitry Andric encodeSubclassData(bool PrintInHex,unsigned SizeInBytes)1525ffd83dbSDimitry Andric static unsigned encodeSubclassData(bool PrintInHex, unsigned SizeInBytes) { 1535ffd83dbSDimitry Andric assert(SizeInBytes <= sizeof(int64_t) && "Excessive size"); 1545ffd83dbSDimitry Andric return SizeInBytes | (PrintInHex ? PrintInHexBit : 0); 1555ffd83dbSDimitry Andric } 1565ffd83dbSDimitry Andric MCConstantExpr(int64_t Value,bool PrintInHex,unsigned SizeInBytes)1575ffd83dbSDimitry Andric MCConstantExpr(int64_t Value, bool PrintInHex, unsigned SizeInBytes) 1585ffd83dbSDimitry Andric : MCExpr(MCExpr::Constant, SMLoc(), 1595ffd83dbSDimitry Andric encodeSubclassData(PrintInHex, SizeInBytes)), Value(Value) {} 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric public: 1620b57cec5SDimitry Andric /// \name Construction 1630b57cec5SDimitry Andric /// @{ 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric static const MCConstantExpr *create(int64_t Value, MCContext &Ctx, 1665ffd83dbSDimitry Andric bool PrintInHex = false, 1675ffd83dbSDimitry Andric unsigned SizeInBytes = 0); 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric /// @} 1700b57cec5SDimitry Andric /// \name Accessors 1710b57cec5SDimitry Andric /// @{ 1720b57cec5SDimitry Andric getValue()1730b57cec5SDimitry Andric int64_t getValue() const { return Value; } getSizeInBytes()1745ffd83dbSDimitry Andric unsigned getSizeInBytes() const { 1755ffd83dbSDimitry Andric return getSubclassData() & SizeInBytesMask; 1765ffd83dbSDimitry Andric } 1770b57cec5SDimitry Andric useHexFormat()1785ffd83dbSDimitry Andric bool useHexFormat() const { return (getSubclassData() & PrintInHexBit) != 0; } 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric /// @} 1810b57cec5SDimitry Andric classof(const MCExpr * E)1820b57cec5SDimitry Andric static bool classof(const MCExpr *E) { 1830b57cec5SDimitry Andric return E->getKind() == MCExpr::Constant; 1840b57cec5SDimitry Andric } 1850b57cec5SDimitry Andric }; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric /// Represent a reference to a symbol from inside an expression. 1880b57cec5SDimitry Andric /// 1890b57cec5SDimitry Andric /// A symbol reference in an expression may be a use of a label, a use of an 1900b57cec5SDimitry Andric /// assembler variable (defined constant), or constitute an implicit definition 1910b57cec5SDimitry Andric /// of the symbol as external. 1920b57cec5SDimitry Andric class MCSymbolRefExpr : public MCExpr { 1930b57cec5SDimitry Andric public: 1940b57cec5SDimitry Andric enum VariantKind : uint16_t { 1950b57cec5SDimitry Andric VK_None, 1960b57cec5SDimitry Andric VK_Invalid, 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric VK_GOT, 1990b57cec5SDimitry Andric VK_GOTOFF, 2000b57cec5SDimitry Andric VK_GOTREL, 2015ffd83dbSDimitry Andric VK_PCREL, 2020b57cec5SDimitry Andric VK_GOTPCREL, 203349cc55cSDimitry Andric VK_GOTPCREL_NORELAX, 2040b57cec5SDimitry Andric VK_GOTTPOFF, 2050b57cec5SDimitry Andric VK_INDNTPOFF, 2060b57cec5SDimitry Andric VK_NTPOFF, 2070b57cec5SDimitry Andric VK_GOTNTPOFF, 2080b57cec5SDimitry Andric VK_PLT, 2090b57cec5SDimitry Andric VK_TLSGD, 2100b57cec5SDimitry Andric VK_TLSLD, 2110b57cec5SDimitry Andric VK_TLSLDM, 2120b57cec5SDimitry Andric VK_TPOFF, 2130b57cec5SDimitry Andric VK_DTPOFF, 2140b57cec5SDimitry Andric VK_TLSCALL, // symbol(tlscall) 2150b57cec5SDimitry Andric VK_TLSDESC, // symbol(tlsdesc) 2160b57cec5SDimitry Andric VK_TLVP, // Mach-O thread local variable relocations 2170b57cec5SDimitry Andric VK_TLVPPAGE, 2180b57cec5SDimitry Andric VK_TLVPPAGEOFF, 2190b57cec5SDimitry Andric VK_PAGE, 2200b57cec5SDimitry Andric VK_PAGEOFF, 2210b57cec5SDimitry Andric VK_GOTPAGE, 2220b57cec5SDimitry Andric VK_GOTPAGEOFF, 2230b57cec5SDimitry Andric VK_SECREL, 2240b57cec5SDimitry Andric VK_SIZE, // symbol@SIZE 2250b57cec5SDimitry Andric VK_WEAKREF, // The link between the symbols in .weakref foo, bar 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric VK_X86_ABS8, 228e8d8bef9SDimitry Andric VK_X86_PLTOFF, 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric VK_ARM_NONE, 2310b57cec5SDimitry Andric VK_ARM_GOT_PREL, 2320b57cec5SDimitry Andric VK_ARM_TARGET1, 2330b57cec5SDimitry Andric VK_ARM_TARGET2, 2340b57cec5SDimitry Andric VK_ARM_PREL31, 2350b57cec5SDimitry Andric VK_ARM_SBREL, // symbol(sbrel) 2360b57cec5SDimitry Andric VK_ARM_TLSLDO, // symbol(tlsldo) 2370b57cec5SDimitry Andric VK_ARM_TLSDESCSEQ, 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric VK_AVR_NONE, 2400b57cec5SDimitry Andric VK_AVR_LO8, 2410b57cec5SDimitry Andric VK_AVR_HI8, 2420b57cec5SDimitry Andric VK_AVR_HLO8, 2430b57cec5SDimitry Andric VK_AVR_DIFF8, 2440b57cec5SDimitry Andric VK_AVR_DIFF16, 2450b57cec5SDimitry Andric VK_AVR_DIFF32, 246fe6060f1SDimitry Andric VK_AVR_PM, 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric VK_PPC_LO, // symbol@l 2490b57cec5SDimitry Andric VK_PPC_HI, // symbol@h 2500b57cec5SDimitry Andric VK_PPC_HA, // symbol@ha 2510b57cec5SDimitry Andric VK_PPC_HIGH, // symbol@high 2520b57cec5SDimitry Andric VK_PPC_HIGHA, // symbol@higha 2530b57cec5SDimitry Andric VK_PPC_HIGHER, // symbol@higher 2540b57cec5SDimitry Andric VK_PPC_HIGHERA, // symbol@highera 2550b57cec5SDimitry Andric VK_PPC_HIGHEST, // symbol@highest 2560b57cec5SDimitry Andric VK_PPC_HIGHESTA, // symbol@highesta 2570b57cec5SDimitry Andric VK_PPC_GOT_LO, // symbol@got@l 2580b57cec5SDimitry Andric VK_PPC_GOT_HI, // symbol@got@h 2590b57cec5SDimitry Andric VK_PPC_GOT_HA, // symbol@got@ha 2600b57cec5SDimitry Andric VK_PPC_TOCBASE, // symbol@tocbase 2610b57cec5SDimitry Andric VK_PPC_TOC, // symbol@toc 2620b57cec5SDimitry Andric VK_PPC_TOC_LO, // symbol@toc@l 2630b57cec5SDimitry Andric VK_PPC_TOC_HI, // symbol@toc@h 2640b57cec5SDimitry Andric VK_PPC_TOC_HA, // symbol@toc@ha 2658bcb0991SDimitry Andric VK_PPC_U, // symbol@u 2668bcb0991SDimitry Andric VK_PPC_L, // symbol@l 2670b57cec5SDimitry Andric VK_PPC_DTPMOD, // symbol@dtpmod 2680b57cec5SDimitry Andric VK_PPC_TPREL_LO, // symbol@tprel@l 2690b57cec5SDimitry Andric VK_PPC_TPREL_HI, // symbol@tprel@h 2700b57cec5SDimitry Andric VK_PPC_TPREL_HA, // symbol@tprel@ha 2710b57cec5SDimitry Andric VK_PPC_TPREL_HIGH, // symbol@tprel@high 2720b57cec5SDimitry Andric VK_PPC_TPREL_HIGHA, // symbol@tprel@higha 2730b57cec5SDimitry Andric VK_PPC_TPREL_HIGHER, // symbol@tprel@higher 2740b57cec5SDimitry Andric VK_PPC_TPREL_HIGHERA, // symbol@tprel@highera 2750b57cec5SDimitry Andric VK_PPC_TPREL_HIGHEST, // symbol@tprel@highest 2760b57cec5SDimitry Andric VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta 2770b57cec5SDimitry Andric VK_PPC_DTPREL_LO, // symbol@dtprel@l 2780b57cec5SDimitry Andric VK_PPC_DTPREL_HI, // symbol@dtprel@h 2790b57cec5SDimitry Andric VK_PPC_DTPREL_HA, // symbol@dtprel@ha 2800b57cec5SDimitry Andric VK_PPC_DTPREL_HIGH, // symbol@dtprel@high 2810b57cec5SDimitry Andric VK_PPC_DTPREL_HIGHA, // symbol@dtprel@higha 2820b57cec5SDimitry Andric VK_PPC_DTPREL_HIGHER, // symbol@dtprel@higher 2830b57cec5SDimitry Andric VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera 2840b57cec5SDimitry Andric VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest 2850b57cec5SDimitry Andric VK_PPC_DTPREL_HIGHESTA, // symbol@dtprel@highesta 2860b57cec5SDimitry Andric VK_PPC_GOT_TPREL, // symbol@got@tprel 2870b57cec5SDimitry Andric VK_PPC_GOT_TPREL_LO, // symbol@got@tprel@l 2880b57cec5SDimitry Andric VK_PPC_GOT_TPREL_HI, // symbol@got@tprel@h 2890b57cec5SDimitry Andric VK_PPC_GOT_TPREL_HA, // symbol@got@tprel@ha 2900b57cec5SDimitry Andric VK_PPC_GOT_DTPREL, // symbol@got@dtprel 2910b57cec5SDimitry Andric VK_PPC_GOT_DTPREL_LO, // symbol@got@dtprel@l 2920b57cec5SDimitry Andric VK_PPC_GOT_DTPREL_HI, // symbol@got@dtprel@h 2930b57cec5SDimitry Andric VK_PPC_GOT_DTPREL_HA, // symbol@got@dtprel@ha 2940b57cec5SDimitry Andric VK_PPC_TLS, // symbol@tls 2950b57cec5SDimitry Andric VK_PPC_GOT_TLSGD, // symbol@got@tlsgd 2960b57cec5SDimitry Andric VK_PPC_GOT_TLSGD_LO, // symbol@got@tlsgd@l 2970b57cec5SDimitry Andric VK_PPC_GOT_TLSGD_HI, // symbol@got@tlsgd@h 2980b57cec5SDimitry Andric VK_PPC_GOT_TLSGD_HA, // symbol@got@tlsgd@ha 2990b57cec5SDimitry Andric VK_PPC_TLSGD, // symbol@tlsgd 300fe6060f1SDimitry Andric VK_PPC_AIX_TLSGD, // symbol@gd 301fe6060f1SDimitry Andric VK_PPC_AIX_TLSGDM, // symbol@m 3025f757f3fSDimitry Andric VK_PPC_AIX_TLSIE, // symbol@ie 30306c3fb27SDimitry Andric VK_PPC_AIX_TLSLE, // symbol@le 3040b57cec5SDimitry Andric VK_PPC_GOT_TLSLD, // symbol@got@tlsld 3050b57cec5SDimitry Andric VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l 3060b57cec5SDimitry Andric VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h 3070b57cec5SDimitry Andric VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha 3085ffd83dbSDimitry Andric VK_PPC_GOT_PCREL, // symbol@got@pcrel 309e8d8bef9SDimitry Andric VK_PPC_GOT_TLSGD_PCREL, // symbol@got@tlsgd@pcrel 310e8d8bef9SDimitry Andric VK_PPC_GOT_TLSLD_PCREL, // symbol@got@tlsld@pcrel 311e8d8bef9SDimitry Andric VK_PPC_GOT_TPREL_PCREL, // symbol@got@tprel@pcrel 312e8d8bef9SDimitry Andric VK_PPC_TLS_PCREL, // symbol@tls@pcrel 3130b57cec5SDimitry Andric VK_PPC_TLSLD, // symbol@tlsld 3140b57cec5SDimitry Andric VK_PPC_LOCAL, // symbol@local 3155ffd83dbSDimitry Andric VK_PPC_NOTOC, // symbol@notoc 316e8d8bef9SDimitry Andric VK_PPC_PCREL_OPT, // .reloc expr, R_PPC64_PCREL_OPT, expr 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric VK_COFF_IMGREL32, // symbol@imgrel (image-relative) 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric VK_Hexagon_LO16, 3210b57cec5SDimitry Andric VK_Hexagon_HI16, 3220b57cec5SDimitry Andric VK_Hexagon_GPREL, 3230b57cec5SDimitry Andric VK_Hexagon_GD_GOT, 3240b57cec5SDimitry Andric VK_Hexagon_LD_GOT, 3250b57cec5SDimitry Andric VK_Hexagon_GD_PLT, 3260b57cec5SDimitry Andric VK_Hexagon_LD_PLT, 3270b57cec5SDimitry Andric VK_Hexagon_IE, 3280b57cec5SDimitry Andric VK_Hexagon_IE_GOT, 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature) 331e8d8bef9SDimitry Andric VK_WASM_TLSREL, // Memory address relative to __tls_base 332e8d8bef9SDimitry Andric VK_WASM_MBREL, // Memory address relative to __memory_base 333e8d8bef9SDimitry Andric VK_WASM_TBREL, // Table index relative to __table_base 334349cc55cSDimitry Andric VK_WASM_GOT_TLS, // Wasm global index of TLS symbol. 33506c3fb27SDimitry Andric VK_WASM_FUNCINDEX, // Wasm function index. 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo 3380b57cec5SDimitry Andric VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi 3390b57cec5SDimitry Andric VK_AMDGPU_REL32_LO, // symbol@rel32@lo 3400b57cec5SDimitry Andric VK_AMDGPU_REL32_HI, // symbol@rel32@hi 3410b57cec5SDimitry Andric VK_AMDGPU_REL64, // symbol@rel64 3420b57cec5SDimitry Andric VK_AMDGPU_ABS32_LO, // symbol@abs32@lo 3430b57cec5SDimitry Andric VK_AMDGPU_ABS32_HI, // symbol@abs32@hi 3440b57cec5SDimitry Andric 3455ffd83dbSDimitry Andric VK_VE_HI32, // symbol@hi 3465ffd83dbSDimitry Andric VK_VE_LO32, // symbol@lo 3475ffd83dbSDimitry Andric VK_VE_PC_HI32, // symbol@pc_hi 3485ffd83dbSDimitry Andric VK_VE_PC_LO32, // symbol@pc_lo 3495ffd83dbSDimitry Andric VK_VE_GOT_HI32, // symbol@got_hi 3505ffd83dbSDimitry Andric VK_VE_GOT_LO32, // symbol@got_lo 3515ffd83dbSDimitry Andric VK_VE_GOTOFF_HI32, // symbol@gotoff_hi 3525ffd83dbSDimitry Andric VK_VE_GOTOFF_LO32, // symbol@gotoff_lo 3535ffd83dbSDimitry Andric VK_VE_PLT_HI32, // symbol@plt_hi 3545ffd83dbSDimitry Andric VK_VE_PLT_LO32, // symbol@plt_lo 3555ffd83dbSDimitry Andric VK_VE_TLS_GD_HI32, // symbol@tls_gd_hi 3565ffd83dbSDimitry Andric VK_VE_TLS_GD_LO32, // symbol@tls_gd_lo 3575ffd83dbSDimitry Andric VK_VE_TPOFF_HI32, // symbol@tpoff_hi 3585ffd83dbSDimitry Andric VK_VE_TPOFF_LO32, // symbol@tpoff_lo 3595ffd83dbSDimitry Andric 3600b57cec5SDimitry Andric VK_TPREL, 3610b57cec5SDimitry Andric VK_DTPREL 3620b57cec5SDimitry Andric }; 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric private: 3650b57cec5SDimitry Andric /// The symbol being referenced. 3660b57cec5SDimitry Andric const MCSymbol *Symbol; 3670b57cec5SDimitry Andric 368e8d8bef9SDimitry Andric // Subclass data stores VariantKind in bits 0..15 and HasSubsectionsViaSymbols 369e8d8bef9SDimitry Andric // in bit 16. 3705ffd83dbSDimitry Andric static const unsigned VariantKindBits = 16; 3715ffd83dbSDimitry Andric static const unsigned VariantKindMask = (1 << VariantKindBits) - 1; 3725ffd83dbSDimitry Andric 3735ffd83dbSDimitry Andric // FIXME: Remove this bit. 374e8d8bef9SDimitry Andric static const unsigned HasSubsectionsViaSymbolsBit = 1 << VariantKindBits; 3755ffd83dbSDimitry Andric encodeSubclassData(VariantKind Kind,bool HasSubsectionsViaSymbols)3765ffd83dbSDimitry Andric static unsigned encodeSubclassData(VariantKind Kind, 3775ffd83dbSDimitry Andric bool HasSubsectionsViaSymbols) { 3785ffd83dbSDimitry Andric return (unsigned)Kind | 3795ffd83dbSDimitry Andric (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0); 3805ffd83dbSDimitry Andric } 3815ffd83dbSDimitry Andric 3820b57cec5SDimitry Andric explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind, 3830b57cec5SDimitry Andric const MCAsmInfo *MAI, SMLoc Loc = SMLoc()); 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric public: 3860b57cec5SDimitry Andric /// \name Construction 3870b57cec5SDimitry Andric /// @{ 3880b57cec5SDimitry Andric create(const MCSymbol * Symbol,MCContext & Ctx)3890b57cec5SDimitry Andric static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) { 3900b57cec5SDimitry Andric return MCSymbolRefExpr::create(Symbol, VK_None, Ctx); 3910b57cec5SDimitry Andric } 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind, 3940b57cec5SDimitry Andric MCContext &Ctx, SMLoc Loc = SMLoc()); 3950b57cec5SDimitry Andric static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind, 3960b57cec5SDimitry Andric MCContext &Ctx); 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric /// @} 3990b57cec5SDimitry Andric /// \name Accessors 4000b57cec5SDimitry Andric /// @{ 4010b57cec5SDimitry Andric getSymbol()4020b57cec5SDimitry Andric const MCSymbol &getSymbol() const { return *Symbol; } 4030b57cec5SDimitry Andric getKind()4045ffd83dbSDimitry Andric VariantKind getKind() const { 4055ffd83dbSDimitry Andric return (VariantKind)(getSubclassData() & VariantKindMask); 4065ffd83dbSDimitry Andric } 4070b57cec5SDimitry Andric hasSubsectionsViaSymbols()4085ffd83dbSDimitry Andric bool hasSubsectionsViaSymbols() const { 4095ffd83dbSDimitry Andric return (getSubclassData() & HasSubsectionsViaSymbolsBit) != 0; 4105ffd83dbSDimitry Andric } 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric /// @} 4130b57cec5SDimitry Andric /// \name Static Utility Functions 4140b57cec5SDimitry Andric /// @{ 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric static StringRef getVariantKindName(VariantKind Kind); 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric static VariantKind getVariantKindForName(StringRef Name); 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric /// @} 4210b57cec5SDimitry Andric classof(const MCExpr * E)4220b57cec5SDimitry Andric static bool classof(const MCExpr *E) { 4230b57cec5SDimitry Andric return E->getKind() == MCExpr::SymbolRef; 4240b57cec5SDimitry Andric } 4250b57cec5SDimitry Andric }; 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric /// Unary assembler expressions. 4280b57cec5SDimitry Andric class MCUnaryExpr : public MCExpr { 4290b57cec5SDimitry Andric public: 4300b57cec5SDimitry Andric enum Opcode { 4310b57cec5SDimitry Andric LNot, ///< Logical negation. 4320b57cec5SDimitry Andric Minus, ///< Unary minus. 4330b57cec5SDimitry Andric Not, ///< Bitwise negation. 4340b57cec5SDimitry Andric Plus ///< Unary plus. 4350b57cec5SDimitry Andric }; 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric private: 4380b57cec5SDimitry Andric const MCExpr *Expr; 4390b57cec5SDimitry Andric MCUnaryExpr(Opcode Op,const MCExpr * Expr,SMLoc Loc)4400b57cec5SDimitry Andric MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc) 4415ffd83dbSDimitry Andric : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {} 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric public: 4440b57cec5SDimitry Andric /// \name Construction 4450b57cec5SDimitry Andric /// @{ 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr, 4480b57cec5SDimitry Andric MCContext &Ctx, SMLoc Loc = SMLoc()); 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { 4510b57cec5SDimitry Andric return create(LNot, Expr, Ctx, Loc); 4520b57cec5SDimitry Andric } 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { 4550b57cec5SDimitry Andric return create(Minus, Expr, Ctx, Loc); 4560b57cec5SDimitry Andric } 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { 4590b57cec5SDimitry Andric return create(Not, Expr, Ctx, Loc); 4600b57cec5SDimitry Andric } 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { 4630b57cec5SDimitry Andric return create(Plus, Expr, Ctx, Loc); 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric /// @} 4670b57cec5SDimitry Andric /// \name Accessors 4680b57cec5SDimitry Andric /// @{ 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric /// Get the kind of this unary expression. getOpcode()4715ffd83dbSDimitry Andric Opcode getOpcode() const { return (Opcode)getSubclassData(); } 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric /// Get the child of this unary expression. getSubExpr()4740b57cec5SDimitry Andric const MCExpr *getSubExpr() const { return Expr; } 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric /// @} 4770b57cec5SDimitry Andric classof(const MCExpr * E)4780b57cec5SDimitry Andric static bool classof(const MCExpr *E) { 4790b57cec5SDimitry Andric return E->getKind() == MCExpr::Unary; 4800b57cec5SDimitry Andric } 4810b57cec5SDimitry Andric }; 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric /// Binary assembler expressions. 4840b57cec5SDimitry Andric class MCBinaryExpr : public MCExpr { 4850b57cec5SDimitry Andric public: 4860b57cec5SDimitry Andric enum Opcode { 4870b57cec5SDimitry Andric Add, ///< Addition. 4880b57cec5SDimitry Andric And, ///< Bitwise and. 4890b57cec5SDimitry Andric Div, ///< Signed division. 4900b57cec5SDimitry Andric EQ, ///< Equality comparison. 4910b57cec5SDimitry Andric GT, ///< Signed greater than comparison (result is either 0 or some 4920b57cec5SDimitry Andric ///< target-specific non-zero value) 4930b57cec5SDimitry Andric GTE, ///< Signed greater than or equal comparison (result is either 0 or 4940b57cec5SDimitry Andric ///< some target-specific non-zero value). 4950b57cec5SDimitry Andric LAnd, ///< Logical and. 4960b57cec5SDimitry Andric LOr, ///< Logical or. 4970b57cec5SDimitry Andric LT, ///< Signed less than comparison (result is either 0 or 4980b57cec5SDimitry Andric ///< some target-specific non-zero value). 4990b57cec5SDimitry Andric LTE, ///< Signed less than or equal comparison (result is either 0 or 5000b57cec5SDimitry Andric ///< some target-specific non-zero value). 5010b57cec5SDimitry Andric Mod, ///< Signed remainder. 5020b57cec5SDimitry Andric Mul, ///< Multiplication. 5030b57cec5SDimitry Andric NE, ///< Inequality comparison. 5040b57cec5SDimitry Andric Or, ///< Bitwise or. 505e8d8bef9SDimitry Andric OrNot, ///< Bitwise or not. 5060b57cec5SDimitry Andric Shl, ///< Shift left. 5070b57cec5SDimitry Andric AShr, ///< Arithmetic shift right. 5080b57cec5SDimitry Andric LShr, ///< Logical shift right. 5090b57cec5SDimitry Andric Sub, ///< Subtraction. 5100b57cec5SDimitry Andric Xor ///< Bitwise exclusive or. 5110b57cec5SDimitry Andric }; 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric private: 5140b57cec5SDimitry Andric const MCExpr *LHS, *RHS; 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, 5170b57cec5SDimitry Andric SMLoc Loc = SMLoc()) MCExpr(MCExpr::Binary,Loc,Op)5185ffd83dbSDimitry Andric : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {} 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric public: 5210b57cec5SDimitry Andric /// \name Construction 5220b57cec5SDimitry Andric /// @{ 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS, 5250b57cec5SDimitry Andric const MCExpr *RHS, MCContext &Ctx, 5260b57cec5SDimitry Andric SMLoc Loc = SMLoc()); 5270b57cec5SDimitry Andric createAdd(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5280b57cec5SDimitry Andric static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS, 5290b57cec5SDimitry Andric MCContext &Ctx) { 5300b57cec5SDimitry Andric return create(Add, LHS, RHS, Ctx); 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric createAnd(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5330b57cec5SDimitry Andric static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS, 5340b57cec5SDimitry Andric MCContext &Ctx) { 5350b57cec5SDimitry Andric return create(And, LHS, RHS, Ctx); 5360b57cec5SDimitry Andric } 5370b57cec5SDimitry Andric createDiv(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5380b57cec5SDimitry Andric static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS, 5390b57cec5SDimitry Andric MCContext &Ctx) { 5400b57cec5SDimitry Andric return create(Div, LHS, RHS, Ctx); 5410b57cec5SDimitry Andric } 5420b57cec5SDimitry Andric createEQ(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5430b57cec5SDimitry Andric static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS, 5440b57cec5SDimitry Andric MCContext &Ctx) { 5450b57cec5SDimitry Andric return create(EQ, LHS, RHS, Ctx); 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric createGT(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5480b57cec5SDimitry Andric static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS, 5490b57cec5SDimitry Andric MCContext &Ctx) { 5500b57cec5SDimitry Andric return create(GT, LHS, RHS, Ctx); 5510b57cec5SDimitry Andric } 5520b57cec5SDimitry Andric createGTE(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5530b57cec5SDimitry Andric static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS, 5540b57cec5SDimitry Andric MCContext &Ctx) { 5550b57cec5SDimitry Andric return create(GTE, LHS, RHS, Ctx); 5560b57cec5SDimitry Andric } 5570b57cec5SDimitry Andric createLAnd(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5580b57cec5SDimitry Andric static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS, 5590b57cec5SDimitry Andric MCContext &Ctx) { 5600b57cec5SDimitry Andric return create(LAnd, LHS, RHS, Ctx); 5610b57cec5SDimitry Andric } 5620b57cec5SDimitry Andric createLOr(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5630b57cec5SDimitry Andric static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS, 5640b57cec5SDimitry Andric MCContext &Ctx) { 5650b57cec5SDimitry Andric return create(LOr, LHS, RHS, Ctx); 5660b57cec5SDimitry Andric } 5670b57cec5SDimitry Andric createLT(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5680b57cec5SDimitry Andric static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS, 5690b57cec5SDimitry Andric MCContext &Ctx) { 5700b57cec5SDimitry Andric return create(LT, LHS, RHS, Ctx); 5710b57cec5SDimitry Andric } 5720b57cec5SDimitry Andric createLTE(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5730b57cec5SDimitry Andric static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS, 5740b57cec5SDimitry Andric MCContext &Ctx) { 5750b57cec5SDimitry Andric return create(LTE, LHS, RHS, Ctx); 5760b57cec5SDimitry Andric } 5770b57cec5SDimitry Andric createMod(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5780b57cec5SDimitry Andric static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS, 5790b57cec5SDimitry Andric MCContext &Ctx) { 5800b57cec5SDimitry Andric return create(Mod, LHS, RHS, Ctx); 5810b57cec5SDimitry Andric } 5820b57cec5SDimitry Andric createMul(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5830b57cec5SDimitry Andric static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS, 5840b57cec5SDimitry Andric MCContext &Ctx) { 5850b57cec5SDimitry Andric return create(Mul, LHS, RHS, Ctx); 5860b57cec5SDimitry Andric } 5870b57cec5SDimitry Andric createNE(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5880b57cec5SDimitry Andric static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS, 5890b57cec5SDimitry Andric MCContext &Ctx) { 5900b57cec5SDimitry Andric return create(NE, LHS, RHS, Ctx); 5910b57cec5SDimitry Andric } 5920b57cec5SDimitry Andric createOr(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5930b57cec5SDimitry Andric static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS, 5940b57cec5SDimitry Andric MCContext &Ctx) { 5950b57cec5SDimitry Andric return create(Or, LHS, RHS, Ctx); 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric createShl(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)5980b57cec5SDimitry Andric static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS, 5990b57cec5SDimitry Andric MCContext &Ctx) { 6000b57cec5SDimitry Andric return create(Shl, LHS, RHS, Ctx); 6010b57cec5SDimitry Andric } 6020b57cec5SDimitry Andric createAShr(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)6030b57cec5SDimitry Andric static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS, 6040b57cec5SDimitry Andric MCContext &Ctx) { 6050b57cec5SDimitry Andric return create(AShr, LHS, RHS, Ctx); 6060b57cec5SDimitry Andric } 6070b57cec5SDimitry Andric createLShr(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)6080b57cec5SDimitry Andric static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS, 6090b57cec5SDimitry Andric MCContext &Ctx) { 6100b57cec5SDimitry Andric return create(LShr, LHS, RHS, Ctx); 6110b57cec5SDimitry Andric } 6120b57cec5SDimitry Andric createSub(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)6130b57cec5SDimitry Andric static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS, 6140b57cec5SDimitry Andric MCContext &Ctx) { 6150b57cec5SDimitry Andric return create(Sub, LHS, RHS, Ctx); 6160b57cec5SDimitry Andric } 6170b57cec5SDimitry Andric createXor(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)6180b57cec5SDimitry Andric static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS, 6190b57cec5SDimitry Andric MCContext &Ctx) { 6200b57cec5SDimitry Andric return create(Xor, LHS, RHS, Ctx); 6210b57cec5SDimitry Andric } 6220b57cec5SDimitry Andric 6230b57cec5SDimitry Andric /// @} 6240b57cec5SDimitry Andric /// \name Accessors 6250b57cec5SDimitry Andric /// @{ 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric /// Get the kind of this binary expression. getOpcode()6285ffd83dbSDimitry Andric Opcode getOpcode() const { return (Opcode)getSubclassData(); } 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric /// Get the left-hand side expression of the binary operator. getLHS()6310b57cec5SDimitry Andric const MCExpr *getLHS() const { return LHS; } 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric /// Get the right-hand side expression of the binary operator. getRHS()6340b57cec5SDimitry Andric const MCExpr *getRHS() const { return RHS; } 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric /// @} 6370b57cec5SDimitry Andric classof(const MCExpr * E)6380b57cec5SDimitry Andric static bool classof(const MCExpr *E) { 6390b57cec5SDimitry Andric return E->getKind() == MCExpr::Binary; 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric }; 6420b57cec5SDimitry Andric 6430b57cec5SDimitry Andric /// This is an extension point for target-specific MCExpr subclasses to 6440b57cec5SDimitry Andric /// implement. 6450b57cec5SDimitry Andric /// 6460b57cec5SDimitry Andric /// NOTE: All subclasses are required to have trivial destructors because 6470b57cec5SDimitry Andric /// MCExprs are bump pointer allocated and not destructed. 6480b57cec5SDimitry Andric class MCTargetExpr : public MCExpr { 6490b57cec5SDimitry Andric virtual void anchor(); 6500b57cec5SDimitry Andric 6510b57cec5SDimitry Andric protected: MCTargetExpr()6520b57cec5SDimitry Andric MCTargetExpr() : MCExpr(Target, SMLoc()) {} 6530b57cec5SDimitry Andric virtual ~MCTargetExpr() = default; 6540b57cec5SDimitry Andric 6550b57cec5SDimitry Andric public: 6560b57cec5SDimitry Andric virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0; 6570b57cec5SDimitry Andric virtual bool evaluateAsRelocatableImpl(MCValue &Res, 6580b57cec5SDimitry Andric const MCAsmLayout *Layout, 6590b57cec5SDimitry Andric const MCFixup *Fixup) const = 0; 6600b57cec5SDimitry Andric // allow Target Expressions to be checked for equality isEqualTo(const MCExpr * x)6610b57cec5SDimitry Andric virtual bool isEqualTo(const MCExpr *x) const { return false; } 6620b57cec5SDimitry Andric // This should be set when assigned expressions are not valid ".set" 6630b57cec5SDimitry Andric // expressions, e.g. registers, and must be inlined. inlineAssignedExpr()6640b57cec5SDimitry Andric virtual bool inlineAssignedExpr() const { return false; } 6650b57cec5SDimitry Andric virtual void visitUsedExpr(MCStreamer& Streamer) const = 0; 6660b57cec5SDimitry Andric virtual MCFragment *findAssociatedFragment() const = 0; 6670b57cec5SDimitry Andric 6680b57cec5SDimitry Andric virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0; 6690b57cec5SDimitry Andric classof(const MCExpr * E)6700b57cec5SDimitry Andric static bool classof(const MCExpr *E) { 6710b57cec5SDimitry Andric return E->getKind() == MCExpr::Target; 6720b57cec5SDimitry Andric } 6730b57cec5SDimitry Andric }; 6740b57cec5SDimitry Andric 6750b57cec5SDimitry Andric } // end namespace llvm 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric #endif // LLVM_MC_MCEXPR_H 678