/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
Line | Count | Source (jump to first uncovered line) |
1 | | //=--- AArch64MCExpr.h - AArch64 specific MC expression classes ---*- C++ -*-=// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file describes AArch64-specific MCExprs, used for modifiers like |
10 | | // ":lo12:" or ":gottprel_g1:". |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64MCEXPR_H |
15 | | #define LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64MCEXPR_H |
16 | | |
17 | | #include "llvm/MC/MCExpr.h" |
18 | | #include "llvm/Support/ErrorHandling.h" |
19 | | |
20 | | namespace llvm { |
21 | | |
22 | | class AArch64MCExpr : public MCTargetExpr { |
23 | | public: |
24 | | enum VariantKind { |
25 | | // Symbol locations specifying (roughly speaking) what calculation should be |
26 | | // performed to construct the final address for the relocated |
27 | | // symbol. E.g. direct, via the GOT, ... |
28 | | VK_ABS = 0x001, |
29 | | VK_SABS = 0x002, |
30 | | VK_PREL = 0x003, |
31 | | VK_GOT = 0x004, |
32 | | VK_DTPREL = 0x005, |
33 | | VK_GOTTPREL = 0x006, |
34 | | VK_TPREL = 0x007, |
35 | | VK_TLSDESC = 0x008, |
36 | | VK_SECREL = 0x009, |
37 | | VK_SymLocBits = 0x00f, |
38 | | |
39 | | // Variants specifying which part of the final address calculation is |
40 | | // used. E.g. the low 12 bits for an ADD/LDR, the middle 16 bits for a |
41 | | // MOVZ/MOVK. |
42 | | VK_PAGE = 0x010, |
43 | | VK_PAGEOFF = 0x020, |
44 | | VK_HI12 = 0x030, |
45 | | VK_G0 = 0x040, |
46 | | VK_G1 = 0x050, |
47 | | VK_G2 = 0x060, |
48 | | VK_G3 = 0x070, |
49 | | VK_AddressFragBits = 0x0f0, |
50 | | |
51 | | // Whether the final relocation is a checked one (where a linker should |
52 | | // perform a range-check on the final address) or not. Note that this field |
53 | | // is unfortunately sometimes omitted from the assembly syntax. E.g. :lo12: |
54 | | // on its own is a non-checked relocation. We side with ELF on being |
55 | | // explicit about this! |
56 | | VK_NC = 0x100, |
57 | | |
58 | | // Convenience definitions for referring to specific textual representations |
59 | | // of relocation specifiers. Note that this means the "_NC" is sometimes |
60 | | // omitted in line with assembly syntax here (VK_LO12 rather than VK_LO12_NC |
61 | | // since a user would write ":lo12:"). |
62 | | VK_CALL = VK_ABS, |
63 | | VK_ABS_PAGE = VK_ABS | VK_PAGE, |
64 | | VK_ABS_PAGE_NC = VK_ABS | VK_PAGE | VK_NC, |
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_PREL_G3 = VK_PREL | VK_G3, |
77 | | VK_PREL_G2 = VK_PREL | VK_G2, |
78 | | VK_PREL_G2_NC = VK_PREL | VK_G2 | VK_NC, |
79 | | VK_PREL_G1 = VK_PREL | VK_G1, |
80 | | VK_PREL_G1_NC = VK_PREL | VK_G1 | VK_NC, |
81 | | VK_PREL_G0 = VK_PREL | VK_G0, |
82 | | VK_PREL_G0_NC = VK_PREL | VK_G0 | VK_NC, |
83 | | VK_GOT_LO12 = VK_GOT | VK_PAGEOFF | VK_NC, |
84 | | VK_GOT_PAGE = VK_GOT | VK_PAGE, |
85 | | VK_DTPREL_G2 = VK_DTPREL | VK_G2, |
86 | | VK_DTPREL_G1 = VK_DTPREL | VK_G1, |
87 | | VK_DTPREL_G1_NC = VK_DTPREL | VK_G1 | VK_NC, |
88 | | VK_DTPREL_G0 = VK_DTPREL | VK_G0, |
89 | | VK_DTPREL_G0_NC = VK_DTPREL | VK_G0 | VK_NC, |
90 | | VK_DTPREL_HI12 = VK_DTPREL | VK_HI12, |
91 | | VK_DTPREL_LO12 = VK_DTPREL | VK_PAGEOFF, |
92 | | VK_DTPREL_LO12_NC = VK_DTPREL | VK_PAGEOFF | VK_NC, |
93 | | VK_GOTTPREL_PAGE = VK_GOTTPREL | VK_PAGE, |
94 | | VK_GOTTPREL_LO12_NC = VK_GOTTPREL | VK_PAGEOFF | VK_NC, |
95 | | VK_GOTTPREL_G1 = VK_GOTTPREL | VK_G1, |
96 | | VK_GOTTPREL_G0_NC = VK_GOTTPREL | VK_G0 | VK_NC, |
97 | | VK_TPREL_G2 = VK_TPREL | VK_G2, |
98 | | VK_TPREL_G1 = VK_TPREL | VK_G1, |
99 | | VK_TPREL_G1_NC = VK_TPREL | VK_G1 | VK_NC, |
100 | | VK_TPREL_G0 = VK_TPREL | VK_G0, |
101 | | VK_TPREL_G0_NC = VK_TPREL | VK_G0 | VK_NC, |
102 | | VK_TPREL_HI12 = VK_TPREL | VK_HI12, |
103 | | VK_TPREL_LO12 = VK_TPREL | VK_PAGEOFF, |
104 | | VK_TPREL_LO12_NC = VK_TPREL | VK_PAGEOFF | VK_NC, |
105 | | VK_TLSDESC_LO12 = VK_TLSDESC | VK_PAGEOFF, |
106 | | VK_TLSDESC_PAGE = VK_TLSDESC | VK_PAGE, |
107 | | VK_SECREL_LO12 = VK_SECREL | VK_PAGEOFF, |
108 | | VK_SECREL_HI12 = VK_SECREL | VK_HI12, |
109 | | |
110 | | VK_INVALID = 0xfff |
111 | | }; |
112 | | |
113 | | private: |
114 | | const MCExpr *Expr; |
115 | | const VariantKind Kind; |
116 | | |
117 | | explicit AArch64MCExpr(const MCExpr *Expr, VariantKind Kind) |
118 | 10.9k | : Expr(Expr), Kind(Kind) {} |
119 | | |
120 | | public: |
121 | | /// @name Construction |
122 | | /// @{ |
123 | | |
124 | | static const AArch64MCExpr *create(const MCExpr *Expr, VariantKind Kind, |
125 | | MCContext &Ctx); |
126 | | |
127 | | /// @} |
128 | | /// @name Accessors |
129 | | /// @{ |
130 | | |
131 | | /// Get the kind of this expression. |
132 | 13.3k | VariantKind getKind() const { return Kind; } |
133 | | |
134 | | /// Get the expression this modifier applies to. |
135 | 3.79k | const MCExpr *getSubExpr() const { return Expr; } |
136 | | |
137 | | /// @} |
138 | | /// @name VariantKind information extractors. |
139 | | /// @{ |
140 | | |
141 | 3.27M | static VariantKind getSymbolLoc(VariantKind Kind) { |
142 | 3.27M | return static_cast<VariantKind>(Kind & VK_SymLocBits); |
143 | 3.27M | } |
144 | | |
145 | 36 | static VariantKind getAddressFrag(VariantKind Kind) { |
146 | 36 | return static_cast<VariantKind>(Kind & VK_AddressFragBits); |
147 | 36 | } |
148 | | |
149 | 1.22k | static bool isNotChecked(VariantKind Kind) { return Kind & VK_NC; } |
150 | | |
151 | | /// @} |
152 | | |
153 | | /// Convert the variant kind into an ELF-appropriate modifier |
154 | | /// (e.g. ":got:", ":lo12:"). |
155 | | StringRef getVariantKindName() const; |
156 | | |
157 | | void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override; |
158 | | |
159 | | void visitUsedExpr(MCStreamer &Streamer) const override; |
160 | | |
161 | | MCFragment *findAssociatedFragment() const override; |
162 | | |
163 | | bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, |
164 | | const MCFixup *Fixup) const override; |
165 | | |
166 | | void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override; |
167 | | |
168 | 448k | static bool classof(const MCExpr *E) { |
169 | 448k | return E->getKind() == MCExpr::Target; |
170 | 448k | } |
171 | | |
172 | 0 | static bool classof(const AArch64MCExpr *) { return true; } |
173 | | }; |
174 | | } // end namespace llvm |
175 | | |
176 | | #endif |