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 classof(const MCExpr *)103 static bool classof(const MCExpr *) { return true; } 104 }; 105 106 inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { 107 E.print(OS); 108 return OS; 109 } 110 111 //// MCConstantExpr - Represent a constant integer expression. 112 class MCConstantExpr : public MCExpr { 113 int64_t Value; 114 MCConstantExpr(int64_t _Value)115 explicit MCConstantExpr(int64_t _Value) 116 : MCExpr(MCExpr::Constant), Value(_Value) {} 117 118 public: 119 /// @name Construction 120 /// @{ 121 122 static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx); 123 124 /// @} 125 /// @name Accessors 126 /// @{ 127 getValue()128 int64_t getValue() const { return Value; } 129 130 /// @} 131 classof(const MCExpr * E)132 static bool classof(const MCExpr *E) { 133 return E->getKind() == MCExpr::Constant; 134 } classof(const MCConstantExpr *)135 static bool classof(const MCConstantExpr *) { return true; } 136 }; 137 138 /// MCSymbolRefExpr - Represent a reference to a symbol from inside an 139 /// expression. 140 /// 141 /// A symbol reference in an expression may be a use of a label, a use of an 142 /// assembler variable (defined constant), or constitute an implicit definition 143 /// of the symbol as external. 144 class MCSymbolRefExpr : public MCExpr { 145 public: 146 enum VariantKind { 147 VK_None, 148 VK_Invalid, 149 150 VK_GOT, 151 VK_GOTOFF, 152 VK_GOTPCREL, 153 VK_GOTTPOFF, 154 VK_INDNTPOFF, 155 VK_NTPOFF, 156 VK_GOTNTPOFF, 157 VK_PLT, 158 VK_TLSGD, 159 VK_TLSLD, 160 VK_TLSLDM, 161 VK_TPOFF, 162 VK_DTPOFF, 163 VK_TLVP, // Mach-O thread local variable relocation 164 VK_SECREL, 165 // FIXME: We'd really like to use the generic Kinds listed above for these. 166 VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT 167 VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF 168 VK_ARM_GOT, 169 VK_ARM_GOTOFF, 170 VK_ARM_TPOFF, 171 VK_ARM_GOTTPOFF, 172 VK_ARM_TARGET1, 173 174 VK_PPC_TOC, // TOC base 175 VK_PPC_TOC_ENTRY, // TOC entry 176 VK_PPC_DARWIN_HA16, // ha16(symbol) 177 VK_PPC_DARWIN_LO16, // lo16(symbol) 178 VK_PPC_GAS_HA16, // symbol@ha 179 VK_PPC_GAS_LO16, // symbol@l 180 VK_PPC_TPREL16_HA, // symbol@tprel@ha 181 VK_PPC_TPREL16_LO, // symbol@tprel@l 182 183 VK_Mips_GPREL, 184 VK_Mips_GOT_CALL, 185 VK_Mips_GOT16, 186 VK_Mips_GOT, 187 VK_Mips_ABS_HI, 188 VK_Mips_ABS_LO, 189 VK_Mips_TLSGD, 190 VK_Mips_TLSLDM, 191 VK_Mips_DTPREL_HI, 192 VK_Mips_DTPREL_LO, 193 VK_Mips_GOTTPREL, 194 VK_Mips_TPREL_HI, 195 VK_Mips_TPREL_LO, 196 VK_Mips_GPOFF_HI, 197 VK_Mips_GPOFF_LO, 198 VK_Mips_GOT_DISP, 199 VK_Mips_GOT_PAGE, 200 VK_Mips_GOT_OFST, 201 VK_Mips_HIGHER, 202 VK_Mips_HIGHEST 203 }; 204 205 private: 206 /// The symbol being referenced. 207 const MCSymbol *Symbol; 208 209 /// The symbol reference modifier. 210 const VariantKind Kind; 211 MCSymbolRefExpr(const MCSymbol * _Symbol,VariantKind _Kind)212 explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind) 213 : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) { 214 assert(Symbol); 215 } 216 217 public: 218 /// @name Construction 219 /// @{ 220 Create(const MCSymbol * Symbol,MCContext & Ctx)221 static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) { 222 return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx); 223 } 224 225 static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind, 226 MCContext &Ctx); 227 static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind, 228 MCContext &Ctx); 229 230 /// @} 231 /// @name Accessors 232 /// @{ 233 getSymbol()234 const MCSymbol &getSymbol() const { return *Symbol; } 235 getKind()236 VariantKind getKind() const { return Kind; } 237 238 /// @} 239 /// @name Static Utility Functions 240 /// @{ 241 242 static StringRef getVariantKindName(VariantKind Kind); 243 244 static VariantKind getVariantKindForName(StringRef Name); 245 246 /// @} 247 classof(const MCExpr * E)248 static bool classof(const MCExpr *E) { 249 return E->getKind() == MCExpr::SymbolRef; 250 } classof(const MCSymbolRefExpr *)251 static bool classof(const MCSymbolRefExpr *) { return true; } 252 }; 253 254 /// MCUnaryExpr - Unary assembler expressions. 255 class MCUnaryExpr : public MCExpr { 256 public: 257 enum Opcode { 258 LNot, ///< Logical negation. 259 Minus, ///< Unary minus. 260 Not, ///< Bitwise negation. 261 Plus ///< Unary plus. 262 }; 263 264 private: 265 Opcode Op; 266 const MCExpr *Expr; 267 MCUnaryExpr(Opcode _Op,const MCExpr * _Expr)268 MCUnaryExpr(Opcode _Op, const MCExpr *_Expr) 269 : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {} 270 271 public: 272 /// @name Construction 273 /// @{ 274 275 static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr, 276 MCContext &Ctx); CreateLNot(const MCExpr * Expr,MCContext & Ctx)277 static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) { 278 return Create(LNot, Expr, Ctx); 279 } CreateMinus(const MCExpr * Expr,MCContext & Ctx)280 static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) { 281 return Create(Minus, Expr, Ctx); 282 } CreateNot(const MCExpr * Expr,MCContext & Ctx)283 static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) { 284 return Create(Not, Expr, Ctx); 285 } CreatePlus(const MCExpr * Expr,MCContext & Ctx)286 static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) { 287 return Create(Plus, Expr, Ctx); 288 } 289 290 /// @} 291 /// @name Accessors 292 /// @{ 293 294 /// getOpcode - Get the kind of this unary expression. getOpcode()295 Opcode getOpcode() const { return Op; } 296 297 /// getSubExpr - Get the child of this unary expression. getSubExpr()298 const MCExpr *getSubExpr() const { return Expr; } 299 300 /// @} 301 classof(const MCExpr * E)302 static bool classof(const MCExpr *E) { 303 return E->getKind() == MCExpr::Unary; 304 } classof(const MCUnaryExpr *)305 static bool classof(const MCUnaryExpr *) { return true; } 306 }; 307 308 /// MCBinaryExpr - Binary assembler expressions. 309 class MCBinaryExpr : public MCExpr { 310 public: 311 enum Opcode { 312 Add, ///< Addition. 313 And, ///< Bitwise and. 314 Div, ///< Signed division. 315 EQ, ///< Equality comparison. 316 GT, ///< Signed greater than comparison (result is either 0 or some 317 ///< target-specific non-zero value) 318 GTE, ///< Signed greater than or equal comparison (result is either 0 or 319 ///< some target-specific non-zero value). 320 LAnd, ///< Logical and. 321 LOr, ///< Logical or. 322 LT, ///< Signed less than comparison (result is either 0 or 323 ///< some target-specific non-zero value). 324 LTE, ///< Signed less than or equal comparison (result is either 0 or 325 ///< some target-specific non-zero value). 326 Mod, ///< Signed remainder. 327 Mul, ///< Multiplication. 328 NE, ///< Inequality comparison. 329 Or, ///< Bitwise or. 330 Shl, ///< Shift left. 331 Shr, ///< Shift right (arithmetic or logical, depending on target) 332 Sub, ///< Subtraction. 333 Xor ///< Bitwise exclusive or. 334 }; 335 336 private: 337 Opcode Op; 338 const MCExpr *LHS, *RHS; 339 MCBinaryExpr(Opcode _Op,const MCExpr * _LHS,const MCExpr * _RHS)340 MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS) 341 : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {} 342 343 public: 344 /// @name Construction 345 /// @{ 346 347 static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS, 348 const MCExpr *RHS, MCContext &Ctx); CreateAdd(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)349 static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS, 350 MCContext &Ctx) { 351 return Create(Add, LHS, RHS, Ctx); 352 } CreateAnd(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)353 static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS, 354 MCContext &Ctx) { 355 return Create(And, LHS, RHS, Ctx); 356 } CreateDiv(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)357 static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS, 358 MCContext &Ctx) { 359 return Create(Div, LHS, RHS, Ctx); 360 } CreateEQ(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)361 static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS, 362 MCContext &Ctx) { 363 return Create(EQ, LHS, RHS, Ctx); 364 } CreateGT(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)365 static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS, 366 MCContext &Ctx) { 367 return Create(GT, LHS, RHS, Ctx); 368 } CreateGTE(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)369 static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS, 370 MCContext &Ctx) { 371 return Create(GTE, LHS, RHS, Ctx); 372 } CreateLAnd(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)373 static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS, 374 MCContext &Ctx) { 375 return Create(LAnd, LHS, RHS, Ctx); 376 } CreateLOr(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)377 static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS, 378 MCContext &Ctx) { 379 return Create(LOr, LHS, RHS, Ctx); 380 } CreateLT(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)381 static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS, 382 MCContext &Ctx) { 383 return Create(LT, LHS, RHS, Ctx); 384 } CreateLTE(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)385 static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS, 386 MCContext &Ctx) { 387 return Create(LTE, LHS, RHS, Ctx); 388 } CreateMod(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)389 static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS, 390 MCContext &Ctx) { 391 return Create(Mod, LHS, RHS, Ctx); 392 } CreateMul(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)393 static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS, 394 MCContext &Ctx) { 395 return Create(Mul, LHS, RHS, Ctx); 396 } CreateNE(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)397 static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS, 398 MCContext &Ctx) { 399 return Create(NE, LHS, RHS, Ctx); 400 } CreateOr(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)401 static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS, 402 MCContext &Ctx) { 403 return Create(Or, LHS, RHS, Ctx); 404 } CreateShl(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)405 static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS, 406 MCContext &Ctx) { 407 return Create(Shl, LHS, RHS, Ctx); 408 } CreateShr(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)409 static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS, 410 MCContext &Ctx) { 411 return Create(Shr, LHS, RHS, Ctx); 412 } CreateSub(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)413 static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS, 414 MCContext &Ctx) { 415 return Create(Sub, LHS, RHS, Ctx); 416 } CreateXor(const MCExpr * LHS,const MCExpr * RHS,MCContext & Ctx)417 static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS, 418 MCContext &Ctx) { 419 return Create(Xor, LHS, RHS, Ctx); 420 } 421 422 /// @} 423 /// @name Accessors 424 /// @{ 425 426 /// getOpcode - Get the kind of this binary expression. getOpcode()427 Opcode getOpcode() const { return Op; } 428 429 /// getLHS - Get the left-hand side expression of the binary operator. getLHS()430 const MCExpr *getLHS() const { return LHS; } 431 432 /// getRHS - Get the right-hand side expression of the binary operator. getRHS()433 const MCExpr *getRHS() const { return RHS; } 434 435 /// @} 436 classof(const MCExpr * E)437 static bool classof(const MCExpr *E) { 438 return E->getKind() == MCExpr::Binary; 439 } classof(const MCBinaryExpr *)440 static bool classof(const MCBinaryExpr *) { return true; } 441 }; 442 443 /// MCTargetExpr - This is an extension point for target-specific MCExpr 444 /// subclasses to implement. 445 /// 446 /// NOTE: All subclasses are required to have trivial destructors because 447 /// MCExprs are bump pointer allocated and not destructed. 448 class MCTargetExpr : public MCExpr { 449 virtual void Anchor(); 450 protected: MCTargetExpr()451 MCTargetExpr() : MCExpr(Target) {} ~MCTargetExpr()452 virtual ~MCTargetExpr() {} 453 public: 454 455 virtual void PrintImpl(raw_ostream &OS) const = 0; 456 virtual bool EvaluateAsRelocatableImpl(MCValue &Res, 457 const MCAsmLayout *Layout) const = 0; 458 virtual void AddValueSymbols(MCAssembler *) const = 0; 459 virtual const MCSection *FindAssociatedSection() const = 0; 460 classof(const MCExpr * E)461 static bool classof(const MCExpr *E) { 462 return E->getKind() == MCExpr::Target; 463 } classof(const MCTargetExpr *)464 static bool classof(const MCTargetExpr *) { return true; } 465 }; 466 467 } // end namespace llvm 468 469 #endif 470