Thanks to visit codestin.com
Credit goes to github.com

Skip to content

cdp1802: gcc's POST_DEC is wrong and doesn't match our expectations #1

@mikpe

Description

@mikpe

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions