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 MCFixup;
23class MCSection;
24class MCSectionData;
25class MCStreamer;
26class MCSymbol;
27class MCValue;
28class raw_ostream;
29class StringRef;
30typedef DenseMap<const MCSectionData*, uint64_t> SectionAddrMap;
31
32/// MCExpr - Base class for the full range of assembler expressions which are
33/// needed for parsing.
34class MCExpr {
35public:
36  enum ExprKind {
37    Binary,    ///< Binary expressions.
38    Constant,  ///< Constant expressions.
39    SymbolRef, ///< References to labels and assigned expressions.
40    Unary,     ///< Unary expressions.
41    Target     ///< Target specific expression.
42  };
43
44private:
45  ExprKind Kind;
46
47  MCExpr(const MCExpr&) = delete;
48  void operator=(const MCExpr&) = delete;
49
50  bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
51                          const MCAsmLayout *Layout,
52                          const SectionAddrMap *Addrs) const;
53
54  bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
55                          const MCAsmLayout *Layout,
56                          const SectionAddrMap *Addrs, bool InSet) const;
57
58protected:
59  explicit MCExpr(ExprKind Kind) : Kind(Kind) {}
60
61  bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
62                                 const MCAsmLayout *Layout,
63                                 const MCFixup *Fixup,
64                                 const SectionAddrMap *Addrs, bool InSet) const;
65
66public:
67  /// @name Accessors
68  /// @{
69
70  ExprKind getKind() const { return Kind; }
71
72  /// @}
73  /// @name Utility Methods
74  /// @{
75
76  void print(raw_ostream &OS) const;
77  void dump() const;
78
79  /// @}
80  /// @name Expression Evaluation
81  /// @{
82
83  /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value.
84  ///
85  /// @param Res - The absolute value, if evaluation succeeds.
86  /// @param Layout - The assembler layout object to use for evaluating symbol
87  /// values. If not given, then only non-symbolic expressions will be
88  /// evaluated.
89  /// @result - True on success.
90  bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
91                          const SectionAddrMap &Addrs) const;
92  bool EvaluateAsAbsolute(int64_t &Res) const;
93  bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
94  bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
95
96  bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
97
98  /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable
99  /// value, i.e. an expression of the fixed form (a - b + constant).
100  ///
101  /// @param Res - The relocatable value, if evaluation succeeds.
102  /// @param Layout - The assembler layout object to use for evaluating values.
103  /// @param Fixup - The Fixup object if available.
104  /// @result - True on success.
105  bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout,
106                             const MCFixup *Fixup) const;
107
108  /// \brief Try to evaluate the expression to the form (a - b + constant) where
109  /// neither a nor b are variables.
110  ///
111  /// This is a more aggressive variant of EvaluateAsRelocatable. The intended
112  /// use is for when relocations are not available, like the .size directive.
113  bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const;
114
115  /// FindAssociatedSection - Find the "associated section" for this expression,
116  /// which is currently defined as the absolute section for constants, or
117  /// otherwise the section associated with the first defined symbol in the
118  /// expression.
119  const MCSection *FindAssociatedSection() const;
120
121  /// @}
122};
123
124inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
125  E.print(OS);
126  return OS;
127}
128
129//// MCConstantExpr - Represent a constant integer expression.
130class MCConstantExpr : public MCExpr {
131  int64_t Value;
132
133  explicit MCConstantExpr(int64_t Value)
134      : MCExpr(MCExpr::Constant), Value(Value) {}
135
136public:
137  /// @name Construction
138  /// @{
139
140  static const MCConstantExpr *Create(int64_t Value, MCContext &Ctx);
141
142  /// @}
143  /// @name Accessors
144  /// @{
145
146  int64_t getValue() const { return Value; }
147
148  /// @}
149
150  static bool classof(const MCExpr *E) {
151    return E->getKind() == MCExpr::Constant;
152  }
153};
154
155/// MCSymbolRefExpr - Represent a reference to a symbol from inside an
156/// expression.
157///
158/// A symbol reference in an expression may be a use of a label, a use of an
159/// assembler variable (defined constant), or constitute an implicit definition
160/// of the symbol as external.
161class MCSymbolRefExpr : public MCExpr {
162public:
163  enum VariantKind {
164    VK_None,
165    VK_Invalid,
166
167    VK_GOT,
168    VK_GOTOFF,
169    VK_GOTPCREL,
170    VK_GOTTPOFF,
171    VK_INDNTPOFF,
172    VK_NTPOFF,
173    VK_GOTNTPOFF,
174    VK_PLT,
175    VK_TLSGD,
176    VK_TLSLD,
177    VK_TLSLDM,
178    VK_TPOFF,
179    VK_DTPOFF,
180    VK_TLVP,      // Mach-O thread local variable relocations
181    VK_TLVPPAGE,
182    VK_TLVPPAGEOFF,
183    VK_PAGE,
184    VK_PAGEOFF,
185    VK_GOTPAGE,
186    VK_GOTPAGEOFF,
187    VK_SECREL,
188    VK_SIZE,      // symbol@SIZE
189    VK_WEAKREF,   // The link between the symbols in .weakref foo, bar
190
191    VK_ARM_NONE,
192    VK_ARM_TARGET1,
193    VK_ARM_TARGET2,
194    VK_ARM_PREL31,
195    VK_ARM_SBREL,          // symbol(sbrel)
196    VK_ARM_TLSLDO,         // symbol(tlsldo)
197    VK_ARM_TLSCALL,        // symbol(tlscall)
198    VK_ARM_TLSDESC,        // symbol(tlsdesc)
199    VK_ARM_TLSDESCSEQ,
200
201    VK_PPC_LO,             // symbol@l
202    VK_PPC_HI,             // symbol@h
203    VK_PPC_HA,             // symbol@ha
204    VK_PPC_HIGHER,         // symbol@higher
205    VK_PPC_HIGHERA,        // symbol@highera
206    VK_PPC_HIGHEST,        // symbol@highest
207    VK_PPC_HIGHESTA,       // symbol@highesta
208    VK_PPC_GOT_LO,         // symbol@got@l
209    VK_PPC_GOT_HI,         // symbol@got@h
210    VK_PPC_GOT_HA,         // symbol@got@ha
211    VK_PPC_TOCBASE,        // symbol@tocbase
212    VK_PPC_TOC,            // symbol@toc
213    VK_PPC_TOC_LO,         // symbol@toc@l
214    VK_PPC_TOC_HI,         // symbol@toc@h
215    VK_PPC_TOC_HA,         // symbol@toc@ha
216    VK_PPC_DTPMOD,         // symbol@dtpmod
217    VK_PPC_TPREL,          // symbol@tprel
218    VK_PPC_TPREL_LO,       // symbol@tprel@l
219    VK_PPC_TPREL_HI,       // symbol@tprel@h
220    VK_PPC_TPREL_HA,       // symbol@tprel@ha
221    VK_PPC_TPREL_HIGHER,   // symbol@tprel@higher
222    VK_PPC_TPREL_HIGHERA,  // symbol@tprel@highera
223    VK_PPC_TPREL_HIGHEST,  // symbol@tprel@highest
224    VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta
225    VK_PPC_DTPREL,         // symbol@dtprel
226    VK_PPC_DTPREL_LO,      // symbol@dtprel@l
227    VK_PPC_DTPREL_HI,      // symbol@dtprel@h
228    VK_PPC_DTPREL_HA,      // symbol@dtprel@ha
229    VK_PPC_DTPREL_HIGHER,  // symbol@dtprel@higher
230    VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera
231    VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest
232    VK_PPC_DTPREL_HIGHESTA,// symbol@dtprel@highesta
233    VK_PPC_GOT_TPREL,      // symbol@got@tprel
234    VK_PPC_GOT_TPREL_LO,   // symbol@got@tprel@l
235    VK_PPC_GOT_TPREL_HI,   // symbol@got@tprel@h
236    VK_PPC_GOT_TPREL_HA,   // symbol@got@tprel@ha
237    VK_PPC_GOT_DTPREL,     // symbol@got@dtprel
238    VK_PPC_GOT_DTPREL_LO,  // symbol@got@dtprel@l
239    VK_PPC_GOT_DTPREL_HI,  // symbol@got@dtprel@h
240    VK_PPC_GOT_DTPREL_HA,  // symbol@got@dtprel@ha
241    VK_PPC_TLS,            // symbol@tls
242    VK_PPC_GOT_TLSGD,      // symbol@got@tlsgd
243    VK_PPC_GOT_TLSGD_LO,   // symbol@got@tlsgd@l
244    VK_PPC_GOT_TLSGD_HI,   // symbol@got@tlsgd@h
245    VK_PPC_GOT_TLSGD_HA,   // symbol@got@tlsgd@ha
246    VK_PPC_TLSGD,          // symbol@tlsgd
247    VK_PPC_GOT_TLSLD,      // symbol@got@tlsld
248    VK_PPC_GOT_TLSLD_LO,   // symbol@got@tlsld@l
249    VK_PPC_GOT_TLSLD_HI,   // symbol@got@tlsld@h
250    VK_PPC_GOT_TLSLD_HA,   // symbol@got@tlsld@ha
251    VK_PPC_TLSLD,          // symbol@tlsld
252    VK_PPC_LOCAL,          // symbol@local
253
254    VK_Mips_GPREL,
255    VK_Mips_GOT_CALL,
256    VK_Mips_GOT16,
257    VK_Mips_GOT,
258    VK_Mips_ABS_HI,
259    VK_Mips_ABS_LO,
260    VK_Mips_TLSGD,
261    VK_Mips_TLSLDM,
262    VK_Mips_DTPREL_HI,
263    VK_Mips_DTPREL_LO,
264    VK_Mips_GOTTPREL,
265    VK_Mips_TPREL_HI,
266    VK_Mips_TPREL_LO,
267    VK_Mips_GPOFF_HI,
268    VK_Mips_GPOFF_LO,
269    VK_Mips_GOT_DISP,
270    VK_Mips_GOT_PAGE,
271    VK_Mips_GOT_OFST,
272    VK_Mips_HIGHER,
273    VK_Mips_HIGHEST,
274    VK_Mips_GOT_HI16,
275    VK_Mips_GOT_LO16,
276    VK_Mips_CALL_HI16,
277    VK_Mips_CALL_LO16,
278    VK_Mips_PCREL_HI16,
279    VK_Mips_PCREL_LO16,
280
281    VK_COFF_IMGREL32 // symbol@imgrel (image-relative)
282  };
283
284private:
285  /// The symbol reference modifier.
286  const unsigned Kind : 16;
287
288  /// Specifies how the variant kind should be printed.
289  const unsigned UseParensForSymbolVariant : 1;
290
291  // FIXME: Remove this bit.
292  const unsigned HasSubsectionsViaSymbols : 1;
293
294  /// The symbol being referenced.
295  const MCSymbol *Symbol;
296
297  explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
298                           const MCAsmInfo *MAI);
299
300public:
301  /// @name Construction
302  /// @{
303
304  static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) {
305    return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx);
306  }
307
308  static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind,
309                                       MCContext &Ctx);
310  static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind,
311                                       MCContext &Ctx);
312
313  /// @}
314  /// @name Accessors
315  /// @{
316
317  const MCSymbol &getSymbol() const { return *Symbol; }
318
319  VariantKind getKind() const { return static_cast<VariantKind>(Kind); }
320
321  void printVariantKind(raw_ostream &OS) const;
322
323  bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
324
325  /// @}
326  /// @name Static Utility Functions
327  /// @{
328
329  static StringRef getVariantKindName(VariantKind Kind);
330
331  static VariantKind getVariantKindForName(StringRef Name);
332
333  /// @}
334
335  static bool classof(const MCExpr *E) {
336    return E->getKind() == MCExpr::SymbolRef;
337  }
338};
339
340/// MCUnaryExpr - Unary assembler expressions.
341class MCUnaryExpr : public MCExpr {
342public:
343  enum Opcode {
344    LNot,  ///< Logical negation.
345    Minus, ///< Unary minus.
346    Not,   ///< Bitwise negation.
347    Plus   ///< Unary plus.
348  };
349
350private:
351  Opcode Op;
352  const MCExpr *Expr;
353
354  MCUnaryExpr(Opcode Op, const MCExpr *Expr)
355      : MCExpr(MCExpr::Unary), Op(Op), Expr(Expr) {}
356
357public:
358  /// @name Construction
359  /// @{
360
361  static const MCUnaryExpr *Create(Opcode Op, const MCExpr *Expr,
362                                   MCContext &Ctx);
363  static const MCUnaryExpr *CreateLNot(const MCExpr *Expr, MCContext &Ctx) {
364    return Create(LNot, Expr, Ctx);
365  }
366  static const MCUnaryExpr *CreateMinus(const MCExpr *Expr, MCContext &Ctx) {
367    return Create(Minus, Expr, Ctx);
368  }
369  static const MCUnaryExpr *CreateNot(const MCExpr *Expr, MCContext &Ctx) {
370    return Create(Not, Expr, Ctx);
371  }
372  static const MCUnaryExpr *CreatePlus(const MCExpr *Expr, MCContext &Ctx) {
373    return Create(Plus, Expr, Ctx);
374  }
375
376  /// @}
377  /// @name Accessors
378  /// @{
379
380  /// getOpcode - Get the kind of this unary expression.
381  Opcode getOpcode() const { return Op; }
382
383  /// getSubExpr - Get the child of this unary expression.
384  const MCExpr *getSubExpr() const { return Expr; }
385
386  /// @}
387
388  static bool classof(const MCExpr *E) {
389    return E->getKind() == MCExpr::Unary;
390  }
391};
392
393/// MCBinaryExpr - Binary assembler expressions.
394class MCBinaryExpr : public MCExpr {
395public:
396  enum Opcode {
397    Add,  ///< Addition.
398    And,  ///< Bitwise and.
399    Div,  ///< Signed division.
400    EQ,   ///< Equality comparison.
401    GT,   ///< Signed greater than comparison (result is either 0 or some
402          ///< target-specific non-zero value)
403    GTE,  ///< Signed greater than or equal comparison (result is either 0 or
404          ///< some target-specific non-zero value).
405    LAnd, ///< Logical and.
406    LOr,  ///< Logical or.
407    LT,   ///< Signed less than comparison (result is either 0 or
408          ///< some target-specific non-zero value).
409    LTE,  ///< Signed less than or equal comparison (result is either 0 or
410          ///< some target-specific non-zero value).
411    Mod,  ///< Signed remainder.
412    Mul,  ///< Multiplication.
413    NE,   ///< Inequality comparison.
414    Or,   ///< Bitwise or.
415    Shl,  ///< Shift left.
416    Shr,  ///< Shift right (arithmetic or logical, depending on target)
417    Sub,  ///< Subtraction.
418    Xor   ///< Bitwise exclusive or.
419  };
420
421private:
422  Opcode Op;
423  const MCExpr *LHS, *RHS;
424
425  MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS)
426      : MCExpr(MCExpr::Binary), Op(Op), LHS(LHS), RHS(RHS) {}
427
428public:
429  /// @name Construction
430  /// @{
431
432  static const MCBinaryExpr *Create(Opcode Op, const MCExpr *LHS,
433                                    const MCExpr *RHS, MCContext &Ctx);
434  static const MCBinaryExpr *CreateAdd(const MCExpr *LHS, const MCExpr *RHS,
435                                       MCContext &Ctx) {
436    return Create(Add, LHS, RHS, Ctx);
437  }
438  static const MCBinaryExpr *CreateAnd(const MCExpr *LHS, const MCExpr *RHS,
439                                       MCContext &Ctx) {
440    return Create(And, LHS, RHS, Ctx);
441  }
442  static const MCBinaryExpr *CreateDiv(const MCExpr *LHS, const MCExpr *RHS,
443                                       MCContext &Ctx) {
444    return Create(Div, LHS, RHS, Ctx);
445  }
446  static const MCBinaryExpr *CreateEQ(const MCExpr *LHS, const MCExpr *RHS,
447                                      MCContext &Ctx) {
448    return Create(EQ, LHS, RHS, Ctx);
449  }
450  static const MCBinaryExpr *CreateGT(const MCExpr *LHS, const MCExpr *RHS,
451                                      MCContext &Ctx) {
452    return Create(GT, LHS, RHS, Ctx);
453  }
454  static const MCBinaryExpr *CreateGTE(const MCExpr *LHS, const MCExpr *RHS,
455                                       MCContext &Ctx) {
456    return Create(GTE, LHS, RHS, Ctx);
457  }
458  static const MCBinaryExpr *CreateLAnd(const MCExpr *LHS, const MCExpr *RHS,
459                                        MCContext &Ctx) {
460    return Create(LAnd, LHS, RHS, Ctx);
461  }
462  static const MCBinaryExpr *CreateLOr(const MCExpr *LHS, const MCExpr *RHS,
463                                       MCContext &Ctx) {
464    return Create(LOr, LHS, RHS, Ctx);
465  }
466  static const MCBinaryExpr *CreateLT(const MCExpr *LHS, const MCExpr *RHS,
467                                      MCContext &Ctx) {
468    return Create(LT, LHS, RHS, Ctx);
469  }
470  static const MCBinaryExpr *CreateLTE(const MCExpr *LHS, const MCExpr *RHS,
471                                       MCContext &Ctx) {
472    return Create(LTE, LHS, RHS, Ctx);
473  }
474  static const MCBinaryExpr *CreateMod(const MCExpr *LHS, const MCExpr *RHS,
475                                       MCContext &Ctx) {
476    return Create(Mod, LHS, RHS, Ctx);
477  }
478  static const MCBinaryExpr *CreateMul(const MCExpr *LHS, const MCExpr *RHS,
479                                       MCContext &Ctx) {
480    return Create(Mul, LHS, RHS, Ctx);
481  }
482  static const MCBinaryExpr *CreateNE(const MCExpr *LHS, const MCExpr *RHS,
483                                      MCContext &Ctx) {
484    return Create(NE, LHS, RHS, Ctx);
485  }
486  static const MCBinaryExpr *CreateOr(const MCExpr *LHS, const MCExpr *RHS,
487                                      MCContext &Ctx) {
488    return Create(Or, LHS, RHS, Ctx);
489  }
490  static const MCBinaryExpr *CreateShl(const MCExpr *LHS, const MCExpr *RHS,
491                                       MCContext &Ctx) {
492    return Create(Shl, LHS, RHS, Ctx);
493  }
494  static const MCBinaryExpr *CreateShr(const MCExpr *LHS, const MCExpr *RHS,
495                                       MCContext &Ctx) {
496    return Create(Shr, LHS, RHS, Ctx);
497  }
498  static const MCBinaryExpr *CreateSub(const MCExpr *LHS, const MCExpr *RHS,
499                                       MCContext &Ctx) {
500    return Create(Sub, LHS, RHS, Ctx);
501  }
502  static const MCBinaryExpr *CreateXor(const MCExpr *LHS, const MCExpr *RHS,
503                                       MCContext &Ctx) {
504    return Create(Xor, LHS, RHS, Ctx);
505  }
506
507  /// @}
508  /// @name Accessors
509  /// @{
510
511  /// getOpcode - Get the kind of this binary expression.
512  Opcode getOpcode() const { return Op; }
513
514  /// getLHS - Get the left-hand side expression of the binary operator.
515  const MCExpr *getLHS() const { return LHS; }
516
517  /// getRHS - Get the right-hand side expression of the binary operator.
518  const MCExpr *getRHS() const { return RHS; }
519
520  /// @}
521
522  static bool classof(const MCExpr *E) {
523    return E->getKind() == MCExpr::Binary;
524  }
525};
526
527/// MCTargetExpr - This is an extension point for target-specific MCExpr
528/// subclasses to implement.
529///
530/// NOTE: All subclasses are required to have trivial destructors because
531/// MCExprs are bump pointer allocated and not destructed.
532class MCTargetExpr : public MCExpr {
533  virtual void anchor();
534protected:
535  MCTargetExpr() : MCExpr(Target) {}
536  virtual ~MCTargetExpr() {}
537public:
538
539  virtual void PrintImpl(raw_ostream &OS) const = 0;
540  virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
541                                         const MCAsmLayout *Layout,
542                                         const MCFixup *Fixup) const = 0;
543  virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
544  virtual const MCSection *FindAssociatedSection() const = 0;
545
546  virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
547
548  static bool classof(const MCExpr *E) {
549    return E->getKind() == MCExpr::Target;
550  }
551};
552
553} // end namespace llvm
554
555#endif
556