With 4.5.0, 4.6.0 and trunk r17011, -mmcs51 can compute the address of a 16-bit array element with its high byte taken from the low byte of the result. The attached test shows it in mcs51-small and mcs51-large: id[3] stays 0 because the store lands somewhere else in xdata.
void update(uint8_t port) __reentrant
{
if (timer[port] && check(port))
if (timer[port])
flags &= 0;
memcpy(ent_a[port].mac, pkt, 6);
ent_b[port].prio = id[port] = ((struct pkt *)pkt)->id;
cost[port] = scratch;
timer[port] = port;
}
With sdcc -mmcs51 -S on the test (plus -I for testfwk.h) the code for id[port] is:
mov a,r3
add a,#_id
mov r4,a
addc a,#(_id >> 8)
mov r3,a
The offset is in r3:r4 and the result in r4:r3. Tracing positionRegs() shows the reverse pass swapping the offset to match a result that spilSomething() had spilt. That result still holds its old regs[], so the swap undoes the earlier match with the real result.
The patch adds the result->isspilt check that ds390 got in r10200. With it the new test no longer fails, and the mcs51-small and mcs51-small-stack-auto regression runs show no new failures.
The patch against r17011 is attached. It has the one-line change in
src/mcs51/ralloc.cand the test assupport/regression/tests/bug-4153.c. Without the change the test fails onid[3]in mcs51-small and mcs51-large, while mcs51-small-stack-auto does not trigger it.A short follow-up in case it makes this easier to look at. Below is a standalone version of the test, without the regression framework. It prints PASS or FAIL through the ucsim simif interface:
With plain 4.5.0 it prints FAIL in the small and large models, and with the patch from this ticket it prints PASS. I also tried shrinking it with cvise, but the function under test barely got smaller, so it seems to need all of those statements to run out of registers.
If another form of report or patch would be easier for you to review, just let me know and I'll redo it. Thanks for taking a look.
I can reproduce the issue using SDCC built from current trunk on my Debian GNU/Linux testing system.
Clearly an issue in the interaction of register allocation and codegen, as wen can see in the asm (compiled with --no-peep --i-code-in-asm), since the register allocator places variables in register in a way that codegen can't handle:
Last edit: Philipp Klaus Krause 2026-10-18
Patch is applied in [r17025].
Related
Commit: [r17025]
The patch from [bugs:#4154] is independent of this one and still applies cleanly on top of [r17025], in case it helps there too.
Thanks for applying this one, and to Philipp for confirming it on trunk.
P.S.: Edited by @spth to fix the links.
Related
Bugs:
#4154Commit: [r17025]
Last edit: Philipp Klaus Krause 2026-10-18