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