MCExpr.h revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
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/Casting.h" 15#include "llvm/Support/DataTypes.h" 16 17namespace llvm { 18class MCAsmInfo; 19class MCAsmLayout; 20class MCAssembler; 21class MCContext; 22class MCSection; 23class MCSectionData; 24class MCSymbol; 25class MCValue; 26class raw_ostream; 27class StringRef; 28typedef DenseMap<const MCSectionData*, uint64_t> SectionAddrMap; 29 30/// MCExpr - Base class for the full range of assembler expressions which are 31/// needed for parsing. 32class MCExpr { 33public: 34 enum ExprKind { 35 Binary, ///< Binary expressions. 36 Constant, ///< Constant expressions. 37 SymbolRef, ///< References to labels and assigned expressions. 38 Unary, ///< Unary expressions. 39 Target ///< Target specific expression. 40 }; 41 42private: 43 ExprKind Kind; 44 45 MCExpr(const MCExpr&) LLVM_DELETED_FUNCTION; 46 void operator=(const MCExpr&) LLVM_DELETED_FUNCTION; 47 48 bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, 49 const MCAsmLayout *Layout, 50 const SectionAddrMap *Addrs) const; 51protected: 52 explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {} 53 54 bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, 55 const MCAsmLayout *Layout, 56 const SectionAddrMap *Addrs, 57 bool InSet) const; 58public: 59 /// @name Accessors 60 /// @{ 61 62 ExprKind getKind() const { return Kind; } 63 64 /// @} 65 /// @name Utility Methods 66 /// @{ 67 68 void print(raw_ostream &OS) const; 69 void dump() const; 70 71 /// @} 72 /// @name Expression Evaluation 73 /// @{ 74 75 /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value. 76 /// 77 /// @param Res - The absolute value, if evaluation succeeds. 78 /// @param Layout - The assembler layout object to use for evaluating symbol 79 /// values. If not given, then only non-symbolic expressions will be 80 /// evaluated. 81 /// @result - True on success. 82 bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, 83 const SectionAddrMap &Addrs) const; 84 bool EvaluateAsAbsolute(int64_t &Res) const; 85 bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; 86 bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; 87 88 /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable 89 /// value, i.e. an expression of the fixed form (a - b + constant). 90 /// 91 /// @param Res - The relocatable value, if evaluation succeeds. 92 /// @param Layout - The assembler layout object to use for evaluating values. 93 /// @result - True on success. 94 bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout) const; 95 96 /// FindAssociatedSection - Find the "associated section" for this expression, 97 /// which is currently defined as the absolute section for constants, or 98 /// otherwise the section associated with the first defined symbol in the 99 /// expression. 100 const MCSection *FindAssociatedSection() const; 101 102 /// @} 103}; 104 105inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { 106 E.print(OS); 107 return OS; 108} 109 110//// MCConstantExpr - Represent a constant integer expression. 111class MCConstantExpr : public MCExpr { 112 int64_t Value; 113 114 explicit MCConstantExpr(int64_t _Value) 115 : MCExpr(MCExpr::Constant), Value(_Value) {} 116 117public: 118 /// @name Construction 119 /// @{ 120 121 static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx); 122 123 /// @} 124 /// @name Accessors 125 /// @{ 126 127 int64_t getValue() const { return Value; } 128 129 /// @} 130 131 static bool classof(const MCExpr *E) { 132 return E->getKind() == MCExpr::Constant; 133 } 134}; 135 136/// MCSymbolRefExpr - Represent a reference to a symbol from inside an 137/// expression. 138/// 139/// A symbol reference in an expression may be a use of a label, a use of an 140/// assembler variable (defined constant), or constitute an implicit definition 141/// of the symbol as external. 142class MCSymbolRefExpr : public MCExpr { 143public: 144 enum VariantKind { 145 VK_None, 146 VK_Invalid, 147 148 VK_GOT, 149 VK_GOTOFF, 150 VK_GOTPCREL, 151 VK_GOTTPOFF, 152 VK_INDNTPOFF, 153 VK_NTPOFF, 154 VK_GOTNTPOFF, 155 VK_PLT, 156 VK_TLSGD, 157 VK_TLSLD, 158 VK_TLSLDM, 159 VK_TPOFF, 160 VK_DTPOFF, 161 VK_TLVP, // Mach-O thread local variable relocations 162 VK_TLVPPAGE, 163 VK_TLVPPAGEOFF, 164 VK_PAGE, 165 VK_PAGEOFF, 166 VK_GOTPAGE, 167 VK_GOTPAGEOFF, 168 VK_SECREL, 169 VK_WEAKREF, // The link between the symbols in .weakref foo, bar 170 171 VK_ARM_NONE, 172 VK_ARM_TARGET1, 173 VK_ARM_TARGET2, 174 VK_ARM_PREL31, 175 VK_ARM_TLSLDO, // symbol(tlsldo) 176 VK_ARM_TLSCALL, // symbol(tlscall) 177 VK_ARM_TLSDESC, // symbol(tlsdesc) 178 VK_ARM_TLSDESCSEQ, 179 180 VK_PPC_LO, // symbol@l 181 VK_PPC_HI, // symbol@h 182 VK_PPC_HA, // symbol@ha 183 VK_PPC_HIGHER, // symbol@higher 184 VK_PPC_HIGHERA, // symbol@highera 185 VK_PPC_HIGHEST, // symbol@highest 186 VK_PPC_HIGHESTA, // symbol@highesta 187 VK_PPC_GOT_LO, // symbol@got@l 188 VK_PPC_GOT_HI, // symbol@got@h 189 VK_PPC_GOT_HA, // symbol@got@ha 190 VK_PPC_TOCBASE, // symbol@tocbase 191 VK_PPC_TOC, // symbol@toc 192 VK_PPC_TOC_LO, // symbol@toc@l 193 VK_PPC_TOC_HI, // symbol@toc@h 194 VK_PPC_TOC_HA, // symbol@toc@ha 195 VK_PPC_DTPMOD, // symbol@dtpmod 196 VK_PPC_TPREL, // symbol@tprel 197 VK_PPC_TPREL_LO, // symbol@tprel@l 198 VK_PPC_TPREL_HI, // symbol@tprel@h 199 VK_PPC_TPREL_HA, // symbol@tprel@ha 200 VK_PPC_TPREL_HIGHER, // symbol@tprel@higher 201 VK_PPC_TPREL_HIGHERA, // symbol@tprel@highera 202 VK_PPC_TPREL_HIGHEST, // symbol@tprel@highest 203 VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta 204 VK_PPC_DTPREL, // symbol@dtprel 205 VK_PPC_DTPREL_LO, // symbol@dtprel@l 206 VK_PPC_DTPREL_HI, // symbol@dtprel@h 207 VK_PPC_DTPREL_HA, // symbol@dtprel@ha 208 VK_PPC_DTPREL_HIGHER, // symbol@dtprel@higher 209 VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera 210 VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest 211 VK_PPC_DTPREL_HIGHESTA,// symbol@dtprel@highesta 212 VK_PPC_GOT_TPREL, // symbol@got@tprel 213 VK_PPC_GOT_TPREL_LO, // symbol@got@tprel@l 214 VK_PPC_GOT_TPREL_HI, // symbol@got@tprel@h 215 VK_PPC_GOT_TPREL_HA, // symbol@got@tprel@ha 216 VK_PPC_GOT_DTPREL, // symbol@got@dtprel 217 VK_PPC_GOT_DTPREL_LO, // symbol@got@dtprel@l 218 VK_PPC_GOT_DTPREL_HI, // symbol@got@dtprel@h 219 VK_PPC_GOT_DTPREL_HA, // symbol@got@dtprel@ha 220 VK_PPC_TLS, // symbol@tls 221 VK_PPC_GOT_TLSGD, // symbol@got@tlsgd 222 VK_PPC_GOT_TLSGD_LO, // symbol@got@tlsgd@l 223 VK_PPC_GOT_TLSGD_HI, // symbol@got@tlsgd@h 224 VK_PPC_GOT_TLSGD_HA, // symbol@got@tlsgd@ha 225 VK_PPC_TLSGD, // symbol@tlsgd 226 VK_PPC_GOT_TLSLD, // symbol@got@tlsld 227 VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l 228 VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h 229 VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha 230 VK_PPC_TLSLD, // symbol@tlsld 231 232 VK_Mips_GPREL, 233 VK_Mips_GOT_CALL, 234 VK_Mips_GOT16, 235 VK_Mips_GOT, 236 VK_Mips_ABS_HI, 237 VK_Mips_ABS_LO, 238 VK_Mips_TLSGD, 239 VK_Mips_TLSLDM, 240 VK_Mips_DTPREL_HI, 241 VK_Mips_DTPREL_LO, 242 VK_Mips_GOTTPREL, 243 VK_Mips_TPREL_HI, 244 VK_Mips_TPREL_LO, 245 VK_Mips_GPOFF_HI, 246 VK_Mips_GPOFF_LO, 247 VK_Mips_GOT_DISP, 248 VK_Mips_GOT_PAGE, 249 VK_Mips_GOT_OFST, 250 VK_Mips_HIGHER, 251 VK_Mips_HIGHEST, 252 VK_Mips_GOT_HI16, 253 VK_Mips_GOT_LO16, 254 VK_Mips_CALL_HI16, 255 VK_Mips_CALL_LO16, 256 257 VK_COFF_IMGREL32 // symbol@imgrel (image-relative) 258 }; 259 260private: 261 /// The symbol being referenced. 262 const MCSymbol *Symbol; 263 264 /// The symbol reference modifier. 265 const VariantKind Kind; 266 267 /// MCAsmInfo that is used to print symbol variants correctly. 268 const MCAsmInfo *MAI; 269 270 explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind, 271 const MCAsmInfo *_MAI) 272 : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind), MAI(_MAI) { 273 assert(Symbol); 274 assert(MAI); 275 } 276 277public: 278 /// @name Construction 279 /// @{ 280 281 static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) { 282 return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx); 283 } 284 285 static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind, 286 MCContext &Ctx); 287 static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind, 288 MCContext &Ctx); 289 290 /// @} 291 /// @name Accessors 292 /// @{ 293 294 const MCSymbol &getSymbol() const { return *Symbol; } 295 const MCAsmInfo &getMCAsmInfo() const { return *MAI; } 296 297 VariantKind getKind() const { return Kind; } 298 299 /// @} 300 /// @name Static Utility Functions 301 /// @{ 302 303 static StringRef getVariantKindName(VariantKind Kind); 304 305 static VariantKind getVariantKindForName(StringRef Name); 306 307 /// @} 308 309 static bool classof(const MCExpr *E) { 310 return E->getKind() == MCExpr::SymbolRef; 311 } 312}; 313 314/// MCUnaryExpr - Unary assembler expressions. 315class MCUnaryExpr : public MCExpr { 316public: 317 enum Opcode { 318 LNot, ///< Logical negation. 319 Minus, ///< Unary minus. 320 Not, ///< Bitwise negation. 321 Plus ///< Unary plus. 322 }; 323 324private: 325 Opcode Op; 326 const MCExpr *Expr; 327 328 MCUnaryExpr(Opcode _Op, const MCExpr *_Expr) 329 : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {} 330 331public: 332 /// @name Construction 333 /// @{ 334 335 static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr, 336 MCContext &Ctx); 337 static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) { 338 return Create(LNot, Expr, Ctx); 339 } 340 static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) { 341 return Create(Minus, Expr, Ctx); 342 } 343 static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) { 344 return Create(Not, Expr, Ctx); 345 } 346 static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) { 347 return Create(Plus, Expr, Ctx); 348 } 349 350 /// @} 351 /// @name Accessors 352 /// @{ 353 354 /// getOpcode - Get the kind of this unary expression. 355 Opcode getOpcode() const { return Op; } 356 357 /// getSubExpr - Get the child of this unary expression. 358 const MCExpr *getSubExpr() const { return Expr; } 359 360 /// @} 361 362 static bool classof(const MCExpr *E) { 363 return E->getKind() == MCExpr::Unary; 364 } 365}; 366 367/// MCBinaryExpr - Binary assembler expressions. 368class MCBinaryExpr : public MCExpr { 369public: 370 enum Opcode { 371 Add, ///< Addition. 372 And, ///< Bitwise and. 373 Div, ///< Signed division. 374 EQ, ///< Equality comparison. 375 GT, ///< Signed greater than comparison (result is either 0 or some 376 ///< target-specific non-zero value) 377 GTE, ///< Signed greater than or equal comparison (result is either 0 or 378 ///< some target-specific non-zero value). 379 LAnd, ///< Logical and. 380 LOr, ///< Logical or. 381 LT, ///< Signed less than comparison (result is either 0 or 382 ///< some target-specific non-zero value). 383 LTE, ///< Signed less than or equal comparison (result is either 0 or 384 ///< some target-specific non-zero value). 385 Mod, ///< Signed remainder. 386 Mul, ///< Multiplication. 387 NE, ///< Inequality comparison. 388 Or, ///< Bitwise or. 389 Shl, ///< Shift left. 390 Shr, ///< Shift right (arithmetic or logical, depending on target) 391 Sub, ///< Subtraction. 392 Xor ///< Bitwise exclusive or. 393 }; 394 395private: 396 Opcode Op; 397 const MCExpr *LHS, *RHS; 398 399 MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS) 400 : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {} 401 402public: 403 /// @name Construction 404 /// @{ 405 406 static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS, 407 const MCExpr *RHS, MCContext &Ctx); 408 static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS, 409 MCContext &Ctx) { 410 return Create(Add, LHS, RHS, Ctx); 411 } 412 static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS, 413 MCContext &Ctx) { 414 return Create(And, LHS, RHS, Ctx); 415 } 416 static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS, 417 MCContext &Ctx) { 418 return Create(Div, LHS, RHS, Ctx); 419 } 420 static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS, 421 MCContext &Ctx) { 422 return Create(EQ, LHS, RHS, Ctx); 423 } 424 static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS, 425 MCContext &Ctx) { 426 return Create(GT, LHS, RHS, Ctx); 427 } 428 static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS, 429 MCContext &Ctx) { 430 return Create(GTE, LHS, RHS, Ctx); 431 } 432 static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS, 433 MCContext &Ctx) { 434 return Create(LAnd, LHS, RHS, Ctx); 435 } 436 static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS, 437 MCContext &Ctx) { 438 return Create(LOr, LHS, RHS, Ctx); 439 } 440 static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS, 441 MCContext &Ctx) { 442 return Create(LT, LHS, RHS, Ctx); 443 } 444 static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS, 445 MCContext &Ctx) { 446 return Create(LTE, LHS, RHS, Ctx); 447 } 448 static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS, 449 MCContext &Ctx) { 450 return Create(Mod, LHS, RHS, Ctx); 451 } 452 static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS, 453 MCContext &Ctx) { 454 return Create(Mul, LHS, RHS, Ctx); 455 } 456 static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS, 457 MCContext &Ctx) { 458 return Create(NE, LHS, RHS, Ctx); 459 } 460 static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS, 461 MCContext &Ctx) { 462 return Create(Or, LHS, RHS, Ctx); 463 } 464 static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS, 465 MCContext &Ctx) { 466 return Create(Shl, LHS, RHS, Ctx); 467 } 468 static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS, 469 MCContext &Ctx) { 470 return Create(Shr, LHS, RHS, Ctx); 471 } 472 static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS, 473 MCContext &Ctx) { 474 return Create(Sub, LHS, RHS, Ctx); 475 } 476 static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS, 477 MCContext &Ctx) { 478 return Create(Xor, LHS, RHS, Ctx); 479 } 480 481 /// @} 482 /// @name Accessors 483 /// @{ 484 485 /// getOpcode - Get the kind of this binary expression. 486 Opcode getOpcode() const { return Op; } 487 488 /// getLHS - Get the left-hand side expression of the binary operator. 489 const MCExpr *getLHS() const { return LHS; } 490 491 /// getRHS - Get the right-hand side expression of the binary operator. 492 const MCExpr *getRHS() const { return RHS; } 493 494 /// @} 495 496 static bool classof(const MCExpr *E) { 497 return E->getKind() == MCExpr::Binary; 498 } 499}; 500 501/// MCTargetExpr - This is an extension point for target-specific MCExpr 502/// subclasses to implement. 503/// 504/// NOTE: All subclasses are required to have trivial destructors because 505/// MCExprs are bump pointer allocated and not destructed. 506class MCTargetExpr : public MCExpr { 507 virtual void anchor(); 508protected: 509 MCTargetExpr() : MCExpr(Target) {} 510 virtual ~MCTargetExpr() {} 511public: 512 513 virtual void PrintImpl(raw_ostream &OS) const = 0; 514 virtual bool EvaluateAsRelocatableImpl(MCValue &Res, 515 const MCAsmLayout *Layout) const = 0; 516 virtual void AddValueSymbols(MCAssembler *) const = 0; 517 virtual const MCSection *FindAssociatedSection() const = 0; 518 519 virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0; 520 521 static bool classof(const MCExpr *E) { 522 return E->getKind() == MCExpr::Target; 523 } 524}; 525 526} // end namespace llvm 527 528#endif 529