Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCExpr.cpp
35294 views
1
//===-- LoongArchMCExpr.cpp - LoongArch specific MC expression classes ----===//
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 contains the implementation of the assembly expression modifiers
10
// accepted by the LoongArch architecture.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "LoongArchMCExpr.h"
15
#include "LoongArchAsmBackend.h"
16
#include "LoongArchFixupKinds.h"
17
#include "llvm/MC/MCContext.h"
18
#include "llvm/MC/MCStreamer.h"
19
#include "llvm/MC/MCSymbolELF.h"
20
#include "llvm/MC/MCValue.h"
21
#include "llvm/Support/Casting.h"
22
#include "llvm/Support/ErrorHandling.h"
23
24
using namespace llvm;
25
26
#define DEBUG_TYPE "loongarch-mcexpr"
27
28
const LoongArchMCExpr *LoongArchMCExpr::create(const MCExpr *Expr,
29
VariantKind Kind, MCContext &Ctx,
30
bool Hint) {
31
return new (Ctx) LoongArchMCExpr(Expr, Kind, Hint);
32
}
33
34
void LoongArchMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
35
VariantKind Kind = getKind();
36
bool HasVariant =
37
((Kind != VK_LoongArch_None) && (Kind != VK_LoongArch_CALL));
38
39
if (HasVariant)
40
OS << '%' << getVariantKindName(getKind()) << '(';
41
Expr->print(OS, MAI);
42
if (HasVariant)
43
OS << ')';
44
}
45
46
bool LoongArchMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
47
const MCAssembler *Asm,
48
const MCFixup *Fixup) const {
49
// Explicitly drop the layout and assembler to prevent any symbolic folding in
50
// the expression handling. This is required to preserve symbolic difference
51
// expressions to emit the paired relocations.
52
if (!getSubExpr()->evaluateAsRelocatable(Res, nullptr, nullptr))
53
return false;
54
55
Res =
56
MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind());
57
// Custom fixup types are not valid with symbol difference expressions.
58
return Res.getSymB() ? getKind() == VK_LoongArch_None : true;
59
}
60
61
void LoongArchMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
62
Streamer.visitUsedExpr(*getSubExpr());
63
}
64
65
StringRef LoongArchMCExpr::getVariantKindName(VariantKind Kind) {
66
switch (Kind) {
67
default:
68
llvm_unreachable("Invalid ELF symbol kind");
69
case VK_LoongArch_CALL_PLT:
70
return "plt";
71
case VK_LoongArch_B16:
72
return "b16";
73
case VK_LoongArch_B21:
74
return "b21";
75
case VK_LoongArch_B26:
76
return "b26";
77
case VK_LoongArch_ABS_HI20:
78
return "abs_hi20";
79
case VK_LoongArch_ABS_LO12:
80
return "abs_lo12";
81
case VK_LoongArch_ABS64_LO20:
82
return "abs64_lo20";
83
case VK_LoongArch_ABS64_HI12:
84
return "abs64_hi12";
85
case VK_LoongArch_PCALA_HI20:
86
return "pc_hi20";
87
case VK_LoongArch_PCALA_LO12:
88
return "pc_lo12";
89
case VK_LoongArch_PCALA64_LO20:
90
return "pc64_lo20";
91
case VK_LoongArch_PCALA64_HI12:
92
return "pc64_hi12";
93
case VK_LoongArch_GOT_PC_HI20:
94
return "got_pc_hi20";
95
case VK_LoongArch_GOT_PC_LO12:
96
return "got_pc_lo12";
97
case VK_LoongArch_GOT64_PC_LO20:
98
return "got64_pc_lo20";
99
case VK_LoongArch_GOT64_PC_HI12:
100
return "got64_pc_hi12";
101
case VK_LoongArch_GOT_HI20:
102
return "got_hi20";
103
case VK_LoongArch_GOT_LO12:
104
return "got_lo12";
105
case VK_LoongArch_GOT64_LO20:
106
return "got64_lo20";
107
case VK_LoongArch_GOT64_HI12:
108
return "got64_hi12";
109
case VK_LoongArch_TLS_LE_HI20:
110
return "le_hi20";
111
case VK_LoongArch_TLS_LE_LO12:
112
return "le_lo12";
113
case VK_LoongArch_TLS_LE64_LO20:
114
return "le64_lo20";
115
case VK_LoongArch_TLS_LE64_HI12:
116
return "le64_hi12";
117
case VK_LoongArch_TLS_IE_PC_HI20:
118
return "ie_pc_hi20";
119
case VK_LoongArch_TLS_IE_PC_LO12:
120
return "ie_pc_lo12";
121
case VK_LoongArch_TLS_IE64_PC_LO20:
122
return "ie64_pc_lo20";
123
case VK_LoongArch_TLS_IE64_PC_HI12:
124
return "ie64_pc_hi12";
125
case VK_LoongArch_TLS_IE_HI20:
126
return "ie_hi20";
127
case VK_LoongArch_TLS_IE_LO12:
128
return "ie_lo12";
129
case VK_LoongArch_TLS_IE64_LO20:
130
return "ie64_lo20";
131
case VK_LoongArch_TLS_IE64_HI12:
132
return "ie64_hi12";
133
case VK_LoongArch_TLS_LD_PC_HI20:
134
return "ld_pc_hi20";
135
case VK_LoongArch_TLS_LD_HI20:
136
return "ld_hi20";
137
case VK_LoongArch_TLS_GD_PC_HI20:
138
return "gd_pc_hi20";
139
case VK_LoongArch_TLS_GD_HI20:
140
return "gd_hi20";
141
case VK_LoongArch_CALL36:
142
return "call36";
143
case VK_LoongArch_TLS_DESC_PC_HI20:
144
return "desc_pc_hi20";
145
case VK_LoongArch_TLS_DESC_PC_LO12:
146
return "desc_pc_lo12";
147
case VK_LoongArch_TLS_DESC64_PC_LO20:
148
return "desc64_pc_lo20";
149
case VK_LoongArch_TLS_DESC64_PC_HI12:
150
return "desc64_pc_hi12";
151
case VK_LoongArch_TLS_DESC_HI20:
152
return "desc_hi20";
153
case VK_LoongArch_TLS_DESC_LO12:
154
return "desc_lo12";
155
case VK_LoongArch_TLS_DESC64_LO20:
156
return "desc64_lo20";
157
case VK_LoongArch_TLS_DESC64_HI12:
158
return "desc64_hi12";
159
case VK_LoongArch_TLS_DESC_LD:
160
return "desc_ld";
161
case VK_LoongArch_TLS_DESC_CALL:
162
return "desc_call";
163
case VK_LoongArch_TLS_LE_HI20_R:
164
return "le_hi20_r";
165
case VK_LoongArch_TLS_LE_ADD_R:
166
return "le_add_r";
167
case VK_LoongArch_TLS_LE_LO12_R:
168
return "le_lo12_r";
169
case VK_LoongArch_PCREL20_S2:
170
return "pcrel_20";
171
case VK_LoongArch_TLS_LD_PCREL20_S2:
172
return "ld_pcrel_20";
173
case VK_LoongArch_TLS_GD_PCREL20_S2:
174
return "gd_pcrel_20";
175
case VK_LoongArch_TLS_DESC_PCREL20_S2:
176
return "desc_pcrel_20";
177
}
178
}
179
180
LoongArchMCExpr::VariantKind
181
LoongArchMCExpr::getVariantKindForName(StringRef name) {
182
return StringSwitch<LoongArchMCExpr::VariantKind>(name)
183
.Case("plt", VK_LoongArch_CALL_PLT)
184
.Case("b16", VK_LoongArch_B16)
185
.Case("b21", VK_LoongArch_B21)
186
.Case("b26", VK_LoongArch_B26)
187
.Case("abs_hi20", VK_LoongArch_ABS_HI20)
188
.Case("abs_lo12", VK_LoongArch_ABS_LO12)
189
.Case("abs64_lo20", VK_LoongArch_ABS64_LO20)
190
.Case("abs64_hi12", VK_LoongArch_ABS64_HI12)
191
.Case("pc_hi20", VK_LoongArch_PCALA_HI20)
192
.Case("pc_lo12", VK_LoongArch_PCALA_LO12)
193
.Case("pc64_lo20", VK_LoongArch_PCALA64_LO20)
194
.Case("pc64_hi12", VK_LoongArch_PCALA64_HI12)
195
.Case("got_pc_hi20", VK_LoongArch_GOT_PC_HI20)
196
.Case("got_pc_lo12", VK_LoongArch_GOT_PC_LO12)
197
.Case("got64_pc_lo20", VK_LoongArch_GOT64_PC_LO20)
198
.Case("got64_pc_hi12", VK_LoongArch_GOT64_PC_HI12)
199
.Case("got_hi20", VK_LoongArch_GOT_HI20)
200
.Case("got_lo12", VK_LoongArch_GOT_LO12)
201
.Case("got64_lo20", VK_LoongArch_GOT64_LO20)
202
.Case("got64_hi12", VK_LoongArch_GOT64_HI12)
203
.Case("le_hi20", VK_LoongArch_TLS_LE_HI20)
204
.Case("le_lo12", VK_LoongArch_TLS_LE_LO12)
205
.Case("le64_lo20", VK_LoongArch_TLS_LE64_LO20)
206
.Case("le64_hi12", VK_LoongArch_TLS_LE64_HI12)
207
.Case("ie_pc_hi20", VK_LoongArch_TLS_IE_PC_HI20)
208
.Case("ie_pc_lo12", VK_LoongArch_TLS_IE_PC_LO12)
209
.Case("ie64_pc_lo20", VK_LoongArch_TLS_IE64_PC_LO20)
210
.Case("ie64_pc_hi12", VK_LoongArch_TLS_IE64_PC_HI12)
211
.Case("ie_hi20", VK_LoongArch_TLS_IE_HI20)
212
.Case("ie_lo12", VK_LoongArch_TLS_IE_LO12)
213
.Case("ie64_lo20", VK_LoongArch_TLS_IE64_LO20)
214
.Case("ie64_hi12", VK_LoongArch_TLS_IE64_HI12)
215
.Case("ld_pc_hi20", VK_LoongArch_TLS_LD_PC_HI20)
216
.Case("ld_hi20", VK_LoongArch_TLS_LD_HI20)
217
.Case("gd_pc_hi20", VK_LoongArch_TLS_GD_PC_HI20)
218
.Case("gd_hi20", VK_LoongArch_TLS_GD_HI20)
219
.Case("call36", VK_LoongArch_CALL36)
220
.Case("desc_pc_hi20", VK_LoongArch_TLS_DESC_PC_HI20)
221
.Case("desc_pc_lo12", VK_LoongArch_TLS_DESC_PC_LO12)
222
.Case("desc64_pc_lo20", VK_LoongArch_TLS_DESC64_PC_LO20)
223
.Case("desc64_pc_hi12", VK_LoongArch_TLS_DESC64_PC_HI12)
224
.Case("desc_hi20", VK_LoongArch_TLS_DESC_HI20)
225
.Case("desc_lo12", VK_LoongArch_TLS_DESC_LO12)
226
.Case("desc64_lo20", VK_LoongArch_TLS_DESC64_LO20)
227
.Case("desc64_hi12", VK_LoongArch_TLS_DESC64_HI12)
228
.Case("desc_ld", VK_LoongArch_TLS_DESC_LD)
229
.Case("desc_call", VK_LoongArch_TLS_DESC_CALL)
230
.Case("le_hi20_r", VK_LoongArch_TLS_LE_HI20_R)
231
.Case("le_add_r", VK_LoongArch_TLS_LE_ADD_R)
232
.Case("le_lo12_r", VK_LoongArch_TLS_LE_LO12_R)
233
.Case("pcrel_20", VK_LoongArch_PCREL20_S2)
234
.Case("ld_pcrel_20", VK_LoongArch_TLS_LD_PCREL20_S2)
235
.Case("gd_pcrel_20", VK_LoongArch_TLS_GD_PCREL20_S2)
236
.Case("desc_pcrel_20", VK_LoongArch_TLS_DESC_PCREL20_S2)
237
.Default(VK_LoongArch_Invalid);
238
}
239
240
static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
241
switch (Expr->getKind()) {
242
case MCExpr::Target:
243
llvm_unreachable("Can't handle nested target expression");
244
break;
245
case MCExpr::Constant:
246
break;
247
case MCExpr::Unary:
248
fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
249
break;
250
case MCExpr::Binary: {
251
const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
252
fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);
253
fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);
254
break;
255
}
256
case MCExpr::SymbolRef: {
257
// We're known to be under a TLS fixup, so any symbol should be
258
// modified. There should be only one.
259
const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
260
cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
261
break;
262
}
263
}
264
}
265
266
void LoongArchMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
267
switch (getKind()) {
268
default:
269
return;
270
case VK_LoongArch_TLS_LE_HI20:
271
case VK_LoongArch_TLS_IE_PC_HI20:
272
case VK_LoongArch_TLS_IE_HI20:
273
case VK_LoongArch_TLS_LD_PC_HI20:
274
case VK_LoongArch_TLS_LD_HI20:
275
case VK_LoongArch_TLS_GD_PC_HI20:
276
case VK_LoongArch_TLS_GD_HI20:
277
case VK_LoongArch_TLS_DESC_PC_HI20:
278
case VK_LoongArch_TLS_DESC_HI20:
279
case VK_LoongArch_TLS_LD_PCREL20_S2:
280
case VK_LoongArch_TLS_GD_PCREL20_S2:
281
case VK_LoongArch_TLS_DESC_PCREL20_S2:
282
break;
283
}
284
fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
285
}
286
287