------- Comment #14 from hutchinsonandy at aim dot com 2008-06-01 15:22 ------- It appears emit_single_push_insn() is BROKEN for targets with:
a)STACK_GROWS_DOWNWARDS+POST_DEC push b)Upwards+POST_INC push. So if any target has this combo and #define PUSH_ROUNDING - it is broken. Fortunately for AVR the whole mess goes away when we #undef PUSH_ROUNDING- which appears so far to be uneccesary. It also cleared some compat test failures! For reference here what I did sort out for emit_single_push_insn There are two problems. 1) For downwards padding, MISTAKE in original (H8) change that for (a) adds size of slot to SP to get address - that would be highest byte of mem! This crashes AVR. /* We have already decremented the stack pointer, so get the previous value. */ offset += (HOST_WIDE_INT) rounded_size; I AM VERY WRONG POST_DEC leaves stack pointer at BOS-1. We must add smallest addressable unit of stack (byte,word?) to get address of MEM. Or perhaps use STACK_POINTER_OFFSET. So above becomes. offset += (HOST_WIDE_INT) STACK_POINTER_OFFSET; 2) For Upwards padding both POST_INC and POST_DEC have PRE_MODIFY sequences created for upwards padding. This is questioned in code and clearly incorrect. I assume no target has this combo. One possible way to fix issue is to use POST_MODIFY. However, that would assume final instructions would not be split and cause stack corruption during interrupt. This matter I have not checked. Someone might consider adding some asserts here! -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27386