expr.c (emit_move_via_integer): Add force argument, pass it on to emit_move_change_mode.
* expr.c (emit_move_via_integer): Add force argument, pass it on to emit_move_change_mode. Update callers. (emit_move_complex): Pass true to new force argument. * function.c (expand_function_end): Move expand_eh_return call earlier. Merge sub-word complex values into a pseudo before copying to the return hard register. From-SVN: r104371
This commit is contained in:
parent
3fb90446b4
commit
652b0932d7
|
@ -1,3 +1,12 @@
|
|||
2005-09-17 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* expr.c (emit_move_via_integer): Add force argument, pass it on
|
||||
to emit_move_change_mode. Update callers.
|
||||
(emit_move_complex): Pass true to new force argument.
|
||||
* function.c (expand_function_end): Move expand_eh_return call
|
||||
earlier. Merge sub-word complex values into a pseudo before
|
||||
copying to the return hard register.
|
||||
|
||||
2005-09-17 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* varasm.c (output_constant): Do not abort on VIEW_CONVERT_EXPRs
|
||||
|
|
12
gcc/expr.c
12
gcc/expr.c
|
@ -2812,7 +2812,7 @@ emit_move_change_mode (enum machine_mode new_mode,
|
|||
emitted, or NULL if such a move could not be generated. */
|
||||
|
||||
static rtx
|
||||
emit_move_via_integer (enum machine_mode mode, rtx x, rtx y)
|
||||
emit_move_via_integer (enum machine_mode mode, rtx x, rtx y, bool force)
|
||||
{
|
||||
enum machine_mode imode;
|
||||
enum insn_code code;
|
||||
|
@ -2827,10 +2827,10 @@ emit_move_via_integer (enum machine_mode mode, rtx x, rtx y)
|
|||
if (code == CODE_FOR_nothing)
|
||||
return NULL_RTX;
|
||||
|
||||
x = emit_move_change_mode (imode, mode, x, false);
|
||||
x = emit_move_change_mode (imode, mode, x, force);
|
||||
if (x == NULL_RTX)
|
||||
return NULL_RTX;
|
||||
y = emit_move_change_mode (imode, mode, y, false);
|
||||
y = emit_move_change_mode (imode, mode, y, force);
|
||||
if (y == NULL_RTX)
|
||||
return NULL_RTX;
|
||||
return emit_insn (GEN_FCN (code) (x, y));
|
||||
|
@ -2973,7 +2973,7 @@ emit_move_complex (enum machine_mode mode, rtx x, rtx y)
|
|||
return get_last_insn ();
|
||||
}
|
||||
|
||||
ret = emit_move_via_integer (mode, x, y);
|
||||
ret = emit_move_via_integer (mode, x, y, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -3011,7 +3011,7 @@ emit_move_ccmode (enum machine_mode mode, rtx x, rtx y)
|
|||
}
|
||||
|
||||
/* Otherwise, find the MODE_INT mode of the same width. */
|
||||
ret = emit_move_via_integer (mode, x, y);
|
||||
ret = emit_move_via_integer (mode, x, y, false);
|
||||
gcc_assert (ret != NULL);
|
||||
return ret;
|
||||
}
|
||||
|
@ -3119,7 +3119,7 @@ emit_move_insn_1 (rtx x, rtx y)
|
|||
fits within a HOST_WIDE_INT. */
|
||||
if (!CONSTANT_P (y) || GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
rtx ret = emit_move_via_integer (mode, x, y);
|
||||
rtx ret = emit_move_via_integer (mode, x, y, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -4403,6 +4403,10 @@ expand_function_end (void)
|
|||
if (flag_exceptions && USING_SJLJ_EXCEPTIONS)
|
||||
sjlj_emit_function_exit_after (get_last_insn ());
|
||||
|
||||
/* If this is an implementation of throw, do what's necessary to
|
||||
communicate between __builtin_eh_return and the epilogue. */
|
||||
expand_eh_return ();
|
||||
|
||||
/* If scalar return value was computed in a pseudo-reg, or was a named
|
||||
return value that got dumped to the stack, copy that to the hard
|
||||
return register. */
|
||||
|
@ -4464,6 +4468,24 @@ expand_function_end (void)
|
|||
TREE_TYPE (decl_result),
|
||||
int_size_in_bytes (TREE_TYPE (decl_result)));
|
||||
}
|
||||
/* In the case of complex integer modes smaller than a word, we'll
|
||||
need to generate some non-trivial bitfield insertions. Do that
|
||||
on a pseudo and not the hard register. */
|
||||
else if (GET_CODE (decl_rtl) == CONCAT
|
||||
&& GET_MODE_CLASS (GET_MODE (decl_rtl)) == MODE_COMPLEX_INT
|
||||
&& GET_MODE_BITSIZE (GET_MODE (decl_rtl)) <= BITS_PER_WORD)
|
||||
{
|
||||
int old_generating_concat_p;
|
||||
rtx tmp;
|
||||
|
||||
old_generating_concat_p = generating_concat_p;
|
||||
generating_concat_p = 0;
|
||||
tmp = gen_reg_rtx (GET_MODE (decl_rtl));
|
||||
generating_concat_p = old_generating_concat_p;
|
||||
|
||||
emit_move_insn (tmp, decl_rtl);
|
||||
emit_move_insn (real_decl_rtl, tmp);
|
||||
}
|
||||
else
|
||||
emit_move_insn (real_decl_rtl, decl_rtl);
|
||||
}
|
||||
|
@ -4505,10 +4527,6 @@ expand_function_end (void)
|
|||
current_function_return_rtx = outgoing;
|
||||
}
|
||||
|
||||
/* If this is an implementation of throw, do what's necessary to
|
||||
communicate between __builtin_eh_return and the epilogue. */
|
||||
expand_eh_return ();
|
||||
|
||||
/* Emit the actual code to clobber return register. */
|
||||
{
|
||||
rtx seq;
|
||||
|
|
Loading…
Reference in New Issue