diff options
| author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-03-14 15:38:55 +0000 |
|---|---|---|
| committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-03-14 15:38:55 +0000 |
| commit | a8d8b9620eeceba743f26beb378820b0ed2f6e7d (patch) | |
| tree | 1c2e5b34b8e26aee9ad132104f2e0aeaee5463b4 /gcc/expr.c | |
| parent | 2a2e48d2c72bb353d3c02609b5e03e23e48c76ee (diff) | |
| download | ppe42-gcc-a8d8b9620eeceba743f26beb378820b0ed2f6e7d.tar.gz ppe42-gcc-a8d8b9620eeceba743f26beb378820b0ed2f6e7d.zip | |
* expr.c (emit_move_insn_1): Split push of complex value when
no suitable push instruction exist.
* i386.md (QImode move/add/shift patterns): Use ANY_QI_REG_P
instead of QI_REG_P.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@40454 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
| -rw-r--r-- | gcc/expr.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/gcc/expr.c b/gcc/expr.c index 382bb234916..44900a61346 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -2786,12 +2786,55 @@ emit_move_insn_1 (x, y) /* Don't split destination if it is a stack push. */ int stack = push_operand (x, GET_MODE (x)); + /* In case we output to the stack, but the size is smaller machine can + push exactly, we need to use move instructions. */ + if (stack + && PUSH_ROUNDING (GET_MODE_SIZE (submode)) != GET_MODE_SIZE (submode)) + { + rtx temp; + int offset1, offset2; + + /* Do not use anti_adjust_stack, since we don't want to update + stack_pointer_delta. */ + temp = expand_binop (Pmode, +#ifdef STACK_GROWS_DOWNWARD + sub_optab, +#else + add_optab, +#endif + stack_pointer_rtx, + GEN_INT + (PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (x)))), + stack_pointer_rtx, + 0, + OPTAB_LIB_WIDEN); + if (temp != stack_pointer_rtx) + emit_move_insn (stack_pointer_rtx, temp); +#ifdef STACK_GROWS_DOWNWARD + offset1 = 0; + offset2 = GET_MODE_SIZE (submode); +#else + offset1 = -PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (x))); + offset2 = (-PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (x))) + + GET_MODE_SIZE (submode)); +#endif + emit_move_insn (change_address (x, submode, + gen_rtx_PLUS (Pmode, + stack_pointer_rtx, + GEN_INT (offset1))), + gen_realpart (submode, y)); + emit_move_insn (change_address (x, submode, + gen_rtx_PLUS (Pmode, + stack_pointer_rtx, + GEN_INT (offset2))), + gen_imagpart (submode, y)); + } /* If this is a stack, push the highpart first, so it will be in the argument order. In that case, change_address is used only to convert the mode, not to change the address. */ - if (stack) + else if (stack) { /* Note that the real part always precedes the imag part in memory regardless of machine's endianness. */ |

