OSDN Git Service

[pf3gnuchains/gcc-fork.git] / gcc / stor-layout.c
index 043ad28..a947447 100644 (file)
@@ -144,13 +144,13 @@ mode_for_size (size, class, limit)
 {
   register enum machine_mode mode;
 
-  if (limit && size > MAX_FIXED_MODE_SIZE)
+  if (limit && size > (unsigned int)(MAX_FIXED_MODE_SIZE))
     return BLKmode;
 
   /* 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 ((unsigned int)GET_MODE_BITSIZE (mode) == size)
       return mode;
 
   return BLKmode;
@@ -170,12 +170,43 @@ smallest_mode_for_size (size, 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 ((unsigned int)GET_MODE_BITSIZE (mode) >= size)
       return mode;
 
   abort ();
 }
 
+/* Find an integer mode of the exact same size, or BLKmode on failure.  */
+
+enum machine_mode
+int_mode_for_mode (mode)
+     enum machine_mode mode;
+{
+  switch (GET_MODE_CLASS (mode))
+    {
+    case MODE_INT:
+    case MODE_PARTIAL_INT:
+      break;
+
+    case MODE_COMPLEX_INT:
+    case MODE_COMPLEX_FLOAT:
+    case MODE_FLOAT:
+      mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
+      break;
+
+    case MODE_RANDOM:
+      if (mode == BLKmode)
+        break;
+      /* FALLTHRU */
+
+    case MODE_CC:
+    default:
+      abort();
+    }
+
+  return mode;
+}
+
 /* Return the value of VALUE, rounded up to a multiple of DIVISOR.  */
 
 tree
@@ -783,6 +814,7 @@ layout_type (type)
            tree ub = TYPE_MAX_VALUE (index);
            tree lb = TYPE_MIN_VALUE (index);
            tree length;
+           tree element_size;
 
            /* If UB is max (lb - 1, x), remove the MAX_EXPR since the
               test for negative below covers it.  */
@@ -815,15 +847,30 @@ layout_type (type)
                && TREE_CODE (TYPE_MAX_VALUE (index)) != INTEGER_CST)
              length = size_binop (MAX_EXPR, length, size_zero_node);
 
-           TYPE_SIZE (type) = size_binop (MULT_EXPR, TYPE_SIZE (element),
-                                          length);
+           /* Special handling for arrays of bits (for Chill).  */
+           element_size = TYPE_SIZE (element);
+           if (TYPE_PACKED (type) && INTEGRAL_TYPE_P (element))
+             {
+               HOST_WIDE_INT maxvalue, minvalue;
+               maxvalue = TREE_INT_CST_LOW (TYPE_MAX_VALUE (element));
+               minvalue = TREE_INT_CST_LOW (TYPE_MIN_VALUE (element));
+               if (maxvalue - minvalue == 1
+                   && (maxvalue == 1 || maxvalue == 0))
+                 element_size = integer_one_node;
+             }
+
+           TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size, length);
 
            /* If we know the size of the element, calculate the total
               size directly, rather than do some division thing below.
               This optimization helps Fortran assumed-size arrays
               (where the size of the array is determined at runtime)
-              substantially.  */
-           if (TYPE_SIZE_UNIT (element) != 0)
+              substantially.
+              Note that we can't do this in the case where the size of
+              the elements is one bit since TYPE_SIZE_UNIT cannot be
+              set correctly in that case.  */
+           if (TYPE_SIZE_UNIT (element) != 0
+               && element_size != integer_one_node)
              {
                TYPE_SIZE_UNIT (type)
                  = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (element), length);
@@ -1335,7 +1382,7 @@ get_best_mode (bitsize, bitpos, align, largest_mode, volatilep)
 
 void
 save_storage_status (p)
-     struct function *p;
+     struct function *p ATTRIBUTE_UNUSED;
 {
 #if 0  /* Need not save, since always 0 and non0 (resp.) within a function.  */
   p->pending_sizes = pending_sizes;
@@ -1348,7 +1395,7 @@ save_storage_status (p)
 
 void
 restore_storage_status (p)
-     struct function *p;
+     struct function *p ATTRIBUTE_UNUSED;
 {
 #if 0
   pending_sizes = p->pending_sizes;