diff options
author | Jim Wilson <wilson@gcc.gnu.org> | 1995-04-27 15:50:50 -0700 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1995-04-27 15:50:50 -0700 |
commit | af55da56a5b64e4e043933007dea8ad1e90a7659 (patch) | |
tree | 13ae052a5e6cc3cb30bc67dbf6127792209446db /gcc | |
parent | 46fccf9e3392b0300f4847c34abf2e671b37d402 (diff) | |
download | gcc-af55da56a5b64e4e043933007dea8ad1e90a7659.zip gcc-af55da56a5b64e4e043933007dea8ad1e90a7659.tar.gz gcc-af55da56a5b64e4e043933007dea8ad1e90a7659.tar.bz2 |
(expand_return): When returning BLKmode structure...
(expand_return): When returning BLKmode structure, use
operand_subword instead of doing arithmetic on the register number.
Also, for structures smaller than word_mode, copy it into a word_mode
temporary and then subreg it.
From-SVN: r9516
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/stmt.c | 14 |
1 files changed, 11 insertions, 3 deletions
@@ -2694,7 +2694,7 @@ expand_return (retval) rtx *result_pseudos = (rtx *) alloca (sizeof (rtx) * n_regs); rtx result_reg; rtx result_val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0); - enum machine_mode tmpmode; + enum machine_mode tmpmode, result_reg_mode; /* Structures smaller than a word are aligned to the least significant byte (to the right). On a BYTES_BIG_ENDIAN machine, this means we @@ -2751,16 +2751,24 @@ expand_return (retval) if (tmpmode == MAX_MACHINE_MODE) abort (); - result_reg = gen_reg_rtx (tmpmode); PUT_MODE (DECL_RTL (DECL_RESULT (current_function_decl)), tmpmode); + if (GET_MODE_SIZE (tmpmode) < GET_MODE_SIZE (word_mode)) + result_reg_mode = word_mode; + else + result_reg_mode = tmpmode; + result_reg = gen_reg_rtx (result_reg_mode); + /* 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), + emit_move_insn (operand_subword (result_reg, i, 0, result_reg_mode), result_pseudos[i]); + if (tmpmode != result_reg_mode) + result_reg = gen_lowpart (tmpmode, result_reg); + expand_value_return (result_reg); } else if (cleanups |