-
Couldn't load subscription status.
- Fork 2
Description
gcc interprets (set (mem:<mode> (post_dec (reg SP))) (reg <val>)) literally as
*(<mode>*)SP = <val>
SP -= sizeof(<mode>)
This is completely broken for argument pushes, but we were able to avoid that by adding push-like moves-to-mem to our .md so the broken generic code doesn't trigger.
The cdp1802 actually wants
*(char*)SP = <lowest byte of val>
SP -= 1
*(char*)SP = <second lowest byte of val>
SP -= 1
...
*(char*)SP = <highest byte of val>
SP -= 1
That is, our pushes are POST_DEC for each byte, but not for the datum as a whole.
This seems to be the reason why dse (due to cselib) removes live stores to the stack: they compute the wrong address ranges for the datums and therefore fail to see that the stores are live. (We currently enforce -fno-dse to avoid that miscompilation.)
PRE_DEC might be better, however everything in the frame ends up at an address off-by-one from what gcc expects.
We do want that off-by-one though since (a) it matches the HW, and (b) generated code often needs a scratch temp at SP+0.