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