X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fstor-layout.c;h=98420fb2dafcfbd0f72d89bf22c04bdc76530ec7;hb=7d22b398620fcbf8df083b5283aac02a6f9f370b;hp=a7ffd4cb6d838f921a89070de720c0a18b6813a7;hpb=0e9fefce708a273f0b4aa4356125eee84df955bc;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index a7ffd4cb6d8..98420fb2daf 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -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 (); @@ -298,20 +298,7 @@ int_mode_for_mode (enum machine_mode mode) unsigned int get_mode_alignment (enum machine_mode mode) { - unsigned int alignment; - - if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT - || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT) - alignment = GET_MODE_UNIT_SIZE (mode); - else - alignment = GET_MODE_SIZE (mode); - - /* Extract the LSB of the size. */ - alignment = alignment & -alignment; - alignment *= BITS_PER_UNIT; - - alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment)); - return alignment; + return MIN (BIGGEST_ALIGNMENT, MAX (1, mode_base_align[mode]*BITS_PER_UNIT)); } /* Return the value of VALUE, rounded up to a multiple of DIVISOR. @@ -410,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; @@ -446,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)); @@ -463,16 +454,21 @@ 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. */; + round up; we'll reduce it again below. We want packing 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. */ + 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) - && !DECL_USER_ALIGN (decl) + && !old_user_align && (DECL_NONADDRESSABLE_P (decl) || DECL_SIZE_UNIT (decl) == 0 || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST)) @@ -2122,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"