From: Jim Wilson Date: Tue, 25 Apr 1995 22:25:28 +0000 (-0700) Subject: (expand_return): When returning BLKmode structure in X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3ffeb8f1c7fd30c30c880000724c87835b2d91fb;p=gcc.git (expand_return): When returning BLKmode structure in registers, copy it to a psuedo-reg instead of to hard registers. From-SVN: r9452 --- diff --git a/gcc/stmt.c b/gcc/stmt.c index 3af00be436d..ac8683b8c85 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -2680,7 +2680,8 @@ expand_return (retval) copying a BLKmode value into registers. We could put this code in a more general area (for use by everyone instead of just function call/return), but until this feature is generally usable it is kept here - (and in expand_call). */ + (and in expand_call). The value must go into a pseudo in case there + are cleanups that will clobber the real return register. */ if (retval_rhs != 0 && TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode @@ -2691,7 +2692,7 @@ expand_return (retval) int bytes = int_size_in_bytes (TREE_TYPE (retval_rhs)); int n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; rtx *result_pseudos = (rtx *) alloca (sizeof (rtx) * n_regs); - rtx result_reg = DECL_RTL (DECL_RESULT (current_function_decl)); + rtx result_reg; rtx result_val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0); enum machine_mode tmpmode; @@ -2733,13 +2734,6 @@ expand_return (retval) } } - /* Now that the value is in pseudos, copy it to the result reg(s). */ - emit_queue (); - free_temp_slots (); - for (i = 0; i < n_regs; i++) - emit_move_insn (gen_rtx (REG, word_mode, REGNO (result_reg) + i), - result_pseudos[i]); - /* Find the smallest integer mode large enough to hold the entire structure and use that mode instead of BLKmode on the USE insn for the return register. */ @@ -2747,17 +2741,25 @@ expand_return (retval) for (tmpmode = GET_CLASS_NARROWEST_MODE (MODE_INT); tmpmode != MAX_MACHINE_MODE; tmpmode = GET_MODE_WIDER_MODE (tmpmode)) - { - /* Have we found a large enough mode? */ - if (GET_MODE_SIZE (tmpmode) >= bytes) - break; - } + { + /* Have we found a large enough mode? */ + if (GET_MODE_SIZE (tmpmode) >= bytes) + break; + } /* No suitable mode found. */ if (tmpmode == MAX_MACHINE_MODE) - abort (); + abort (); + + result_reg = gen_reg_rtx (tmpmode); + PUT_MODE (DECL_RTL (DECL_RESULT (current_function_decl)), tmpmode); - PUT_MODE (result_reg, tmpmode); + /* Now that the value is in pseudos, copy it to the result reg(s). */ + emit_queue (); + free_temp_slots (); + for (i = 0; i < n_regs; i++) + emit_move_insn (gen_rtx (REG, word_mode, REGNO (result_reg) + i), + result_pseudos[i]); expand_value_return (result_reg); }