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