diff options
| author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-12-13 08:08:46 +0000 |
|---|---|---|
| committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-12-13 08:08:46 +0000 |
| commit | 3cb7a12915b19dc2f21263f46764df080e75aab8 (patch) | |
| tree | 3e381c6cb02cd2615bcd811bfcbbab696131e626 /gcc/expr.c | |
| parent | b60e927ab48e632454bc2c2b0aecf460325a8332 (diff) | |
| download | ppe42-gcc-3cb7a12915b19dc2f21263f46764df080e75aab8.tar.gz ppe42-gcc-3cb7a12915b19dc2f21263f46764df080e75aab8.zip | |
PR debug/25023
PR target/25293
* expr.c (emit_move_resolve_push): Handle PRE_MODIFY
and POST_MODIFY with CONST_INT adjustment equal to PUSH_ROUNDING.
Fix POST_INC/POST_DEC handling if PUSH_ROUNDING is not identity.
* config/i386/i386.md (pushhi2, pushqi2): Use pushl instead of pushw.
Set mode to SI, adjust constraints.
(pushhi2_rex64, pushqi2_rex64): Set mode to DI.
* config/i386/i386.h (PUSH_ROUNDING): Round up to 4 instead of 2 for
32-bit code.
* gcc.target/i386/pr25293.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108463 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
| -rw-r--r-- | gcc/expr.c | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/gcc/expr.c b/gcc/expr.c index de66a0d3173..2e26ef05cdc 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -2852,6 +2852,19 @@ emit_move_resolve_push (enum machine_mode mode, rtx x) #endif if (code == PRE_DEC || code == POST_DEC) adjust = -adjust; + else if (code == PRE_MODIFY || code == POST_MODIFY) + { + rtx expr = XEXP (XEXP (x, 0), 1); + HOST_WIDE_INT val; + + gcc_assert (GET_CODE (expr) == PLUS || GET_CODE (expr) == MINUS); + gcc_assert (GET_CODE (XEXP (expr, 1)) == CONST_INT); + val = INTVAL (XEXP (expr, 1)); + if (GET_CODE (expr) == MINUS) + val = -val; + gcc_assert (adjust == val || adjust == -val); + adjust = val; + } /* Do not use anti_adjust_stack, since we don't want to update stack_pointer_delta. */ @@ -2865,13 +2878,13 @@ emit_move_resolve_push (enum machine_mode mode, rtx x) { case PRE_INC: case PRE_DEC: + case PRE_MODIFY: temp = stack_pointer_rtx; break; case POST_INC: - temp = plus_constant (stack_pointer_rtx, -GET_MODE_SIZE (mode)); - break; case POST_DEC: - temp = plus_constant (stack_pointer_rtx, GET_MODE_SIZE (mode)); + case POST_MODIFY: + temp = plus_constant (stack_pointer_rtx, -adjust); break; default: gcc_unreachable (); |

