LLVM: include/llvm/ExecutionEngine/JITLink/loongarch.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef LLVM_EXECUTIONENGINE_JITLINK_LOONGARCH_H
14#define LLVM_EXECUTIONENGINE_JITLINK_LOONGARCH_H
15
22
23namespace llvm {
26
27
29
30
31
32
33
35
36
37
38
39
40
41
42
43
44
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
112
113
114
115
116
117
118
119
120
121
122
123
125
126
127
128
129
130
131
132
133
134
135
136
138
139
140
141
142
143
144
145
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
163
164
165
166
167
168
169
170
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
231
232
233
234
235
236
238
239
240
241
242
243
245
246
247
248
249
250
252
253
254
255
256
257
259
260
261
262
263
264
266
267
268
269
270
271
273
274
275
276
277
278
280
281
282
283
284
285
287
288
289
290
291
292
294
295
296
297
298
299
301
302
303
304
305
306
308
309
310
311
312
313
315
316
317
318
319
320
322};
323
324
325
327
328
330 return Hi == 63 ? Val >> Lo : (Val & ((((uint64_t)1 << (Hi + 1)) - 1))) >> Lo;
331}
332
333
336
337 char *BlockWorkingMem = B.getAlreadyMutableContent().data();
338 char *FixupPtr = BlockWorkingMem + E.getOffset();
339 uint64_t FixupAddress = (B.getAddress() + E.getOffset()).getValue();
340 uint64_t TargetAddress = E.getTarget().getAddress().getValue();
341 int64_t Addend = E.getAddend();
342
343 switch (E.getKind()) {
345 *(ulittle64_t *)FixupPtr = TargetAddress + Addend;
346 break;
349 if (Value > std::numeric_limits<uint32_t>::max())
351 *(ulittle32_t *)FixupPtr = Value;
352 break;
353 }
355 int64_t Value = TargetAddress - FixupAddress + Addend;
356
359
362
363 uint32_t RawInstr = *(little32_t *)FixupPtr;
366 *(little32_t *)FixupPtr = RawInstr | Imm15_0;
367 break;
368 }
370 int64_t Value = TargetAddress - FixupAddress + Addend;
371
374
377
378 uint32_t RawInstr = *(little32_t *)FixupPtr;
382 *(little32_t *)FixupPtr = RawInstr | Imm15_0 | Imm20_16;
383 break;
384 }
386 int64_t Value = TargetAddress - FixupAddress + Addend;
387
390
393
394 uint32_t RawInstr = *(little32_t *)FixupPtr;
398 *(little32_t *)FixupPtr = RawInstr | Imm15_0 | Imm25_16;
399 break;
400 }
402 int64_t Value = TargetAddress - FixupAddress + Addend;
403
406 *(little32_t *)FixupPtr = Value;
407 break;
408 }
410 int64_t Value = FixupAddress - TargetAddress + Addend;
413 *(little32_t *)FixupPtr = Value;
414 break;
415 }
417 *(little64_t *)FixupPtr = TargetAddress - FixupAddress + Addend;
418 break;
423 uint64_t PCPage = FixupAddress & ~static_cast<uint64_t>(0xfff);
424
425 int64_t PageDelta = TargetPage - PCPage;
428
429 uint32_t RawInstr = *(little32_t *)FixupPtr;
431 *(little32_t *)FixupPtr = RawInstr | Imm31_12;
432 break;
433 }
435 uint64_t TargetOffset = (TargetAddress + Addend) & 0xfff;
436
437 uint32_t RawInstr = *(ulittle32_t *)FixupPtr;
438 uint32_t Imm11_0 = TargetOffset << 10;
439 *(ulittle32_t *)FixupPtr = RawInstr | Imm11_0;
440 break;
441 }
443 int64_t Value = TargetAddress - FixupAddress + Addend;
444
447
450
451 uint32_t Pcaddu18i = *(little32_t *)FixupPtr;
453 *(little32_t *)FixupPtr = Pcaddu18i | Hi20;
454 uint32_t Jirl = *(little32_t *)(FixupPtr + 4);
456 *(little32_t *)(FixupPtr + 4) = Jirl | Lo16;
457 break;
458 }
460 int64_t Value = *(reinterpret_cast<const int8_t *>(FixupPtr));
461 Value += ((TargetAddress + Addend) & 0x3f);
462 *FixupPtr = (*FixupPtr & 0xc0) | (static_cast<int8_t>(Value) & 0x3f);
463 break;
464 }
467 TargetAddress + *(reinterpret_cast<const int8_t *>(FixupPtr)) + Addend;
468 *FixupPtr = static_cast<int8_t>(Value);
469 break;
470 }
474 *(little16_t *)FixupPtr = static_cast<int16_t>(Value);
475 break;
476 }
480 *(little32_t *)FixupPtr = static_cast<int32_t>(Value);
481 break;
482 }
486 *(little64_t *)FixupPtr = static_cast<int64_t>(Value);
487 break;
488 }
490 const uint32_t Maxcount = 1 + 64 / 7;
492 const char *Error = nullptr;
495
499 ": extra space for uleb128");
500
502 encodeULEB128((Orig + TargetAddress + Addend) & Mask,
503 (reinterpret_cast<uint8_t *>(FixupPtr)), Count);
504 break;
505 }
507 int64_t Value = *(reinterpret_cast<const int8_t *>(FixupPtr));
508 Value -= ((TargetAddress + Addend) & 0x3f);
509 *FixupPtr = (*FixupPtr & 0xc0) | (static_cast<int8_t>(Value) & 0x3f);
510 break;
511 }
514 *(reinterpret_cast<const int8_t *>(FixupPtr)) - TargetAddress - Addend;
515 *FixupPtr = static_cast<int8_t>(Value);
516 break;
517 }
521 *(little16_t *)FixupPtr = static_cast<int16_t>(Value);
522 break;
523 }
527 *(little32_t *)FixupPtr = static_cast<int32_t>(Value);
528 break;
529 }
533 *(little64_t *)FixupPtr = static_cast<int64_t>(Value);
534 break;
535 }
537 const uint32_t Maxcount = 1 + 64 / 7;
539 const char *Error = nullptr;
542
546 ": extra space for uleb128");
547
549 encodeULEB128((Orig - TargetAddress - Addend) & Mask,
550 (reinterpret_cast<uint8_t *>(FixupPtr)), Count);
551 break;
552 }
554
555 break;
556 default:
558 "In graph " + G.getName() + ", section " + B.getSection().getName() +
560 }
561
563}
564
565
569 G.getPointerSize()};
570}
571
572
573
574
575
576
577
578
583 auto StubContent =
585 return {reinterpret_cast<const char *>(StubContent), StubEntrySize};
586}
587
588
589
590
591
592
593
594
595
596
598 Symbol *InitialTarget = nullptr,
599 uint64_t InitialAddend = 0) {
602 if (InitialTarget)
604 *InitialTarget, InitialAddend);
605 return G.addAnonymousSymbol(B, 0, G.getPointerSize(), false, false);
606}
607
608
609
612 Symbol &PointerSymbol) {
613 Block &StubContentBlock = G.createContentBlock(
615 StubContentBlock.addEdge(Page20, 0, PointerSymbol, 0);
617 return G.addAnonymousSymbol(StubContentBlock, 0, StubEntrySize, true, false);
618}
619
620
622public:
624
626 Edge::Kind KindToSet = Edge::Invalid;
627 switch (E.getKind()) {
630 break;
633 break;
634 default:
635 return false;
636 }
637 assert(KindToSet != Edge::Invalid &&
638 "Fell through switch, but no new kind to set");
640 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
641 << B->getFixupAddress(E) << " (" << B->getAddress() << " + "
642 << formatv("{0:x}", E.getOffset()) << ")\n";
643 });
644 E.setKind(KindToSet);
646 return true;
647 }
648
652
653private:
655 if (!GOTSection)
658 return *GOTSection;
659 }
660
661 Section *GOTSection = nullptr;
662};
663
664
666public:
668
670
673 .getTarget().isDefined()) {
675 dbgs() << " Fixing " << G.getEdgeKindName(E.getKind()) << " edge at "
676 << B->getFixupAddress(E) << " (" << B->getAddress() << " + "
677 << formatv("{0:x}", E.getOffset()) << ")\n";
678 });
680 return true;
681 }
682 return false;
683 }
684
689
690public:
697
700};
701
702}
703}
704}
705
706#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
StringRef - Represent a constant reference to a string, i.e.
Target - Wrapper for Target specific information.
LLVM Value Representation.
An Addressable with content and edges.
void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)
Add an edge to this block.
Represents fixups and constraints in the LinkGraph.
Represents an object file section.
A CRTP base for tables that are built on demand, e.g.
Symbol & getEntryForTarget(LinkGraph &G, Symbol &Target)
Global Offset Table Builder.
Definition loongarch.h:621
Symbol & createEntry(LinkGraph &G, Symbol &Target)
Definition loongarch.h:649
bool visitEdge(LinkGraph &G, Block *B, Edge &E)
Definition loongarch.h:625
static StringRef getSectionName()
Definition loongarch.h:623
static StringRef getSectionName()
Definition loongarch.h:669
PLTTableManager(GOTTableManager &GOT)
Definition loongarch.h:667
Section & getStubsSection(LinkGraph &G)
Definition loongarch.h:691
Symbol & createEntry(LinkGraph &G, Symbol &Target)
Definition loongarch.h:685
bool visitEdge(LinkGraph &G, Block *B, Edge &E)
Definition loongarch.h:671
Section * StubsSection
Definition loongarch.h:699
GOTTableManager & GOT
Definition loongarch.h:698
Represents an address in the executor process.
Definition loongarch.h:25
Symbol & createAnonymousPointerJumpStub(LinkGraph &G, Section &StubSection, Symbol &PointerSymbol)
Create a jump stub that jumps via the pointer at the given symbol and an anonymous symbol pointing to...
Definition loongarch.h:610
Symbol & createAnonymousPointer(LinkGraph &G, Section &PointerSection, Symbol *InitialTarget=nullptr, uint64_t InitialAddend=0)
Creates a new pointer block in the given section and returns an Anonymous symbol pointing to it.
Definition loongarch.h:597
ArrayRef< char > getStubBlockContent(LinkGraph &G)
Definition loongarch.h:582
LLVM_ABI const char * getEdgeKindName(Edge::Kind K)
Returns a string name for the given loongarch edge.
ArrayRef< char > getGOTEntryBlockContent(LinkGraph &G)
Definition loongarch.h:567
EdgeKind_loongarch
Represents loongarch fixups.
Definition loongarch.h:28
@ Branch16PCRel
A 16-bit PC-relative branch.
Definition loongarch.h:67
@ Add16
16 bits label addition
Definition loongarch.h:251
@ AddUleb128
ULEB128 bits label addition.
Definition loongarch.h:272
@ RequestGOTAndTransformToPage20
A GOT entry getter/constructor, transformed to Page20 pointing at the GOT entry for the original targ...
Definition loongarch.h:191
@ Sub16
16 bits label subtraction
Definition loongarch.h:293
@ NegDelta32
A 32-bit negative delta.
Definition loongarch.h:137
@ SubUleb128
ULEB128 bits label subtraction.
Definition loongarch.h:314
@ Sub8
8 bits label subtraction
Definition loongarch.h:286
@ PageOffset12
The 12-bit offset of the target within its page.
Definition loongarch.h:171
@ Sub32
32 bits label subtraction
Definition loongarch.h:300
@ Add64
64 bits label addition
Definition loongarch.h:265
@ Sub6
low 6 bits label subtraction
Definition loongarch.h:279
@ Add8
8 bits label addition
Definition loongarch.h:244
@ Delta32
A 32-bit delta.
Definition loongarch.h:124
@ Page20
The signed 20-bit delta from the fixup page to the page containing the target.
Definition loongarch.h:162
@ Pointer64
A plain 64-bit pointer value relocation.
Definition loongarch.h:34
@ Delta64
A 64-bit delta.
Definition loongarch.h:146
@ RequestGOTAndTransformToPageOffset12
A GOT entry getter/constructor, transformed to Pageoffset12 pointing at the GOT entry for the origina...
Definition loongarch.h:207
@ Call36PCRel
A 36-bit PC-relative call.
Definition loongarch.h:230
@ Add6
low 6 bits label addition
Definition loongarch.h:237
@ Branch21PCRel
A 21-bit PC-relative branch.
Definition loongarch.h:89
@ Branch26PCRel
A 26-bit PC-relative branch.
Definition loongarch.h:111
@ Add32
32 bits label addition
Definition loongarch.h:258
@ Pointer32
A plain 32-bit pointer value relocation.
Definition loongarch.h:45
@ AlignRelaxable
Alignment requirement used by linker relaxation.
Definition loongarch.h:321
@ Sub64
64 bits label subtraction
Definition loongarch.h:307
Error applyFixup(LinkGraph &G, Block &B, const Edge &E)
Apply fixup expression for edge to block content.
Definition loongarch.h:334
LLVM_ABI const uint8_t LA32StubContent[StubEntrySize]
LLVM_ABI const uint8_t LA64StubContent[StubEntrySize]
LLVM_ABI const char NullPointerContent[8]
loongarch null pointer content.
uint32_t extractBits(uint64_t Val, unsigned Hi, unsigned Lo)
Definition loongarch.h:329
constexpr size_t StubEntrySize
loongarch stub content.
Definition loongarch.h:579
LLVM_ABI Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B, const Edge &E)
Create an out of range error for the given edge in the given block.
LLVM_ABI Error makeAlignmentError(llvm::orc::ExecutorAddr Loc, uint64_t Value, int N, const Edge &E)
uint64_t read64le(const void *P)
uint16_t read16le(const void *P)
uint32_t read32le(const void *P)
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.