expr.c (write_complex_part): Use simplify_gen_subreg when the submode is at least...
authorRichard Henderson <rth@redhat.com>
Thu, 2 Dec 2004 22:23:08 +0000 (14:23 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 2 Dec 2004 22:23:08 +0000 (14:23 -0800)
        * expr.c (write_complex_part): Use simplify_gen_subreg when the
        submode is at least as large as a word.
        (read_complex_part): Likewise.

From-SVN: r91664

gcc/ChangeLog
gcc/expr.c

index 7acdb818ef15e3b7be99d4fb86a4056e769c57e0..3bfaa0eead24bad532a2f8b98874fab36cc89eae 100644 (file)
@@ -1,3 +1,9 @@
+2004-12-02  Richard Henderson  <rth@redhat.com>
+
+       * expr.c (write_complex_part): Use simplify_gen_subreg when the
+       submode is at least as large as a word.
+       (read_complex_part): Likewise.
+
 2004-12-02  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR bootstrap/18532
index f16f82f10a7184cd2e018c7f1f9a3316f221e463..ec25713c5e91ee1a32f5d9c33e3d578fb2cfbea4 100644 (file)
@@ -2580,16 +2580,32 @@ clear_storage_libcall_fn (int for_call)
 static void
 write_complex_part (rtx cplx, rtx val, bool imag_p)
 {
+  enum machine_mode cmode;
+  enum machine_mode imode;
+  unsigned ibitsize;
+
   if (GET_CODE (cplx) == CONCAT)
-    emit_move_insn (XEXP (cplx, imag_p), val);
-  else
     {
-      enum machine_mode cmode = GET_MODE (cplx);
-      enum machine_mode imode = GET_MODE_INNER (cmode);
-      unsigned ibitsize = GET_MODE_BITSIZE (imode);
+      emit_move_insn (XEXP (cplx, imag_p), val);
+      return;
+    }
 
-      store_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, imode, val);
+  cmode = GET_MODE (cplx);
+  imode = GET_MODE_INNER (cmode);
+  ibitsize = GET_MODE_BITSIZE (imode);
+
+  /* If the sub-object is at least word sized, then we know that subregging
+     will work.  This special case is important, since store_bit_field
+     wants to operate on integer modes, and there's rarely an OImode to
+     correspond to TCmode.  */
+  if (ibitsize >= BITS_PER_WORD)
+    {
+      rtx part = simplify_gen_subreg (imode, cplx, cmode,
+                                     imag_p ? GET_MODE_SIZE (imode) : 0);
+      emit_move_insn (part, val);
     }
+  else
+    store_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, imode, val);
 }
 
 /* Extract one of the components of the complex value CPLX.  Extract the
@@ -2620,6 +2636,18 @@ read_complex_part (rtx cplx, bool imag_p)
        }
     }
 
+  /* If the sub-object is at least word sized, then we know that subregging
+     will work.  This special case is important, since extract_bit_field
+     wants to operate on integer modes, and there's rarely an OImode to
+     correspond to TCmode.  */
+  if (ibitsize >= BITS_PER_WORD)
+    {
+      rtx ret = simplify_gen_subreg (imode, cplx, cmode,
+                                    imag_p ? GET_MODE_SIZE (imode) : 0);
+      gcc_assert (ret != NULL);
+      return ret;
+    }
+
   return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0,
                            true, NULL_RTX, imode, imode);
 }