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