MCExpr.h revision a0a2f8734cdfc19d44201b791a969bcdda96bb70
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/Support/Casting.h" 14#include "llvm/System/DataTypes.h" 15 16namespace llvm { 17class MCAsmInfo; 18class MCAsmLayout; 19class MCContext; 20class MCSymbol; 21class MCValue; 22class raw_ostream; 23class StringRef; 24 25/// MCExpr - Base class for the full range of assembler expressions which are 26/// needed for parsing. 27class MCExpr { 28public: 29 enum ExprKind { 30 Binary, ///< Binary expressions. 31 Constant, ///< Constant expressions. 32 SymbolRef, ///< References to labels and assigned expressions. 33 Unary, ///< Unary expressions. 34 Target ///< Target specific expression. 35 }; 36 37private: 38 ExprKind Kind; 39 40 MCExpr(const MCExpr&); // DO NOT IMPLEMENT 41 void operator=(const MCExpr&); // DO NOT IMPLEMENT 42 43protected: 44 explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {} 45 46 bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, 47 bool InSet) const; 48public: 49 /// @name Accessors 50 /// @{ 51 52 ExprKind getKind() const { return Kind; } 53 54 /// @} 55 /// @name Utility Methods 56 /// @{ 57 58 void print(raw_ostream &OS) const; 59 void dump() const; 60 61 /// @} 62 /// @name Expression Evaluation 63 /// @{ 64 65 /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value. 66 /// 67 /// @param Res - The absolute value, if evaluation succeeds. 68 /// @param Layout - The assembler layout object to use for evaluating symbol 69 /// values. If not given, then only non-symbolic expressions will be 70 /// evaluated. 71 /// @result - True on success. 72 bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout *Layout = 0) const; 73 74 /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable 75 /// value, i.e. an expression of the fixed form (a - b + constant). 76 /// 77 /// @param Res - The relocatable value, if evaluation succeeds. 78 /// @param Layout - The assembler layout object to use for evaluating values. 79 /// @result - True on success. 80 bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout = 0) const; 81 82 /// @} 83 84 static bool classof(const MCExpr *) { return true; } 85}; 86 87inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { 88 E.print(OS); 89 return OS; 90} 91 92//// MCConstantExpr - Represent a constant integer expression. 93class MCConstantExpr : public MCExpr { 94 int64_t Value; 95 96 explicit MCConstantExpr(int64_t _Value) 97 : MCExpr(MCExpr::Constant), Value(_Value) {} 98 99public: 100 /// @name Construction 101 /// @{ 102 103 static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx); 104 105 /// @} 106 /// @name Accessors 107 /// @{ 108 109 int64_t getValue() const { return Value; } 110 111 /// @} 112 113 static bool classof(const MCExpr *E) { 114 return E->getKind() == MCExpr::Constant; 115 } 116 static bool classof(const MCConstantExpr *) { return true; } 117}; 118 119/// MCSymbolRefExpr - Represent a reference to a symbol from inside an 120/// expression. 121/// 122/// A symbol reference in an expression may be a use of a label, a use of an 123/// assembler variable (defined constant), or constitute an implicit definition 124/// of the symbol as external. 125class MCSymbolRefExpr : public MCExpr { 126public: 127 enum VariantKind { 128 VK_None, 129 VK_Invalid, 130 131 VK_GOT, 132 VK_GOTOFF, 133 VK_GOTPCREL, 134 VK_GOTTPOFF, 135 VK_INDNTPOFF, 136 VK_NTPOFF, 137 VK_GOTNTPOFF, 138 VK_PLT, 139 VK_TLSGD, 140 VK_TPOFF, 141 VK_ARM_HI16, // The R_ARM_MOVT_ABS relocation (:upper16: in the asm file) 142 VK_ARM_LO16, // The R_ARM_MOVW_ABS_NC relocation (:lower16: in the asm file) 143 VK_ARM_PLT, // ARM-style PLT symbol references. i.e., (PLT) instead of @PLT 144 VK_TLVP // Mach-O thread local variable relocation 145 }; 146 147private: 148 /// The symbol being referenced. 149 const MCSymbol *Symbol; 150 151 /// The symbol reference modifier. 152 const VariantKind Kind; 153 154 explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind) 155 : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) {} 156 157public: 158 /// @name Construction 159 /// @{ 160 161 static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) { 162 return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx); 163 } 164 165 static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind, 166 MCContext &Ctx); 167 static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind, 168 MCContext &Ctx); 169 170 /// @} 171 /// @name Accessors 172 /// @{ 173 174 const MCSymbol &getSymbol() const { return *Symbol; } 175 176 VariantKind getKind() const { return Kind; } 177 178 /// @} 179 /// @name Static Utility Functions 180 /// @{ 181 182 static StringRef getVariantKindName(VariantKind Kind); 183 184 static VariantKind getVariantKindForName(StringRef Name); 185 186 /// @} 187 188 static bool classof(const MCExpr *E) { 189 return E->getKind() == MCExpr::SymbolRef; 190 } 191 static bool classof(const MCSymbolRefExpr *) { return true; } 192}; 193 194/// MCUnaryExpr - Unary assembler expressions. 195class MCUnaryExpr : public MCExpr { 196public: 197 enum Opcode { 198 LNot, ///< Logical negation. 199 Minus, ///< Unary minus. 200 Not, ///< Bitwise negation. 201 Plus ///< Unary plus. 202 }; 203 204private: 205 Opcode Op; 206 const MCExpr *Expr; 207 208 MCUnaryExpr(Opcode _Op, const MCExpr *_Expr) 209 : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {} 210 211public: 212 /// @name Construction 213 /// @{ 214 215 static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr, 216 MCContext &Ctx); 217 static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) { 218 return Create(LNot, Expr, Ctx); 219 } 220 static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) { 221 return Create(Minus, Expr, Ctx); 222 } 223 static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) { 224 return Create(Not, Expr, Ctx); 225 } 226 static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) { 227 return Create(Plus, Expr, Ctx); 228 } 229 230 /// @} 231 /// @name Accessors 232 /// @{ 233 234 /// getOpcode - Get the kind of this unary expression. 235 Opcode getOpcode() const { return Op; } 236 237 /// getSubExpr - Get the child of this unary expression. 238 const MCExpr *getSubExpr() const { return Expr; } 239 240 /// @} 241 242 static bool classof(const MCExpr *E) { 243 return E->getKind() == MCExpr::Unary; 244 } 245 static bool classof(const MCUnaryExpr *) { return true; } 246}; 247 248/// MCBinaryExpr - Binary assembler expressions. 249class MCBinaryExpr : public MCExpr { 250public: 251 enum Opcode { 252 Add, ///< Addition. 253 And, ///< Bitwise and. 254 Div, ///< Signed division. 255 EQ, ///< Equality comparison. 256 GT, ///< Signed greater than comparison (result is either 0 or some 257 ///< target-specific non-zero value) 258 GTE, ///< Signed greater than or equal comparison (result is either 0 or 259 ///< some target-specific non-zero value). 260 LAnd, ///< Logical and. 261 LOr, ///< Logical or. 262 LT, ///< Signed less than comparison (result is either 0 or 263 ///< some target-specific non-zero value). 264 LTE, ///< Signed less than or equal comparison (result is either 0 or 265 ///< some target-specific non-zero value). 266 Mod, ///< Signed remainder. 267 Mul, ///< Multiplication. 268 NE, ///< Inequality comparison. 269 Or, ///< Bitwise or. 270 Shl, ///< Shift left. 271 Shr, ///< Shift right (arithmetic or logical, depending on target) 272 Sub, ///< Subtraction. 273 Xor ///< Bitwise exclusive or. 274 }; 275 276private: 277 Opcode Op; 278 const MCExpr *LHS, *RHS; 279 280 MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS) 281 : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {} 282 283public: 284 /// @name Construction 285 /// @{ 286 287 static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS, 288 const MCExpr *RHS, MCContext &Ctx); 289 static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS, 290 MCContext &Ctx) { 291 return Create(Add, LHS, RHS, Ctx); 292 } 293 static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS, 294 MCContext &Ctx) { 295 return Create(And, LHS, RHS, Ctx); 296 } 297 static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS, 298 MCContext &Ctx) { 299 return Create(Div, LHS, RHS, Ctx); 300 } 301 static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS, 302 MCContext &Ctx) { 303 return Create(EQ, LHS, RHS, Ctx); 304 } 305 static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS, 306 MCContext &Ctx) { 307 return Create(GT, LHS, RHS, Ctx); 308 } 309 static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS, 310 MCContext &Ctx) { 311 return Create(GTE, LHS, RHS, Ctx); 312 } 313 static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS, 314 MCContext &Ctx) { 315 return Create(LAnd, LHS, RHS, Ctx); 316 } 317 static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS, 318 MCContext &Ctx) { 319 return Create(LOr, LHS, RHS, Ctx); 320 } 321 static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS, 322 MCContext &Ctx) { 323 return Create(LT, LHS, RHS, Ctx); 324 } 325 static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS, 326 MCContext &Ctx) { 327 return Create(LTE, LHS, RHS, Ctx); 328 } 329 static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS, 330 MCContext &Ctx) { 331 return Create(Mod, LHS, RHS, Ctx); 332 } 333 static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS, 334 MCContext &Ctx) { 335 return Create(Mul, LHS, RHS, Ctx); 336 } 337 static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS, 338 MCContext &Ctx) { 339 return Create(NE, LHS, RHS, Ctx); 340 } 341 static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS, 342 MCContext &Ctx) { 343 return Create(Or, LHS, RHS, Ctx); 344 } 345 static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS, 346 MCContext &Ctx) { 347 return Create(Shl, LHS, RHS, Ctx); 348 } 349 static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS, 350 MCContext &Ctx) { 351 return Create(Shr, LHS, RHS, Ctx); 352 } 353 static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS, 354 MCContext &Ctx) { 355 return Create(Sub, LHS, RHS, Ctx); 356 } 357 static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS, 358 MCContext &Ctx) { 359 return Create(Xor, LHS, RHS, Ctx); 360 } 361 362 /// @} 363 /// @name Accessors 364 /// @{ 365 366 /// getOpcode - Get the kind of this binary expression. 367 Opcode getOpcode() const { return Op; } 368 369 /// getLHS - Get the left-hand side expression of the binary operator. 370 const MCExpr *getLHS() const { return LHS; } 371 372 /// getRHS - Get the right-hand side expression of the binary operator. 373 const MCExpr *getRHS() const { return RHS; } 374 375 /// @} 376 377 static bool classof(const MCExpr *E) { 378 return E->getKind() == MCExpr::Binary; 379 } 380 static bool classof(const MCBinaryExpr *) { return true; } 381}; 382 383/// MCTargetExpr - This is an extension point for target-specific MCExpr 384/// subclasses to implement. 385/// 386/// NOTE: All subclasses are required to have trivial destructors because 387/// MCExprs are bump pointer allocated and not destructed. 388class MCTargetExpr : public MCExpr { 389 virtual void Anchor(); 390protected: 391 MCTargetExpr() : MCExpr(Target) {} 392 virtual ~MCTargetExpr() {} 393public: 394 395 virtual void PrintImpl(raw_ostream &OS) const = 0; 396 virtual bool EvaluateAsRelocatableImpl(MCValue &Res, 397 const MCAsmLayout *Layout) const = 0; 398 399 400 static bool classof(const MCExpr *E) { 401 return E->getKind() == MCExpr::Target; 402 } 403 static bool classof(const MCTargetExpr *) { return true; } 404}; 405 406} // end namespace llvm 407 408#endif 409