| ... | @@ -6,6 +6,7 @@ pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuCont | ... | @@ -6,6 +6,7 @@ pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuCont |
| 6 | else switch (native_arch) { | 6 | else switch (native_arch) { |
| 7 | .aarch64, .aarch64_be => Aarch64, | 7 | .aarch64, .aarch64_be => Aarch64, |
| 8 | .arm, .armeb, .thumb, .thumbeb => Arm, | 8 | .arm, .armeb, .thumb, .thumbeb => Arm, |
| | 9 | .hexagon => Hexagon, |
| 9 | .loongarch32, .loongarch64 => LoongArch, | 10 | .loongarch32, .loongarch64 => LoongArch, |
| 10 | .riscv32, .riscv32be, .riscv64, .riscv64be => Riscv, | 11 | .riscv32, .riscv32be, .riscv64, .riscv64be => Riscv, |
| 11 | .s390x => S390x, | 12 | .s390x => S390x, |
| ... | @@ -181,6 +182,13 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native { | ... | @@ -181,6 +182,13 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native { |
| 181 | }, | 182 | }, |
| 182 | else => null, | 183 | else => null, |
| 183 | }, | 184 | }, |
| | 185 | .hexagon => switch (builtin.os.tag) { |
| | 186 | .linux => .{ |
| | 187 | .r = uc.mcontext.gregs, |
| | 188 | .pc = uc.mcontext.pc, |
| | 189 | }, |
| | 190 | else => null, |
| | 191 | }, |
| 184 | .loongarch64 => switch (builtin.os.tag) { | 192 | .loongarch64 => switch (builtin.os.tag) { |
| 185 | .linux => .{ | 193 | .linux => .{ |
| 186 | .r = uc.mcontext.regs, // includes r0 (hardwired zero) | 194 | .r = uc.mcontext.regs, // includes r0 (hardwired zero) |
| ... | @@ -502,6 +510,74 @@ pub const Aarch64 = extern struct { | ... | @@ -502,6 +510,74 @@ pub const Aarch64 = extern struct { |
| 502 | } | 510 | } |
| 503 | }; | 511 | }; |
| 504 | | 512 | |
| | 513 | /// This is an `extern struct` so that inline assembly in `current` can use field offsets. |
| | 514 | pub const Hexagon = extern struct { |
| | 515 | /// The numbered general-purpose registers r0 - r31. |
| | 516 | r: [32]u32, |
| | 517 | pc: u32, |
| | 518 | |
| | 519 | pub inline fn current() Hexagon { |
| | 520 | var ctx: Hexagon = undefined; |
| | 521 | asm volatile ( |
| | 522 | \\ memw(r0 + #0) = r0 |
| | 523 | \\ memw(r0 + #4) = r1 |
| | 524 | \\ memw(r0 + #8) = r2 |
| | 525 | \\ memw(r0 + #12) = r3 |
| | 526 | \\ memw(r0 + #16) = r4 |
| | 527 | \\ memw(r0 + #20) = r5 |
| | 528 | \\ memw(r0 + #24) = r6 |
| | 529 | \\ memw(r0 + #28) = r7 |
| | 530 | \\ memw(r0 + #32) = r8 |
| | 531 | \\ memw(r0 + #36) = r9 |
| | 532 | \\ memw(r0 + #40) = r10 |
| | 533 | \\ memw(r0 + #44) = r11 |
| | 534 | \\ memw(r0 + #48) = r12 |
| | 535 | \\ memw(r0 + #52) = r13 |
| | 536 | \\ memw(r0 + #56) = r14 |
| | 537 | \\ memw(r0 + #60) = r15 |
| | 538 | \\ memw(r0 + #64) = r16 |
| | 539 | \\ memw(r0 + #68) = r17 |
| | 540 | \\ memw(r0 + #72) = r18 |
| | 541 | \\ memw(r0 + #76) = r19 |
| | 542 | \\ memw(r0 + #80) = r20 |
| | 543 | \\ memw(r0 + #84) = r21 |
| | 544 | \\ memw(r0 + #88) = r22 |
| | 545 | \\ memw(r0 + #92) = r23 |
| | 546 | \\ memw(r0 + #96) = r24 |
| | 547 | \\ memw(r0 + #100) = r25 |
| | 548 | \\ memw(r0 + #104) = r26 |
| | 549 | \\ memw(r0 + #108) = r27 |
| | 550 | \\ memw(r0 + #112) = r28 |
| | 551 | \\ memw(r0 + #116) = r29 |
| | 552 | \\ memw(r0 + #120) = r30 |
| | 553 | \\ memw(r0 + #124) = r31 |
| | 554 | \\ r1 = pc |
| | 555 | \\ memw(r0 + #128) = r1 |
| | 556 | \\ r1 = memw(r0 + #4) |
| | 557 | : |
| | 558 | : [gprs] "{r0}" (&ctx), |
| | 559 | : .{ .memory = true }); |
| | 560 | return ctx; |
| | 561 | } |
| | 562 | |
| | 563 | pub fn dwarfRegisterBytes(ctx: *Hexagon, register_num: u16) DwarfRegisterError![]u8 { |
| | 564 | // Sourced from LLVM's HexagonRegisterInfo.td, which disagrees with LLDB... |
| | 565 | switch (register_num) { |
| | 566 | 0...31 => return @ptrCast(&ctx.r[register_num]), |
| | 567 | 76 => return @ptrCast(&ctx.pc), |
| | 568 | |
| | 569 | // This is probably covering some numbers that aren't actually mapped, but seriously, |
| | 570 | // look at that file. I really can't be bothered to make it more precise. |
| | 571 | 32...75 => return error.UnsupportedRegister, |
| | 572 | 77...259 => return error.UnsupportedRegister, |
| | 573 | // 999999...1000030 => return error.UnsupportedRegister, |
| | 574 | // 9999999...10000030 => return error.UnsupportedRegister, |
| | 575 | |
| | 576 | else => return error.InvalidRegister, |
| | 577 | } |
| | 578 | } |
| | 579 | }; |
| | 580 | |
| 505 | /// This is an `extern struct` so that inline assembly in `current` can use field offsets. | 581 | /// This is an `extern struct` so that inline assembly in `current` can use field offsets. |
| 506 | pub const LoongArch = extern struct { | 582 | pub const LoongArch = extern struct { |
| 507 | /// The numbered general-purpose registers r0 - r31. r0 must be zero. | 583 | /// The numbered general-purpose registers r0 - r31. r0 must be zero. |