1//==- AArch64MCExpr.h - AArch64 specific MC expression classes --*- 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// This file describes AArch64-specific MCExprs, used for modifiers like
11// ":lo12:" or ":gottprel_g1:".
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_AARCH64MCEXPR_H
16#define LLVM_AARCH64MCEXPR_H
17
18#include "llvm/MC/MCExpr.h"
19
20namespace llvm {
21
22class AArch64MCExpr : public MCTargetExpr {
23public:
24  enum VariantKind {
25    VK_AARCH64_None,
26    VK_AARCH64_GOT,      // :got: modifier in assembly
27    VK_AARCH64_GOT_LO12, // :got_lo12:
28    VK_AARCH64_LO12,     // :lo12:
29
30    VK_AARCH64_ABS_G0, // :abs_g0:
31    VK_AARCH64_ABS_G0_NC, // :abs_g0_nc:
32    VK_AARCH64_ABS_G1,
33    VK_AARCH64_ABS_G1_NC,
34    VK_AARCH64_ABS_G2,
35    VK_AARCH64_ABS_G2_NC,
36    VK_AARCH64_ABS_G3,
37
38    VK_AARCH64_SABS_G0, // :abs_g0_s:
39    VK_AARCH64_SABS_G1,
40    VK_AARCH64_SABS_G2,
41
42    VK_AARCH64_DTPREL_G2, // :dtprel_g2:
43    VK_AARCH64_DTPREL_G1,
44    VK_AARCH64_DTPREL_G1_NC,
45    VK_AARCH64_DTPREL_G0,
46    VK_AARCH64_DTPREL_G0_NC,
47    VK_AARCH64_DTPREL_HI12,
48    VK_AARCH64_DTPREL_LO12,
49    VK_AARCH64_DTPREL_LO12_NC,
50
51    VK_AARCH64_GOTTPREL_G1, // :gottprel:
52    VK_AARCH64_GOTTPREL_G0_NC,
53    VK_AARCH64_GOTTPREL,
54    VK_AARCH64_GOTTPREL_LO12,
55
56    VK_AARCH64_TPREL_G2, // :tprel:
57    VK_AARCH64_TPREL_G1,
58    VK_AARCH64_TPREL_G1_NC,
59    VK_AARCH64_TPREL_G0,
60    VK_AARCH64_TPREL_G0_NC,
61    VK_AARCH64_TPREL_HI12,
62    VK_AARCH64_TPREL_LO12,
63    VK_AARCH64_TPREL_LO12_NC,
64
65    VK_AARCH64_TLSDESC, // :tlsdesc:
66    VK_AARCH64_TLSDESC_LO12
67  };
68
69private:
70  const VariantKind Kind;
71  const MCExpr *Expr;
72
73  explicit AArch64MCExpr(VariantKind _Kind, const MCExpr *_Expr)
74    : Kind(_Kind), Expr(_Expr) {}
75
76public:
77  /// @name Construction
78  /// @{
79
80  static const AArch64MCExpr *Create(VariantKind Kind, const MCExpr *Expr,
81                                     MCContext &Ctx);
82
83  static const AArch64MCExpr *CreateLo12(const MCExpr *Expr, MCContext &Ctx) {
84    return Create(VK_AARCH64_LO12, Expr, Ctx);
85  }
86
87  static const AArch64MCExpr *CreateGOT(const MCExpr *Expr, MCContext &Ctx) {
88    return Create(VK_AARCH64_GOT, Expr, Ctx);
89  }
90
91  static const AArch64MCExpr *CreateGOTLo12(const MCExpr *Expr,
92                                            MCContext &Ctx) {
93    return Create(VK_AARCH64_GOT_LO12, Expr, Ctx);
94  }
95
96  static const AArch64MCExpr *CreateDTPREL_G1(const MCExpr *Expr,
97                                             MCContext &Ctx) {
98    return Create(VK_AARCH64_DTPREL_G1, Expr, Ctx);
99  }
100
101  static const AArch64MCExpr *CreateDTPREL_G0_NC(const MCExpr *Expr,
102                                                MCContext &Ctx) {
103    return Create(VK_AARCH64_DTPREL_G0_NC, Expr, Ctx);
104  }
105
106  static const AArch64MCExpr *CreateGOTTPREL(const MCExpr *Expr,
107                                             MCContext &Ctx) {
108    return Create(VK_AARCH64_GOTTPREL, Expr, Ctx);
109  }
110
111  static const AArch64MCExpr *CreateGOTTPRELLo12(const MCExpr *Expr,
112                                                 MCContext &Ctx) {
113    return Create(VK_AARCH64_GOTTPREL_LO12, Expr, Ctx);
114  }
115
116  static const AArch64MCExpr *CreateTLSDesc(const MCExpr *Expr,
117                                            MCContext &Ctx) {
118    return Create(VK_AARCH64_TLSDESC, Expr, Ctx);
119  }
120
121  static const AArch64MCExpr *CreateTLSDescLo12(const MCExpr *Expr,
122                                                MCContext &Ctx) {
123    return Create(VK_AARCH64_TLSDESC_LO12, Expr, Ctx);
124  }
125
126  static const AArch64MCExpr *CreateTPREL_G1(const MCExpr *Expr,
127                                             MCContext &Ctx) {
128    return Create(VK_AARCH64_TPREL_G1, Expr, Ctx);
129  }
130
131  static const AArch64MCExpr *CreateTPREL_G0_NC(const MCExpr *Expr,
132                                                MCContext &Ctx) {
133    return Create(VK_AARCH64_TPREL_G0_NC, Expr, Ctx);
134  }
135
136  /// @}
137  /// @name Accessors
138  /// @{
139
140  /// getOpcode - Get the kind of this expression.
141  VariantKind getKind() const { return Kind; }
142
143  /// getSubExpr - Get the child of this expression.
144  const MCExpr *getSubExpr() const { return Expr; }
145
146  /// @}
147
148  void PrintImpl(raw_ostream &OS) const;
149  bool EvaluateAsRelocatableImpl(MCValue &Res,
150                                 const MCAsmLayout *Layout) const;
151  void AddValueSymbols(MCAssembler *) const;
152  const MCSection *FindAssociatedSection() const {
153    return getSubExpr()->FindAssociatedSection();
154  }
155
156  void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const;
157
158  static bool classof(const MCExpr *E) {
159    return E->getKind() == MCExpr::Target;
160  }
161
162  static bool classof(const AArch64MCExpr *) { return true; }
163
164};
165} // end namespace llvm
166
167#endif
168