Motivation
rcbios sio_wr5/sio_rd1 used to be a single function with a runtime port
variable (port = ls_port ? PORT_SIO_B_CTRL : PORT_SIO_A_CTRL; port_out_rt(port,…)),
which merged the A/B channel helpers and saved 14 B (rc700-gensmedet 583d7ef /
8fdb1a7). That relied on the backend emitting OUT (C),A / IN A,(C) for a
runtime port. #44 (1d7124d) intentionally removed that path: IN A,(C)/OUT (C),A
put B on the high address bits, only coincidentally harmless on RC700's low-8-bit
port decode, so the selector now rejects a non-constant port.
Consequence: the port variable becomes a G_PHI of two constant ports
(0x0A / 0x0B), and the addrspace(2) load/store on it fails to select
(cannot select G_LOAD/G_STORE addrspace 2). rcbios worked around this by
branching on ls_port and using a constant port literal in each branch
(rc700-gensmedet, restores the per-channel form), which costs the 14 B back.
Request
Teach the backend to select an address_space(2) byte load/store whose address
is a G_PHI (or select) of compile-time-constant ports: sink the IN/OUT
into each predecessor where the port is a known constant, emitting IN A,(n) /
OUT (n),A with the concrete constant per edge, then PHI the loaded value. This
recovers the single-function size win WITHOUT baking the #44 IN A,(C)
high-address-bits assumption (every emitted instruction still uses a constant n).
Scope: a pre-isel/combiner transform (split the port load/store per PHI
predecessor) or an ISel pattern that recognizes a PHI/select of constant ports.
Not required for correctness (the branch-with-constant form is correct); this is
a size optimization to restore the 14 B.
Acceptance
Motivation
rcbios
sio_wr5/sio_rd1used to be a single function with a runtimeportvariable (
port = ls_port ? PORT_SIO_B_CTRL : PORT_SIO_A_CTRL; port_out_rt(port,…)),which merged the A/B channel helpers and saved 14 B (rc700-gensmedet 583d7ef /
8fdb1a7). That relied on the backend emitting
OUT (C),A/IN A,(C)for aruntime port. #44 (1d7124d) intentionally removed that path:
IN A,(C)/OUT (C),Aput B on the high address bits, only coincidentally harmless on RC700's low-8-bit
port decode, so the selector now rejects a non-constant port.
Consequence: the
portvariable becomes aG_PHIof two constant ports(0x0A / 0x0B), and the addrspace(2) load/store on it fails to select
(
cannot select G_LOAD/G_STORE addrspace 2). rcbios worked around this bybranching on
ls_portand using a constant port literal in each branch(rc700-gensmedet, restores the per-channel form), which costs the 14 B back.
Request
Teach the backend to select an
address_space(2)byte load/store whose addressis a
G_PHI(or select) of compile-time-constant ports: sink theIN/OUTinto each predecessor where the port is a known constant, emitting
IN A,(n)/OUT (n),Awith the concrete constant per edge, then PHI the loaded value. Thisrecovers the single-function size win WITHOUT baking the #44
IN A,(C)high-address-bits assumption (every emitted instruction still uses a constant n).
Scope: a pre-isel/combiner transform (split the port load/store per PHI
predecessor) or an ISel pattern that recognizes a PHI/select of constant ports.
Not required for correctness (the branch-with-constant form is correct); this is
a size optimization to restore the 14 B.
Acceptance
per-edge
IN A,(n)/OUT (n),A(lit test).sio_wr5/sio_rd1can return to the single-portform and stillselect; 14 B recovered. Runtime port (genuinely non-constant) stays rejected
per [Z80] address_space(2) PHI in Legalizer crashes on conditional port I/O #44.