summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/stor-layout.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>1999-10-16 06:09:09 +0000
committerobrien <obrien@FreeBSD.org>1999-10-16 06:09:09 +0000
commitcae8fa8120c70195f34a2456f18c4c848a2d3e0c (patch)
treef7d3a3ab9c32694206552e767626366f016f2062 /contrib/gcc/stor-layout.c
parent84656b55b6e25e30322dc903a05de53706361d3d (diff)
downloadFreeBSD-src-cae8fa8120c70195f34a2456f18c4c848a2d3e0c.zip
FreeBSD-src-cae8fa8120c70195f34a2456f18c4c848a2d3e0c.tar.gz
Virgin import of the GCC 2.95.1 compilers
Diffstat (limited to 'contrib/gcc/stor-layout.c')
-rw-r--r--contrib/gcc/stor-layout.c98
1 files changed, 78 insertions, 20 deletions
diff --git a/contrib/gcc/stor-layout.c b/contrib/gcc/stor-layout.c
index 043ad28..798a795 100644
--- a/contrib/gcc/stor-layout.c
+++ b/contrib/gcc/stor-layout.c
@@ -53,8 +53,6 @@ int maximum_field_alignment;
May be overridden by front-ends. */
int set_alignment = 0;
-static enum machine_mode smallest_mode_for_size PROTO((unsigned int,
- enum mode_class));
static tree layout_record PROTO((tree));
static void layout_union PROTO((tree));
@@ -144,13 +142,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;
@@ -159,7 +157,7 @@ mode_for_size (size, class, limit)
/* Similar, but never return BLKmode; return the narrowest mode that
contains at least the requested number of bits. */
-static enum machine_mode
+enum machine_mode
smallest_mode_for_size (size, class)
unsigned int size;
enum mode_class class;
@@ -170,12 +168,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
@@ -252,7 +281,8 @@ layout_decl (decl, known_align)
{
DECL_BIT_FIELD_TYPE (decl) = DECL_BIT_FIELD (decl) ? type : 0;
if (maximum_field_alignment != 0)
- DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
+ DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl),
+ (unsigned)maximum_field_alignment);
else if (DECL_PACKED (decl))
DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
}
@@ -268,7 +298,7 @@ layout_decl (decl, known_align)
if (xmode != BLKmode
&& known_align % GET_MODE_ALIGNMENT (xmode) == 0)
{
- DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
+ DECL_ALIGN (decl) = MAX ((unsigned) GET_MODE_ALIGNMENT (xmode),
DECL_ALIGN (decl));
DECL_MODE (decl) = xmode;
DECL_SIZE (decl) = size_int (GET_MODE_BITSIZE (xmode));
@@ -382,7 +412,7 @@ layout_record (rec)
It does, however, affect the alignment of the next field
within the structure. */
if (! integer_zerop (DECL_SIZE (field)))
- record_align = MAX (record_align, desired_align);
+ record_align = MAX ((int)record_align, desired_align);
else if (! DECL_PACKED (field))
desired_align = TYPE_ALIGN (TREE_TYPE (field));
/* A named bit field of declared type `int'
@@ -395,11 +425,11 @@ layout_record (rec)
else if (DECL_PACKED (field))
type_align = MIN (type_align, BITS_PER_UNIT);
- record_align = MAX (record_align, type_align);
+ record_align = MAX ((int)record_align, type_align);
}
}
else
- record_align = MAX (record_align, desired_align);
+ record_align = MAX ((int)record_align, desired_align);
#endif
/* Does this field automatically have alignment it needs
@@ -783,6 +813,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 +846,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);
@@ -866,7 +912,7 @@ layout_type (type)
MODE_INT, 1);
if (STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT
- && TYPE_ALIGN (type) < TREE_INT_CST_LOW (TYPE_SIZE (type))
+ && (int)TYPE_ALIGN (type) < TREE_INT_CST_LOW (TYPE_SIZE (type))
&& TYPE_MODE (type) != BLKmode)
{
TYPE_NO_FORCE_BLK (type) = 1;
@@ -932,7 +978,7 @@ layout_type (type)
then stick with BLKmode. */
if (STRICT_ALIGNMENT
&& ! (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
- || (TYPE_ALIGN (type)
+ || ((int)TYPE_ALIGN (type)
>= TREE_INT_CST_LOW (TYPE_SIZE (type)))))
{
if (TYPE_MODE (type) != BLKmode)
@@ -964,7 +1010,7 @@ layout_type (type)
then stick with BLKmode. */
&& (! STRICT_ALIGNMENT
|| TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
- || TYPE_ALIGN (type) >= TREE_INT_CST_LOW (TYPE_SIZE (type))))
+ || (int)TYPE_ALIGN (type) >= TREE_INT_CST_LOW (TYPE_SIZE (type))))
{
tree field;
/* A union which has any BLKmode members must itself be BLKmode;
@@ -1037,6 +1083,18 @@ layout_type (type)
&& TREE_CODE (type) != ARRAY_TYPE)))
TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type));
+ /* Do machine-dependent extra alignment. */
+#ifdef ROUND_TYPE_ALIGN
+ TYPE_ALIGN (type)
+ = ROUND_TYPE_ALIGN (type, TYPE_ALIGN (type), BITS_PER_UNIT);
+#endif
+
+#ifdef ROUND_TYPE_SIZE
+ if (TYPE_SIZE (type) != 0)
+ TYPE_SIZE (type)
+ = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type));
+#endif
+
/* Evaluate nonconstant size only once, either now or as soon as safe. */
if (TYPE_SIZE (type) != 0 && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
TYPE_SIZE (type) = variable_size (TYPE_SIZE (type));
@@ -1335,7 +1393,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 +1406,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;
OpenPOWER on IntegriCloud