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