diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 53c85b14906..428eccbe673 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +Wed Mar 29 15:39:10 2000 Richard Kenner + + * stor-layout.c (bit_from_pos, byte_from_pos): New functions. + (pos_from_byte, pos_from_bit, normalize_offset): Likewise. + (normalize_rli, rli_size_so_far, rli_size_unit_so_far): Use them. + * tree.c (bit_position, byte_position): Likewise. + * tree.h: Declare new functions. + 2000-03-29 Nick Clifton * config/arm/arm.c: Minor formatting changes/ diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 7621e61508e..966945fe9a2 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -433,6 +433,86 @@ start_record_layout (t) return rli; } +/* These four routines perform computations that convert between + the offset/bitpos forms and byte and bit offsets. */ + +tree +bit_from_pos (offset, bitpos) + tree offset, bitpos; +{ + return size_binop (PLUS_EXPR, bitpos, + size_binop (MULT_EXPR, convert (bitsizetype, offset), + bitsize_unit_node)); +} + +tree +byte_from_pos (offset, bitpos) + tree offset, bitpos; +{ + return size_binop (PLUS_EXPR, offset, + convert (sizetype, + size_binop (CEIL_DIV_EXPR, bitpos, + bitsize_unit_node))); +} + +void +pos_from_byte (poffset, pbitpos, off_align, pos) + tree *poffset, *pbitpos; + unsigned int off_align; + tree pos; +{ + *poffset + = size_binop (MULT_EXPR, + convert (sizetype, + size_binop (FLOOR_DIV_EXPR, pos, + bitsize_int (off_align + / BITS_PER_UNIT))), + size_int (off_align / BITS_PER_UNIT)); + *pbitpos = size_binop (MULT_EXPR, + size_binop (FLOOR_MOD_EXPR, pos, + bitsize_int (off_align / BITS_PER_UNIT)), + bitsize_unit_node); +} + +void +pos_from_bit (poffset, pbitpos, off_align, pos) + tree *poffset, *pbitpos; + unsigned int off_align; + tree pos; +{ + *poffset = size_binop (MULT_EXPR, + convert (sizetype, + size_binop (FLOOR_DIV_EXPR, pos, + bitsize_int (off_align))), + size_int (off_align / BITS_PER_UNIT)); + *pbitpos = size_binop (FLOOR_MOD_EXPR, pos, bitsize_int (off_align)); +} + +/* Given a pointer to bit and byte offsets and an offset alignment, + normalize the offsets so they are within the alignment. */ + +void +normalize_offset (poffset, pbitpos, off_align) + tree *poffset, *pbitpos; + unsigned int off_align; +{ + /* If the bit position is now larger than it should be, adjust it + downwards. */ + if (compare_tree_int (*pbitpos, off_align) >= 0) + { + tree extra_aligns = size_binop (FLOOR_DIV_EXPR, *pbitpos, + bitsize_int (off_align)); + + *poffset + = size_binop (PLUS_EXPR, *poffset, + size_binop (MULT_EXPR, convert (sizetype, extra_aligns), + size_int (off_align / BITS_PER_UNIT))); + + *pbitpos + = size_binop (FLOOR_MOD_EXPR, *pbitpos, bitsize_int (off_align)); + } +} + /* Print debugging information about the information in RLI. */ void @@ -462,22 +542,7 @@ void normalize_rli (rli) record_layout_info rli; { - /* If the bit position is now larger than it should be, adjust it - downwards. */ - if (compare_tree_int (rli->bitpos, rli->offset_align) >= 0) - { - tree extra_aligns = size_binop (FLOOR_DIV_EXPR, rli->bitpos, - bitsize_int (rli->offset_align)); - - rli->offset - = size_binop (PLUS_EXPR, rli->offset, - size_binop (MULT_EXPR, convert (sizetype, extra_aligns), - size_int (rli->offset_align - / BITS_PER_UNIT))); - - rli->bitpos = size_binop (FLOOR_MOD_EXPR, rli->bitpos, - bitsize_int (rli->offset_align)); - } + normalize_offset (&rli->offset, &rli->bitpos, rli->offset_align); } /* Returns the size in bytes allocated so far. */ @@ -486,10 +551,7 @@ tree rli_size_unit_so_far (rli) record_layout_info rli; { - return size_binop (PLUS_EXPR, rli->offset, - convert (sizetype, - size_binop (CEIL_DIV_EXPR, rli->bitpos, - bitsize_unit_node))); + return byte_from_pos (rli->offset, rli->bitpos); } /* Returns the size in bits allocated so far. */ @@ -498,9 +560,7 @@ tree rli_size_so_far (rli) record_layout_info rli; { - return size_binop (PLUS_EXPR, rli->bitpos, - size_binop (MULT_EXPR, convert (bitsizetype, rli->offset), - bitsize_unit_node)); + return bit_from_pos (rli->offset, rli->bitpos); } /* Called from place_field to handle unions. */ diff --git a/gcc/tree.c b/gcc/tree.c index 381d5f0ed1d..826327e0ee6 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -2321,11 +2321,9 @@ tree bit_position (field) tree field; { - return size_binop (PLUS_EXPR, DECL_FIELD_BIT_OFFSET (field), - size_binop (MULT_EXPR, - convert (bitsizetype, - DECL_FIELD_OFFSET (field)), - bitsize_unit_node)); + + return bit_from_pos (DECL_FIELD_OFFSET (field), + DECL_FIELD_BIT_OFFSET (field)); } /* Likewise, but return as an integer. Abort if it cannot be represented @@ -2346,11 +2344,8 @@ tree byte_position (field) tree field; { - return size_binop (PLUS_EXPR, DECL_FIELD_OFFSET (field), - convert (sizetype, - size_binop (FLOOR_DIV_EXPR, - DECL_FIELD_BIT_OFFSET (field), - bitsize_unit_node))); + return byte_from_pos (DECL_FIELD_OFFSET (field), + DECL_FIELD_BIT_OFFSET (field)); } /* Likewise, but return as an integer. Abort if it cannot be represented diff --git a/gcc/tree.h b/gcc/tree.h index bc1e01d2510..95f68ab93f1 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1802,6 +1802,14 @@ typedef struct record_layout_info } *record_layout_info; extern record_layout_info start_record_layout PARAMS ((tree)); +extern tree bit_from_pos PARAMS ((tree, tree)); +extern tree byte_from_pos PARAMS ((tree, tree)); +extern void pos_from_byte PARAMS ((tree *, tree *, unsigned int, + tree)); +extern void pos_from_bit PARAMS ((tree *, tree *, unsigned int, + tree)); +extern void normalize_offset PARAMS ((tree *, tree *, + unsigned int)); extern tree rli_size_unit_so_far PARAMS ((record_layout_info)); extern tree rli_size_so_far PARAMS ((record_layout_info)); extern void normalize_rli PARAMS ((record_layout_info));