(expand_return): When returning BLKmode structure...
authorJim Wilson <wilson@gcc.gnu.org>
Thu, 27 Apr 1995 22:50:50 +0000 (15:50 -0700)
committerJim Wilson <wilson@gcc.gnu.org>
Thu, 27 Apr 1995 22:50:50 +0000 (15:50 -0700)
(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

gcc/stmt.c

index ac8683b8c852e4aaf0c7b06ae85989a13e6c369d..6b2e80b6ba30195c312625af5c33bdd8e2e9535c 100644 (file)
@@ -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