Claude’s last session stopped at exactly the useful point: phase 2 had been committed, and phase 3 had just rewritten the libc smoke Makefile before the model hit a rate limit.
The committed phase 2 result is solid:
FMV.W.X/FMV.X.WFLW/FSWFLD/FSD- compressed FP load/store forms, both register-relative and stack-relative
The captured phase-2 UART log shows all three forced asm round-trips passing.
Today I picked up phase 3. The reset path now sets gp, clears
.bss, calls __libc_init_array, runs main, then calls
__libc_fini_array if main returns. The linker script now keeps
the init/fini arrays and provides __global_pointer$. The P68 libc
shim no longer overrides malloc, free, calloc, or realloc;
newlib’s allocator uses _sbrk.
Then we stopped pretending the dormant FP arithmetic in newlib was someone else’s problem. P70 now implements the D subset that the linked image reaches: add/sub/mul/div, multiply-add variants, comparisons, class, and int/double conversions.
The smoke program links against real -lc -lm -lgcc and exercises
stdio, heap allocation, and %f formatting:
P70 phase 3+4 libc/FPU revival
printf-int: 1 22 333
printf-hex: 0xdeadbeef
printf-str: hello from real libc
printf-double: 3.125
snprintf into malloc'd buf at 0xe548
malloc(16)=0xe548 malloc(128)=0xe560 malloc(1024)=0xe5e8
realloc round-trip: abcdefgXYZ
P70 phase 3+4 PASS - newlib stdio + malloc + FPU work
Harness:
[harness] run ended after 60579 post-load cycles
[harness] halted=1, halt_code=0x00000001
Josh called the right ending: P70 should not stop at “printf
works”; it should show AtomVM getting past the P68-era issues as the
last step. The first try only ran the old hello beam and still hit the
expected missing-init.beam wall. That was not enough, so the final
shape bundles lib.avm and runs the process ping-pong example.
The P70 AtomVM build keeps the pinned P68 AtomVM checkout, builds a
P70 libAtomVM with floating point enabled, uses a host CMake build to
package AtomVM’s atomvmlib.avm, uses the host packbeam from that
checkout, and assembles the same 16 MiB boot image layout: stage-0 at
zero, lib.avm at 8 MiB, and main.avm at 12 MiB.
Captured AtomVM run:
AtomVM on P70 (real newlib + FPU subset)
Starting AtomVM revision 0.8.0-dev+git.5e47d64
Found startup beam: pingpong.beam
pingpong starting
pingpong done: 32 round trips
Return value: ok
AtomVM exited result=0
The important result is that AtomVM now loads the bundled stdlib pack,
gets past init.beam, runs pingpong.beam, spawns a process, sends
32 ping/pong message round trips, prints through io:format/2, and
halts PASS:
[harness] === run ended after 9193286 post-load cycles ===
[harness] halted=1, halt_code=0x00000001
Honest status
| step | status |
|---|---|
| F/D bit-motion asm smoke | PASS |
| libc smoke build | PASS |
| libc smoke Verilator run | PASS |
%f formatting through _dtoa_r | PASS |
AtomVM stdlib pack bundled as lib.avm | PASS |
| AtomVM process ping-pong on P70 real libc | PASS |
| F/D architectural compliance | NOT RUN |
| LibreLane hardening | NOT RUN |
This is now rtl-pass, not hardened. It is also still not full F/D
compliance: subnormals, exception flags, sqrt, min/max, sign
injection, and broad single-precision coverage are not proven. The
next sensible AtomVM work is broader library/application coverage on
top of this runtime, not the basic process demo anymore.