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