/src/keystone/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
Line | Count | Source |
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_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64MCEXPR_H |
16 | | #define LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64MCEXPR_H |
17 | | |
18 | | #include "llvm/MC/MCExpr.h" |
19 | | #include "llvm/Support/ErrorHandling.h" |
20 | | |
21 | | namespace llvm_ks { |
22 | | |
23 | | class AArch64MCExpr : public MCTargetExpr { |
24 | | public: |
25 | | enum VariantKind { |
26 | | VK_NONE = 0x000, |
27 | | |
28 | | // Symbol locations specifying (roughly speaking) what calculation should be |
29 | | // performed to construct the final address for the relocated |
30 | | // symbol. E.g. direct, via the GOT, ... |
31 | | VK_ABS = 0x001, |
32 | | VK_SABS = 0x002, |
33 | | VK_GOT = 0x003, |
34 | | VK_DTPREL = 0x004, |
35 | | VK_GOTTPREL = 0x005, |
36 | | VK_TPREL = 0x006, |
37 | | VK_TLSDESC = 0x007, |
38 | | VK_SymLocBits = 0x00f, |
39 | | |
40 | | // Variants specifying which part of the final address calculation is |
41 | | // used. E.g. the low 12 bits for an ADD/LDR, the middle 16 bits for a |
42 | | // MOVZ/MOVK. |
43 | | VK_PAGE = 0x010, |
44 | | VK_PAGEOFF = 0x020, |
45 | | VK_HI12 = 0x030, |
46 | | VK_G0 = 0x040, |
47 | | VK_G1 = 0x050, |
48 | | VK_G2 = 0x060, |
49 | | VK_G3 = 0x070, |
50 | | VK_AddressFragBits = 0x0f0, |
51 | | |
52 | | // Whether the final relocation is a checked one (where a linker should |
53 | | // perform a range-check on the final address) or not. Note that this field |
54 | | // is unfortunately sometimes omitted from the assembly syntax. E.g. :lo12: |
55 | | // on its own is a non-checked relocation. We side with ELF on being |
56 | | // explicit about this! |
57 | | VK_NC = 0x100, |
58 | | |
59 | | // Convenience definitions for referring to specific textual representations |
60 | | // of relocation specifiers. Note that this means the "_NC" is sometimes |
61 | | // omitted in line with assembly syntax here (VK_LO12 rather than VK_LO12_NC |
62 | | // since a user would write ":lo12:"). |
63 | | VK_CALL = VK_ABS, |
64 | | VK_ABS_PAGE = VK_ABS | VK_PAGE, |
65 | | VK_ABS_G3 = VK_ABS | VK_G3, |
66 | | VK_ABS_G2 = VK_ABS | VK_G2, |
67 | | VK_ABS_G2_S = VK_SABS | VK_G2, |
68 | | VK_ABS_G2_NC = VK_ABS | VK_G2 | VK_NC, |
69 | | VK_ABS_G1 = VK_ABS | VK_G1, |
70 | | VK_ABS_G1_S = VK_SABS | VK_G1, |
71 | | VK_ABS_G1_NC = VK_ABS | VK_G1 | VK_NC, |
72 | | VK_ABS_G0 = VK_ABS | VK_G0, |
73 | | VK_ABS_G0_S = VK_SABS | VK_G0, |
74 | | VK_ABS_G0_NC = VK_ABS | VK_G0 | VK_NC, |
75 | | VK_LO12 = VK_ABS | VK_PAGEOFF | VK_NC, |
76 | | VK_GOT_LO12 = VK_GOT | VK_PAGEOFF | VK_NC, |
77 | | VK_GOT_PAGE = VK_GOT | VK_PAGE, |
78 | | VK_DTPREL_G2 = VK_DTPREL | VK_G2, |
79 | | VK_DTPREL_G1 = VK_DTPREL | VK_G1, |
80 | | VK_DTPREL_G1_NC = VK_DTPREL | VK_G1 | VK_NC, |
81 | | VK_DTPREL_G0 = VK_DTPREL | VK_G0, |
82 | | VK_DTPREL_G0_NC = VK_DTPREL | VK_G0 | VK_NC, |
83 | | VK_DTPREL_HI12 = VK_DTPREL | VK_HI12, |
84 | | VK_DTPREL_LO12 = VK_DTPREL | VK_PAGEOFF, |
85 | | VK_DTPREL_LO12_NC = VK_DTPREL | VK_PAGEOFF | VK_NC, |
86 | | VK_GOTTPREL_PAGE = VK_GOTTPREL | VK_PAGE, |
87 | | VK_GOTTPREL_LO12_NC = VK_GOTTPREL | VK_PAGEOFF | VK_NC, |
88 | | VK_GOTTPREL_G1 = VK_GOTTPREL | VK_G1, |
89 | | VK_GOTTPREL_G0_NC = VK_GOTTPREL | VK_G0 | VK_NC, |
90 | | VK_TPREL_G2 = VK_TPREL | VK_G2, |
91 | | VK_TPREL_G1 = VK_TPREL | VK_G1, |
92 | | VK_TPREL_G1_NC = VK_TPREL | VK_G1 | VK_NC, |
93 | | VK_TPREL_G0 = VK_TPREL | VK_G0, |
94 | | VK_TPREL_G0_NC = VK_TPREL | VK_G0 | VK_NC, |
95 | | VK_TPREL_HI12 = VK_TPREL | VK_HI12, |
96 | | VK_TPREL_LO12 = VK_TPREL | VK_PAGEOFF, |
97 | | VK_TPREL_LO12_NC = VK_TPREL | VK_PAGEOFF | VK_NC, |
98 | | VK_TLSDESC_LO12 = VK_TLSDESC | VK_PAGEOFF | VK_NC, |
99 | | VK_TLSDESC_PAGE = VK_TLSDESC | VK_PAGE, |
100 | | |
101 | | VK_INVALID = 0xfff |
102 | | }; |
103 | | |
104 | | private: |
105 | | const MCExpr *Expr; |
106 | | const VariantKind Kind; |
107 | | |
108 | | explicit AArch64MCExpr(const MCExpr *Expr, VariantKind Kind) |
109 | 9 | : Expr(Expr), Kind(Kind) {} |
110 | | |
111 | | public: |
112 | | /// @name Construction |
113 | | /// @{ |
114 | | |
115 | | static const AArch64MCExpr *create(const MCExpr *Expr, VariantKind Kind, |
116 | | MCContext &Ctx); |
117 | | |
118 | | /// @} |
119 | | /// @name Accessors |
120 | | /// @{ |
121 | | |
122 | | /// Get the kind of this expression. |
123 | 0 | VariantKind getKind() const { return Kind; } |
124 | | |
125 | | /// Get the expression this modifier applies to. |
126 | 0 | const MCExpr *getSubExpr() const { return Expr; } |
127 | | |
128 | | /// @} |
129 | | /// @name VariantKind information extractors. |
130 | | /// @{ |
131 | | |
132 | 3.03k | static VariantKind getSymbolLoc(VariantKind Kind) { |
133 | 3.03k | return static_cast<VariantKind>(Kind & VK_SymLocBits); |
134 | 3.03k | } |
135 | | |
136 | 0 | static VariantKind getAddressFrag(VariantKind Kind) { |
137 | 0 | return static_cast<VariantKind>(Kind & VK_AddressFragBits); |
138 | 0 | } |
139 | | |
140 | 3.03k | static bool isNotChecked(VariantKind Kind) { return Kind & VK_NC; } |
141 | | |
142 | | /// @} |
143 | | |
144 | | /// Convert the variant kind into an ELF-appropriate modifier |
145 | | /// (e.g. ":got:", ":lo12:"). |
146 | | StringRef getVariantKindName() const; |
147 | | |
148 | | void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override; |
149 | | |
150 | | void visitUsedExpr(MCStreamer &Streamer) const override; |
151 | | |
152 | | MCFragment *findAssociatedFragment() const override; |
153 | | |
154 | | bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, |
155 | | const MCFixup *Fixup) const override; |
156 | | |
157 | | void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override; |
158 | | |
159 | 15 | static bool classof(const MCExpr *E) { |
160 | 15 | return E->getKind() == MCExpr::Target; |
161 | 15 | } |
162 | | |
163 | 0 | static bool classof(const AArch64MCExpr *) { return true; } |
164 | | }; |
165 | | } // end namespace llvm_ks |
166 | | |
167 | | #endif |