Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

X86_64

cpu_context.X86_64
const X86_64 = struct

File

lib/std/debug/cpu_context.zig:1837

Code

const X86_64 = struct {
    gprs: std.enums.EnumArray(GprName, Gpr),

    /// The order here intentionally matches the order of the DWARF register mappings. It's unclear
    /// where those mappings actually originated from---the ordering of the first 4 registers seems
    /// quite unusual---but it is currently convenient for us to match DWARF.
    pub const GprName = enum {
        // zig fmt: off
        rax, rdx, rcx, rbx,
        rsi, rdi, rbp, rsp,
        r8,  r9,  r10, r11,
        r12, r13, r14, r15,
        rip,
        // zig fmt: on
    };
    pub const Gpr = u64;

    pub inline fn current() X86_64 {
        var ctx: X86_64 = undefined;
        asm volatile (
            \\ movq %%rax, 0x00(%%rdi)
            \\ movq %%rdx, 0x08(%%rdi)
            \\ movq %%rcx, 0x10(%%rdi)
            \\ movq %%rbx, 0x18(%%rdi)
            \\ movq %%rsi, 0x20(%%rdi)
            \\ movq %%rdi, 0x28(%%rdi)
            \\ movq %%rbp, 0x30(%%rdi)
            \\ movq %%rsp, 0x38(%%rdi)
            \\ movq %%r8,  0x40(%%rdi)
            \\ movq %%r9,  0x48(%%rdi)
            \\ movq %%r10, 0x50(%%rdi)
            \\ movq %%r11, 0x58(%%rdi)
            \\ movq %%r12, 0x60(%%rdi)
            \\ movq %%r13, 0x68(%%rdi)
            \\ movq %%r14, 0x70(%%rdi)
            \\ movq %%r15, 0x78(%%rdi)
            \\ leaq (%%rip), %%rax
            \\ movq %%rax, 0x80(%%rdi)
            :
            : [gprs] "{rdi}" (&ctx.gprs.values),
            : .{ .rax = true, .memory = true });
        return ctx;
    }

    pub fn getFp(ctx: *const X86_64) usize {
        // On x32, registers are 64 bits but `usize` is 32 bits.
        return @intCast(ctx.gprs.get(.rbp));
    }
    pub fn getPc(ctx: *const X86_64) usize {
        // On x32, registers are 64 bits but `usize` is 32 bits.
        return @intCast(ctx.gprs.get(.rip));
    }

    pub fn dwarfRegisterBytes(ctx: *X86_64, register_num: u16) DwarfRegisterError![]u8 {
        // System V Application Binary Interface AMD64 Architecture Processor Supplement
        //   ยง 3.6.2 "DWARF Register Number Mapping"
        switch (register_num) {
            // The order of `Gpr` intentionally matches DWARF's mappings.
            0...16 => return @ptrCast(&ctx.gprs.values[register_num]),

            17...32 => return error.UnsupportedRegister, // xmm0 - xmm15
            33...40 => return error.UnsupportedRegister, // st0 - st7
            41...48 => return error.UnsupportedRegister, // mm0 - mm7
            49 => return error.UnsupportedRegister, // rflags
            50...55 => return error.UnsupportedRegister, // es, cs, ss, ds, fs, gs
            58...59 => return error.UnsupportedRegister, // fs.base, gs.base
            62 => return error.UnsupportedRegister, // tr
            63 => return error.UnsupportedRegister, // ldtr
            64 => return error.UnsupportedRegister, // mxcsr
            65 => return error.UnsupportedRegister, // fcw
            66 => return error.UnsupportedRegister, // fsw
            67...82 => return error.UnsupportedRegister, // xmm16 - xmm31 (AVX-512)
            118...125 => return error.UnsupportedRegister, // k0 - k7 (AVX-512)
            130...145 => return error.UnsupportedRegister, // r16 - r31 (APX)

            else => return error.InvalidRegister,
        }
    }
}