| ... | @@ -8,6 +8,7 @@ else switch (native_arch) { | ... | @@ -8,6 +8,7 @@ else switch (native_arch) { |
| 8 | .arm, .armeb, .thumb, .thumbeb => Arm, | 8 | .arm, .armeb, .thumb, .thumbeb => Arm, |
| 9 | .hexagon => Hexagon, | 9 | .hexagon => Hexagon, |
| 10 | .loongarch32, .loongarch64 => LoongArch, | 10 | .loongarch32, .loongarch64 => LoongArch, |
| | 11 | .mips, .mipsel, .mips64, .mips64el => Mips, |
| 11 | .riscv32, .riscv32be, .riscv64, .riscv64be => Riscv, | 12 | .riscv32, .riscv32be, .riscv64, .riscv64be => Riscv, |
| 12 | .s390x => S390x, | 13 | .s390x => S390x, |
| 13 | .x86 => X86, | 14 | .x86 => X86, |
| ... | @@ -196,6 +197,25 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native { | ... | @@ -196,6 +197,25 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native { |
| 196 | }, | 197 | }, |
| 197 | else => null, | 198 | else => null, |
| 198 | }, | 199 | }, |
| | 200 | .mips, .mipsel => switch (builtin.os.tag) { |
| | 201 | // The O32 kABI uses 64-bit fields for some reason... |
| | 202 | .linux => .{ |
| | 203 | .r = s: { |
| | 204 | var regs: [32]Mips.Gpr = undefined; |
| | 205 | for (uc.mcontext.regs, 0..) |r, i| regs[i] = @truncate(r); // includes r0 (hardwired zero) |
| | 206 | break :s regs; |
| | 207 | }, |
| | 208 | .pc = @truncate(uc.mcontext.pc), |
| | 209 | }, |
| | 210 | else => null, |
| | 211 | }, |
| | 212 | .mips64, .mips64el => switch (builtin.os.tag) { |
| | 213 | .linux => .{ |
| | 214 | .r = uc.mcontext.regs, // includes r0 (hardwired zero) |
| | 215 | .pc = uc.mcontext.pc, |
| | 216 | }, |
| | 217 | else => null, |
| | 218 | }, |
| 199 | .riscv32, .riscv64 => switch (builtin.os.tag) { | 219 | .riscv32, .riscv64 => switch (builtin.os.tag) { |
| 200 | .linux => .{ | 220 | .linux => .{ |
| 201 | .r = [1]usize{0} ++ uc.mcontext.gregs[1..].*, // r0 position is used for pc; replace with zero | 221 | .r = [1]usize{0} ++ uc.mcontext.gregs[1..].*, // r0 position is used for pc; replace with zero |
| ... | @@ -678,6 +698,116 @@ pub const LoongArch = extern struct { | ... | @@ -678,6 +698,116 @@ pub const LoongArch = extern struct { |
| 678 | } | 698 | } |
| 679 | }; | 699 | }; |
| 680 | | 700 | |
| | 701 | /// This is an `extern struct` so that inline assembly in `current` can use field offsets. |
| | 702 | pub const Mips = extern struct { |
| | 703 | /// The numbered general-purpose registers r0 - r31. r0 must be zero. |
| | 704 | r: [32]Gpr, |
| | 705 | pc: Gpr, |
| | 706 | |
| | 707 | pub const Gpr = if (builtin.target.cpu.arch.isMIPS64()) u64 else u32; |
| | 708 | |
| | 709 | pub inline fn current() Mips { |
| | 710 | var ctx: Mips = undefined; |
| | 711 | asm volatile (if (Gpr == u64) |
| | 712 | \\ .set push |
| | 713 | \\ .set noat |
| | 714 | \\ .set noreorder |
| | 715 | \\ .set nomacro |
| | 716 | \\ sd $zero, 0($t0) |
| | 717 | \\ sd $at, 8($t0) |
| | 718 | \\ sd $v0, 16($t0) |
| | 719 | \\ sd $v1, 24($t0) |
| | 720 | \\ sd $a0, 32($t0) |
| | 721 | \\ sd $a1, 40($t0) |
| | 722 | \\ sd $a2, 48($t0) |
| | 723 | \\ sd $a3, 56($t0) |
| | 724 | \\ sd $a4, 64($t0) |
| | 725 | \\ sd $a5, 72($t0) |
| | 726 | \\ sd $a6, 80($t0) |
| | 727 | \\ sd $a7, 88($t0) |
| | 728 | \\ sd $t0, 96($t0) |
| | 729 | \\ sd $t1, 104($t0) |
| | 730 | \\ sd $t2, 112($t0) |
| | 731 | \\ sd $t3, 120($t0) |
| | 732 | \\ sd $s0, 128($t0) |
| | 733 | \\ sd $s1, 136($t0) |
| | 734 | \\ sd $s2, 144($t0) |
| | 735 | \\ sd $s3, 152($t0) |
| | 736 | \\ sd $s4, 160($t0) |
| | 737 | \\ sd $s5, 168($t0) |
| | 738 | \\ sd $s6, 176($t0) |
| | 739 | \\ sd $s7, 184($t0) |
| | 740 | \\ sd $t8, 192($t0) |
| | 741 | \\ sd $t9, 200($t0) |
| | 742 | \\ sd $k0, 208($t0) |
| | 743 | \\ sd $k1, 216($t0) |
| | 744 | \\ sd $gp, 224($t0) |
| | 745 | \\ sd $sp, 232($t0) |
| | 746 | \\ sd $fp, 240($t0) |
| | 747 | \\ sd $ra, 248($t0) |
| | 748 | \\ bal 1f |
| | 749 | \\1: |
| | 750 | \\ sd $ra, 256($t0) |
| | 751 | \\ ld $ra, 248($t0) |
| | 752 | \\ .set pop |
| | 753 | else |
| | 754 | \\ .set push |
| | 755 | \\ .set noat |
| | 756 | \\ .set noreorder |
| | 757 | \\ .set nomacro |
| | 758 | \\ sw $zero, 0($t4) |
| | 759 | \\ sw $at, 4($t4) |
| | 760 | \\ sw $v0, 8($t4) |
| | 761 | \\ sw $v1, 12($t4) |
| | 762 | \\ sw $a0, 16($t4) |
| | 763 | \\ sw $a1, 20($t4) |
| | 764 | \\ sw $a2, 24($t4) |
| | 765 | \\ sw $a3, 28($t4) |
| | 766 | \\ sw $t0, 32($t4) |
| | 767 | \\ sw $t1, 36($t4) |
| | 768 | \\ sw $t2, 40($t4) |
| | 769 | \\ sw $t3, 44($t4) |
| | 770 | \\ sw $t4, 48($t4) |
| | 771 | \\ sw $t5, 52($t4) |
| | 772 | \\ sw $t6, 56($t4) |
| | 773 | \\ sw $t7, 60($t4) |
| | 774 | \\ sw $s0, 64($t4) |
| | 775 | \\ sw $s1, 68($t4) |
| | 776 | \\ sw $s2, 72($t4) |
| | 777 | \\ sw $s3, 76($t4) |
| | 778 | \\ sw $s4, 80($t4) |
| | 779 | \\ sw $s5, 84($t4) |
| | 780 | \\ sw $s6, 88($t4) |
| | 781 | \\ sw $s7, 92($t4) |
| | 782 | \\ sw $t8, 96($t4) |
| | 783 | \\ sw $t9, 100($t4) |
| | 784 | \\ sw $k0, 104($t4) |
| | 785 | \\ sw $k1, 108($t4) |
| | 786 | \\ sw $gp, 112($t4) |
| | 787 | \\ sw $sp, 116($t4) |
| | 788 | \\ sw $fp, 120($t4) |
| | 789 | \\ sw $ra, 124($t4) |
| | 790 | \\ bal 1f |
| | 791 | \\1: |
| | 792 | \\ sw $ra, 128($t4) |
| | 793 | \\ lw $ra, 124($t4) |
| | 794 | \\ .set pop |
| | 795 | : |
| | 796 | : [gprs] "{$12}" (&ctx), |
| | 797 | : .{ .memory = true }); |
| | 798 | return ctx; |
| | 799 | } |
| | 800 | |
| | 801 | pub fn dwarfRegisterBytes(ctx: *Mips, register_num: u16) DwarfRegisterError![]u8 { |
| | 802 | switch (register_num) { |
| | 803 | 0...31 => return @ptrCast(&ctx.r[register_num]), |
| | 804 | 37 => return @ptrCast(&ctx.pc), |
| | 805 | |
| | 806 | else => return error.InvalidRegister, |
| | 807 | } |
| | 808 | } |
| | 809 | }; |
| | 810 | |
| 681 | /// This is an `extern struct` so that inline assembly in `current` can use field offsets. | 811 | /// This is an `extern struct` so that inline assembly in `current` can use field offsets. |
| 682 | pub const Riscv = extern struct { | 812 | pub const Riscv = extern struct { |
| 683 | /// The numbered general-purpose registers r0 - r31. r0 must be zero. | 813 | /// The numbered general-purpose registers r0 - r31. r0 must be zero. |