New functions for manipulating position

Richard Kenner kenner@vlsi1.ultra.nyu.edu
Wed Mar 29 12:36:00 GMT 2000

I just commited this patch:

Wed Mar 29 15:39:10 2000  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

* 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.

*** stor-layout.c	2000/03/27 01:26:16	1.62
--- stor-layout.c	2000/03/29 19:56:50
*************** start_record_layout (t)
*** 434,437 ****
--- 434,517 ----
}

+ /* 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.  */

*************** normalize_rli (rli)
*** 463,482 ****
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));
!     }
}

--- 543,547 ----
record_layout_info rli;
{
!   normalize_offset (&rli->offset, &rli->bitpos, rli->offset_align);
}

*************** rli_size_unit_so_far (rli)
*** 487,494 ****
record_layout_info rli;
{
!   return size_binop (PLUS_EXPR, rli->offset,
! 		     convert (sizetype,
! 			      size_binop (CEIL_DIV_EXPR, rli->bitpos,
! 					  bitsize_unit_node)));
}

--- 552,556 ----
record_layout_info rli;
{
!   return byte_from_pos (rli->offset, rli->bitpos);
}

*************** rli_size_so_far (rli)
*** 499,505 ****
record_layout_info rli;
{
!   return size_binop (PLUS_EXPR, rli->bitpos,
! 		     size_binop (MULT_EXPR, convert (bitsizetype, rli->offset),
! 				 bitsize_unit_node));
}

--- 561,565 ----
record_layout_info rli;
{
!   return bit_from_pos (rli->offset, rli->bitpos);
}

*** tree.c	2000/03/26 19:01:54	1.132
--- tree.c	2000/03/29 19:57:40
*************** bit_position (field)
*** 2322,2330 ****
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));
}

--- 2322,2328 ----
tree field;
{
!
!   return bit_from_pos (DECL_FIELD_OFFSET (field),
! 		       DECL_FIELD_BIT_OFFSET (field));
}

*************** byte_position (field)
*** 2347,2355 ****
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)));
}

--- 2345,2350 ----
tree field;
{
!   return byte_from_pos (DECL_FIELD_OFFSET (field),
! 			DECL_FIELD_BIT_OFFSET (field));
}

*** tree.h	2000/03/28 17:01:49	1.153
--- tree.h	2000/03/29 19:58:18
*************** typedef struct record_layout_info
*** 1803,1806 ****
--- 1803,1814 ----

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));