MCExpr.h revision 8f714fedba35bc454ff372f084090f14a25c8933
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 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 MCAsmLayout *Layout, 48 const SectionAddrMap *Addrs) const; 49protected: 50 explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {} 51 52 bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, 53 const SectionAddrMap *Addrs, 54 bool InSet) const; 55public: 56 /// @name Accessors 57 /// @{ 58 59 ExprKind getKind() const { return Kind; } 60 61 /// @} 62 /// @name Utility Methods 63 /// @{ 64 65 void print(raw_ostream &OS) const; 66 void dump() const; 67 68 /// @} 69 /// @name Expression Evaluation 70 /// @{ 71 72 /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value. 73 /// 74 /// @param Res - The absolute value, if evaluation succeeds. 75 /// @param Layout - The assembler layout object to use for evaluating symbol 76 /// values. If not given, then only non-symbolic expressions will be 77 /// evaluated. 78 /// @result - True on success. 79 bool EvaluateAsAbsolute(int64_t &Res) const { 80 return EvaluateAsAbsolute(Res, 0, 0); 81 } 82 bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const{ 83 return EvaluateAsAbsolute(Res, &Layout, 0); 84 } 85 bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, 86 const SectionAddrMap &Addrs) const { 87 return EvaluateAsAbsolute(Res, &Layout, &Addrs); 88 } 89 90 /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable 91 /// value, i.e. an expression of the fixed form (a - b + constant). 92 /// 93 /// @param Res - The relocatable value, if evaluation succeeds. 94 /// @param Layout - The assembler layout object to use for evaluating values. 95 /// @result - True on success. 96 bool EvaluateAsRelocatable(MCValue &Res, 97 const MCAsmLayout *Layout = 0) const { 98 return EvaluateAsRelocatableImpl(Res, Layout, 0, false); 99 } 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_ARM_HI16, // The R_ARM_MOVT_ABS relocation (:upper16: in the .s file) 165 VK_ARM_LO16, // The R_ARM_MOVW_ABS_NC relocation (:lower16: in the .w file) 166 // FIXME: We'd really like to use the generic Kinds listed above for these. 167 VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT 168 VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF 169 VK_ARM_GOT, 170 VK_ARM_GOTOFF, 171 VK_ARM_TPOFF, 172 VK_ARM_GOTTPOFF, 173 174 VK_PPC_TOC, 175 VK_PPC_HA16, // ha16(symbol) 176 VK_PPC_LO16 // lo16(symbol) 177 }; 178 179private: 180 /// The symbol being referenced. 181 const MCSymbol *Symbol; 182 183 /// The symbol reference modifier. 184 const VariantKind Kind; 185 186 explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind) 187 : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) {} 188 189public: 190 /// @name Construction 191 /// @{ 192 193 static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) { 194 return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx); 195 } 196 197 static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind, 198 MCContext &Ctx); 199 static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind, 200 MCContext &Ctx); 201 202 /// @} 203 /// @name Accessors 204 /// @{ 205 206 const MCSymbol &getSymbol() const { return *Symbol; } 207 208 VariantKind getKind() const { return Kind; } 209 210 /// @} 211 /// @name Static Utility Functions 212 /// @{ 213 214 static StringRef getVariantKindName(VariantKind Kind); 215 216 static VariantKind getVariantKindForName(StringRef Name); 217 218 /// @} 219 220 static bool classof(const MCExpr *E) { 221 return E->getKind() == MCExpr::SymbolRef; 222 } 223 static bool classof(const MCSymbolRefExpr *) { return true; } 224}; 225 226/// MCUnaryExpr - Unary assembler expressions. 227class MCUnaryExpr : public MCExpr { 228public: 229 enum Opcode { 230 LNot, ///< Logical negation. 231 Minus, ///< Unary minus. 232 Not, ///< Bitwise negation. 233 Plus ///< Unary plus. 234 }; 235 236private: 237 Opcode Op; 238 const MCExpr *Expr; 239 240 MCUnaryExpr(Opcode _Op, const MCExpr *_Expr) 241 : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {} 242 243public: 244 /// @name Construction 245 /// @{ 246 247 static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr, 248 MCContext &Ctx); 249 static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) { 250 return Create(LNot, Expr, Ctx); 251 } 252 static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) { 253 return Create(Minus, Expr, Ctx); 254 } 255 static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) { 256 return Create(Not, Expr, Ctx); 257 } 258 static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) { 259 return Create(Plus, Expr, Ctx); 260 } 261 262 /// @} 263 /// @name Accessors 264 /// @{ 265 266 /// getOpcode - Get the kind of this unary expression. 267 Opcode getOpcode() const { return Op; } 268 269 /// getSubExpr - Get the child of this unary expression. 270 const MCExpr *getSubExpr() const { return Expr; } 271 272 /// @} 273 274 static bool classof(const MCExpr *E) { 275 return E->getKind() == MCExpr::Unary; 276 } 277 static bool classof(const MCUnaryExpr *) { return true; } 278}; 279 280/// MCBinaryExpr - Binary assembler expressions. 281class MCBinaryExpr : public MCExpr { 282public: 283 enum Opcode { 284 Add, ///< Addition. 285 And, ///< Bitwise and. 286 Div, ///< Signed division. 287 EQ, ///< Equality comparison. 288 GT, ///< Signed greater than comparison (result is either 0 or some 289 ///< target-specific non-zero value) 290 GTE, ///< Signed greater than or equal comparison (result is either 0 or 291 ///< some target-specific non-zero value). 292 LAnd, ///< Logical and. 293 LOr, ///< Logical or. 294 LT, ///< Signed less than comparison (result is either 0 or 295 ///< some target-specific non-zero value). 296 LTE, ///< Signed less than or equal comparison (result is either 0 or 297 ///< some target-specific non-zero value). 298 Mod, ///< Signed remainder. 299 Mul, ///< Multiplication. 300 NE, ///< Inequality comparison. 301 Or, ///< Bitwise or. 302 Shl, ///< Shift left. 303 Shr, ///< Shift right (arithmetic or logical, depending on target) 304 Sub, ///< Subtraction. 305 Xor ///< Bitwise exclusive or. 306 }; 307 308private: 309 Opcode Op; 310 const MCExpr *LHS, *RHS; 311 312 MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS) 313 : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {} 314 315public: 316 /// @name Construction 317 /// @{ 318 319 static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS, 320 const MCExpr *RHS, MCContext &Ctx); 321 static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS, 322 MCContext &Ctx) { 323 return Create(Add, LHS, RHS, Ctx); 324 } 325 static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS, 326 MCContext &Ctx) { 327 return Create(And, LHS, RHS, Ctx); 328 } 329 static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS, 330 MCContext &Ctx) { 331 return Create(Div, LHS, RHS, Ctx); 332 } 333 static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS, 334 MCContext &Ctx) { 335 return Create(EQ, LHS, RHS, Ctx); 336 } 337 static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS, 338 MCContext &Ctx) { 339 return Create(GT, LHS, RHS, Ctx); 340 } 341 static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS, 342 MCContext &Ctx) { 343 return Create(GTE, LHS, RHS, Ctx); 344 } 345 static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS, 346 MCContext &Ctx) { 347 return Create(LAnd, LHS, RHS, Ctx); 348 } 349 static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS, 350 MCContext &Ctx) { 351 return Create(LOr, LHS, RHS, Ctx); 352 } 353 static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS, 354 MCContext &Ctx) { 355 return Create(LT, LHS, RHS, Ctx); 356 } 357 static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS, 358 MCContext &Ctx) { 359 return Create(LTE, LHS, RHS, Ctx); 360 } 361 static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS, 362 MCContext &Ctx) { 363 return Create(Mod, LHS, RHS, Ctx); 364 } 365 static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS, 366 MCContext &Ctx) { 367 return Create(Mul, LHS, RHS, Ctx); 368 } 369 static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS, 370 MCContext &Ctx) { 371 return Create(NE, LHS, RHS, Ctx); 372 } 373 static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS, 374 MCContext &Ctx) { 375 return Create(Or, LHS, RHS, Ctx); 376 } 377 static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS, 378 MCContext &Ctx) { 379 return Create(Shl, LHS, RHS, Ctx); 380 } 381 static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS, 382 MCContext &Ctx) { 383 return Create(Shr, LHS, RHS, Ctx); 384 } 385 static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS, 386 MCContext &Ctx) { 387 return Create(Sub, LHS, RHS, Ctx); 388 } 389 static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS, 390 MCContext &Ctx) { 391 return Create(Xor, LHS, RHS, Ctx); 392 } 393 394 /// @} 395 /// @name Accessors 396 /// @{ 397 398 /// getOpcode - Get the kind of this binary expression. 399 Opcode getOpcode() const { return Op; } 400 401 /// getLHS - Get the left-hand side expression of the binary operator. 402 const MCExpr *getLHS() const { return LHS; } 403 404 /// getRHS - Get the right-hand side expression of the binary operator. 405 const MCExpr *getRHS() const { return RHS; } 406 407 /// @} 408 409 static bool classof(const MCExpr *E) { 410 return E->getKind() == MCExpr::Binary; 411 } 412 static bool classof(const MCBinaryExpr *) { return true; } 413}; 414 415/// MCTargetExpr - This is an extension point for target-specific MCExpr 416/// subclasses to implement. 417/// 418/// NOTE: All subclasses are required to have trivial destructors because 419/// MCExprs are bump pointer allocated and not destructed. 420class MCTargetExpr : public MCExpr { 421 virtual void Anchor(); 422protected: 423 MCTargetExpr() : MCExpr(Target) {} 424 virtual ~MCTargetExpr() {} 425public: 426 427 virtual void PrintImpl(raw_ostream &OS) const = 0; 428 virtual bool EvaluateAsRelocatableImpl(MCValue &Res, 429 const MCAsmLayout *Layout) const = 0; 430 431 432 static bool classof(const MCExpr *E) { 433 return E->getKind() == MCExpr::Target; 434 } 435 static bool classof(const MCTargetExpr *) { return true; } 436}; 437 438} // end namespace llvm 439 440#endif 441