diff options
Diffstat (limited to 'llvm/include/llvm/MC/MCExpr.h')
-rw-r--r-- | llvm/include/llvm/MC/MCExpr.h | 237 |
1 files changed, 147 insertions, 90 deletions
diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h index eb2786501f84..803c0d443bee 100644 --- a/llvm/include/llvm/MC/MCExpr.h +++ b/llvm/include/llvm/MC/MCExpr.h @@ -34,7 +34,7 @@ using SectionAddrMap = DenseMap<const MCSection *, uint64_t>; /// needed for parsing. class MCExpr { public: - enum ExprKind { + enum ExprKind : uint8_t { Binary, ///< Binary expressions. Constant, ///< Constant expressions. SymbolRef, ///< References to labels and assigned expressions. @@ -43,7 +43,14 @@ public: }; private: + static const unsigned NumSubclassDataBits = 24; + static_assert( + NumSubclassDataBits == CHAR_BIT * (sizeof(unsigned) - sizeof(ExprKind)), + "ExprKind and SubclassData together should take up one word"); + ExprKind Kind; + /// Field reserved for use by MCExpr subclasses. + unsigned SubclassData : NumSubclassDataBits; SMLoc Loc; bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, @@ -51,13 +58,19 @@ private: const SectionAddrMap *Addrs, bool InSet) const; protected: - explicit MCExpr(ExprKind Kind, SMLoc Loc) : Kind(Kind), Loc(Loc) {} + explicit MCExpr(ExprKind Kind, SMLoc Loc, unsigned SubclassData = 0) + : Kind(Kind), SubclassData(SubclassData), Loc(Loc) { + assert(SubclassData < (1 << NumSubclassDataBits) && + "Subclass data too large"); + } bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, const MCFixup *Fixup, const SectionAddrMap *Addrs, bool InSet) const; + unsigned getSubclassData() const { return SubclassData; } + public: MCExpr(const MCExpr &) = delete; MCExpr &operator=(const MCExpr &) = delete; @@ -130,29 +143,39 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { //// Represent a constant integer expression. class MCConstantExpr : public MCExpr { int64_t Value; - bool PrintInHex = false; - explicit MCConstantExpr(int64_t Value) - : MCExpr(MCExpr::Constant, SMLoc()), Value(Value) {} + // Subclass data stores SizeInBytes in bits 0..7 and PrintInHex in bit 8. + static const unsigned SizeInBytesBits = 8; + static const unsigned SizeInBytesMask = (1 << SizeInBytesBits) - 1; + static const unsigned PrintInHexBit = 1 << SizeInBytesBits; + + static unsigned encodeSubclassData(bool PrintInHex, unsigned SizeInBytes) { + assert(SizeInBytes <= sizeof(int64_t) && "Excessive size"); + return SizeInBytes | (PrintInHex ? PrintInHexBit : 0); + } - MCConstantExpr(int64_t Value, bool PrintInHex) - : MCExpr(MCExpr::Constant, SMLoc()), Value(Value), - PrintInHex(PrintInHex) {} + MCConstantExpr(int64_t Value, bool PrintInHex, unsigned SizeInBytes) + : MCExpr(MCExpr::Constant, SMLoc(), + encodeSubclassData(PrintInHex, SizeInBytes)), Value(Value) {} public: /// \name Construction /// @{ static const MCConstantExpr *create(int64_t Value, MCContext &Ctx, - bool PrintInHex = false); + bool PrintInHex = false, + unsigned SizeInBytes = 0); /// @} /// \name Accessors /// @{ int64_t getValue() const { return Value; } + unsigned getSizeInBytes() const { + return getSubclassData() & SizeInBytesMask; + } - bool useHexFormat() const { return PrintInHex; } + bool useHexFormat() const { return (getSubclassData() & PrintInHexBit) != 0; } /// @} @@ -175,6 +198,7 @@ public: VK_GOT, VK_GOTOFF, VK_GOTREL, + VK_PCREL, VK_GOTPCREL, VK_GOTTPOFF, VK_INDNTPOFF, @@ -186,9 +210,9 @@ public: VK_TLSLDM, VK_TPOFF, VK_DTPOFF, - VK_TLSCALL, // symbol(tlscall) - VK_TLSDESC, // symbol(tlsdesc) - VK_TLVP, // Mach-O thread local variable relocations + VK_TLSCALL, // symbol(tlscall) + VK_TLSDESC, // symbol(tlsdesc) + VK_TLVP, // Mach-O thread local variable relocations VK_TLVPPAGE, VK_TLVPPAGEOFF, VK_PAGE, @@ -196,8 +220,8 @@ public: VK_GOTPAGE, VK_GOTPAGEOFF, VK_SECREL, - VK_SIZE, // symbol@SIZE - VK_WEAKREF, // The link between the symbols in .weakref foo, bar + VK_SIZE, // symbol@SIZE + VK_WEAKREF, // The link between the symbols in .weakref foo, bar VK_X86_ABS8, @@ -206,8 +230,8 @@ public: VK_ARM_TARGET1, VK_ARM_TARGET2, VK_ARM_PREL31, - VK_ARM_SBREL, // symbol(sbrel) - VK_ARM_TLSLDO, // symbol(tlsldo) + VK_ARM_SBREL, // symbol(sbrel) + VK_ARM_TLSLDO, // symbol(tlsldo) VK_ARM_TLSDESCSEQ, VK_AVR_NONE, @@ -218,68 +242,69 @@ public: VK_AVR_DIFF16, VK_AVR_DIFF32, - VK_PPC_LO, // symbol@l - VK_PPC_HI, // symbol@h - VK_PPC_HA, // symbol@ha - VK_PPC_HIGH, // symbol@high - VK_PPC_HIGHA, // symbol@higha - VK_PPC_HIGHER, // symbol@higher - VK_PPC_HIGHERA, // symbol@highera - VK_PPC_HIGHEST, // symbol@highest - VK_PPC_HIGHESTA, // symbol@highesta - VK_PPC_GOT_LO, // symbol@got@l - VK_PPC_GOT_HI, // symbol@got@h - VK_PPC_GOT_HA, // symbol@got@ha - VK_PPC_TOCBASE, // symbol@tocbase - VK_PPC_TOC, // symbol@toc - VK_PPC_TOC_LO, // symbol@toc@l - VK_PPC_TOC_HI, // symbol@toc@h - VK_PPC_TOC_HA, // symbol@toc@ha - VK_PPC_U, // symbol@u - VK_PPC_L, // symbol@l - VK_PPC_DTPMOD, // symbol@dtpmod - VK_PPC_TPREL_LO, // symbol@tprel@l - VK_PPC_TPREL_HI, // symbol@tprel@h - VK_PPC_TPREL_HA, // symbol@tprel@ha - VK_PPC_TPREL_HIGH, // symbol@tprel@high - VK_PPC_TPREL_HIGHA, // symbol@tprel@higha - VK_PPC_TPREL_HIGHER, // symbol@tprel@higher - VK_PPC_TPREL_HIGHERA, // symbol@tprel@highera - VK_PPC_TPREL_HIGHEST, // symbol@tprel@highest - VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta - VK_PPC_DTPREL_LO, // symbol@dtprel@l - VK_PPC_DTPREL_HI, // symbol@dtprel@h - VK_PPC_DTPREL_HA, // symbol@dtprel@ha - VK_PPC_DTPREL_HIGH, // symbol@dtprel@high - VK_PPC_DTPREL_HIGHA, // symbol@dtprel@higha - VK_PPC_DTPREL_HIGHER, // symbol@dtprel@higher - VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera - VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest - VK_PPC_DTPREL_HIGHESTA,// symbol@dtprel@highesta - VK_PPC_GOT_TPREL, // symbol@got@tprel - VK_PPC_GOT_TPREL_LO, // symbol@got@tprel@l - VK_PPC_GOT_TPREL_HI, // symbol@got@tprel@h - VK_PPC_GOT_TPREL_HA, // symbol@got@tprel@ha - VK_PPC_GOT_DTPREL, // symbol@got@dtprel - VK_PPC_GOT_DTPREL_LO, // symbol@got@dtprel@l - VK_PPC_GOT_DTPREL_HI, // symbol@got@dtprel@h - VK_PPC_GOT_DTPREL_HA, // symbol@got@dtprel@ha - VK_PPC_TLS, // symbol@tls - VK_PPC_GOT_TLSGD, // symbol@got@tlsgd - VK_PPC_GOT_TLSGD_LO, // symbol@got@tlsgd@l - VK_PPC_GOT_TLSGD_HI, // symbol@got@tlsgd@h - VK_PPC_GOT_TLSGD_HA, // symbol@got@tlsgd@ha - VK_PPC_TLSGD, // symbol@tlsgd - VK_PPC_GOT_TLSLD, // symbol@got@tlsld - VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l - VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h - VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha - VK_PPC_TLSLD, // symbol@tlsld - VK_PPC_LOCAL, // symbol@local + VK_PPC_LO, // symbol@l + VK_PPC_HI, // symbol@h + VK_PPC_HA, // symbol@ha + VK_PPC_HIGH, // symbol@high + VK_PPC_HIGHA, // symbol@higha + VK_PPC_HIGHER, // symbol@higher + VK_PPC_HIGHERA, // symbol@highera + VK_PPC_HIGHEST, // symbol@highest + VK_PPC_HIGHESTA, // symbol@highesta + VK_PPC_GOT_LO, // symbol@got@l + VK_PPC_GOT_HI, // symbol@got@h + VK_PPC_GOT_HA, // symbol@got@ha + VK_PPC_TOCBASE, // symbol@tocbase + VK_PPC_TOC, // symbol@toc + VK_PPC_TOC_LO, // symbol@toc@l + VK_PPC_TOC_HI, // symbol@toc@h + VK_PPC_TOC_HA, // symbol@toc@ha + VK_PPC_U, // symbol@u + VK_PPC_L, // symbol@l + VK_PPC_DTPMOD, // symbol@dtpmod + VK_PPC_TPREL_LO, // symbol@tprel@l + VK_PPC_TPREL_HI, // symbol@tprel@h + VK_PPC_TPREL_HA, // symbol@tprel@ha + VK_PPC_TPREL_HIGH, // symbol@tprel@high + VK_PPC_TPREL_HIGHA, // symbol@tprel@higha + VK_PPC_TPREL_HIGHER, // symbol@tprel@higher + VK_PPC_TPREL_HIGHERA, // symbol@tprel@highera + VK_PPC_TPREL_HIGHEST, // symbol@tprel@highest + VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta + VK_PPC_DTPREL_LO, // symbol@dtprel@l + VK_PPC_DTPREL_HI, // symbol@dtprel@h + VK_PPC_DTPREL_HA, // symbol@dtprel@ha + VK_PPC_DTPREL_HIGH, // symbol@dtprel@high + VK_PPC_DTPREL_HIGHA, // symbol@dtprel@higha + VK_PPC_DTPREL_HIGHER, // symbol@dtprel@higher + VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera + VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest + VK_PPC_DTPREL_HIGHESTA, // symbol@dtprel@highesta + VK_PPC_GOT_TPREL, // symbol@got@tprel + VK_PPC_GOT_TPREL_LO, // symbol@got@tprel@l + VK_PPC_GOT_TPREL_HI, // symbol@got@tprel@h + VK_PPC_GOT_TPREL_HA, // symbol@got@tprel@ha + VK_PPC_GOT_DTPREL, // symbol@got@dtprel + VK_PPC_GOT_DTPREL_LO, // symbol@got@dtprel@l + VK_PPC_GOT_DTPREL_HI, // symbol@got@dtprel@h + VK_PPC_GOT_DTPREL_HA, // symbol@got@dtprel@ha + VK_PPC_TLS, // symbol@tls + VK_PPC_GOT_TLSGD, // symbol@got@tlsgd + VK_PPC_GOT_TLSGD_LO, // symbol@got@tlsgd@l + VK_PPC_GOT_TLSGD_HI, // symbol@got@tlsgd@h + VK_PPC_GOT_TLSGD_HA, // symbol@got@tlsgd@ha + VK_PPC_TLSGD, // symbol@tlsgd + VK_PPC_GOT_TLSLD, // symbol@got@tlsld + VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l + VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h + VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha + VK_PPC_GOT_PCREL, // symbol@got@pcrel + VK_PPC_TLSLD, // symbol@tlsld + VK_PPC_LOCAL, // symbol@local + VK_PPC_NOTOC, // symbol@notoc VK_COFF_IMGREL32, // symbol@imgrel (image-relative) - VK_Hexagon_PCREL, VK_Hexagon_LO16, VK_Hexagon_HI16, VK_Hexagon_GPREL, @@ -302,22 +327,52 @@ public: VK_AMDGPU_ABS32_LO, // symbol@abs32@lo VK_AMDGPU_ABS32_HI, // symbol@abs32@hi + VK_VE_HI32, // symbol@hi + VK_VE_LO32, // symbol@lo + VK_VE_PC_HI32, // symbol@pc_hi + VK_VE_PC_LO32, // symbol@pc_lo + VK_VE_GOT_HI32, // symbol@got_hi + VK_VE_GOT_LO32, // symbol@got_lo + VK_VE_GOTOFF_HI32, // symbol@gotoff_hi + VK_VE_GOTOFF_LO32, // symbol@gotoff_lo + VK_VE_PLT_HI32, // symbol@plt_hi + VK_VE_PLT_LO32, // symbol@plt_lo + VK_VE_TLS_GD_HI32, // symbol@tls_gd_hi + VK_VE_TLS_GD_LO32, // symbol@tls_gd_lo + VK_VE_TPOFF_HI32, // symbol@tpoff_hi + VK_VE_TPOFF_LO32, // symbol@tpoff_lo + VK_TPREL, VK_DTPREL }; private: - /// The symbol reference modifier. - const VariantKind Kind; + /// The symbol being referenced. + const MCSymbol *Symbol; + + // Subclass data stores VariantKind in bits 0..15, UseParensForSymbolVariant + // in bit 16 and HasSubsectionsViaSymbols in bit 17. + static const unsigned VariantKindBits = 16; + static const unsigned VariantKindMask = (1 << VariantKindBits) - 1; /// Specifies how the variant kind should be printed. - const unsigned UseParensForSymbolVariant : 1; + static const unsigned UseParensForSymbolVariantBit = 1 << VariantKindBits; // FIXME: Remove this bit. - const unsigned HasSubsectionsViaSymbols : 1; + static const unsigned HasSubsectionsViaSymbolsBit = + 1 << (VariantKindBits + 1); + + static unsigned encodeSubclassData(VariantKind Kind, + bool UseParensForSymbolVariant, + bool HasSubsectionsViaSymbols) { + return (unsigned)Kind | + (UseParensForSymbolVariant ? UseParensForSymbolVariantBit : 0) | + (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0); + } - /// The symbol being referenced. - const MCSymbol *Symbol; + bool useParensForSymbolVariant() const { + return (getSubclassData() & UseParensForSymbolVariantBit) != 0; + } explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind, const MCAsmInfo *MAI, SMLoc Loc = SMLoc()); @@ -341,11 +396,15 @@ public: const MCSymbol &getSymbol() const { return *Symbol; } - VariantKind getKind() const { return Kind; } + VariantKind getKind() const { + return (VariantKind)(getSubclassData() & VariantKindMask); + } void printVariantKind(raw_ostream &OS) const; - bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; } + bool hasSubsectionsViaSymbols() const { + return (getSubclassData() & HasSubsectionsViaSymbolsBit) != 0; + } /// @} /// \name Static Utility Functions @@ -373,11 +432,10 @@ public: }; private: - Opcode Op; const MCExpr *Expr; MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc) - : MCExpr(MCExpr::Unary, Loc), Op(Op), Expr(Expr) {} + : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {} public: /// \name Construction @@ -407,7 +465,7 @@ public: /// @{ /// Get the kind of this unary expression. - Opcode getOpcode() const { return Op; } + Opcode getOpcode() const { return (Opcode)getSubclassData(); } /// Get the child of this unary expression. const MCExpr *getSubExpr() const { return Expr; } @@ -449,12 +507,11 @@ public: }; private: - Opcode Op; const MCExpr *LHS, *RHS; MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, SMLoc Loc = SMLoc()) - : MCExpr(MCExpr::Binary, Loc), Op(Op), LHS(LHS), RHS(RHS) {} + : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {} public: /// \name Construction @@ -564,7 +621,7 @@ public: /// @{ /// Get the kind of this binary expression. - Opcode getOpcode() const { return Op; } + Opcode getOpcode() const { return (Opcode)getSubclassData(); } /// Get the left-hand side expression of the binary operator. const MCExpr *getLHS() const { return LHS; } |