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