zig/lib/std/Io/fiber.zig
David Rubin 8259d8d631 minimal
2026-02-20 05:34:54 +01:00

323 lines
8.7 KiB
Zig

pub const supported = switch (builtin.cpu.arch) {
.aarch64, .riscv64, .x86_64 => true,
else => false,
};
/// Stores the cpu state of an inactive fiber.
pub const Context = switch (builtin.cpu.arch) {
.aarch64 => extern struct {
sp: u64,
fp: u64,
pc: u64,
},
.riscv64 => extern struct {
sp: u64,
fp: u64,
pc: u64,
},
.x86_64 => extern struct {
rsp: u64,
rbp: u64,
rip: u64,
},
else => |arch| @compileError("unimplemented architecture: " ++ @tagName(arch)),
};
pub const Switch = extern struct { old: *Context, new: *Context };
/// Fills `s.old` with the current cpu state, and restores the cpu state stored in `s.new`.
pub inline fn contextSwitch(s: *const Switch) *const Switch {
return switch (builtin.cpu.arch) {
.aarch64 => asm volatile (
\\ ldp x0, x2, [x1]
\\ ldr x3, [x2, #16]
\\ mov x4, sp
\\ stp x4, fp, [x0]
\\ adr x5, 0f
\\ ldp x4, fp, [x2]
\\ str x5, [x0, #16]
\\ mov sp, x4
\\ br x3
\\0:
: [received_message] "={x1}" (-> *const Switch),
: [message_to_send] "{x1}" (s),
: .{
.x0 = true,
.x1 = true,
.x2 = true,
.x3 = true,
.x4 = true,
.x5 = true,
.x6 = true,
.x7 = true,
.x8 = true,
.x9 = true,
.x10 = true,
.x11 = true,
.x12 = true,
.x13 = true,
.x14 = true,
.x15 = true,
.x16 = true,
.x17 = true,
.x19 = true,
.x20 = true,
.x21 = true,
.x22 = true,
.x23 = true,
.x24 = true,
.x25 = true,
.x26 = true,
.x27 = true,
.x28 = true,
.x30 = true,
.z0 = true,
.z1 = true,
.z2 = true,
.z3 = true,
.z4 = true,
.z5 = true,
.z6 = true,
.z7 = true,
.z8 = true,
.z9 = true,
.z10 = true,
.z11 = true,
.z12 = true,
.z13 = true,
.z14 = true,
.z15 = true,
.z16 = true,
.z17 = true,
.z18 = true,
.z19 = true,
.z20 = true,
.z21 = true,
.z22 = true,
.z23 = true,
.z24 = true,
.z25 = true,
.z26 = true,
.z27 = true,
.z28 = true,
.z29 = true,
.z30 = true,
.z31 = true,
.p0 = true,
.p1 = true,
.p2 = true,
.p3 = true,
.p4 = true,
.p5 = true,
.p6 = true,
.p7 = true,
.p8 = true,
.p9 = true,
.p10 = true,
.p11 = true,
.p12 = true,
.p13 = true,
.p14 = true,
.p15 = true,
.fpcr = true,
.fpsr = true,
.ffr = true,
.memory = true,
}),
.riscv64 => asm volatile (
\\ ld a0, 0(a1)
\\ ld a2, 8(a1)
\\ lla a3, 0f
\\ sd sp, 0(a0)
\\ sd fp, 8(a0)
\\ sd a3, 16(a0)
\\ ld sp, 0(a2)
\\ ld fp, 8(a2)
\\ ld a3, 16(a2)
\\ jr a3
\\0:
: [received_message] "={a1}" (-> *const Switch),
: [message_to_send] "{a1}" (s),
: .{
.x1 = true,
.x3 = true,
.x4 = true,
.x5 = true,
.x6 = true,
.x7 = true,
.x9 = true,
.x10 = true,
.x11 = true,
.x12 = true,
.x13 = true,
.x14 = true,
.x15 = true,
.x16 = true,
.x17 = true,
.x18 = true,
.x19 = true,
.x20 = true,
.x21 = true,
.x22 = true,
.x23 = true,
.x24 = true,
.x25 = true,
.x26 = true,
.x27 = true,
.x28 = true,
.x29 = true,
.x30 = true,
.x31 = true,
.f0 = true,
.f1 = true,
.f2 = true,
.f3 = true,
.f4 = true,
.f5 = true,
.f6 = true,
.f7 = true,
.f8 = true,
.f9 = true,
.f10 = true,
.f11 = true,
.f12 = true,
.f13 = true,
.f14 = true,
.f15 = true,
.f16 = true,
.f17 = true,
.f18 = true,
.f19 = true,
.f20 = true,
.f21 = true,
.f22 = true,
.f23 = true,
.f24 = true,
.f25 = true,
.f26 = true,
.f27 = true,
.f28 = true,
.f29 = true,
.f30 = true,
.f31 = true,
.v0 = true,
.v1 = true,
.v2 = true,
.v3 = true,
.v4 = true,
.v5 = true,
.v6 = true,
.v7 = true,
.v8 = true,
.v9 = true,
.v10 = true,
.v11 = true,
.v12 = true,
.v13 = true,
.v14 = true,
.v15 = true,
.v16 = true,
.v17 = true,
.v18 = true,
.v19 = true,
.v20 = true,
.v21 = true,
.v22 = true,
.v23 = true,
.v24 = true,
.v25 = true,
.v26 = true,
.v27 = true,
.v28 = true,
.v29 = true,
.v30 = true,
.v31 = true,
.vtype = true,
.vl = true,
.vxsat = true,
.vxrm = true,
.vcsr = true,
.fflags = true,
.frm = true,
.memory = true,
}),
.x86_64 => asm volatile (
\\ movq 0(%%rsi), %%rax
\\ movq 8(%%rsi), %%rcx
\\ leaq 0f(%%rip), %%rdx
\\ movq %%rsp, 0(%%rax)
\\ movq %%rbp, 8(%%rax)
\\ movq %%rdx, 16(%%rax)
\\ movq 0(%%rcx), %%rsp
\\ movq 8(%%rcx), %%rbp
\\ jmpq *16(%%rcx)
\\0:
: [received_message] "={rsi}" (-> *const Switch),
: [message_to_send] "{rsi}" (s),
: .{
.rax = true,
.rcx = true,
.rdx = true,
.rbx = true,
.rsi = true,
.rdi = true,
.r8 = true,
.r9 = true,
.r10 = true,
.r11 = true,
.r12 = true,
.r13 = true,
.r14 = true,
.r15 = true,
.mm0 = true,
.mm1 = true,
.mm2 = true,
.mm3 = true,
.mm4 = true,
.mm5 = true,
.mm6 = true,
.mm7 = true,
.zmm0 = true,
.zmm1 = true,
.zmm2 = true,
.zmm3 = true,
.zmm4 = true,
.zmm5 = true,
.zmm6 = true,
.zmm7 = true,
.zmm8 = true,
.zmm9 = true,
.zmm10 = true,
.zmm11 = true,
.zmm12 = true,
.zmm13 = true,
.zmm14 = true,
.zmm15 = true,
.zmm16 = true,
.zmm17 = true,
.zmm18 = true,
.zmm19 = true,
.zmm20 = true,
.zmm21 = true,
.zmm22 = true,
.zmm23 = true,
.zmm24 = true,
.zmm25 = true,
.zmm26 = true,
.zmm27 = true,
.zmm28 = true,
.zmm29 = true,
.zmm30 = true,
.zmm31 = true,
.fpsr = true,
.fpcr = true,
.mxcsr = true,
.rflags = true,
.dirflag = true,
.memory = true,
}),
else => |arch| @compileError("unimplemented architecture: " ++ @tagName(arch)),
};
}
const builtin = @import("builtin");