diff options
Diffstat (limited to 'contrib/gcc/stor-layout.c')
-rw-r--r-- | contrib/gcc/stor-layout.c | 288 |
1 files changed, 201 insertions, 87 deletions
diff --git a/contrib/gcc/stor-layout.c b/contrib/gcc/stor-layout.c index e743c37..043ad28 100644 --- a/contrib/gcc/stor-layout.c +++ b/contrib/gcc/stor-layout.c @@ -1,5 +1,5 @@ /* C-compiler utilities for types and variables storage layout - Copyright (C) 1987, 88, 92, 93, 94, 1995 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc. This file is part of GNU CC. @@ -20,19 +20,22 @@ Boston, MA 02111-1307, USA. */ #include "config.h" -#include <stdio.h> +#include "system.h" #include "tree.h" +#include "rtl.h" #include "flags.h" +#include "except.h" #include "function.h" +#include "expr.h" +#include "toplev.h" #define CEIL(x,y) (((x) + (y) - 1) / (y)) /* Data type for the expressions representing sizes of data types. - It is the first integer type laid out. - In C, this is int. */ + It is the first integer type laid out. */ -tree sizetype; +struct sizetype_tab sizetype_tab; /* An integer constant with value 0 whose type is sizetype. */ @@ -50,10 +53,6 @@ int maximum_field_alignment; May be overridden by front-ends. */ int set_alignment = 0; -#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)); @@ -254,13 +253,14 @@ 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); - else if (flag_pack_struct) + else if (DECL_PACKED (decl)) DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT); } if (DECL_BIT_FIELD (decl) && TYPE_SIZE (type) != 0 - && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) + && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST + && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT) { register enum machine_mode xmode = mode_for_size (TREE_INT_CST_LOW (DECL_SIZE (decl)), MODE_INT, 1); @@ -277,6 +277,15 @@ layout_decl (decl, known_align) } } + /* Turn off DECL_BIT_FIELD if we won't need it set. */ + if (DECL_BIT_FIELD (decl) && TYPE_MODE (type) == BLKmode + && known_align % TYPE_ALIGN (type) == 0 + && DECL_SIZE (decl) != 0 + && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST + || (TREE_INT_CST_LOW (DECL_SIZE (decl)) % BITS_PER_UNIT) == 0) + && DECL_ALIGN (decl) >= TYPE_ALIGN (type)) + DECL_BIT_FIELD (decl) = 0; + /* Evaluate nonconstant size only once, either now or as soon as safe. */ if (DECL_SIZE (decl) != 0 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST) DECL_SIZE (decl) = variable_size (DECL_SIZE (decl)); @@ -299,11 +308,7 @@ layout_record (rec) tree rec; { register tree field; -#ifdef STRUCTURE_SIZE_BOUNDARY - unsigned record_align = MAX (STRUCTURE_SIZE_BOUNDARY, TYPE_ALIGN (rec)); -#else unsigned record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec)); -#endif /* These must be laid out *after* the record is. */ tree pending_statics = NULL_TREE; /* Record size so far is CONST_SIZE + VAR_SIZE bits, @@ -311,17 +316,22 @@ layout_record (rec) and VAR_SIZE is a tree expression. If VAR_SIZE is null, the size is just CONST_SIZE. Naturally we try to avoid using VAR_SIZE. */ - register int const_size = 0; + register HOST_WIDE_INT const_size = 0; register tree var_size = 0; /* Once we start using VAR_SIZE, this is the maximum alignment that we know VAR_SIZE has. */ register int var_align = BITS_PER_UNIT; +#ifdef STRUCTURE_SIZE_BOUNDARY + /* Packed structures don't need to have minimum size. */ + if (! TYPE_PACKED (rec)) + record_align = MAX (record_align, STRUCTURE_SIZE_BOUNDARY); +#endif for (field = TYPE_FIELDS (rec); field; field = TREE_CHAIN (field)) { register int known_align = var_size ? var_align : const_size; - register int desired_align; + register int desired_align = 0; /* If FIELD is static, then treat it like a separate variable, not really like a structure field. @@ -329,7 +339,7 @@ layout_record (rec) In both cases, all we do is lay out the decl, and we do it *after* the record is laid out. */ - if (TREE_STATIC (field)) + if (TREE_CODE (field) == VAR_DECL) { pending_statics = tree_cons (NULL_TREE, field, pending_statics); continue; @@ -352,6 +362,9 @@ layout_record (rec) #ifdef BIGGEST_FIELD_ALIGNMENT desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT); #endif +#ifdef ADJUST_FIELD_ALIGN + desired_align = ADJUST_FIELD_ALIGN (field, desired_align); +#endif /* Record must have at least as much alignment as any field. Otherwise, the alignment of the field within the record @@ -379,7 +392,7 @@ layout_record (rec) int type_align = TYPE_ALIGN (TREE_TYPE (field)); if (maximum_field_alignment != 0) type_align = MIN (type_align, maximum_field_alignment); - else if (flag_pack_struct) + else if (DECL_PACKED (field)) type_align = MIN (type_align, BITS_PER_UNIT); record_align = MAX (record_align, type_align); @@ -408,7 +421,7 @@ layout_record (rec) { if (const_size > 0) var_size = size_binop (PLUS_EXPR, var_size, - size_int (const_size)); + bitsize_int (const_size, 0L)); const_size = 0; var_size = round_up (var_size, desired_align); var_align = MIN (var_align, desired_align); @@ -421,23 +434,18 @@ layout_record (rec) && TREE_TYPE (field) != error_mark_node && DECL_BIT_FIELD_TYPE (field) && !DECL_PACKED (field) - /* If #pragma pack is in effect, turn off this feature. */ && maximum_field_alignment == 0 - && !flag_pack_struct && !integer_zerop (DECL_SIZE (field))) { int type_align = TYPE_ALIGN (TREE_TYPE (field)); register tree dsize = DECL_SIZE (field); int field_size = TREE_INT_CST_LOW (dsize); - /* A bit field may not span the unit of alignment of its type. - Advance to next boundary if necessary. */ - /* ??? There is some uncertainty here as to what - should be done if type_align is less than the width of the type. - That can happen because the width exceeds BIGGEST_ALIGNMENT - or because it exceeds maximum_field_alignment. */ - if (const_size / type_align - != (const_size + (field_size % type_align) - 1) / type_align) + /* A bit field may not span more units of alignment of its type + than its type itself. Advance to next boundary if necessary. */ + if (((const_size + field_size + type_align - 1) / type_align + - const_size / type_align) + > TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (field))) / type_align) const_size = CEIL (const_size, type_align) * type_align; } #endif @@ -458,11 +466,15 @@ layout_record (rec) if (maximum_field_alignment != 0) type_align = MIN (type_align, maximum_field_alignment); - else if (flag_pack_struct) + /* ??? This test is opposite the test in the containing if + statement, so this code is unreachable currently. */ + else if (DECL_PACKED (field)) type_align = MIN (type_align, BITS_PER_UNIT); /* A bit field may not span the unit of alignment of its type. Advance to next boundary if necessary. */ + /* ??? This code should match the code above for the + PCC_BITFIELD_TYPE_MATTERS case. */ if (const_size / type_align != (const_size + field_size - 1) / type_align) const_size = CEIL (const_size, type_align) * type_align; @@ -473,7 +485,7 @@ layout_record (rec) if (var_size && const_size) DECL_FIELD_BITPOS (field) - = size_binop (PLUS_EXPR, var_size, size_int (const_size)); + = size_binop (PLUS_EXPR, var_size, bitsize_int (const_size, 0L)); else if (var_size) DECL_FIELD_BITPOS (field) = var_size; else @@ -499,8 +511,9 @@ layout_record (rec) if (dsize == 0) /* Do nothing. */; else if (TREE_CODE (dsize) == INTEGER_CST + && ! TREE_CONSTANT_OVERFLOW (dsize) && TREE_INT_CST_HIGH (dsize) == 0 - && TREE_INT_CST_LOW (dsize) + const_size > const_size) + && TREE_INT_CST_LOW (dsize) + const_size >= const_size) /* Use const_size if there's no overflow. */ const_size += TREE_INT_CST_LOW (dsize); else @@ -525,7 +538,7 @@ layout_record (rec) { if (const_size) var_size - = size_binop (PLUS_EXPR, var_size, size_int (const_size)); + = size_binop (PLUS_EXPR, var_size, bitsize_int (const_size, 0L)); TYPE_SIZE (rec) = var_size; } @@ -536,6 +549,11 @@ layout_record (rec) TYPE_ALIGN (rec) = MAX (TYPE_ALIGN (rec), record_align); #endif + /* Record the un-rounded size in the binfo node. But first we check + the size of TYPE_BINFO to make sure that BINFO_SIZE is available. */ + if (TYPE_BINFO (rec) && TREE_VEC_LENGTH (TYPE_BINFO (rec)) > 6) + TYPE_BINFO_SIZE (rec) = TYPE_SIZE (rec); + #ifdef ROUND_TYPE_SIZE TYPE_SIZE (rec) = ROUND_TYPE_SIZE (rec, TYPE_SIZE (rec), TYPE_ALIGN (rec)); #else @@ -557,11 +575,7 @@ layout_union (rec) tree rec; { register tree field; -#ifdef STRUCTURE_SIZE_BOUNDARY - unsigned union_align = STRUCTURE_SIZE_BOUNDARY; -#else unsigned union_align = BITS_PER_UNIT; -#endif /* The size of the union, based on the fields scanned so far, is max (CONST_SIZE, VAR_SIZE). @@ -569,6 +583,12 @@ layout_union (rec) register int const_size = 0; register tree var_size = 0; +#ifdef STRUCTURE_SIZE_BOUNDARY + /* Packed structures don't need to have minimum size. */ + if (! TYPE_PACKED (rec)) + union_align = STRUCTURE_SIZE_BOUNDARY; +#endif + /* If this is a QUAL_UNION_TYPE, we want to process the fields in the reverse order in building the COND_EXPR that denotes its size. We reverse them again later. */ @@ -582,7 +602,7 @@ layout_union (rec) continue; layout_decl (field, 0); - DECL_FIELD_BITPOS (field) = size_int (0); + DECL_FIELD_BITPOS (field) = bitsize_int (0L, 0L); /* Union must be at least as aligned as any field requires. */ @@ -612,7 +632,7 @@ layout_union (rec) else if (TREE_CODE (rec) == QUAL_UNION_TYPE) var_size = fold (build (COND_EXPR, sizetype, DECL_QUALIFIER (field), DECL_SIZE (field), - var_size ? var_size : integer_zero_node)); + var_size ? var_size : bitsize_int (0L, 0L))); } if (TREE_CODE (rec) == QUAL_UNION_TYPE) @@ -620,13 +640,13 @@ layout_union (rec) /* Determine the ultimate size of the union (in bytes). */ if (NULL == var_size) - TYPE_SIZE (rec) = size_int (CEIL (const_size, BITS_PER_UNIT) - * BITS_PER_UNIT); + TYPE_SIZE (rec) = bitsize_int (CEIL (const_size, BITS_PER_UNIT) + * BITS_PER_UNIT, 0L); else if (const_size == 0) TYPE_SIZE (rec) = var_size; else TYPE_SIZE (rec) = size_binop (MAX_EXPR, var_size, - round_up (size_int (const_size), + round_up (bitsize_int (const_size, 0L), BITS_PER_UNIT)); /* Determine the desired alignment. */ @@ -685,20 +705,28 @@ layout_type (type) of the language-specific code. */ abort (); + case BOOLEAN_TYPE: /* Used for Java, Pascal, and Chill. */ + if (TYPE_PRECISION (type) == 0) + TYPE_PRECISION (type) = 1; /* default to one byte/boolean. */ + /* ... fall through ... */ + case INTEGER_TYPE: case ENUMERAL_TYPE: + case CHAR_TYPE: if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST && tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0) TREE_UNSIGNED (type) = 1; TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type), MODE_INT); - TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type))); + TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)), 0L); + TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type))); break; case REAL_TYPE: TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0); - TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type))); + TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)), 0L); + TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type))); break; case COMPLEX_TYPE: @@ -708,30 +736,35 @@ layout_type (type) (TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE ? MODE_COMPLEX_INT : MODE_COMPLEX_FLOAT), 0); - TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type))); + TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)), 0L); + TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type))); break; case VOID_TYPE: TYPE_SIZE (type) = size_zero_node; + TYPE_SIZE_UNIT (type) = size_zero_node; TYPE_ALIGN (type) = 1; TYPE_MODE (type) = VOIDmode; break; case OFFSET_TYPE: - TYPE_SIZE (type) = size_int (POINTER_SIZE); + TYPE_SIZE (type) = bitsize_int (POINTER_SIZE, 0L); + TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT); TYPE_MODE (type) = ptr_mode; break; case FUNCTION_TYPE: case METHOD_TYPE: TYPE_MODE (type) = mode_for_size (2 * POINTER_SIZE, MODE_INT, 0); - TYPE_SIZE (type) = size_int (2 * POINTER_SIZE); + TYPE_SIZE (type) = bitsize_int (2 * POINTER_SIZE, 0); + TYPE_SIZE_UNIT (type) = size_int ((2 * POINTER_SIZE) / BITS_PER_UNIT); break; case POINTER_TYPE: case REFERENCE_TYPE: TYPE_MODE (type) = ptr_mode; - TYPE_SIZE (type) = size_int (POINTER_SIZE); + TYPE_SIZE (type) = bitsize_int (POINTER_SIZE, 0L); + TYPE_SIZE_UNIT (type) = size_int (POINTER_SIZE / BITS_PER_UNIT); TREE_UNSIGNED (type) = 1; TYPE_PRECISION (type) = POINTER_SIZE; break; @@ -767,8 +800,11 @@ layout_type (type) lb, 0)) ub = TREE_OPERAND (ub, 0); + /* The initial subtraction should happen in the original type so + that (possible) negative values are handled appropriately. */ length = size_binop (PLUS_EXPR, size_one_node, - size_binop (MINUS_EXPR, ub, lb)); + fold (build (MINUS_EXPR, TREE_TYPE (lb), + ub, lb))); /* If neither bound is a constant and sizetype is signed, make sure the size is never negative. We should really do this @@ -779,8 +815,19 @@ 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, length, - TYPE_SIZE (element)); + TYPE_SIZE (type) = size_binop (MULT_EXPR, TYPE_SIZE (element), + 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) + { + TYPE_SIZE_UNIT (type) + = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (element), length); + } } /* Now round the alignment and size, @@ -795,8 +842,15 @@ layout_type (type) #ifdef ROUND_TYPE_SIZE if (TYPE_SIZE (type) != 0) - TYPE_SIZE (type) - = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type)); + { + tree tmp; + tmp = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type)); + /* If the rounding changed the size of the type, remove any + pre-calculated TYPE_SIZE_UNIT. */ + if (simple_cst_equal (TYPE_SIZE (type), tmp) != 1) + TYPE_SIZE_UNIT (type) = NULL; + TYPE_SIZE (type) = tmp; + } #endif TYPE_MODE (type) = BLKmode; @@ -828,6 +882,8 @@ layout_type (type) if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) { tree field; + enum machine_mode mode = VOIDmode; + /* A record which has any BLKmode members must itself be BLKmode; it can't go in a register. Unless the member is BLKmode only because it isn't aligned. */ @@ -853,13 +909,23 @@ layout_type (type) != ((TREE_INT_CST_LOW (DECL_SIZE (field)) + bitpos - 1) / BITS_PER_WORD) /* But there is no problem if the field is entire words. */ - && TREE_INT_CST_LOW (DECL_SIZE (field)) % BITS_PER_WORD == 0) + && TREE_INT_CST_LOW (DECL_SIZE (field)) % BITS_PER_WORD != 0) goto record_lose; + + /* 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. */ + if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field))) + mode = DECL_MODE (field); } - TYPE_MODE (type) - = mode_for_size (TREE_INT_CST_LOW (TYPE_SIZE (type)), - MODE_INT, 1); + if (mode != VOIDmode) + /* We only have one real field; use its mode. */ + TYPE_MODE (type) = mode; + else + TYPE_MODE (type) + = mode_for_size (TREE_INT_CST_LOW (TYPE_SIZE (type)), + MODE_INT, 1); /* If structure's known alignment is less than what the scalar mode would need, and it matters, @@ -922,25 +988,7 @@ layout_type (type) } break; - /* Pascal and Chill types */ - case BOOLEAN_TYPE: /* store one byte/boolean for now. */ - TYPE_MODE (type) = QImode; - TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type))); - TYPE_PRECISION (type) = 1; - TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type)); - if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST - && tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0) - TREE_UNSIGNED (type) = 1; - break; - - case CHAR_TYPE: - TYPE_MODE (type) = QImode; - TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type))); - TYPE_PRECISION (type) = GET_MODE_BITSIZE (TYPE_MODE (type)); - TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type)); - break; - - case SET_TYPE: + case SET_TYPE: /* Used by Chill and Pascal. */ if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) != INTEGER_CST || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) != INTEGER_CST) abort(); @@ -950,16 +998,17 @@ layout_type (type) #define SET_WORD_SIZE BITS_PER_WORD #endif int alignment = set_alignment ? set_alignment : SET_WORD_SIZE; - int size_in_bits = - TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) - - TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) + 1; + int size_in_bits + = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + - TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) + 1); int rounded_size = ((size_in_bits + alignment - 1) / alignment) * alignment; if (rounded_size > alignment) TYPE_MODE (type) = BLKmode; else TYPE_MODE (type) = mode_for_size (alignment, MODE_INT, 1); - TYPE_SIZE (type) = size_int (rounded_size); + TYPE_SIZE (type) = bitsize_int (rounded_size, 0L); + TYPE_SIZE_UNIT (type) = size_int (rounded_size / BITS_PER_UNIT); TYPE_ALIGN (type) = alignment; TYPE_PRECISION (type) = size_in_bits; } @@ -992,6 +1041,19 @@ layout_type (type) if (TYPE_SIZE (type) != 0 && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) TYPE_SIZE (type) = variable_size (TYPE_SIZE (type)); + /* If we failed to find a simple way to calculate the unit size + of the type above, find it by division. */ + if (TYPE_SIZE_UNIT (type) == 0 && TYPE_SIZE (type) != 0) + { + TYPE_SIZE_UNIT (type) = size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (type), + size_int (BITS_PER_UNIT)); + } + + /* Once again evaluate only once, either now or as soon as safe. */ + if (TYPE_SIZE_UNIT (type) != 0 + && TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST) + TYPE_SIZE_UNIT (type) = variable_size (TYPE_SIZE_UNIT (type)); + /* Also layout any other variants of the type. */ if (TYPE_NEXT_VARIANT (type) || type != TYPE_MAIN_VARIANT (type)) @@ -999,6 +1061,7 @@ layout_type (type) tree variant; /* Record layout info of this variant. */ tree size = TYPE_SIZE (type); + tree size_unit = TYPE_SIZE_UNIT (type); int align = TYPE_ALIGN (type); enum machine_mode mode = TYPE_MODE (type); @@ -1008,6 +1071,7 @@ layout_type (type) variant = TYPE_NEXT_VARIANT (variant)) { TYPE_SIZE (variant) = size; + TYPE_SIZE_UNIT (variant) = size_unit; TYPE_ALIGN (variant) = align; TYPE_MODE (variant) = mode; } @@ -1053,9 +1117,7 @@ make_signed_type (precision) is the type for size values. */ if (sizetype == 0) - { - sizetype = type; - } + set_sizetype (type); /* Lay out the type: set its alignment, size, etc. */ @@ -1079,13 +1141,65 @@ make_unsigned_type (precision) if (sizetype == 0) { - sizetype = type; + TREE_UNSIGNED (type) = 1; + set_sizetype (type); } fixup_unsigned_type (type); return type; } +/* Set sizetype to TYPE, and initialize *sizetype accordingly. + Also update the type of any standard type's sizes made so far. */ + +void +set_sizetype (type) + tree type; +{ + int oprecision = TYPE_PRECISION (type), precision; + + sizetype = type; + + /* The *bitsizetype types use a precision that avoids overflows when + calculating signed sizes / offsets in bits. + + We are allocating bitsizetype once and change it in place when + we decide later that we want to change it. This way, we avoid the + hassle of changing all the TYPE_SIZE (TREE_TYPE (sometype)) + individually in each front end. */ + if (! bitsizetype) + bitsizetype = make_node (INTEGER_TYPE); + if (TYPE_NAME (sizetype) && ! TYPE_NAME (bitsizetype)) + TYPE_NAME (bitsizetype) = TYPE_NAME (sizetype); + + precision = oprecision + BITS_PER_UNIT_LOG + 1; + /* However, when cross-compiling from a 32 bit to a 64 bit host, + we are limited to 64 bit precision. */ + if (precision > 2 * HOST_BITS_PER_WIDE_INT) + precision = 2 * HOST_BITS_PER_WIDE_INT; + TYPE_PRECISION (bitsizetype) = precision; + if (TREE_UNSIGNED (type)) + fixup_unsigned_type (bitsizetype); + else + fixup_signed_type (bitsizetype); + layout_type (bitsizetype); + + if (TREE_UNSIGNED (type)) + { + usizetype = sizetype; + ubitsizetype = bitsizetype; + ssizetype = make_signed_type (oprecision); + sbitsizetype = make_signed_type (precision); + } + else + { + ssizetype = sizetype; + sbitsizetype = bitsizetype; + usizetype = make_unsigned_type (oprecision); + ubitsizetype = make_unsigned_type (precision); + } +} + /* Set the extreme values of TYPE based on its precision in bits, then lay it out. Used when make_signed_type won't do because the tree code is not INTEGER_TYPE. @@ -1170,14 +1284,14 @@ get_best_mode (bitsize, bitpos, align, largest_mode, volatilep) int volatilep; { enum machine_mode mode; - int unit; + int unit = 0; /* Find the narrowest integer mode that contains the bit field. */ for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) { unit = GET_MODE_BITSIZE (mode); - if (bitpos / unit == (bitpos + bitsize - 1) / unit) + if ((bitpos % unit) + bitsize <= unit) break; } |