Skip to content
Merged
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `examples/basic.zig` and `examples/scheduler.zig`, runnable via
`zig build examples`.
- GitHub Actions CI building and testing on Linux and Windows (x86_64).
- Expanded test coverage: cross-platform FP control-state preservation, nested
fibers, deep-stack yields, many yields, local-variable integrity, interleaved
independent fibers, and allocation-failure cleanup.

### Fixed

- The SysV (Linux/BSD) context switch now preserves the MXCSR control bits and
the x87 control word across a switch, matching the Windows path and the SysV
ABI. Previously a fiber that changed the rounding mode or FP exception masks
could leak that state into whatever ran next.

### Removed

Expand Down
16 changes: 16 additions & 0 deletions src/arch/x86_64_sysv.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,17 @@ fn fiberSwapNaked() callconv(.naked) void {
\\ pushq %%r13
\\ pushq %%r14
\\ pushq %%r15
\\ // MXCSR (+0) and x87 control word (+8) in a 16-byte slot
\\ subq $16, %%rsp
\\ stmxcsr 0(%%rsp)
\\ fnstcw 8(%%rsp)
\\ // switch stacks
\\ movq %%rsp, (%%rdi)
\\ movq (%%rsi), %%rsp
\\ // restore MXCSR + x87 control word
\\ ldmxcsr 0(%%rsp)
\\ fldcw 8(%%rsp)
\\ addq $16, %%rsp
\\ popq %%r15
\\ popq %%r14
\\ popq %%r13
Expand Down Expand Up @@ -46,5 +55,12 @@ pub fn initStack(
@as(*usize, @ptrFromInt(sp)).* = 0;
}

// MXCSR (+0) / x87 control word (+8) 16-byte slot with defaults, matching
// the Windows layout so the first swap-in loads a sane FP environment.
sp -= @sizeOf(usize);
@as(*usize, @ptrFromInt(sp)).* = 0x0000037F; // x87 control word (slot+8)
sp -= @sizeOf(usize);
@as(*usize, @ptrFromInt(sp)).* = 0x00001F80; // MXCSR (slot+0)

return sp;
}
Loading
Loading