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