Fixes for C++ structure layout breakage.
authorJim Wilson <wilson@cygnus.com>
Wed, 25 Oct 2000 01:30:25 +0000 (01:30 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Wed, 25 Oct 2000 01:30:25 +0000 (18:30 -0700)
* expmed.c (store_bit_field): Move integer pun code down after
code that calls emit_move_insn for entire register move.
* stor-layout.c (compute_record_mode): Revert Mar 25, Aug 18, and
Oct 20 changes.  Only store mode in TYPE_MODE if RECORD_TYPE.

From-SVN: r37041

gcc/ChangeLog
gcc/expmed.c
gcc/stor-layout.c

index e4c278bf4123bb6ad6096f569228fdc7497e4e3a..6e87a7899996cff63a96cd88799ca6667847e5b2 100644 (file)
@@ -1,3 +1,10 @@
+2000-10-24  Jim Wilson  <wilson@cygnus.com>
+
+       * expmed.c (store_bit_field): Move integer pun code down after
+       code that calls emit_move_insn for entire register move.
+       * stor-layout.c (compute_record_mode): Revert Mar 25, Aug 18, and
+       Oct 20 changes.  Only store mode in TYPE_MODE if RECORD_TYPE.
+       
 2000-10-24  Richard Henderson  <rth@cygnus.com>
 
        * rtlanal.c (rtx_unstable_p, rtx_varies_p): Don't consider pic
index 260506215618e3dc38501984b4857eba48d7043f..254d052d8b5162e1d5785b0f46cc06d826e38c65 100644 (file)
@@ -269,21 +269,6 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
       op0 = SUBREG_REG (op0);
     }
 
-  /* Make sure we are playing with integral modes.  Pun with subregs
-     if we aren't.  */
-  {
-    enum machine_mode imode = int_mode_for_mode (GET_MODE (op0));
-    if (imode != GET_MODE (op0))
-      {
-       if (GET_CODE (op0) == MEM)
-         op0 = change_address (op0, imode, NULL_RTX);
-       else if (imode != BLKmode)
-         op0 = gen_lowpart (imode, op0);
-       else
-         abort ();
-      }
-  }
-
   /* If OP0 is a register, BITPOS must count within a word.
      But as we have it, it counts within whatever size OP0 now has.
      On a bigendian machine, these are not the same, so convert.  */
@@ -337,6 +322,23 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
       return value;
     }
 
+  /* Make sure we are playing with integral modes.  Pun with subregs
+     if we aren't.  This must come after the entire register case above,
+     since that case is valid for any mode.  The following cases are only
+     valid for integral modes.  */
+  {
+    enum machine_mode imode = int_mode_for_mode (GET_MODE (op0));
+    if (imode != GET_MODE (op0))
+      {
+       if (GET_CODE (op0) == MEM)
+         op0 = change_address (op0, imode, NULL_RTX);
+       else if (imode != BLKmode)
+         op0 = gen_lowpart (imode, op0);
+       else
+         abort ();
+      }
+  }
+
   /* Storing an lsb-aligned field in a register
      can be done with a movestrict instruction.  */
 
index ea9ee013dd780d076db036a66c2c266dd1cde11b..797b4cea17da24c5d9e4bd0f99b2db91ea42635f 100644 (file)
@@ -1065,12 +1065,8 @@ compute_record_mode (type)
 
       /* If this field is the whole struct, remember its mode so
         that, say, we can put a double in a class into a DF
-        register instead of forcing it to live in the stack.  However,
-        we don't support using such a mode if there is no integer mode
-        of the same size, so don't set it here.  */
-      if (field == TYPE_FIELDS (type) && TREE_CHAIN (field) == 0
-         && int_mode_for_mode (DECL_MODE (field)) != BLKmode
-         && operand_equal_p (DECL_SIZE (field), TYPE_SIZE (type), 1))
+        register instead of forcing it to live in the stack.  */
+      if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field)))
        mode = DECL_MODE (field);
 
 #ifdef STRUCT_FORCE_BLK
@@ -1081,8 +1077,9 @@ compute_record_mode (type)
 #endif /* STRUCT_FORCE_BLK  */
     }
 
-  if (mode != VOIDmode)
-    /* We only have one real field; use its mode.  */
+  /* If we only have one real field; use its mode.  This only applies to
+     RECORD_TYPE.  This does not apply to unions.  */
+  if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode)
     TYPE_MODE (type) = mode;
   else
     TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);