summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2005-09-17 18:38:36 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2005-09-17 18:38:36 +0000
commit80e467e287ab9691aebede717bef9ff519a743f8 (patch)
tree586ee19cf00f968f147f254400212285835033a4 /gcc
parent3bcf853d9aa0fdb734c3ce66b9688e45dd0a4e0e (diff)
downloadgcc-80e467e287ab9691aebede717bef9ff519a743f8.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104371 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/expr.c12
-rw-r--r--gcc/function.c26
3 files changed, 37 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 91150416660..abf9fe06017 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/expr.c b/gcc/expr.c
index 50886bcc8cd..e99be6c40a6 100644
--- a/gcc/expr.c
+++ b/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;
}
diff --git a/gcc/function.c b/gcc/function.c
index 014b38cf613..2df1eff5b44 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -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;