|
4 | 4 | pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuContext"))
|
5 | 5 | root.debug.CpuContext
|
6 | 6 | else switch (native_arch) {
|
| 7 | + .aarch64, .aarch64_be => Aarch64, |
| 8 | + .arm, .armeb, .thumb, .thumbeb => Arm, |
| 9 | + .loongarch32, .loongarch64 => LoongArch, |
7 | 10 | .x86 => X86,
|
8 | 11 | .x86_64 => X86_64,
|
9 |
| - .arm, .armeb, .thumb, .thumbeb => Arm, |
10 |
| - .aarch64, .aarch64_be => Aarch64, |
11 | 12 | else => noreturn,
|
12 | 13 | };
|
13 | 14 |
|
@@ -173,6 +174,13 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
|
173 | 174 | },
|
174 | 175 | else => null,
|
175 | 176 | },
|
| 177 | + .loongarch64 => switch (builtin.os.tag) { |
| 178 | + .linux => .{ |
| 179 | + .r = uc.mcontext.regs, // includes r0 (hardwired zero) |
| 180 | + .pc = uc.mcontext.pc, |
| 181 | + }, |
| 182 | + else => null, |
| 183 | + }, |
176 | 184 | else => null,
|
177 | 185 | };
|
178 | 186 | }
|
@@ -465,6 +473,104 @@ pub const Aarch64 = extern struct {
|
465 | 473 | }
|
466 | 474 | };
|
467 | 475 |
|
| 476 | +/// This is an `extern struct` so that inline assembly in `current` can use field offsets. |
| 477 | +pub const LoongArch = extern struct { |
| 478 | + /// The numbered general-purpose registers r0 - r31. r0 must be zero. |
| 479 | + r: [32]usize, |
| 480 | + pc: usize, |
| 481 | + |
| 482 | + pub inline fn current() LoongArch { |
| 483 | + var ctx: LoongArch = undefined; |
| 484 | + asm volatile (if (@sizeOf(usize) == 8) |
| 485 | + \\ st.d $zero, $t0, 0 |
| 486 | + \\ st.d $ra, $t0, 8 |
| 487 | + \\ st.d $tp, $t0, 16 |
| 488 | + \\ st.d $sp, $t0, 24 |
| 489 | + \\ st.d $a0, $t0, 32 |
| 490 | + \\ st.d $a1, $t0, 40 |
| 491 | + \\ st.d $a2, $t0, 48 |
| 492 | + \\ st.d $a3, $t0, 56 |
| 493 | + \\ st.d $a4, $t0, 64 |
| 494 | + \\ st.d $a5, $t0, 72 |
| 495 | + \\ st.d $a6, $t0, 80 |
| 496 | + \\ st.d $a7, $t0, 88 |
| 497 | + \\ st.d $t0, $t0, 96 |
| 498 | + \\ st.d $t1, $t0, 104 |
| 499 | + \\ st.d $t2, $t0, 112 |
| 500 | + \\ st.d $t3, $t0, 120 |
| 501 | + \\ st.d $t4, $t0, 128 |
| 502 | + \\ st.d $t5, $t0, 136 |
| 503 | + \\ st.d $t6, $t0, 144 |
| 504 | + \\ st.d $t7, $t0, 152 |
| 505 | + \\ st.d $t8, $t0, 160 |
| 506 | + \\ st.d $r21, $t0, 168 |
| 507 | + \\ st.d $fp, $t0, 176 |
| 508 | + \\ st.d $s0, $t0, 184 |
| 509 | + \\ st.d $s1, $t0, 192 |
| 510 | + \\ st.d $s2, $t0, 200 |
| 511 | + \\ st.d $s3, $t0, 208 |
| 512 | + \\ st.d $s4, $t0, 216 |
| 513 | + \\ st.d $s5, $t0, 224 |
| 514 | + \\ st.d $s6, $t0, 232 |
| 515 | + \\ st.d $s7, $t0, 240 |
| 516 | + \\ st.d $s8, $t0, 248 |
| 517 | + \\ bl 1f |
| 518 | + \\1: |
| 519 | + \\ st.d $ra, $t0, 256 |
| 520 | + \\ ld.d $ra, $t0, 8 |
| 521 | + else |
| 522 | + \\ st.w $zero, $t0, 0 |
| 523 | + \\ st.w $ra, $t0, 4 |
| 524 | + \\ st.w $tp, $t0, 8 |
| 525 | + \\ st.w $sp, $t0, 12 |
| 526 | + \\ st.w $a0, $t0, 16 |
| 527 | + \\ st.w $a1, $t0, 20 |
| 528 | + \\ st.w $a2, $t0, 24 |
| 529 | + \\ st.w $a3, $t0, 28 |
| 530 | + \\ st.w $a4, $t0, 32 |
| 531 | + \\ st.w $a5, $t0, 36 |
| 532 | + \\ st.w $a6, $t0, 40 |
| 533 | + \\ st.w $a7, $t0, 44 |
| 534 | + \\ st.w $t0, $t0, 48 |
| 535 | + \\ st.w $t1, $t0, 52 |
| 536 | + \\ st.w $t2, $t0, 56 |
| 537 | + \\ st.w $t3, $t0, 60 |
| 538 | + \\ st.w $t4, $t0, 64 |
| 539 | + \\ st.w $t5, $t0, 68 |
| 540 | + \\ st.w $t6, $t0, 72 |
| 541 | + \\ st.w $t7, $t0, 76 |
| 542 | + \\ st.w $t8, $t0, 80 |
| 543 | + \\ st.w $r21, $t0, 84 |
| 544 | + \\ st.w $fp, $t0, 88 |
| 545 | + \\ st.w $s0, $t0, 92 |
| 546 | + \\ st.w $s1, $t0, 96 |
| 547 | + \\ st.w $s2, $t0, 100 |
| 548 | + \\ st.w $s3, $t0, 104 |
| 549 | + \\ st.w $s4, $t0, 108 |
| 550 | + \\ st.w $s5, $t0, 112 |
| 551 | + \\ st.w $s6, $t0, 116 |
| 552 | + \\ st.w $s7, $t0, 120 |
| 553 | + \\ st.w $s8, $t0, 124 |
| 554 | + \\ bl 1f |
| 555 | + \\1: |
| 556 | + \\ st.w $ra, $t0, 128 |
| 557 | + \\ ld.w $ra, $t0, 4 |
| 558 | + : |
| 559 | + : [gprs] "{$r12}" (&ctx), |
| 560 | + : .{ .memory = true }); |
| 561 | + return ctx; |
| 562 | + } |
| 563 | + |
| 564 | + pub fn dwarfRegisterBytes(ctx: *LoongArch, register_num: u16) DwarfRegisterError![]u8 { |
| 565 | + switch (register_num) { |
| 566 | + 0...31 => return @ptrCast(&ctx.r[register_num]), |
| 567 | + 32 => return @ptrCast(&ctx.pc), |
| 568 | + |
| 569 | + else => return error.InvalidRegister, |
| 570 | + } |
| 571 | + } |
| 572 | +}; |
| 573 | + |
468 | 574 | const signal_ucontext_t = switch (native_os) {
|
469 | 575 | .linux => std.os.linux.ucontext_t,
|
470 | 576 | .emscripten => std.os.emscripten.ucontext_t,
|
|
0 commit comments