stp: keep the designated bridge recording out of internal RAM

The report on the PR is that it will not link for KP_9000_6XHML_X2, with
"?ASlink-Error-Could not get N consecutive bytes in internal RAM for area OSEG"
five times over. It builds here on sdcc 4.2.0 and 4.5.0 for that same machine
and the same commit, so something in the toolchain differs, but the pressure it
is complaining about is mine and it costs little to give back.

stp_in() is __banked, so its temporaries get exclusive DSEG instead of
overlaying with anything else. Recording the designated bridge put four more
live values across a memcpy in the middle of it and the register allocator
answered with five spill locations. The module went from 5 bytes of DSEG to 12,
and from 17 sloc references to 49.

Moving that block into a __reentrant helper puts its temporaries on the stack
instead. The module now claims no DSEG at all, 5 bytes better than before the
recording was added, and the image sits at 95 bytes of DSEG against 101 on main.
It costs 170 bytes of BANK2, where there is room.
This commit is contained in:
d00f
2026-08-18 23:29:16 +02:00
committed by d00f
parent a6c5f558bf
commit 4d7a2e28c7
+17 -9
View File
@@ -141,6 +141,22 @@ struct stp_pkt_in {
#define STP_O ((__xdata struct stp_pkt *)&uip_buf[RTL_FRAME_DESC_SIZE])
#define STP_I ((__xdata struct stp_pkt_in *)&uip_buf[0])
/* __reentrant so the temporaries land on the stack: stp_in() is __banked and
* its locals get exclusive internal RAM, which is what runs out first here. */
static void stp_record_designated(uint8_t port) __reentrant
{
stp_dbridge[port].prio = STP_I->bridge.prio;
stp_dbridge[port].ext = STP_I->bridge.ext;
memcpy(stp_dbridge[port].mac, STP_I->bridge.mac, 6);
stp_dpid[port] = ((uint16_t)STP_I->port_prio << 8) | STP_I->port_id;
stp_cost_scratch = STP_I->root_path_cost;
stp_dcost[port] = ((stp_cost_scratch & 0xff) << 24)
| ((stp_cost_scratch & 0xff00) << 8)
| ((stp_cost_scratch >> 8) & 0xff00)
| (stp_cost_scratch >> 24);
}
signed char cmpMAC(__xdata uint8_t *m1, __xdata uint8_t *m2) __reentrant
{
for (uint8_t i = 0; i < 6; i++) {
@@ -452,15 +468,7 @@ void stp_in(void) __banked
return;
}
stp_dbridge[port].prio = STP_I->bridge.prio;
stp_dbridge[port].ext = STP_I->bridge.ext;
memcpy(stp_dbridge[port].mac, STP_I->bridge.mac, 6);
stp_dpid[port] = ((uint16_t)STP_I->port_prio << 8) | STP_I->port_id;
stp_cost_scratch = STP_I->root_path_cost;
stp_dcost[port] = ((stp_cost_scratch & 0xff) << 24)
| ((stp_cost_scratch & 0xff00) << 8)
| ((stp_cost_scratch >> 8) & 0xff00)
| (stp_cost_scratch >> 24);
stp_record_designated(port);
/* Better root than the one we know? */
if (STP_I->root.prio < root_bridge.prio