1 //=--- AArch64MCExpr.h - AArch64 specific MC expression classes ---*- C++ -*-=//
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
7 //===----------------------------------------------------------------------===//
9 // This file describes AArch64-specific MCExprs, used for modifiers like
10 // ":lo12:" or ":gottprel_g1:".
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64MCEXPR_H
15 #define LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64MCEXPR_H
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/Support/ErrorHandling.h"
22 class AArch64MCExpr
: public MCTargetExpr
{
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, ...
37 VK_SymLocBits
= 0x00f,
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
49 VK_AddressFragBits
= 0x0f0,
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!
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:").
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
,
115 const VariantKind Kind
;
117 explicit AArch64MCExpr(const MCExpr
*Expr
, VariantKind Kind
)
118 : Expr(Expr
), Kind(Kind
) {}
121 /// @name Construction
124 static const AArch64MCExpr
*create(const MCExpr
*Expr
, VariantKind Kind
,
131 /// Get the kind of this expression.
132 VariantKind
getKind() const { return Kind
; }
134 /// Get the expression this modifier applies to.
135 const MCExpr
*getSubExpr() const { return Expr
; }
138 /// @name VariantKind information extractors.
141 static VariantKind
getSymbolLoc(VariantKind Kind
) {
142 return static_cast<VariantKind
>(Kind
& VK_SymLocBits
);
145 static VariantKind
getAddressFrag(VariantKind Kind
) {
146 return static_cast<VariantKind
>(Kind
& VK_AddressFragBits
);
149 static bool isNotChecked(VariantKind Kind
) { return Kind
& VK_NC
; }
153 /// Convert the variant kind into an ELF-appropriate modifier
154 /// (e.g. ":got:", ":lo12:").
155 StringRef
getVariantKindName() const;
157 void printImpl(raw_ostream
&OS
, const MCAsmInfo
*MAI
) const override
;
159 void visitUsedExpr(MCStreamer
&Streamer
) const override
;
161 MCFragment
*findAssociatedFragment() const override
;
163 bool evaluateAsRelocatableImpl(MCValue
&Res
, const MCAsmLayout
*Layout
,
164 const MCFixup
*Fixup
) const override
;
166 void fixELFSymbolsInTLSFixups(MCAssembler
&Asm
) const override
;
168 static bool classof(const MCExpr
*E
) {
169 return E
->getKind() == MCExpr::Target
;
172 static bool classof(const AArch64MCExpr
*) { return true; }
174 } // end namespace llvm