aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1993-06-27 21:14:04 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1993-06-27 21:14:04 -0400
commit5e9bec999ea3f54fc6abfabc9d43bacfdd550892 (patch)
tree389918c825ddc54d4c8b37ba134c9a83bac5395e
parent457a2d9ce658ff0e39f6c0b7bf23de5470e4c7a8 (diff)
downloadgcc-5e9bec999ea3f54fc6abfabc9d43bacfdd550892.zip
gcc-5e9bec999ea3f54fc6abfabc9d43bacfdd550892.tar.gz
gcc-5e9bec999ea3f54fc6abfabc9d43bacfdd550892.tar.bz2
Add prototypes for layout_record and layout_union.
(smallest_mode_for_size): New function. (variable_size): Allow variable sizes if global_bindings_p returns a negative value. (mode_for_size): Fix incorrect comment. (layout_decl): If DECL has a size already, don't copy from type. (layout_type, case INTEGER_TYPE, ENUMERAL_TYPE): Use smallest integer mode that fits, whether or not it fits exactly. From-SVN: r4776
-rw-r--r--gcc/stor-layout.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index c0efe3d..620c0bb 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -1,5 +1,5 @@
/* C-compiler utilities for types and variables storage layout
- Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1992, 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -47,6 +47,11 @@ int maximum_field_alignment;
#define GET_MODE_ALIGNMENT(MODE) \
MIN (BIGGEST_ALIGNMENT, \
MAX (1, (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT)))
+
+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));
/* SAVE_EXPRs for sizes of types and decls, waiting to be expanded. */
@@ -79,7 +84,13 @@ variable_size (size)
{
size = save_expr (size);
- if (global_bindings_p ())
+ /* If the language-processor is to take responsibility for variable-sized
+ items (e.g., languages which have elaboration procedures like Ada),
+ just return SIZE unchanged. */
+ if (global_bindings_p () < 0)
+ return size;
+
+ else if (global_bindings_p ())
{
if (TREE_CONSTANT (size))
error ("type size can't be explicitly evaluated");
@@ -120,7 +131,7 @@ mode_for_size (size, class, limit)
if (limit && size > MAX_FIXED_MODE_SIZE)
return BLKmode;
- /* Get the last mode which has this size, in the specified class. */
+ /* 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)
@@ -129,6 +140,26 @@ mode_for_size (size, class, limit)
return BLKmode;
}
+/* Similar, but never return BLKmode; return the narrowest mode that
+ contains at least the requested number of bits. */
+
+static enum machine_mode
+smallest_mode_for_size (size, class)
+ unsigned int size;
+ enum mode_class class;
+{
+ register enum machine_mode mode;
+
+ /* Get the first mode which has at least 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)
+ return mode;
+
+ abort ();
+}
+
/* Return the value of VALUE, rounded up to a multiple of DIVISOR. */
tree
@@ -179,8 +210,9 @@ layout_decl (decl, known_align)
/* Usually the size and mode come from the data type without change. */
DECL_MODE (decl) = TYPE_MODE (type);
- DECL_SIZE (decl) = TYPE_SIZE (type);
TREE_UNSIGNED (decl) = TREE_UNSIGNED (type);
+ if (DECL_SIZE (decl) == 0)
+ DECL_SIZE (decl) = TYPE_SIZE (type);
if (code == FIELD_DECL && DECL_BIT_FIELD (decl))
{
@@ -669,11 +701,8 @@ layout_type (type)
if (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) >= 0)
TREE_UNSIGNED (type) = 1;
- /* We pass 0 for the last arg of mode_for_size because otherwise
- on the Apollo using long long causes a crash.
- It seems better to use integer modes than to try to support
- integer types with BLKmode. */
- TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_INT, 0);
+ TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type),
+ MODE_INT);
TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
break;