diff options
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/expr.c | 26 |
2 files changed, 20 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2ee859beb6c..30c4dca091d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2010-06-17 Richard Guenther <rguenther@suse.de> + + * expr.c (get_inner_reference): Use double_int for bit_offset + calculation. + 2010-06-16 DJ Delorie <dj@redhat.com> * common.opt (-fstrict-volatile-bitfields): new. diff --git a/gcc/expr.c b/gcc/expr.c index 0d0bb23fbf8..08efff7156f 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5984,7 +5984,7 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, enum machine_mode mode = VOIDmode; bool blkmode_bitfield = false; tree offset = size_zero_node; - tree bit_offset = bitsize_zero_node; + double_int bit_offset = double_int_zero; /* First get the mode, signedness, and size. We do this from just the outermost expression. */ @@ -6045,8 +6045,9 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, switch (TREE_CODE (exp)) { case BIT_FIELD_REF: - bit_offset = size_binop (PLUS_EXPR, bit_offset, - TREE_OPERAND (exp, 2)); + bit_offset + = double_int_add (bit_offset, + tree_to_double_int (TREE_OPERAND (exp, 2))); break; case COMPONENT_REF: @@ -6061,8 +6062,9 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, break; offset = size_binop (PLUS_EXPR, offset, this_offset); - bit_offset = size_binop (PLUS_EXPR, bit_offset, - DECL_FIELD_BIT_OFFSET (field)); + bit_offset = double_int_add (bit_offset, + tree_to_double_int + (DECL_FIELD_BIT_OFFSET (field))); /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN. */ } @@ -6094,8 +6096,8 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, break; case IMAGPART_EXPR: - bit_offset = size_binop (PLUS_EXPR, bit_offset, - bitsize_int (*pbitsize)); + bit_offset = double_int_add (bit_offset, + uhwi_to_double_int (*pbitsize)); break; case VIEW_CONVERT_EXPR: @@ -6126,9 +6128,11 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, this conversion. */ if (host_integerp (offset, 0)) { - double_int tem = double_int_mul (tree_to_double_int (offset), - uhwi_to_double_int (BITS_PER_UNIT)); - tem = double_int_add (tem, tree_to_double_int (bit_offset)); + double_int tem = double_int_lshift (tree_to_double_int (offset), + BITS_PER_UNIT == 8 + ? 3 : exact_log2 (BITS_PER_UNIT), + HOST_BITS_PER_DOUBLE_INT, true); + tem = double_int_add (tem, bit_offset); if (double_int_fits_in_shwi_p (tem)) { *pbitpos = double_int_to_shwi (tem); @@ -6139,7 +6143,7 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, /* Otherwise, split it up. */ if (offset) { - *pbitpos = tree_low_cst (bit_offset, 0); + *pbitpos = double_int_to_shwi (bit_offset); *poffset = offset; } |