mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-09-02 15:02:51 +08:00
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:
+17
-9
@@ -141,6 +141,22 @@ struct stp_pkt_in {
|
|||||||
#define STP_O ((__xdata struct stp_pkt *)&uip_buf[RTL_FRAME_DESC_SIZE])
|
#define STP_O ((__xdata struct stp_pkt *)&uip_buf[RTL_FRAME_DESC_SIZE])
|
||||||
#define STP_I ((__xdata struct stp_pkt_in *)&uip_buf[0])
|
#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
|
signed char cmpMAC(__xdata uint8_t *m1, __xdata uint8_t *m2) __reentrant
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < 6; i++) {
|
for (uint8_t i = 0; i < 6; i++) {
|
||||||
@@ -452,15 +468,7 @@ void stp_in(void) __banked
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
stp_dbridge[port].prio = STP_I->bridge.prio;
|
stp_record_designated(port);
|
||||||
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);
|
|
||||||
|
|
||||||
/* Better root than the one we know? */
|
/* Better root than the one we know? */
|
||||||
if (STP_I->root.prio < root_bridge.prio
|
if (STP_I->root.prio < root_bridge.prio
|
||||||
|
|||||||
Reference in New Issue
Block a user