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