OSDN Git Service

* config/h8300/h8300.md (*one_complsi2_h8300): Change to
[pf3gnuchains/gcc-fork.git] / gcc / stor-layout.c
index c29c22d..98420fb 100644 (file)
@@ -203,10 +203,10 @@ variable_size (tree size)
 #define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode)
 #endif
 
-/* Return the machine mode to use for a nonscalar of SIZE bits.
-   The mode must be in class CLASS, and have exactly that many bits.
-   If LIMIT is nonzero, modes of wider than MAX_FIXED_MODE_SIZE will not
-   be used.  */
+/* Return the machine mode to use for a nonscalar of SIZE bits.  The
+   mode must be in class CLASS, and have exactly that many value bits;
+   it may have padding as well.  If LIMIT is nonzero, modes of wider
+   than MAX_FIXED_MODE_SIZE will not be used.  */
 
 enum machine_mode
 mode_for_size (unsigned int size, enum mode_class class, int limit)
@@ -219,7 +219,7 @@ mode_for_size (unsigned int size, enum mode_class class, int limit)
   /* Get the first mode which has this size, in the specified class.  */
   for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
        mode = GET_MODE_WIDER_MODE (mode))
-    if (GET_MODE_BITSIZE (mode) == size)
+    if (GET_MODE_PRECISION (mode) == size)
       return mode;
 
   return BLKmode;
@@ -242,7 +242,7 @@ mode_for_size_tree (tree size, enum mode_class class, int limit)
 }
 
 /* Similar, but never return BLKmode; return the narrowest mode that
-   contains at least the requested number of bits.  */
+   contains at least the requested number of value bits.  */
 
 enum machine_mode
 smallest_mode_for_size (unsigned int size, enum mode_class class)
@@ -253,7 +253,7 @@ smallest_mode_for_size (unsigned int size, enum mode_class class)
      specified class.  */
   for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
        mode = GET_MODE_WIDER_MODE (mode))
-    if (GET_MODE_BITSIZE (mode) >= size)
+    if (GET_MODE_PRECISION (mode) >= size)
       return mode;
 
   abort ();
@@ -397,6 +397,8 @@ layout_decl (tree decl, unsigned int known_align)
   else
     /* For fields, it's a bit more complicated...  */
     {
+      bool old_user_align = DECL_USER_ALIGN (decl);
+
       if (DECL_BIT_FIELD (decl))
        {
          DECL_BIT_FIELD_TYPE (decl) = type;
@@ -433,7 +435,9 @@ layout_decl (tree decl, unsigned int known_align)
              enum machine_mode xmode
                = mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
 
-             if (xmode != BLKmode && known_align >= GET_MODE_ALIGNMENT (xmode))
+             if (xmode != BLKmode 
+                 && (known_align == 0
+                     || known_align >= GET_MODE_ALIGNMENT (xmode)))
                {
                  DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
                                           DECL_ALIGN (decl));
@@ -451,25 +455,24 @@ layout_decl (tree decl, unsigned int known_align)
       else if (DECL_PACKED (decl) && DECL_USER_ALIGN (decl))
        /* Don't touch DECL_ALIGN.  For other packed fields, go ahead and
           round up; we'll reduce it again below.  We want packing to
-          supercede USER_ALIGN inherited from the type, but defer to
+          supersede USER_ALIGN inherited from the type, but defer to
           alignment explicitly specified on the field decl.  */;
       else
-       {
-         do_type_align (type, decl);
-
-         /* If the field is of variable size, we can't misalign it since we
-            have no way to make a temporary to align the result.  But this
-            isn't an issue if the decl is not addressable.  Likewise if it
-            is of unknown size.
-
-            Note that do_type_align may set DECL_USER_ALIGN, so we don't
-            want to check it again here.  */
-         if (DECL_PACKED (decl)
-             && (DECL_NONADDRESSABLE_P (decl)
-                 || DECL_SIZE_UNIT (decl) == 0
-                 || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
-           DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
-       }
+       do_type_align (type, decl);
+
+      /* If the field is of variable size, we can't misalign it since we
+        have no way to make a temporary to align the result.  But this
+        isn't an issue if the decl is not addressable.  Likewise if it
+        is of unknown size.
+
+        Note that do_type_align may set DECL_USER_ALIGN, so we need to
+        check old_user_align instead.  */
+      if (DECL_PACKED (decl)
+         && !old_user_align
+         && (DECL_NONADDRESSABLE_P (decl)
+             || DECL_SIZE_UNIT (decl) == 0
+             || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
+       DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
 
       /* Should this be controlled by DECL_USER_ALIGN, too?  */
       if (maximum_field_alignment != 0)
@@ -2115,4 +2118,27 @@ get_best_mode (int bitsize, int bitpos, unsigned int align,
   return mode;
 }
 
+/* Gets minimal and maximal values for MODE (signed or unsigned depending on
+   SIGN).  */
+
+void
+get_mode_bounds (enum machine_mode mode, int sign, rtx *mmin, rtx *mmax)
+{
+  int size = GET_MODE_BITSIZE (mode);
+
+  if (size > HOST_BITS_PER_WIDE_INT)
+    abort ();
+
+  if (sign)
+    {
+      *mmin = GEN_INT (-((unsigned HOST_WIDE_INT) 1 << (size - 1)));
+      *mmax = GEN_INT (((unsigned HOST_WIDE_INT) 1 << (size - 1)) - 1);
+    }
+  else
+    {
+      *mmin = const0_rtx;
+      *mmax = GEN_INT (((unsigned HOST_WIDE_INT) 1 << (size - 1) << 1) - 1);
+    }
+}
+
 #include "gt-stor-layout.h"