MCExpr.h revision 2c4d5125c708bb35140fc2a40b02beb1add101db
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_TLSLD, 141 VK_TLSLDM, 142 VK_TPOFF, 143 VK_DTPOFF, 144 VK_ARM_HI16, // The R_ARM_MOVT_ABS relocation (:upper16: in the .s file) 145 VK_ARM_LO16, // The R_ARM_MOVW_ABS_NC relocation (:lower16: in the .w file) 146 // FIXME: We'd really like to use the generic Kinds listed above for these. 147 VK_ARM_PLT, // ARM-style PLT references. i.e., (PLT) instead of @PLT 148 VK_ARM_TLSGD, // ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF 149 VK_ARM_GOT, 150 VK_ARM_GOTOFF, 151 VK_ARM_TPOFF, 152 VK_ARM_GOTTPOFF, 153 VK_TLVP // Mach-O thread local variable relocation 154 }; 155 156private: 157 /// The symbol being referenced. 158 const MCSymbol *Symbol; 159 160 /// The symbol reference modifier. 161 const VariantKind Kind; 162 163 explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind) 164 : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) {} 165 166public: 167 /// @name Construction 168 /// @{ 169 170 static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) { 171 return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx); 172 } 173 174 static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind, 175 MCContext &Ctx); 176 static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind, 177 MCContext &Ctx); 178 179 /// @} 180 /// @name Accessors 181 /// @{ 182 183 const MCSymbol &getSymbol() const { return *Symbol; } 184 185 VariantKind getKind() const { return Kind; } 186 187 /// @} 188 /// @name Static Utility Functions 189 /// @{ 190 191 static StringRef getVariantKindName(VariantKind Kind); 192 193 static VariantKind getVariantKindForName(StringRef Name); 194 195 /// @} 196 197 static bool classof(const MCExpr *E) { 198 return E->getKind() == MCExpr::SymbolRef; 199 } 200 static bool classof(const MCSymbolRefExpr *) { return true; } 201}; 202 203/// MCUnaryExpr - Unary assembler expressions. 204class MCUnaryExpr : public MCExpr { 205public: 206 enum Opcode { 207 LNot, ///< Logical negation. 208 Minus, ///< Unary minus. 209 Not, ///< Bitwise negation. 210 Plus ///< Unary plus. 211 }; 212 213private: 214 Opcode Op; 215 const MCExpr *Expr; 216 217 MCUnaryExpr(Opcode _Op, const MCExpr *_Expr) 218 : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {} 219 220public: 221 /// @name Construction 222 /// @{ 223 224 static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr, 225 MCContext &Ctx); 226 static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) { 227 return Create(LNot, Expr, Ctx); 228 } 229 static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) { 230 return Create(Minus, Expr, Ctx); 231 } 232 static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) { 233 return Create(Not, Expr, Ctx); 234 } 235 static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) { 236 return Create(Plus, Expr, Ctx); 237 } 238 239 /// @} 240 /// @name Accessors 241 /// @{ 242 243 /// getOpcode - Get the kind of this unary expression. 244 Opcode getOpcode() const { return Op; } 245 246 /// getSubExpr - Get the child of this unary expression. 247 const MCExpr *getSubExpr() const { return Expr; } 248 249 /// @} 250 251 static bool classof(const MCExpr *E) { 252 return E->getKind() == MCExpr::Unary; 253 } 254 static bool classof(const MCUnaryExpr *) { return true; } 255}; 256 257/// MCBinaryExpr - Binary assembler expressions. 258class MCBinaryExpr : public MCExpr { 259public: 260 enum Opcode { 261 Add, ///< Addition. 262 And, ///< Bitwise and. 263 Div, ///< Signed division. 264 EQ, ///< Equality comparison. 265 GT, ///< Signed greater than comparison (result is either 0 or some 266 ///< target-specific non-zero value) 267 GTE, ///< Signed greater than or equal comparison (result is either 0 or 268 ///< some target-specific non-zero value). 269 LAnd, ///< Logical and. 270 LOr, ///< Logical or. 271 LT, ///< Signed less than comparison (result is either 0 or 272 ///< some target-specific non-zero value). 273 LTE, ///< Signed less than or equal comparison (result is either 0 or 274 ///< some target-specific non-zero value). 275 Mod, ///< Signed remainder. 276 Mul, ///< Multiplication. 277 NE, ///< Inequality comparison. 278 Or, ///< Bitwise or. 279 Shl, ///< Shift left. 280 Shr, ///< Shift right (arithmetic or logical, depending on target) 281 Sub, ///< Subtraction. 282 Xor ///< Bitwise exclusive or. 283 }; 284 285private: 286 Opcode Op; 287 const MCExpr *LHS, *RHS; 288 289 MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS) 290 : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {} 291 292public: 293 /// @name Construction 294 /// @{ 295 296 static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS, 297 const MCExpr *RHS, MCContext &Ctx); 298 static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS, 299 MCContext &Ctx) { 300 return Create(Add, LHS, RHS, Ctx); 301 } 302 static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS, 303 MCContext &Ctx) { 304 return Create(And, LHS, RHS, Ctx); 305 } 306 static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS, 307 MCContext &Ctx) { 308 return Create(Div, LHS, RHS, Ctx); 309 } 310 static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS, 311 MCContext &Ctx) { 312 return Create(EQ, LHS, RHS, Ctx); 313 } 314 static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS, 315 MCContext &Ctx) { 316 return Create(GT, LHS, RHS, Ctx); 317 } 318 static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS, 319 MCContext &Ctx) { 320 return Create(GTE, LHS, RHS, Ctx); 321 } 322 static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS, 323 MCContext &Ctx) { 324 return Create(LAnd, LHS, RHS, Ctx); 325 } 326 static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS, 327 MCContext &Ctx) { 328 return Create(LOr, LHS, RHS, Ctx); 329 } 330 static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS, 331 MCContext &Ctx) { 332 return Create(LT, LHS, RHS, Ctx); 333 } 334 static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS, 335 MCContext &Ctx) { 336 return Create(LTE, LHS, RHS, Ctx); 337 } 338 static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS, 339 MCContext &Ctx) { 340 return Create(Mod, LHS, RHS, Ctx); 341 } 342 static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS, 343 MCContext &Ctx) { 344 return Create(Mul, LHS, RHS, Ctx); 345 } 346 static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS, 347 MCContext &Ctx) { 348 return Create(NE, LHS, RHS, Ctx); 349 } 350 static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS, 351 MCContext &Ctx) { 352 return Create(Or, LHS, RHS, Ctx); 353 } 354 static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS, 355 MCContext &Ctx) { 356 return Create(Shl, LHS, RHS, Ctx); 357 } 358 static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS, 359 MCContext &Ctx) { 360 return Create(Shr, LHS, RHS, Ctx); 361 } 362 static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS, 363 MCContext &Ctx) { 364 return Create(Sub, LHS, RHS, Ctx); 365 } 366 static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS, 367 MCContext &Ctx) { 368 return Create(Xor, LHS, RHS, Ctx); 369 } 370 371 /// @} 372 /// @name Accessors 373 /// @{ 374 375 /// getOpcode - Get the kind of this binary expression. 376 Opcode getOpcode() const { return Op; } 377 378 /// getLHS - Get the left-hand side expression of the binary operator. 379 const MCExpr *getLHS() const { return LHS; } 380 381 /// getRHS - Get the right-hand side expression of the binary operator. 382 const MCExpr *getRHS() const { return RHS; } 383 384 /// @} 385 386 static bool classof(const MCExpr *E) { 387 return E->getKind() == MCExpr::Binary; 388 } 389 static bool classof(const MCBinaryExpr *) { return true; } 390}; 391 392/// MCTargetExpr - This is an extension point for target-specific MCExpr 393/// subclasses to implement. 394/// 395/// NOTE: All subclasses are required to have trivial destructors because 396/// MCExprs are bump pointer allocated and not destructed. 397class MCTargetExpr : public MCExpr { 398 virtual void Anchor(); 399protected: 400 MCTargetExpr() : MCExpr(Target) {} 401 virtual ~MCTargetExpr() {} 402public: 403 404 virtual void PrintImpl(raw_ostream &OS) const = 0; 405 virtual bool EvaluateAsRelocatableImpl(MCValue &Res, 406 const MCAsmLayout *Layout) const = 0; 407 408 409 static bool classof(const MCExpr *E) { 410 return E->getKind() == MCExpr::Target; 411 } 412 static bool classof(const MCTargetExpr *) { return true; } 413}; 414 415} // end namespace llvm 416 417#endif 418