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