| ... | ... | @@ -6,6 +6,7 @@ pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuCont |
| 6 | 6 | else switch (native_arch) { |
| 7 | 7 | .aarch64, .aarch64_be => Aarch64, |
| 8 | 8 | .arm, .armeb, .thumb, .thumbeb => Arm, |
| 9 | .hexagon => Hexagon, |
| 9 | 10 | .loongarch32, .loongarch64 => LoongArch, |
| 10 | 11 | .riscv32, .riscv32be, .riscv64, .riscv64be => Riscv, |
| 11 | 12 | .s390x => S390x, |
| ... | ... | @@ -181,6 +182,13 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native { |
| 181 | 182 | }, |
| 182 | 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 | 192 | .loongarch64 => switch (builtin.os.tag) { |
| 185 | 193 | .linux => .{ |
| 186 | 194 | .r = uc.mcontext.regs, // includes r0 (hardwired zero) |
| ... | ... | @@ -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 | 581 | /// This is an `extern struct` so that inline assembly in `current` can use field offsets. |
| 506 | 582 | pub const LoongArch = extern struct { |
| 507 | 583 | /// The numbered general-purpose registers r0 - r31. r0 must be zero. |