Stage 0: trap-frame parity across all 3 arches (FABRIC-3.md §XXVIII)
First stage of the preemptive context-switching plan (see ~/.claude/plans/logical-snuggling-bear.md). Pure foundation work -- every arch's ISR now saves the full register set on interrupt entry, so a trap frame is in principle sufficient to resume execution anywhere it was taken. No FORTH-visible behavior changes. amd64: added FXSAVE/FXRSTOR, closing a genuine pre-existing correctness gap (not just future-preemption prep) -- confirmed live double-precision FP code reachable from ordinary interpreter dispatch (vm_runtime.c Loop #5/#6), and the ISR previously saved zero FP/SSE state. rbp repurposed as a fixed anchor so the 16-byte-aligned FXSAVE area can be carved out of an unpredictably-aligned rsp without disturbing existing argument reads. aarch64: extended the trap frame 672->800 bytes, adding v8-v15 (AAPCS64 callee-saved, previously excluded on call-site-only reasoning that doesn't hold for an async trap). riscv64: extended the trap frame 320->512 bytes, adding s0-s11 and fs0-fs11 (the latter still correctly gated behind sstatus.FS != Off). All 3 architectures re-verified clean boot to ok> under the new frames -- amd64 through hundreds of timer ticks with FXSAVE/FXRSTOR live on every interrupt, aarch64 through 987 ticks, riscv64 clean on the now-larger FS-conditional block. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016UNhH1mhi52i6Qihh7ZV5S
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
2a30212bd3
commit
15672ce17c
@@ -75,20 +75,48 @@ isr_common_entry:
|
||||
* [rsp+152] = rflags
|
||||
*/
|
||||
|
||||
/* FABRIC-3.md SXXVIII (Stage 0, preemptive-context-switch trap-frame
|
||||
* parity, 2026-09-13): FXSAVE/FXRSTOR added here to close a real,
|
||||
* pre-existing gap, not just a future-preemption nicety -- confirmed
|
||||
* live double-precision FP code reachable from ordinary interpreter
|
||||
* dispatch (vm_runtime.c's Loop #5/#6 physics inference, called from
|
||||
* vm_tick() during word execution, not just at boot). The GPR pushes
|
||||
* above only cover integer state; on x86-64 SysV all XMM registers are
|
||||
* caller-saved, meaning the compiler is free to leave a live value in
|
||||
* one between any two instructions of straight-line code -- an
|
||||
* asynchronous interrupt is not a call site the interrupted code's own
|
||||
* instructions know about, so nothing here previously guaranteed FP
|
||||
* state actually survived a timer tick landing mid-computation.
|
||||
*
|
||||
* rbp is repurposed below as a fixed anchor pointing at "rsp right after
|
||||
* the 15 GPR pushes" (rbp's own true pushed value already lives safely
|
||||
* on the stack above and is restored by the ordinary `pop rbp` later) --
|
||||
* FXSAVE requires a 16-byte-aligned address and rsp's alignment here is
|
||||
* unpredictable (the interrupt could have landed anywhere), so the
|
||||
* FXSAVE area is carved out and aligned separately, with rbp used to
|
||||
* keep addressing everything else at its original, fixed offsets
|
||||
* regardless of that adjustment. */
|
||||
mov rbp, rsp
|
||||
sub rsp, 528 /* 512-byte FXSAVE area + 16 slack for alignment */
|
||||
and rsp, -16
|
||||
fxsave [rsp]
|
||||
|
||||
/* Set up arguments for isr_common_handler(vector, error, rip, cs, rflags, cr2) */
|
||||
mov rdi, [rsp + 120] /* vector */
|
||||
mov rsi, [rsp + 128] /* error */
|
||||
mov rdx, [rsp + 136] /* rip */
|
||||
mov rcx, [rsp + 144] /* cs */
|
||||
mov r8, [rsp + 152] /* rflags */
|
||||
mov rdi, [rbp + 120] /* vector */
|
||||
mov rsi, [rbp + 128] /* error */
|
||||
mov rdx, [rbp + 136] /* rip */
|
||||
mov rcx, [rbp + 144] /* cs */
|
||||
mov r8, [rbp + 152] /* rflags */
|
||||
mov r9, cr2 /* cr2 */
|
||||
|
||||
/* Pass stack frame pointer (after pushes) as 7th argument */
|
||||
mov rax, rsp
|
||||
push rax
|
||||
push rbp
|
||||
call isr_common_handler
|
||||
add rsp, 8
|
||||
|
||||
fxrstor [rsp]
|
||||
mov rsp, rbp /* collapse back to right after the GPR pushes */
|
||||
|
||||
/* Restore general-purpose registers */
|
||||
pop r15
|
||||
pop r14
|
||||
|
||||
Reference in New Issue
Block a user