OSDN Git Service

* expr.c (emit_move_via_integer): Add force argument, pass it on
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 17 Sep 2005 18:38:36 +0000 (18:38 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 17 Sep 2005 18:38:36 +0000 (18:38 +0000)
        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

gcc/ChangeLog
gcc/expr.c
gcc/function.c

index 9115041..abf9fe0 100644 (file)
@@ -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
 2005-09-17  Eric Botcazou  <ebotcazou@adacore.com>
 
        * varasm.c (output_constant): Do not abort on VIEW_CONVERT_EXPRs
index 50886bc..e99be6c 100644 (file)
@@ -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
    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;
 {
   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;
 
   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;
   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));
   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 ();
        }
 
          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;
     }
       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.  */
     }
 
   /* 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;
 }
   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)
     {
      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;
     }
       if (ret)
        return ret;
     }
index 014b38c..2df1eff 100644 (file)
@@ -4403,6 +4403,10 @@ expand_function_end (void)
   if (flag_exceptions && USING_SJLJ_EXCEPTIONS)
     sjlj_emit_function_exit_after (get_last_insn ());
 
   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.  */
   /* 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)));
            }
                                 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);
        }
          else
            emit_move_insn (real_decl_rtl, decl_rtl);
        }
@@ -4505,10 +4527,6 @@ expand_function_end (void)
       current_function_return_rtx = outgoing;
     }
 
       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;
   /* Emit the actual code to clobber return register.  */
   {
     rtx seq;