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