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