re PR rtl-optimization/20306 (FP complex modes moved via GPRs)
authorDavid Edelsohn <edelsohn@gnu.org>
Fri, 11 Mar 2005 22:58:49 +0000 (22:58 +0000)
committerDavid Edelsohn <dje@gcc.gnu.org>
Fri, 11 Mar 2005 22:58:49 +0000 (17:58 -0500)
        PR rtl-optimization/20306
        * expr.c (emit_move_complex): Set try_int false if mode is
        MODE_COMPLEX_FLOAT and mov_optab exists for inner mode.  Only try
        emit_block_move if try_int is true.

From-SVN: r96312

gcc/ChangeLog
gcc/expr.c

index 5c2b620571a15997340b959fa0e63ede7b262c45..51901ed86e901d84ccf965cf7b51b033efc5c9f3 100644 (file)
@@ -1,3 +1,10 @@
+2005-03-11  David Edelsohn  <edelsohn@gnu.org>
+
+       PR rtl-optimization/20306
+       * expr.c (emit_move_complex): Set try_int false if mode is
+       MODE_COMPLEX_FLOAT and mov_optab exists for inner mode.  Only try
+       emit_block_move if try_int is true.
+
 2005-03-11  Richard Henderson  <rth@redhat.com>
 
        PR target/20415
index 775a83a3cfce7599e7aab4dcad7ebd94a1956d67..9e08315531f0fd17e25aeb26977a86bf2c6db656 100644 (file)
@@ -2877,19 +2877,14 @@ emit_move_complex (enum machine_mode mode, rtx x, rtx y)
   if (push_operand (x, mode))
     return emit_move_complex_push (mode, x, y);
 
-  /* For memory to memory moves, optimal behavior can be had with the
-     existing block move logic.  */
-  if (MEM_P (x) && MEM_P (y))
-    {
-      emit_block_move (x, y, GEN_INT (GET_MODE_SIZE (mode)),
-                      BLOCK_OP_NO_LIBCALL);
-      return get_last_insn ();
-    }
-
   /* See if we can coerce the target into moving both values at once.  */
 
+  /* Move floating point as parts.  */
+  if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
+      && mov_optab->handlers[GET_MODE_INNER (mode)].insn_code != CODE_FOR_nothing)
+    try_int = false;
   /* Not possible if the values are inherently not adjacent.  */
-  if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
+  else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
     try_int = false;
   /* Is possible if both are registers (or subregs of registers).  */
   else if (register_operand (x, mode) && register_operand (y, mode))
@@ -2907,7 +2902,18 @@ emit_move_complex (enum machine_mode mode, rtx x, rtx y)
 
   if (try_int)
     {
-      rtx ret = emit_move_via_integer (mode, x, y);
+      rtx ret;
+
+      /* For memory to memory moves, optimal behavior can be had with the
+        existing block move logic.  */
+      if (MEM_P (x) && MEM_P (y))
+       {
+         emit_block_move (x, y, GEN_INT (GET_MODE_SIZE (mode)),
+                          BLOCK_OP_NO_LIBCALL);
+         return get_last_insn ();
+       }
+
+      ret = emit_move_via_integer (mode, x, y);
       if (ret)
        return ret;
     }