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.

Sparc

This is an extern struct so that inline assembly in current can use field offsets.

cpu_context.Sparc
const Sparc = extern struct

File

lib/std/debug/cpu_context.zig:1514

Code

const Sparc = extern struct {
    g: [8]Gpr,
    o: [8]Gpr,
    l: [8]Gpr,
    i: [8]Gpr,
    pc: Gpr,

    pub const Gpr = if (native_arch == .sparc64) u64 else u32;

    pub inline fn current() Sparc {
        flushWindows();

        var ctx: Sparc = undefined;
        asm volatile (if (Gpr == u64)
                \\ stx %g0, [%l0 + 0]
                \\ stx %g1, [%l0 + 8]
                \\ stx %g2, [%l0 + 16]
                \\ stx %g3, [%l0 + 24]
                \\ stx %g4, [%l0 + 32]
                \\ stx %g5, [%l0 + 40]
                \\ stx %g6, [%l0 + 48]
                \\ stx %g7, [%l0 + 56]
                \\ stx %o0, [%l0 + 64]
                \\ stx %o1, [%l0 + 72]
                \\ stx %o2, [%l0 + 80]
                \\ stx %o3, [%l0 + 88]
                \\ stx %o4, [%l0 + 96]
                \\ stx %o5, [%l0 + 104]
                \\ stx %o6, [%l0 + 112]
                \\ stx %o7, [%l0 + 120]
                \\ stx %l0, [%l0 + 128]
                \\ stx %l1, [%l0 + 136]
                \\ stx %l2, [%l0 + 144]
                \\ stx %l3, [%l0 + 152]
                \\ stx %l4, [%l0 + 160]
                \\ stx %l5, [%l0 + 168]
                \\ stx %l6, [%l0 + 176]
                \\ stx %l7, [%l0 + 184]
                \\ stx %i0, [%l0 + 192]
                \\ stx %i1, [%l0 + 200]
                \\ stx %i2, [%l0 + 208]
                \\ stx %i3, [%l0 + 216]
                \\ stx %i4, [%l0 + 224]
                \\ stx %i5, [%l0 + 232]
                \\ stx %i6, [%l0 + 240]
                \\ stx %i7, [%l0 + 248]
                \\ call 1f
                \\1:
                \\ stx %o7, [%l0 + 256]
            else
                \\ std %g0, [%l0 + 0]
                \\ std %g2, [%l0 + 8]
                \\ std %g4, [%l0 + 16]
                \\ std %g6, [%l0 + 24]
                \\ std %o0, [%l0 + 32]
                \\ std %o2, [%l0 + 40]
                \\ std %o4, [%l0 + 48]
                \\ std %o6, [%l0 + 56]
                \\ std %l0, [%l0 + 64]
                \\ std %l2, [%l0 + 72]
                \\ std %l4, [%l0 + 80]
                \\ std %l6, [%l0 + 88]
                \\ std %i0, [%l0 + 96]
                \\ std %i2, [%l0 + 104]
                \\ std %i4, [%l0 + 112]
                \\ std %i6, [%l0 + 120]
                \\ call 1f
                \\1:
                \\ st %o7, [%l0 + 128]
            :
            : [ctx] "{l0}" (&ctx),
            : .{ .o7 = true, .memory = true });
        return ctx;
    }

    noinline fn flushWindows() void {
        // Flush all register windows except the current one (hence `noinline`). This ensures that
        // we actually see meaningful data on the stack when we walk the frame chain.
        if (comptime builtin.target.cpu.has(.sparc, .v9))
            asm volatile ("flushw" ::: .{ .memory = true })
        else
            asm volatile ("ta 3" ::: .{ .memory = true }); // ST_FLUSH_WINDOWS
    }

    pub fn getFp(ctx: *const Sparc) usize {
        return ctx.i[6];
    }
    pub fn getPc(ctx: *const Sparc) usize {
        return ctx.pc;
    }

    pub fn dwarfRegisterBytes(ctx: *Sparc, register_num: u16) DwarfRegisterError![]u8 {
        switch (register_num) {
            0...7 => return @ptrCast(&ctx.g[register_num]),
            8...15 => return @ptrCast(&ctx.o[register_num - 8]),
            16...23 => return @ptrCast(&ctx.l[register_num - 16]),
            24...31 => return @ptrCast(&ctx.i[register_num - 24]),
            32 => return @ptrCast(&ctx.pc),

            else => return error.InvalidRegister,
        }
    }
}