From 652b0932d7753aec43306dee62e5005492a6cf3c Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 17 Sep 2005 11:38:36 -0700 Subject: [PATCH] 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 --- gcc/ChangeLog | 9 +++++++++ gcc/expr.c | 12 ++++++------ gcc/function.c | 26 ++++++++++++++++++++++---- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9115041..abf9fe0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2005-09-17 Richard Henderson + + * 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 * varasm.c (output_constant): Do not abort on VIEW_CONVERT_EXPRs diff --git a/gcc/expr.c b/gcc/expr.c index 50886bc..e99be6c 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 014b38c..2df1eff 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; -- 2.7.4