mixed_math_word_m_slash_mod() had the identical bug class already fixed
in M* (commit 9a09949): it reconstructed the dividend from
`(dhigh << 32) | (dlow & 0xFFFFFFFF)`, the same wrong "32-bit halves of a
64-bit value" assumption. Latent for small inputs (fits in 32 bits, so the
reconstruction coincidentally worked), confirmed genuinely broken for a
true wide double -- feeding M*'s own correct 10^24 output into it gave a
quotient/remainder wrong by many orders of magnitude and the wrong sign.
Unlike M*, this one can't just switch to __int128 -- __int128's own `/`/`%`
need libgcc's __udivti3/__umodti3 for 128-bit division, unavailable in
this freestanding, -nostdlib build (the exact constraint
src/starkernel/arch/amd64/timer.c's own doc comment already flagged:
__int128 multiply/shift-by-constant/compare/subtract all compile clean,
only division doesn't). Fixed instead with a hand-rolled unsigned
128-by-64-bit bit-serial (restoring) long division -- 128 iterations of
shift-by-1/compare/subtract only, all in the safe set. Operates on
magnitudes via unsigned negation from 0 (well-defined even for the
extreme negative edge); signs reapplied afterward matching the same C99
truncating-toward-zero convention the previous, narrower implementation
already used, unchanged.
Verified: rebuilt all three architectures, confirmed clean link with no
__udivti3/__umodti3 undefined-symbol errors. Booted and tested all three,
identical results: 1000000000000 1000000000000 M* SWAP 1000000 M/MOD ->
1000000000000000000 remainder 0 (exact division, the case that was wrong
by orders of magnitude before); three sign-combination cases all correct
(-+, +-, --), confirming sign handling survived the magnitude-only
rewrite. T15 (original small-input case) unaffected. Full 24-case
exerciser reran clean on all three, no regressions.
All bugs found by the std79 exerciser campaign, including this one found
while fixing another, are now closed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EXieurDfDSsDFdnSyusuWo
capsules/
FORTH personality files loaded by the VM at boot. A capsule is an immutable, content-addressed payload; its XXHash64 hash is its identity. Any mutation changes the hash and the birth protocol rejects the image.
Key files
| File | Type | Purpose |
|---|---|---|
init.4th |
(m) MAMA_INIT |
Default Mama VM personality — loaded at LBN 2048 |
ACL.4th |
user | Word-level ACL system; self-activating at boot |
zuse.4th |
user | Bootstrap superuser; loaded by ACL.4th |
doe.4th |
user | DoE workload words (EXEC-DOE) — opt-in |
init-0.4th … init-9.4th |
(p) |
Numbered personality variants |
init-l8-*.4th |
(p) |
L8 Jacquard mode variants (stable/volatile/diverse/temporal/transition/omni) |
hermes/init.4th |
(p) |
Hermes baby VM personality |
artemis/init.4th |
(p) |
Artemis baby VM personality |
Block namespace
Block ranges are shared across all loaded capsules — collisions cause silent word-definition overwrites.
| Range | Owner |
|---|---|
| 2048–2099 | init.4th |
| 2100–2199 | doe.4th |
| 3000–3999 | workload capsules |
| 4000+ | user-defined (ACL.4th, zuse.4th, …) |
Each block is limited to 1024 bytes. Verify with wc -c before committing.
See also
experiments/bare_metal/README.md— DoE protocols and block namespace rulesdocs/03-architecture/word-acl/DESIGN.md— ACL system designtools/mkcapsule.c— assembles capsules intocapsule_generated.c- Project root