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