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