The design section-10.7 correctness gate the foundational switch owed: explicitly
scribble EVERY callee-saved register, switch, and verify each survived.
- Extended swap_context to the COMPLETE AAPCS64 callee-saved set: integer
x19-x28 + fp/lr + sp AND the FP regs d8-d15 (21-slot context). Per AAPCS64
6.1.2 only the low 64 bits of v8-v15 are callee-saved, so d8-d15 is exactly
sufficient; x18 is Apple's reserved platform register, untouched.
- naked scribble_verify(self_ctx, peer, base): loads a unique sentinel into all
18 callee-saved regs, bl swap_context to yield, and on resume counts the regs
that did not survive. Honors its own caller ABI via a 176-byte frame that
saves+restores the caller's callee-saved; base reloaded post-swap (x2 not
preserved); the original lr round-trips through the swap.
- The gate is a 2-fiber MUTUAL scribble (A and B scribble DISTINCT sentinels into
the same physical regs), so a value survives only if swap_context saved and
restored it. A lone fiber yielding to an idle peer would NOT exercise
preservation.
Locked by examples/1808-concurrency-fiber-switch-stress.sx (aarch64-pinned):
A/B mismatches: 0. Validity proven by negative controls: dropping the d8-d15
save/restore reports 8/8 mismatches (the FP regs); dropping x27/x28 reports 2/2.
Adversarial review (worker): no critical bugs — callee-saved set complete and
correct, all frame offsets / 16-alignment / the lr-sp dance verified against
AAPCS64. Applied its one recommendation: boot zeroes the FP ctx slots so a first
switch-to loads 0, not garbage, into d8-d15. Residual gaps (spec-correct for a
call-boundary swap, documented in the header): FPCR/FPSR/NZCV + TPIDR/TLS are not
swapped, fp=0 blocks unwind past a fiber trampoline — these matter at the N×M:1 /
signals stages, not the single-thread switch.
Suite green 734/0. Next: B1.3b (x86_64 sibling + mmap guard-page stacks).