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 "Utils/AArch64BaseInfo.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/Support/Casting.h"
20 #include "llvm/Support/ErrorHandling.h"
24 class AArch64MCExpr
: public MCTargetExpr
{
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, ...
43 VK_SymLocBits
= 0x00f,
45 // Variants specifying which part of the final address calculation is
46 // used. E.g. the low 12 bits for an ADD/LDR, the middle 16 bits for a
56 VK_AddressFragBits
= 0x0f0,
58 // Whether the final relocation is a checked one (where a linker should
59 // perform a range-check on the final address) or not. Note that this field
60 // is unfortunately sometimes omitted from the assembly syntax. E.g. :lo12:
61 // on its own is a non-checked relocation. We side with ELF on being
62 // explicit about this!
65 // Convenience definitions for referring to specific textual representations
66 // of relocation specifiers. Note that this means the "_NC" is sometimes
67 // omitted in line with assembly syntax here (VK_LO12 rather than VK_LO12_NC
68 // since a user would write ":lo12:").
70 VK_ABS_PAGE
= VK_ABS
| VK_PAGE
,
71 VK_ABS_PAGE_NC
= VK_ABS
| VK_PAGE
| VK_NC
,
72 VK_ABS_G3
= VK_ABS
| VK_G3
,
73 VK_ABS_G2
= VK_ABS
| VK_G2
,
74 VK_ABS_G2_S
= VK_SABS
| VK_G2
,
75 VK_ABS_G2_NC
= VK_ABS
| VK_G2
| VK_NC
,
76 VK_ABS_G1
= VK_ABS
| VK_G1
,
77 VK_ABS_G1_S
= VK_SABS
| VK_G1
,
78 VK_ABS_G1_NC
= VK_ABS
| VK_G1
| VK_NC
,
79 VK_ABS_G0
= VK_ABS
| VK_G0
,
80 VK_ABS_G0_S
= VK_SABS
| VK_G0
,
81 VK_ABS_G0_NC
= VK_ABS
| VK_G0
| VK_NC
,
82 VK_LO12
= VK_ABS
| VK_PAGEOFF
| VK_NC
,
83 VK_PREL_G3
= VK_PREL
| VK_G3
,
84 VK_PREL_G2
= VK_PREL
| VK_G2
,
85 VK_PREL_G2_NC
= VK_PREL
| VK_G2
| VK_NC
,
86 VK_PREL_G1
= VK_PREL
| VK_G1
,
87 VK_PREL_G1_NC
= VK_PREL
| VK_G1
| VK_NC
,
88 VK_PREL_G0
= VK_PREL
| VK_G0
,
89 VK_PREL_G0_NC
= VK_PREL
| VK_G0
| VK_NC
,
90 VK_GOT_LO12
= VK_GOT
| VK_PAGEOFF
| VK_NC
,
91 VK_GOT_PAGE
= VK_GOT
| VK_PAGE
,
92 VK_GOT_PAGE_LO15
= VK_GOT
| VK_LO15
| VK_NC
,
93 VK_GOT_AUTH_LO12
= VK_GOT_AUTH
| VK_PAGEOFF
| VK_NC
,
94 VK_GOT_AUTH_PAGE
= VK_GOT_AUTH
| VK_PAGE
,
95 VK_DTPREL_G2
= VK_DTPREL
| VK_G2
,
96 VK_DTPREL_G1
= VK_DTPREL
| VK_G1
,
97 VK_DTPREL_G1_NC
= VK_DTPREL
| VK_G1
| VK_NC
,
98 VK_DTPREL_G0
= VK_DTPREL
| VK_G0
,
99 VK_DTPREL_G0_NC
= VK_DTPREL
| VK_G0
| VK_NC
,
100 VK_DTPREL_HI12
= VK_DTPREL
| VK_HI12
,
101 VK_DTPREL_LO12
= VK_DTPREL
| VK_PAGEOFF
,
102 VK_DTPREL_LO12_NC
= VK_DTPREL
| VK_PAGEOFF
| VK_NC
,
103 VK_GOTTPREL_PAGE
= VK_GOTTPREL
| VK_PAGE
,
104 VK_GOTTPREL_LO12_NC
= VK_GOTTPREL
| VK_PAGEOFF
| VK_NC
,
105 VK_GOTTPREL_G1
= VK_GOTTPREL
| VK_G1
,
106 VK_GOTTPREL_G0_NC
= VK_GOTTPREL
| VK_G0
| VK_NC
,
107 VK_TPREL_G2
= VK_TPREL
| VK_G2
,
108 VK_TPREL_G1
= VK_TPREL
| VK_G1
,
109 VK_TPREL_G1_NC
= VK_TPREL
| VK_G1
| VK_NC
,
110 VK_TPREL_G0
= VK_TPREL
| VK_G0
,
111 VK_TPREL_G0_NC
= VK_TPREL
| VK_G0
| VK_NC
,
112 VK_TPREL_HI12
= VK_TPREL
| VK_HI12
,
113 VK_TPREL_LO12
= VK_TPREL
| VK_PAGEOFF
,
114 VK_TPREL_LO12_NC
= VK_TPREL
| VK_PAGEOFF
| VK_NC
,
115 VK_TLSDESC_LO12
= VK_TLSDESC
| VK_PAGEOFF
,
116 VK_TLSDESC_PAGE
= VK_TLSDESC
| VK_PAGE
,
117 VK_SECREL_LO12
= VK_SECREL
| VK_PAGEOFF
,
118 VK_SECREL_HI12
= VK_SECREL
| VK_HI12
,
126 const VariantKind Kind
;
129 explicit AArch64MCExpr(const MCExpr
*Expr
, VariantKind Kind
)
130 : Expr(Expr
), Kind(Kind
) {}
133 /// @name Construction
136 static const AArch64MCExpr
*create(const MCExpr
*Expr
, VariantKind Kind
,
143 /// Get the kind of this expression.
144 VariantKind
getKind() const { return Kind
; }
146 /// Get the expression this modifier applies to.
147 const MCExpr
*getSubExpr() const { return Expr
; }
150 /// @name VariantKind information extractors.
153 static VariantKind
getSymbolLoc(VariantKind Kind
) {
154 return static_cast<VariantKind
>(Kind
& VK_SymLocBits
);
157 static VariantKind
getAddressFrag(VariantKind Kind
) {
158 return static_cast<VariantKind
>(Kind
& VK_AddressFragBits
);
161 static bool isNotChecked(VariantKind Kind
) { return Kind
& VK_NC
; }
165 /// Convert the variant kind into an ELF-appropriate modifier
166 /// (e.g. ":got:", ":lo12:").
167 StringRef
getVariantKindName() const;
169 void printImpl(raw_ostream
&OS
, const MCAsmInfo
*MAI
) const override
;
171 void visitUsedExpr(MCStreamer
&Streamer
) const override
;
173 MCFragment
*findAssociatedFragment() const override
;
175 bool evaluateAsRelocatableImpl(MCValue
&Res
, const MCAssembler
*Asm
,
176 const MCFixup
*Fixup
) const override
;
178 void fixELFSymbolsInTLSFixups(MCAssembler
&Asm
) const override
;
180 static bool classof(const MCExpr
*E
) {
181 return E
->getKind() == MCExpr::Target
;
185 class AArch64AuthMCExpr final
: public AArch64MCExpr
{
186 uint16_t Discriminator
;
187 AArch64PACKey::ID Key
;
189 explicit AArch64AuthMCExpr(const MCExpr
*Expr
, uint16_t Discriminator
,
190 AArch64PACKey::ID Key
, bool HasAddressDiversity
)
191 : AArch64MCExpr(Expr
, HasAddressDiversity
? VK_AUTHADDR
: VK_AUTH
),
192 Discriminator(Discriminator
), Key(Key
) {}
195 static const AArch64AuthMCExpr
*
196 create(const MCExpr
*Expr
, uint16_t Discriminator
, AArch64PACKey::ID Key
,
197 bool HasAddressDiversity
, MCContext
&Ctx
);
199 AArch64PACKey::ID
getKey() const { return Key
; }
200 uint16_t getDiscriminator() const { return Discriminator
; }
201 bool hasAddressDiversity() const { return getKind() == VK_AUTHADDR
; }
203 void printImpl(raw_ostream
&OS
, const MCAsmInfo
*MAI
) const override
;
205 void visitUsedExpr(MCStreamer
&Streamer
) const override
;
207 MCFragment
*findAssociatedFragment() const override
;
209 bool evaluateAsRelocatableImpl(MCValue
&Res
, const MCAssembler
*Asm
,
210 const MCFixup
*Fixup
) const override
;
212 static bool classof(const MCExpr
*E
) {
213 return isa
<AArch64MCExpr
>(E
) && classof(cast
<AArch64MCExpr
>(E
));
216 static bool classof(const AArch64MCExpr
*E
) {
217 return E
->getKind() == VK_AUTH
|| E
->getKind() == VK_AUTHADDR
;
220 } // end namespace llvm