diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/expr.c | 14 | ||||
-rw-r--r-- | gcc/stor-layout.c | 16 |
3 files changed, 34 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 37fc76e1180..964849e1c3c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Mon Jul 27 17:18:52 1998 Dave Brolley <brolley@cygnus.com> + + * stor-layout.c (layout_type): Handle arrays of bits, for Chill. + + * expr.c (get_inner_reference): Handle zero-based, unsigned, array + index conversion. + Mon Jul 27 14:51:33 1998 Jeffrey A Law (law@cygnus.com) * mn10300.h (DEBUGGER_AUTO_OFFSET): Define. diff --git a/gcc/expr.c b/gcc/expr.c index fd43689724b..208db5cb2d8 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -4546,8 +4546,20 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode, index_type = TREE_TYPE (index); } + /* Optimize the special-case of a zero lower bound. + + We convert the low_bound to sizetype to avoid some problems + with constant folding. (E.g. suppose the lower bound is 1, + and its mode is QI. Without the conversion, (ARRAY + +(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1)) + +INDEX), which becomes (ARRAY+255+INDEX). Oops!) + + But sizetype isn't quite right either (especially if + the lowbound is negative). FIXME */ + if (! integer_zerop (low_bound)) - index = fold (build (MINUS_EXPR, index_type, index, low_bound)); + index = fold (build (MINUS_EXPR, index_type, index, + convert (sizetype, low_bound))); if (TREE_CODE (index) == INTEGER_CST) { diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 043ad286be3..b44a411e9da 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -783,6 +783,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,8 +816,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, 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. |