Bare Eof reads a stale register on xtensa windowed
while not Eof do begin Readln(x); Write(x, ' ') end;
Writeln(Eof);
{ stdin "2\n3\n": FPC and x86-64 print `2 3 TRUE`; xtensa windowed `2 FALSE` }
Cause and fix
The parser lowers bare Eof and Eof() to special call id -210, and each
backend calls the builtin unit's PXXStdinEof. In ir_codegen_xtensa.inc the
arm was just EmitCallProc. Under Call0 the result is in a2, so that is
enough. Under the windowed ABI (call8) the callee's a2 is the caller's a10.
The general call path, and each helper that returns a value, moves a10 to a2
afterwards; this arm did not. The arm now does that move when the ABI is
windowed.
The other special-call arms in the xtensa backend that call EmitCallProc
either return nothing (SetLength, the Readln family) or already move the
result.
Measured (2026-09-29, fixedpoint 8c0075b5edd6)
test/test_bare_eof_on_stdin_on_every_target.paswith.in. It reads four lines untilEof, asksEoftwice between reads (both answers must agree), then prints the finalEofand uses it in anif..expectedis FPC's.- Rows: x86-64, i386, riscv32, xtensa windowed and xtensa Call0. It equals FPC on all five.
- The previous compiler passes on x86-64, i386, riscv32 and Call0. On
windowed,
Eofnever becomes true: the program prints2 3 -7 40and then zeros until it is killed. The rows carry a timeout for that reason. - wasm32 still refuses bare
Eof. That is deliberate and in LOGBOOK: wasm32 has no stdin at all (no PXXSysRead arm, no Readln lowering), so aPXXStdinEofcall there would answer TRUE with input waiting.