|
14 | 14 | #define LLVM_EXECUTIONENGINE_JITLINK_LOONGARCH_H
|
15 | 15 |
|
16 | 16 | #include "TableManager.h"
|
| 17 | +#include "llvm/ADT/StringExtras.h" |
17 | 18 | #include "llvm/ExecutionEngine/JITLink/JITLink.h"
|
18 | 19 | #include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h"
|
| 20 | +#include "llvm/Support/LEB128.h" |
19 | 21 |
|
20 | 22 | namespace llvm {
|
21 | 23 | namespace jitlink {
|
@@ -226,6 +228,90 @@ enum EdgeKind_loongarch : Edge::Kind {
|
226 | 228 | ///
|
227 | 229 | Call36PCRel,
|
228 | 230 |
|
| 231 | + /// low 6 bits label addition |
| 232 | + /// |
| 233 | + /// Fixup expression: |
| 234 | + /// Fixup <- (*{1}Fixup + (Target + Addend) & 0x3f) : int8 |
| 235 | + /// |
| 236 | + Add6, |
| 237 | + |
| 238 | + /// 8 bits label addition |
| 239 | + /// |
| 240 | + /// Fixup expression: |
| 241 | + /// Fixup <- (*{1}Fixup + Target + Addend) : int8 |
| 242 | + /// |
| 243 | + Add8, |
| 244 | + |
| 245 | + /// 16 bits label addition |
| 246 | + /// |
| 247 | + /// Fixup expression: |
| 248 | + /// Fixup <- (*{2}Fixup + Target + Addend) : int16 |
| 249 | + /// |
| 250 | + Add16, |
| 251 | + |
| 252 | + /// 32 bits label addition |
| 253 | + /// |
| 254 | + /// Fixup expression: |
| 255 | + /// Fixup <- (*{4}Fixup + Target + Addend) : int32 |
| 256 | + /// |
| 257 | + Add32, |
| 258 | + |
| 259 | + /// 64 bits label addition |
| 260 | + /// |
| 261 | + /// Fixup expression: |
| 262 | + /// Fixup <- (*{8}Fixup + Target + Addend) : int64 |
| 263 | + /// |
| 264 | + Add64, |
| 265 | + |
| 266 | + /// ULEB128 bits label addition |
| 267 | + /// |
| 268 | + /// Fixup expression: |
| 269 | + /// Fixup <- (Fixup + Target + Addend) : uleb128 |
| 270 | + /// |
| 271 | + AddUleb128, |
| 272 | + |
| 273 | + /// low 6 bits label subtraction |
| 274 | + /// |
| 275 | + /// Fixup expression: |
| 276 | + /// Fixup <- (*{1}Fixup - (Target + Addend) & 0x3f) : int8 |
| 277 | + /// |
| 278 | + Sub6, |
| 279 | + |
| 280 | + /// 8 bits label subtraction |
| 281 | + /// |
| 282 | + /// Fixup expression: |
| 283 | + /// Fixup <- (*{1}Fixup - Target - Addend) : int8 |
| 284 | + /// |
| 285 | + Sub8, |
| 286 | + |
| 287 | + /// 16 bits label subtraction |
| 288 | + /// |
| 289 | + /// Fixup expression: |
| 290 | + /// Fixup <- (*{2}Fixup - Target - Addend) : int16 |
| 291 | + /// |
| 292 | + Sub16, |
| 293 | + |
| 294 | + /// 32 bits label subtraction |
| 295 | + /// |
| 296 | + /// Fixup expression: |
| 297 | + /// Fixup <- (*{4}Fixup - Target - Addend) : int32 |
| 298 | + /// |
| 299 | + Sub32, |
| 300 | + |
| 301 | + /// 64 bits label subtraction |
| 302 | + /// |
| 303 | + /// Fixup expression: |
| 304 | + /// Fixup <- (*{8}Fixup - Target - Addend) : int64 |
| 305 | + /// |
| 306 | + Sub64, |
| 307 | + |
| 308 | + /// ULEB128 bits label subtraction |
| 309 | + /// |
| 310 | + /// Fixup expression: |
| 311 | + /// Fixup <- (Fixup - Target - Addend) : uleb128 |
| 312 | + /// |
| 313 | + SubUleb128, |
| 314 | + |
229 | 315 | /// Alignment requirement used by linker relaxation.
|
230 | 316 | ///
|
231 | 317 | /// Linker relaxation will use this to ensure all code sequences are properly
|
@@ -369,6 +455,100 @@ inline Error applyFixup(LinkGraph &G, Block &B, const Edge &E) {
|
369 | 455 | *(little32_t *)(FixupPtr + 4) = Jirl | Lo16;
|
370 | 456 | break;
|
371 | 457 | }
|
| 458 | + case Add6: { |
| 459 | + int64_t Value = *(reinterpret_cast<const int8_t *>(FixupPtr)); |
| 460 | + Value += ((TargetAddress + Addend) & 0x3f); |
| 461 | + *FixupPtr = (*FixupPtr & 0xc0) | (static_cast<int8_t>(Value) & 0x3f); |
| 462 | + break; |
| 463 | + } |
| 464 | + case Add8: { |
| 465 | + int64_t Value = |
| 466 | + TargetAddress + *(reinterpret_cast<const int8_t *>(FixupPtr)) + Addend; |
| 467 | + *FixupPtr = static_cast<int8_t>(Value); |
| 468 | + break; |
| 469 | + } |
| 470 | + case Add16: { |
| 471 | + int64_t Value = |
| 472 | + TargetAddress + support::endian::read16le(FixupPtr) + Addend; |
| 473 | + *(little16_t *)FixupPtr = static_cast<int16_t>(Value); |
| 474 | + break; |
| 475 | + } |
| 476 | + case Add32: { |
| 477 | + int64_t Value = |
| 478 | + TargetAddress + support::endian::read32le(FixupPtr) + Addend; |
| 479 | + *(little32_t *)FixupPtr = static_cast<int32_t>(Value); |
| 480 | + break; |
| 481 | + } |
| 482 | + case Add64: { |
| 483 | + int64_t Value = |
| 484 | + TargetAddress + support::endian::read64le(FixupPtr) + Addend; |
| 485 | + *(little64_t *)FixupPtr = static_cast<int64_t>(Value); |
| 486 | + break; |
| 487 | + } |
| 488 | + case AddUleb128: { |
| 489 | + const uint32_t Maxcount = 1 + 64 / 7; |
| 490 | + uint32_t Count; |
| 491 | + const char *Error = nullptr; |
| 492 | + uint64_t Orig = decodeULEB128((reinterpret_cast<const uint8_t *>(FixupPtr)), |
| 493 | + &Count, nullptr, &Error); |
| 494 | + |
| 495 | + if (Count > Maxcount || (Count == Maxcount && Error)) |
| 496 | + return make_error<JITLinkError>( |
| 497 | + "0x" + llvm::utohexstr(orc::ExecutorAddr(FixupAddress).getValue()) + |
| 498 | + ": extra space for uleb128"); |
| 499 | + |
| 500 | + uint64_t Mask = Count < Maxcount ? (1ULL << 7 * Count) - 1 : -1ULL; |
| 501 | + encodeULEB128((Orig + TargetAddress + Addend) & Mask, |
| 502 | + (reinterpret_cast<uint8_t *>(FixupPtr)), Count); |
| 503 | + break; |
| 504 | + } |
| 505 | + case Sub6: { |
| 506 | + int64_t Value = *(reinterpret_cast<const int8_t *>(FixupPtr)); |
| 507 | + Value -= ((TargetAddress + Addend) & 0x3f); |
| 508 | + *FixupPtr = (*FixupPtr & 0xc0) | (static_cast<int8_t>(Value) & 0x3f); |
| 509 | + break; |
| 510 | + } |
| 511 | + case Sub8: { |
| 512 | + int64_t Value = |
| 513 | + *(reinterpret_cast<const int8_t *>(FixupPtr)) - TargetAddress - Addend; |
| 514 | + *FixupPtr = static_cast<int8_t>(Value); |
| 515 | + break; |
| 516 | + } |
| 517 | + case Sub16: { |
| 518 | + int64_t Value = |
| 519 | + support::endian::read16le(FixupPtr) - TargetAddress - Addend; |
| 520 | + *(little16_t *)FixupPtr = static_cast<int16_t>(Value); |
| 521 | + break; |
| 522 | + } |
| 523 | + case Sub32: { |
| 524 | + int64_t Value = |
| 525 | + support::endian::read32le(FixupPtr) - TargetAddress - Addend; |
| 526 | + *(little32_t *)FixupPtr = static_cast<int32_t>(Value); |
| 527 | + break; |
| 528 | + } |
| 529 | + case Sub64: { |
| 530 | + int64_t Value = |
| 531 | + support::endian::read64le(FixupPtr) - TargetAddress - Addend; |
| 532 | + *(little64_t *)FixupPtr = static_cast<int64_t>(Value); |
| 533 | + break; |
| 534 | + } |
| 535 | + case SubUleb128: { |
| 536 | + const uint32_t Maxcount = 1 + 64 / 7; |
| 537 | + uint32_t Count; |
| 538 | + const char *Error = nullptr; |
| 539 | + uint64_t Orig = decodeULEB128((reinterpret_cast<const uint8_t *>(FixupPtr)), |
| 540 | + &Count, nullptr, &Error); |
| 541 | + |
| 542 | + if (Count > Maxcount || (Count == Maxcount && Error)) |
| 543 | + return make_error<JITLinkError>( |
| 544 | + "0x" + llvm::utohexstr(orc::ExecutorAddr(FixupAddress).getValue()) + |
| 545 | + ": extra space for uleb128"); |
| 546 | + |
| 547 | + uint64_t Mask = Count < Maxcount ? (1ULL << 7 * Count) - 1 : -1ULL; |
| 548 | + encodeULEB128((Orig - TargetAddress - Addend) & Mask, |
| 549 | + (reinterpret_cast<uint8_t *>(FixupPtr)), Count); |
| 550 | + break; |
| 551 | + } |
372 | 552 | case AlignRelaxable:
|
373 | 553 | // Ignore when the relaxation pass did not run
|
374 | 554 | break;
|
|
0 commit comments