xtensa windowed: an aggregate result past 128 bytes of frame does not compile
Found on the S3: import re in any Nil Python program failed with
target xtensa windowed: aggregate-result frame offset out of range. The
reduced repro is a function that returns
record ok: Boolean; n: Integer; a, b: array[0..13] of Integer end (120 B)
through a local of that type. With 104 B it compiled. riscv32, x86-64 and xtensa
Call0 were fine.
Mechanism
In windowed mode the hidden result pointer arrives in a2 and is stored to the
result local's frame slot, addressed from a15, before the parameter copy. The
address was formed with addi a9, a15, off, which takes -128..127, and any
larger offset hit Error. The Call0 arm uses EmitFrameAddrXtensa, which
materialises large offsets, but that helper bases on a7. In windowed mode, a7
is not the frame pointer yet at this point.
Fix
symtab.inc: past imm8, the offset goes through EmitLoadConstXtensa (movi,
or a literal-pool l32r past ±2047) and add a9, a15, a9. That writes only a9,
so a2 stays intact.
Test
test-xtensa, hosted (--platform=posix --xtensa-soft-mulhigh), with x86-64 as
the oracle:
test/test_xtensa_windowed_large_aggregate_result.pasat 120 B, 1 KB and 8 KB, under windowed and Call0;test/test_xtensa_windowed_regex_search.pas, which runs regex.pas (ReRunAt);- a build-only row for Nil Python
import rewith theexamples/esp32/nilpy-s3/build.shflags.
On the compiler one commit back, the windowed builds fail.