* simplify-rtx.c (simplify_subreg): In the CONCAT case, check whether
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Dec 2004 20:28:14 +0000 (20:28 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Dec 2004 20:28:14 +0000 (20:28 +0000)
the request subreg is entirely contained in the requested component.
(simplify_gen_subreg): Return null for CONCATs that are rejected
by simplify_subreg.
* expmed.c (store_bit_field): Create a temporary when changing the
value to an integer mode.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@91965 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/expmed.c
gcc/simplify-rtx.c

index 3c3f735..d63fe39 100644 (file)
@@ -1,3 +1,12 @@
+2004-12-09  Richard Sandiford  <rsandifo@redhat.com>
+
+       * simplify-rtx.c (simplify_subreg): In the CONCAT case, check whether
+       the request subreg is entirely contained in the requested component.
+       (simplify_gen_subreg): Return null for CONCATs that are rejected
+       by simplify_subreg.
+       * expmed.c (store_bit_field): Create a temporary when changing the
+       value to an integer mode.
+
 2004-12-09  David Edelsohn  <edelsohn@gnu.org>
 
        * real.c (ibm_extended): Correct comment.
index 47fc2d2..10a95b3 100644 (file)
@@ -591,16 +591,18 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       offset = 0;
     }
 
-  /* If VALUE is a floating-point mode, access it as an integer of the
-     corresponding size.  This can occur on a machine with 64 bit registers
-     that uses SFmode for float.  This can also occur for unaligned float
-     structure fields.  */
+  /* If VALUE has a floating-point or complex mode, access it as an
+     integer of the corresponding size.  This can occur on a machine
+     with 64 bit registers that uses SFmode for float.  It can also
+     occur for unaligned float or complex fields.  */
   orig_value = value;
-  if (GET_MODE_CLASS (GET_MODE (value)) != MODE_INT
+  if (GET_MODE (value) != VOIDmode
+      && GET_MODE_CLASS (GET_MODE (value)) != MODE_INT
       && GET_MODE_CLASS (GET_MODE (value)) != MODE_PARTIAL_INT)
-    value = gen_lowpart ((GET_MODE (value) == VOIDmode
-                         ? word_mode : int_mode_for_mode (GET_MODE (value))),
-                        value);
+    {
+      value = gen_reg_rtx (int_mode_for_mode (GET_MODE (value)));
+      emit_move_insn (gen_lowpart (GET_MODE (orig_value), value), orig_value);
+    }
 
   /* Now OFFSET is nonzero only if OP0 is memory
      and is therefore always measured in bytes.  */
index 580782d..2ac5661 100644 (file)
@@ -3722,17 +3722,20 @@ simplify_subreg (enum machine_mode outermode, rtx op,
      of real and imaginary part.  */
   if (GET_CODE (op) == CONCAT)
     {
-      int is_realpart = byte < (unsigned int) GET_MODE_UNIT_SIZE (innermode);
-      rtx part = is_realpart ? XEXP (op, 0) : XEXP (op, 1);
-      unsigned int final_offset;
-      rtx res;
+      unsigned int inner_size, final_offset;
+      rtx part, res;
+
+      inner_size = GET_MODE_UNIT_SIZE (innermode);
+      part = byte < inner_size ? XEXP (op, 0) : XEXP (op, 1);
+      final_offset = byte % inner_size;
+      if (final_offset + GET_MODE_SIZE (outermode) > inner_size)
+       return NULL_RTX;
 
-      final_offset = byte % (GET_MODE_UNIT_SIZE (innermode));
       res = simplify_subreg (outermode, part, GET_MODE (part), final_offset);
       if (res)
        return res;
       if (validate_subreg (outermode, GET_MODE (part), part, final_offset))
-        return gen_rtx_SUBREG (outermode, part, final_offset);
+       return gen_rtx_SUBREG (outermode, part, final_offset);
       return NULL_RTX;
     }
 
@@ -3786,7 +3789,9 @@ simplify_gen_subreg (enum machine_mode outermode, rtx op,
   if (newx)
     return newx;
 
-  if (GET_CODE (op) == SUBREG || GET_MODE (op) == VOIDmode)
+  if (GET_CODE (op) == SUBREG
+      || GET_CODE (op) == CONCAT
+      || GET_MODE (op) == VOIDmode)
     return NULL_RTX;
 
   if (validate_subreg (outermode, innermode, op, byte))