Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 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_GOTPCREL_NORELAX, |
||
| 204 | VK_GOTTPOFF, |
||
| 205 | VK_INDNTPOFF, |
||
| 206 | VK_NTPOFF, |
||
| 207 | VK_GOTNTPOFF, |
||
| 208 | VK_PLT, |
||
| 209 | VK_TLSGD, |
||
| 210 | VK_TLSLD, |
||
| 211 | VK_TLSLDM, |
||
| 212 | VK_TPOFF, |
||
| 213 | VK_DTPOFF, |
||
| 214 | VK_TLSCALL, // symbol(tlscall) |
||
| 215 | VK_TLSDESC, // symbol(tlsdesc) |
||
| 216 | VK_TLVP, // Mach-O thread local variable relocations |
||
| 217 | VK_TLVPPAGE, |
||
| 218 | VK_TLVPPAGEOFF, |
||
| 219 | VK_PAGE, |
||
| 220 | VK_PAGEOFF, |
||
| 221 | VK_GOTPAGE, |
||
| 222 | VK_GOTPAGEOFF, |
||
| 223 | VK_SECREL, |
||
| 224 | VK_SIZE, // symbol@SIZE |
||
| 225 | VK_WEAKREF, // The link between the symbols in .weakref foo, bar |
||
| 226 | |||
| 227 | VK_X86_ABS8, |
||
| 228 | VK_X86_PLTOFF, |
||
| 229 | |||
| 230 | VK_ARM_NONE, |
||
| 231 | VK_ARM_GOT_PREL, |
||
| 232 | VK_ARM_TARGET1, |
||
| 233 | VK_ARM_TARGET2, |
||
| 234 | VK_ARM_PREL31, |
||
| 235 | VK_ARM_SBREL, // symbol(sbrel) |
||
| 236 | VK_ARM_TLSLDO, // symbol(tlsldo) |
||
| 237 | VK_ARM_TLSDESCSEQ, |
||
| 238 | |||
| 239 | VK_AVR_NONE, |
||
| 240 | VK_AVR_LO8, |
||
| 241 | VK_AVR_HI8, |
||
| 242 | VK_AVR_HLO8, |
||
| 243 | VK_AVR_DIFF8, |
||
| 244 | VK_AVR_DIFF16, |
||
| 245 | VK_AVR_DIFF32, |
||
| 246 | VK_AVR_PM, |
||
| 247 | |||
| 248 | VK_PPC_LO, // symbol@l |
||
| 249 | VK_PPC_HI, // symbol@h |
||
| 250 | VK_PPC_HA, // symbol@ha |
||
| 251 | VK_PPC_HIGH, // symbol@high |
||
| 252 | VK_PPC_HIGHA, // symbol@higha |
||
| 253 | VK_PPC_HIGHER, // symbol@higher |
||
| 254 | VK_PPC_HIGHERA, // symbol@highera |
||
| 255 | VK_PPC_HIGHEST, // symbol@highest |
||
| 256 | VK_PPC_HIGHESTA, // symbol@highesta |
||
| 257 | VK_PPC_GOT_LO, // symbol@got@l |
||
| 258 | VK_PPC_GOT_HI, // symbol@got@h |
||
| 259 | VK_PPC_GOT_HA, // symbol@got@ha |
||
| 260 | VK_PPC_TOCBASE, // symbol@tocbase |
||
| 261 | VK_PPC_TOC, // symbol@toc |
||
| 262 | VK_PPC_TOC_LO, // symbol@toc@l |
||
| 263 | VK_PPC_TOC_HI, // symbol@toc@h |
||
| 264 | VK_PPC_TOC_HA, // symbol@toc@ha |
||
| 265 | VK_PPC_U, // symbol@u |
||
| 266 | VK_PPC_L, // symbol@l |
||
| 267 | VK_PPC_DTPMOD, // symbol@dtpmod |
||
| 268 | VK_PPC_TPREL_LO, // symbol@tprel@l |
||
| 269 | VK_PPC_TPREL_HI, // symbol@tprel@h |
||
| 270 | VK_PPC_TPREL_HA, // symbol@tprel@ha |
||
| 271 | VK_PPC_TPREL_HIGH, // symbol@tprel@high |
||
| 272 | VK_PPC_TPREL_HIGHA, // symbol@tprel@higha |
||
| 273 | VK_PPC_TPREL_HIGHER, // symbol@tprel@higher |
||
| 274 | VK_PPC_TPREL_HIGHERA, // symbol@tprel@highera |
||
| 275 | VK_PPC_TPREL_HIGHEST, // symbol@tprel@highest |
||
| 276 | VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta |
||
| 277 | VK_PPC_DTPREL_LO, // symbol@dtprel@l |
||
| 278 | VK_PPC_DTPREL_HI, // symbol@dtprel@h |
||
| 279 | VK_PPC_DTPREL_HA, // symbol@dtprel@ha |
||
| 280 | VK_PPC_DTPREL_HIGH, // symbol@dtprel@high |
||
| 281 | VK_PPC_DTPREL_HIGHA, // symbol@dtprel@higha |
||
| 282 | VK_PPC_DTPREL_HIGHER, // symbol@dtprel@higher |
||
| 283 | VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera |
||
| 284 | VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest |
||
| 285 | VK_PPC_DTPREL_HIGHESTA, // symbol@dtprel@highesta |
||
| 286 | VK_PPC_GOT_TPREL, // symbol@got@tprel |
||
| 287 | VK_PPC_GOT_TPREL_LO, // symbol@got@tprel@l |
||
| 288 | VK_PPC_GOT_TPREL_HI, // symbol@got@tprel@h |
||
| 289 | VK_PPC_GOT_TPREL_HA, // symbol@got@tprel@ha |
||
| 290 | VK_PPC_GOT_DTPREL, // symbol@got@dtprel |
||
| 291 | VK_PPC_GOT_DTPREL_LO, // symbol@got@dtprel@l |
||
| 292 | VK_PPC_GOT_DTPREL_HI, // symbol@got@dtprel@h |
||
| 293 | VK_PPC_GOT_DTPREL_HA, // symbol@got@dtprel@ha |
||
| 294 | VK_PPC_TLS, // symbol@tls |
||
| 295 | VK_PPC_GOT_TLSGD, // symbol@got@tlsgd |
||
| 296 | VK_PPC_GOT_TLSGD_LO, // symbol@got@tlsgd@l |
||
| 297 | VK_PPC_GOT_TLSGD_HI, // symbol@got@tlsgd@h |
||
| 298 | VK_PPC_GOT_TLSGD_HA, // symbol@got@tlsgd@ha |
||
| 299 | VK_PPC_TLSGD, // symbol@tlsgd |
||
| 300 | VK_PPC_AIX_TLSGD, // symbol@gd |
||
| 301 | VK_PPC_AIX_TLSGDM, // symbol@m |
||
| 302 | VK_PPC_GOT_TLSLD, // symbol@got@tlsld |
||
| 303 | VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l |
||
| 304 | VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h |
||
| 305 | VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha |
||
| 306 | VK_PPC_GOT_PCREL, // symbol@got@pcrel |
||
| 307 | VK_PPC_GOT_TLSGD_PCREL, // symbol@got@tlsgd@pcrel |
||
| 308 | VK_PPC_GOT_TLSLD_PCREL, // symbol@got@tlsld@pcrel |
||
| 309 | VK_PPC_GOT_TPREL_PCREL, // symbol@got@tprel@pcrel |
||
| 310 | VK_PPC_TLS_PCREL, // symbol@tls@pcrel |
||
| 311 | VK_PPC_TLSLD, // symbol@tlsld |
||
| 312 | VK_PPC_LOCAL, // symbol@local |
||
| 313 | VK_PPC_NOTOC, // symbol@notoc |
||
| 314 | VK_PPC_PCREL_OPT, // .reloc expr, R_PPC64_PCREL_OPT, expr |
||
| 315 | |||
| 316 | VK_COFF_IMGREL32, // symbol@imgrel (image-relative) |
||
| 317 | |||
| 318 | VK_Hexagon_LO16, |
||
| 319 | VK_Hexagon_HI16, |
||
| 320 | VK_Hexagon_GPREL, |
||
| 321 | VK_Hexagon_GD_GOT, |
||
| 322 | VK_Hexagon_LD_GOT, |
||
| 323 | VK_Hexagon_GD_PLT, |
||
| 324 | VK_Hexagon_LD_PLT, |
||
| 325 | VK_Hexagon_IE, |
||
| 326 | VK_Hexagon_IE_GOT, |
||
| 327 | |||
| 328 | VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature) |
||
| 329 | VK_WASM_TLSREL, // Memory address relative to __tls_base |
||
| 330 | VK_WASM_MBREL, // Memory address relative to __memory_base |
||
| 331 | VK_WASM_TBREL, // Table index relative to __table_base |
||
| 332 | VK_WASM_GOT_TLS, // Wasm global index of TLS symbol. |
||
| 333 | |||
| 334 | VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo |
||
| 335 | VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi |
||
| 336 | VK_AMDGPU_REL32_LO, // symbol@rel32@lo |
||
| 337 | VK_AMDGPU_REL32_HI, // symbol@rel32@hi |
||
| 338 | VK_AMDGPU_REL64, // symbol@rel64 |
||
| 339 | VK_AMDGPU_ABS32_LO, // symbol@abs32@lo |
||
| 340 | VK_AMDGPU_ABS32_HI, // symbol@abs32@hi |
||
| 341 | |||
| 342 | VK_VE_HI32, // symbol@hi |
||
| 343 | VK_VE_LO32, // symbol@lo |
||
| 344 | VK_VE_PC_HI32, // symbol@pc_hi |
||
| 345 | VK_VE_PC_LO32, // symbol@pc_lo |
||
| 346 | VK_VE_GOT_HI32, // symbol@got_hi |
||
| 347 | VK_VE_GOT_LO32, // symbol@got_lo |
||
| 348 | VK_VE_GOTOFF_HI32, // symbol@gotoff_hi |
||
| 349 | VK_VE_GOTOFF_LO32, // symbol@gotoff_lo |
||
| 350 | VK_VE_PLT_HI32, // symbol@plt_hi |
||
| 351 | VK_VE_PLT_LO32, // symbol@plt_lo |
||
| 352 | VK_VE_TLS_GD_HI32, // symbol@tls_gd_hi |
||
| 353 | VK_VE_TLS_GD_LO32, // symbol@tls_gd_lo |
||
| 354 | VK_VE_TPOFF_HI32, // symbol@tpoff_hi |
||
| 355 | VK_VE_TPOFF_LO32, // symbol@tpoff_lo |
||
| 356 | |||
| 357 | VK_TPREL, |
||
| 358 | VK_DTPREL |
||
| 359 | }; |
||
| 360 | |||
| 361 | private: |
||
| 362 | /// The symbol being referenced. |
||
| 363 | const MCSymbol *Symbol; |
||
| 364 | |||
| 365 | // Subclass data stores VariantKind in bits 0..15 and HasSubsectionsViaSymbols |
||
| 366 | // in bit 16. |
||
| 367 | static const unsigned VariantKindBits = 16; |
||
| 368 | static const unsigned VariantKindMask = (1 << VariantKindBits) - 1; |
||
| 369 | |||
| 370 | // FIXME: Remove this bit. |
||
| 371 | static const unsigned HasSubsectionsViaSymbolsBit = 1 << VariantKindBits; |
||
| 372 | |||
| 373 | static unsigned encodeSubclassData(VariantKind Kind, |
||
| 374 | bool HasSubsectionsViaSymbols) { |
||
| 375 | return (unsigned)Kind | |
||
| 376 | (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0); |
||
| 377 | } |
||
| 378 | |||
| 379 | explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind, |
||
| 380 | const MCAsmInfo *MAI, SMLoc Loc = SMLoc()); |
||
| 381 | |||
| 382 | public: |
||
| 383 | /// \name Construction |
||
| 384 | /// @{ |
||
| 385 | |||
| 386 | static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) { |
||
| 387 | return MCSymbolRefExpr::create(Symbol, VK_None, Ctx); |
||
| 388 | } |
||
| 389 | |||
| 390 | static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind, |
||
| 391 | MCContext &Ctx, SMLoc Loc = SMLoc()); |
||
| 392 | static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind, |
||
| 393 | MCContext &Ctx); |
||
| 394 | |||
| 395 | /// @} |
||
| 396 | /// \name Accessors |
||
| 397 | /// @{ |
||
| 398 | |||
| 399 | const MCSymbol &getSymbol() const { return *Symbol; } |
||
| 400 | |||
| 401 | VariantKind getKind() const { |
||
| 402 | return (VariantKind)(getSubclassData() & VariantKindMask); |
||
| 403 | } |
||
| 404 | |||
| 405 | bool hasSubsectionsViaSymbols() const { |
||
| 406 | return (getSubclassData() & HasSubsectionsViaSymbolsBit) != 0; |
||
| 407 | } |
||
| 408 | |||
| 409 | /// @} |
||
| 410 | /// \name Static Utility Functions |
||
| 411 | /// @{ |
||
| 412 | |||
| 413 | static StringRef getVariantKindName(VariantKind Kind); |
||
| 414 | |||
| 415 | static VariantKind getVariantKindForName(StringRef Name); |
||
| 416 | |||
| 417 | /// @} |
||
| 418 | |||
| 419 | static bool classof(const MCExpr *E) { |
||
| 420 | return E->getKind() == MCExpr::SymbolRef; |
||
| 421 | } |
||
| 422 | }; |
||
| 423 | |||
| 424 | /// Unary assembler expressions. |
||
| 425 | class MCUnaryExpr : public MCExpr { |
||
| 426 | public: |
||
| 427 | enum Opcode { |
||
| 428 | LNot, ///< Logical negation. |
||
| 429 | Minus, ///< Unary minus. |
||
| 430 | Not, ///< Bitwise negation. |
||
| 431 | Plus ///< Unary plus. |
||
| 432 | }; |
||
| 433 | |||
| 434 | private: |
||
| 435 | const MCExpr *Expr; |
||
| 436 | |||
| 437 | MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc) |
||
| 438 | : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {} |
||
| 439 | |||
| 440 | public: |
||
| 441 | /// \name Construction |
||
| 442 | /// @{ |
||
| 443 | |||
| 444 | static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr, |
||
| 445 | MCContext &Ctx, SMLoc Loc = SMLoc()); |
||
| 446 | |||
| 447 | static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { |
||
| 448 | return create(LNot, Expr, Ctx, Loc); |
||
| 449 | } |
||
| 450 | |||
| 451 | static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { |
||
| 452 | return create(Minus, Expr, Ctx, Loc); |
||
| 453 | } |
||
| 454 | |||
| 455 | static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { |
||
| 456 | return create(Not, Expr, Ctx, Loc); |
||
| 457 | } |
||
| 458 | |||
| 459 | static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { |
||
| 460 | return create(Plus, Expr, Ctx, Loc); |
||
| 461 | } |
||
| 462 | |||
| 463 | /// @} |
||
| 464 | /// \name Accessors |
||
| 465 | /// @{ |
||
| 466 | |||
| 467 | /// Get the kind of this unary expression. |
||
| 468 | Opcode getOpcode() const { return (Opcode)getSubclassData(); } |
||
| 469 | |||
| 470 | /// Get the child of this unary expression. |
||
| 471 | const MCExpr *getSubExpr() const { return Expr; } |
||
| 472 | |||
| 473 | /// @} |
||
| 474 | |||
| 475 | static bool classof(const MCExpr *E) { |
||
| 476 | return E->getKind() == MCExpr::Unary; |
||
| 477 | } |
||
| 478 | }; |
||
| 479 | |||
| 480 | /// Binary assembler expressions. |
||
| 481 | class MCBinaryExpr : public MCExpr { |
||
| 482 | public: |
||
| 483 | enum Opcode { |
||
| 484 | Add, ///< Addition. |
||
| 485 | And, ///< Bitwise and. |
||
| 486 | Div, ///< Signed division. |
||
| 487 | EQ, ///< Equality comparison. |
||
| 488 | GT, ///< Signed greater than comparison (result is either 0 or some |
||
| 489 | ///< target-specific non-zero value) |
||
| 490 | GTE, ///< Signed greater than or equal comparison (result is either 0 or |
||
| 491 | ///< some target-specific non-zero value). |
||
| 492 | LAnd, ///< Logical and. |
||
| 493 | LOr, ///< Logical or. |
||
| 494 | LT, ///< Signed less than comparison (result is either 0 or |
||
| 495 | ///< some target-specific non-zero value). |
||
| 496 | LTE, ///< Signed less than or equal comparison (result is either 0 or |
||
| 497 | ///< some target-specific non-zero value). |
||
| 498 | Mod, ///< Signed remainder. |
||
| 499 | Mul, ///< Multiplication. |
||
| 500 | NE, ///< Inequality comparison. |
||
| 501 | Or, ///< Bitwise or. |
||
| 502 | OrNot, ///< Bitwise or not. |
||
| 503 | Shl, ///< Shift left. |
||
| 504 | AShr, ///< Arithmetic shift right. |
||
| 505 | LShr, ///< Logical shift right. |
||
| 506 | Sub, ///< Subtraction. |
||
| 507 | Xor ///< Bitwise exclusive or. |
||
| 508 | }; |
||
| 509 | |||
| 510 | private: |
||
| 511 | const MCExpr *LHS, *RHS; |
||
| 512 | |||
| 513 | MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, |
||
| 514 | SMLoc Loc = SMLoc()) |
||
| 515 | : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {} |
||
| 516 | |||
| 517 | public: |
||
| 518 | /// \name Construction |
||
| 519 | /// @{ |
||
| 520 | |||
| 521 | static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS, |
||
| 522 | const MCExpr *RHS, MCContext &Ctx, |
||
| 523 | SMLoc Loc = SMLoc()); |
||
| 524 | |||
| 525 | static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS, |
||
| 526 | MCContext &Ctx) { |
||
| 527 | return create(Add, LHS, RHS, Ctx); |
||
| 528 | } |
||
| 529 | |||
| 530 | static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS, |
||
| 531 | MCContext &Ctx) { |
||
| 532 | return create(And, LHS, RHS, Ctx); |
||
| 533 | } |
||
| 534 | |||
| 535 | static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS, |
||
| 536 | MCContext &Ctx) { |
||
| 537 | return create(Div, LHS, RHS, Ctx); |
||
| 538 | } |
||
| 539 | |||
| 540 | static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS, |
||
| 541 | MCContext &Ctx) { |
||
| 542 | return create(EQ, LHS, RHS, Ctx); |
||
| 543 | } |
||
| 544 | |||
| 545 | static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS, |
||
| 546 | MCContext &Ctx) { |
||
| 547 | return create(GT, LHS, RHS, Ctx); |
||
| 548 | } |
||
| 549 | |||
| 550 | static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS, |
||
| 551 | MCContext &Ctx) { |
||
| 552 | return create(GTE, LHS, RHS, Ctx); |
||
| 553 | } |
||
| 554 | |||
| 555 | static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS, |
||
| 556 | MCContext &Ctx) { |
||
| 557 | return create(LAnd, LHS, RHS, Ctx); |
||
| 558 | } |
||
| 559 | |||
| 560 | static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS, |
||
| 561 | MCContext &Ctx) { |
||
| 562 | return create(LOr, LHS, RHS, Ctx); |
||
| 563 | } |
||
| 564 | |||
| 565 | static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS, |
||
| 566 | MCContext &Ctx) { |
||
| 567 | return create(LT, LHS, RHS, Ctx); |
||
| 568 | } |
||
| 569 | |||
| 570 | static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS, |
||
| 571 | MCContext &Ctx) { |
||
| 572 | return create(LTE, LHS, RHS, Ctx); |
||
| 573 | } |
||
| 574 | |||
| 575 | static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS, |
||
| 576 | MCContext &Ctx) { |
||
| 577 | return create(Mod, LHS, RHS, Ctx); |
||
| 578 | } |
||
| 579 | |||
| 580 | static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS, |
||
| 581 | MCContext &Ctx) { |
||
| 582 | return create(Mul, LHS, RHS, Ctx); |
||
| 583 | } |
||
| 584 | |||
| 585 | static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS, |
||
| 586 | MCContext &Ctx) { |
||
| 587 | return create(NE, LHS, RHS, Ctx); |
||
| 588 | } |
||
| 589 | |||
| 590 | static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS, |
||
| 591 | MCContext &Ctx) { |
||
| 592 | return create(Or, LHS, RHS, Ctx); |
||
| 593 | } |
||
| 594 | |||
| 595 | static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS, |
||
| 596 | MCContext &Ctx) { |
||
| 597 | return create(Shl, LHS, RHS, Ctx); |
||
| 598 | } |
||
| 599 | |||
| 600 | static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS, |
||
| 601 | MCContext &Ctx) { |
||
| 602 | return create(AShr, LHS, RHS, Ctx); |
||
| 603 | } |
||
| 604 | |||
| 605 | static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS, |
||
| 606 | MCContext &Ctx) { |
||
| 607 | return create(LShr, LHS, RHS, Ctx); |
||
| 608 | } |
||
| 609 | |||
| 610 | static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS, |
||
| 611 | MCContext &Ctx) { |
||
| 612 | return create(Sub, LHS, RHS, Ctx); |
||
| 613 | } |
||
| 614 | |||
| 615 | static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS, |
||
| 616 | MCContext &Ctx) { |
||
| 617 | return create(Xor, LHS, RHS, Ctx); |
||
| 618 | } |
||
| 619 | |||
| 620 | /// @} |
||
| 621 | /// \name Accessors |
||
| 622 | /// @{ |
||
| 623 | |||
| 624 | /// Get the kind of this binary expression. |
||
| 625 | Opcode getOpcode() const { return (Opcode)getSubclassData(); } |
||
| 626 | |||
| 627 | /// Get the left-hand side expression of the binary operator. |
||
| 628 | const MCExpr *getLHS() const { return LHS; } |
||
| 629 | |||
| 630 | /// Get the right-hand side expression of the binary operator. |
||
| 631 | const MCExpr *getRHS() const { return RHS; } |
||
| 632 | |||
| 633 | /// @} |
||
| 634 | |||
| 635 | static bool classof(const MCExpr *E) { |
||
| 636 | return E->getKind() == MCExpr::Binary; |
||
| 637 | } |
||
| 638 | }; |
||
| 639 | |||
| 640 | /// This is an extension point for target-specific MCExpr subclasses to |
||
| 641 | /// implement. |
||
| 642 | /// |
||
| 643 | /// NOTE: All subclasses are required to have trivial destructors because |
||
| 644 | /// MCExprs are bump pointer allocated and not destructed. |
||
| 645 | class MCTargetExpr : public MCExpr { |
||
| 646 | virtual void anchor(); |
||
| 647 | |||
| 648 | protected: |
||
| 649 | MCTargetExpr() : MCExpr(Target, SMLoc()) {} |
||
| 650 | virtual ~MCTargetExpr() = default; |
||
| 651 | |||
| 652 | public: |
||
| 653 | virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0; |
||
| 654 | virtual bool evaluateAsRelocatableImpl(MCValue &Res, |
||
| 655 | const MCAsmLayout *Layout, |
||
| 656 | const MCFixup *Fixup) const = 0; |
||
| 657 | // allow Target Expressions to be checked for equality |
||
| 658 | virtual bool isEqualTo(const MCExpr *x) const { return false; } |
||
| 659 | // This should be set when assigned expressions are not valid ".set" |
||
| 660 | // expressions, e.g. registers, and must be inlined. |
||
| 661 | virtual bool inlineAssignedExpr() const { return false; } |
||
| 662 | virtual void visitUsedExpr(MCStreamer& Streamer) const = 0; |
||
| 663 | virtual MCFragment *findAssociatedFragment() const = 0; |
||
| 664 | |||
| 665 | virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0; |
||
| 666 | |||
| 667 | static bool classof(const MCExpr *E) { |
||
| 668 | return E->getKind() == MCExpr::Target; |
||
| 669 | } |
||
| 670 | }; |
||
| 671 | |||
| 672 | } // end namespace llvm |
||
| 673 | |||
| 674 | #endif // LLVM_MC_MCEXPR_H |