full 16 bit addressing support for 16 bit targets

Joern Rennecke amylaar@cygnus.co.uk
Fri Oct 24 09:35:00 GMT 1997


Jim Wilson:
> It seems curious that you have code in make_signed_type to max precision
> at 2 * HOST_BITS_PER_WIDE_INT, but you do not have such a limit in the
> nearly identical code in make_unsigned_type.  Shouldn't it be in both
> places?

Richard Kenner:
> This is a *very* complex issue and I really don't see how to do it nearly
> efficiently because DECL_FIELD_OFFSET would need to be the wider type.

> This seems a good patch for EGCS.  Try it out there (making sure it works
> with GNAT, which is the trickiest case for this sort of thing).  Once you
> are satisfied you have something working and efficient, please send me the
> final patch.

I've fixed these problems now and did some testing with the d10v and
i386-linux ports.  Here is the new patch:

Tue Oct 14 23:11:05 1997  J"orn Rennecke <amylaar@cygnus.co.uk>

	* c-decl.c (init_decl_processing): Use bitsizetype for type sizes.
	* expr.c (get_inner_reference): Use sbitsizetype for type sizes.
	* fold-const.c (size_int): Replace with
	(size_int_wide).
	(make_bit_field_ref): Use bitsize_int for bit position.
	* stor-layout.c (sizetype): Delete.
	(sizetype_tab, sbitsizetype, ubitsizetype): Declare.
	(layout_record, layout_union, layout_type):
	Use bitsize_int for bit size.
	(make_signed_type, make_unsigned_type): Initialize *bitsizetype.
	* tree.h (size_int): Don't delcare, #define.
	(size_int_wide, sizetype_tab, sbitsize, ubitsize): Declare.
	(bitsize_int, size_int_2, BITS_PER_UNIT_LOG, sizetype, bitsizetype):
	Define.
	* c-typeck.c (c_sizeof, c_sizeof_nowarn, c_size_in_bytes):
	Convert result to sizetype.
	(really_start_incremental_init, push_init_level):
	Set type of constructor_bit_index to sbitsizetype.
	(push_init_level): Use unsigned arithmetic to determine padding.
	(output_init_element): Likewise.

Tue Oct 14 23:12:06 1997  J"orn Rennecke <amylaar@cygnus.co.uk>

	* cp/decl.c (init_decl_processing): Use bitsizetype for type sizes.
	* cp/decl2.c (sizetype): Don't declare.
	* cp/typeck.c (c_sizeof): Convert result of *_DIV_EXPR to sizetype.
	(c_sizeof_nowarn, build_binary_op_nodefault): Likewise.
	(build_component_addr, unary_complex_lvalue): Likewise.
	* cp/rtti.c (expand_class_desc): Likewise.
	* cp/class.c (get_vfield_offset): Likewise.

Index: c-decl.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/c-decl.c,v
retrieving revision 1.6
diff -p -r1.6 c-decl.c
*** c-decl.c	1997/09/27 18:16:06	1.6
--- c-decl.c	1997/10/14 23:09:46
*************** init_decl_processing ()
*** 2908,2931 ****
    /* `unsigned long' is the standard type for sizeof.
       Traditionally, use a signed type.
       Note that stddef.h uses `unsigned long',
!      and this must agree, even of long and int are the same size.  */
    sizetype
      = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)));
    if (flag_traditional && TREE_UNSIGNED (sizetype))
!     sizetype = signed_type (sizetype);
  
    ptrdiff_type_node
      = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
  
!   TREE_TYPE (TYPE_SIZE (integer_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (char_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (unsigned_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (long_unsigned_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (long_integer_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (long_long_integer_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (long_long_unsigned_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (short_integer_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (short_unsigned_type_node)) = sizetype;
  
    error_mark_node = make_node (ERROR_MARK);
    TREE_TYPE (error_mark_node) = error_mark_node;
--- 2908,2934 ----
    /* `unsigned long' is the standard type for sizeof.
       Traditionally, use a signed type.
       Note that stddef.h uses `unsigned long',
!      and this must agree, even if long and int are the same size.  */
    sizetype
      = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)));
    if (flag_traditional && TREE_UNSIGNED (sizetype))
!     {
!       sizetype = signed_type (sizetype);
!       bitsizetype = sbitsizetype;
!     }
  
    ptrdiff_type_node
      = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
  
!   TREE_TYPE (TYPE_SIZE (integer_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (char_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (unsigned_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (long_unsigned_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (long_integer_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (long_long_integer_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (long_long_unsigned_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (short_integer_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (short_unsigned_type_node)) = bitsizetype;
  
    error_mark_node = make_node (ERROR_MARK);
    TREE_TYPE (error_mark_node) = error_mark_node;
Index: c-typeck.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/c-typeck.c,v
retrieving revision 1.2
diff -p -r1.2 c-typeck.c
*** c-typeck.c	1997/09/27 03:46:33	1.2
--- c-typeck.c	1997/10/14 23:09:59
*************** c_sizeof (type)
*** 825,830 ****
--- 825,831 ----
    /* Convert in case a char is more than one unit.  */
    t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 
  		  size_int (TYPE_PRECISION (char_type_node)));
+   t = convert (sizetype, t);
    /* size_binop does not put the constant in range, so do it now.  */
    if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0))
      TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1;
*************** c_sizeof_nowarn (type)
*** 848,853 ****
--- 849,855 ----
    /* Convert in case a char is more than one unit.  */
    t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 
  		  size_int (TYPE_PRECISION (char_type_node)));
+   t = convert (sizetype, t);
    force_fit_type (t, 0);
    return t;
  }
*************** c_size_in_bytes (type)
*** 876,881 ****
--- 878,884 ----
    /* Convert in case a char is more than one unit.  */
    t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 
  		     size_int (BITS_PER_UNIT));
+   t = convert (sizetype, t);
    force_fit_type (t, 0);
    return t;
  }
*************** really_start_incremental_init (type)
*** 5301,5306 ****
--- 5304,5310 ----
  	constructor_fields = TREE_CHAIN (constructor_fields);
        constructor_unfilled_fields = constructor_fields;
        constructor_bit_index = copy_node (integer_zero_node);
+       TREE_TYPE (constructor_bit_index) = sbitsizetype;
      }
    else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
      {
*************** push_init_level (implicit)
*** 5380,5392 ****
        if (! tree_int_cst_equal (constructor_bit_index,
  				DECL_FIELD_BITPOS (constructor_fields)))
  	{
! 	  int next = (TREE_INT_CST_LOW
! 		      (DECL_FIELD_BITPOS (constructor_fields))
! 		      / BITS_PER_UNIT);
! 	  int here = (TREE_INT_CST_LOW (constructor_bit_index)
! 		      / BITS_PER_UNIT);
! 
! 	  assemble_zeros (next - here);
  	}
        /* Indicate that we have now filled the structure up to the current
  	 field.  */
--- 5384,5400 ----
        if (! tree_int_cst_equal (constructor_bit_index,
  				DECL_FIELD_BITPOS (constructor_fields)))
  	{
! 	  /* By using unsigned arithmetic, the result will be correct even
! 	     in case of overflows, if BITS_PER_UNIT is a power of two.  */
! 	  unsigned next = (TREE_INT_CST_LOW
! 			   (DECL_FIELD_BITPOS (constructor_fields))
! 			   / (unsigned)BITS_PER_UNIT);
! 	  unsigned here = (TREE_INT_CST_LOW (constructor_bit_index)
! 			   / (unsigned)BITS_PER_UNIT);
! 
! 	  assemble_zeros ((next - here)
! 			  * (unsigned)BITS_PER_UNIT
! 			  / (unsigned)BITS_PER_UNIT);
  	}
        /* Indicate that we have now filled the structure up to the current
  	 field.  */
*************** push_init_level (implicit)
*** 5478,5483 ****
--- 5486,5492 ----
  	constructor_fields = TREE_CHAIN (constructor_fields);
        constructor_unfilled_fields = constructor_fields;
        constructor_bit_index = copy_node (integer_zero_node);
+       TREE_TYPE (constructor_bit_index) = sbitsizetype;
      }
    else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
      {
*************** output_init_element (value, type, field,
*** 5972,5983 ****
  		  if (! tree_int_cst_equal (constructor_bit_index,
  					    DECL_FIELD_BITPOS (field)))
  		    {
! 		      int next = (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
! 				  / BITS_PER_UNIT);
! 		      int here = (TREE_INT_CST_LOW (constructor_bit_index)
! 				  / BITS_PER_UNIT);
! 
! 		      assemble_zeros (next - here);
  		    }
  		}
  	      output_constant (digest_init (type, value,
--- 5981,5999 ----
  		  if (! tree_int_cst_equal (constructor_bit_index,
  					    DECL_FIELD_BITPOS (field)))
  		    {
! 		      /* By using unsigned arithmetic, the result will be
! 			 correct even in case of overflows, if BITS_PER_UNIT
! 			 is a power of two.  */
! 		      unsigned next = (TREE_INT_CST_LOW
! 				       (DECL_FIELD_BITPOS (field))
! 				       / (unsigned)BITS_PER_UNIT);
! 		      unsigned here = (TREE_INT_CST_LOW
! 				       (constructor_bit_index)
! 				       / (unsigned)BITS_PER_UNIT);
! 
! 		      assemble_zeros ((next - here)
! 				      * (unsigned)BITS_PER_UNIT
! 				      / (unsigned)BITS_PER_UNIT);
  		    }
  		}
  	      output_constant (digest_init (type, value,
Index: expr.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/expr.c,v
retrieving revision 1.11
diff -p -r1.11 expr.c
*** expr.c	1997/09/27 18:16:12	1.11
--- expr.c	1997/10/14 23:10:25
*************** get_inner_reference (exp, pbitsize, pbit
*** 4347,4361 ****
  	  if (! integer_zerop (low_bound))
  	    index = fold (build (MINUS_EXPR, index_type, index, low_bound));
  
! 	  if (TYPE_PRECISION (index_type) != TYPE_PRECISION (sizetype))
  	    {
  	      index = convert (type_for_size (TYPE_PRECISION (sizetype), 0),
  			       index);
  	      index_type = TREE_TYPE (index);
  	    }
  
! 	  index = fold (build (MULT_EXPR, index_type, index,
! 			       convert (index_type,
  					TYPE_SIZE (TREE_TYPE (exp)))));
  
  	  if (TREE_CODE (index) == INTEGER_CST
--- 4347,4366 ----
  	  if (! integer_zerop (low_bound))
  	    index = fold (build (MINUS_EXPR, index_type, index, low_bound));
  
! 	  if (TREE_CODE (index) == INTEGER_CST)
! 	    {
! 	      index = convert (sbitsizetype, index);
! 	      index_type = TREE_TYPE (index);
! 	    }
! 	  else if (TYPE_PRECISION (index_type) != TYPE_PRECISION (sizetype))
  	    {
  	      index = convert (type_for_size (TYPE_PRECISION (sizetype), 0),
  			       index);
  	      index_type = TREE_TYPE (index);
  	    }
  
! 	  index = fold (build (MULT_EXPR, sbitsizetype, index,
! 			       convert (sbitsizetype,
  					TYPE_SIZE (TREE_TYPE (exp)))));
  
  	  if (TREE_CODE (index) == INTEGER_CST
*************** get_inner_reference (exp, pbitsize, pbit
*** 4363,4370 ****
  	    *pbitpos += TREE_INT_CST_LOW (index);
  	  else
  	    offset = size_binop (PLUS_EXPR, offset,
! 				 size_binop (FLOOR_DIV_EXPR, index,
! 					     size_int (BITS_PER_UNIT)));
  	}
        else if (TREE_CODE (exp) != NON_LVALUE_EXPR
  	       && ! ((TREE_CODE (exp) == NOP_EXPR
--- 4368,4376 ----
  	    *pbitpos += TREE_INT_CST_LOW (index);
  	  else
  	    offset = size_binop (PLUS_EXPR, offset,
! 				 convert (sizetype,
! 					  size_binop (FLOOR_DIV_EXPR, index,
! 						      size_int (BITS_PER_UNIT))));
  	}
        else if (TREE_CODE (exp) != NON_LVALUE_EXPR
  	       && ! ((TREE_CODE (exp) == NOP_EXPR
Index: fold-const.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/fold-const.c,v
retrieving revision 1.5
diff -p -r1.5 fold-const.c
*** fold-const.c	1997/09/23 18:35:51	1.5
--- fold-const.c	1997/10/14 23:10:33
*************** Boston, MA 02111-1307, USA.  */
*** 27,33 ****
    @@ for cross-compilers.  */
  
  
! /* The entry points in this file are fold, size_int, size_binop
     and force_fit_type.
  
     fold takes a tree as argument and returns a simplified tree.
--- 27,33 ----
    @@ for cross-compilers.  */
  
  
! /* The entry points in this file are fold, size_int_wide, size_binop
     and force_fit_type.
  
     fold takes a tree as argument and returns a simplified tree.
*************** const_binop (code, arg1, arg2, notrunc)
*** 1396,1428 ****
    return 0;
  }
  
! /* Return an INTEGER_CST with value V and type from `sizetype'.  */
  
  tree
! size_int (number)
!      unsigned HOST_WIDE_INT number;
  {
    register tree t;
    /* Type-size nodes already made for small sizes.  */
!   static tree size_table[2*HOST_BITS_PER_WIDE_INT + 1];
  
!   if (number < 2*HOST_BITS_PER_WIDE_INT + 1
!       && size_table[number] != 0)
!     return size_table[number];
!   if (number < 2*HOST_BITS_PER_WIDE_INT + 1)
      {
        push_obstacks_nochange ();
        /* Make this a permanent node.  */
        end_temporary_allocation ();
        t = build_int_2 (number, 0);
!       TREE_TYPE (t) = sizetype;
!       size_table[number] = t;
        pop_obstacks ();
      }
    else
      {
!       t = build_int_2 (number, 0);
!       TREE_TYPE (t) = sizetype;
        TREE_OVERFLOW (t) = TREE_CONSTANT_OVERFLOW (t) = force_fit_type (t, 0);
      }
    return t;
--- 1396,1430 ----
    return 0;
  }
  
! /* Return an INTEGER_CST with value V .  The type is determined by bit_p:
!    if it is zero, the type is taken from sizetype; if it is one, the type
!    is taken from bitsizetype.  */
  
  tree
! size_int_wide (number, high, bit_p)
!      unsigned HOST_WIDE_INT number, high;
  {
    register tree t;
    /* Type-size nodes already made for small sizes.  */
!   static tree size_table[2*HOST_BITS_PER_WIDE_INT + 1][2];
  
!   if (number < 2*HOST_BITS_PER_WIDE_INT + 1 && ! high
!       && size_table[number][bit_p] != 0)
!     return size_table[number][bit_p];
!   if (number < 2*HOST_BITS_PER_WIDE_INT + 1 && ! high)
      {
        push_obstacks_nochange ();
        /* Make this a permanent node.  */
        end_temporary_allocation ();
        t = build_int_2 (number, 0);
!       TREE_TYPE (t) = sizetype_tab[bit_p];
!       size_table[number][bit_p] = t;
        pop_obstacks ();
      }
    else
      {
!       t = build_int_2 (number, high);
!       TREE_TYPE (t) = sizetype_tab[bit_p];
        TREE_OVERFLOW (t) = TREE_CONSTANT_OVERFLOW (t) = force_fit_type (t, 0);
      }
    return t;
*************** make_bit_field_ref (inner, type, bitsize
*** 2294,2300 ****
       int unsignedp;
  {
    tree result = build (BIT_FIELD_REF, type, inner,
! 		       size_int (bitsize), size_int (bitpos));
  
    TREE_UNSIGNED (result) = unsignedp;
  
--- 2296,2302 ----
       int unsignedp;
  {
    tree result = build (BIT_FIELD_REF, type, inner,
! 		       size_int (bitsize), bitsize_int (bitpos, 0L));
  
    TREE_UNSIGNED (result) = unsignedp;
  
Index: stor-layout.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/stor-layout.c,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 stor-layout.c
*** stor-layout.c	1997/08/11 15:57:13	1.1.1.1
--- stor-layout.c	1997/10/14 23:10:48
*************** Boston, MA 02111-1307, USA.  */
*** 33,39 ****
     It is the first integer type laid out.
     In C, this is int.  */
  
! tree sizetype;
  
  /* An integer constant with value 0 whose type is sizetype.  */
  
--- 33,39 ----
     It is the first integer type laid out.
     In C, this is int.  */
  
! tree sizetype_tab[2], sbitsizetype, ubitsizetype;
  
  /* An integer constant with value 0 whose type is sizetype.  */
  
*************** layout_record (rec)
*** 418,424 ****
  	    {
  	      if (const_size > 0)
  		var_size = size_binop (PLUS_EXPR, var_size,
! 				       size_int (const_size));
  	      const_size = 0;
  	      var_size = round_up (var_size, desired_align);
  	      var_align = MIN (var_align, desired_align);
--- 418,424 ----
  	    {
  	      if (const_size > 0)
  		var_size = size_binop (PLUS_EXPR, var_size,
! 				       bitsize_int (const_size, 0L));
  	      const_size = 0;
  	      var_size = round_up (var_size, desired_align);
  	      var_align = MIN (var_align, desired_align);
*************** layout_record (rec)
*** 478,484 ****
  
        if (var_size && const_size)
  	DECL_FIELD_BITPOS (field)
! 	  = size_binop (PLUS_EXPR, var_size, size_int (const_size));
        else if (var_size)
  	DECL_FIELD_BITPOS (field) = var_size;
        else
--- 478,484 ----
  
        if (var_size && const_size)
  	DECL_FIELD_BITPOS (field)
! 	  = size_binop (PLUS_EXPR, var_size, bitsize_int (const_size, 0L));
        else if (var_size)
  	DECL_FIELD_BITPOS (field) = var_size;
        else
*************** layout_record (rec)
*** 531,537 ****
      {
        if (const_size)
  	var_size
! 	  = size_binop (PLUS_EXPR, var_size, size_int (const_size));
        TYPE_SIZE (rec) = var_size;
      }
  
--- 531,537 ----
      {
        if (const_size)
  	var_size
! 	  = size_binop (PLUS_EXPR, var_size, bitsize_int (const_size, 0L));
        TYPE_SIZE (rec) = var_size;
      }
  
*************** layout_union (rec)
*** 588,594 ****
  	continue;
  
        layout_decl (field, 0);
!       DECL_FIELD_BITPOS (field) = size_int (0);
  
        /* Union must be at least as aligned as any field requires.  */
  
--- 588,594 ----
  	continue;
  
        layout_decl (field, 0);
!       DECL_FIELD_BITPOS (field) = bitsize_int (0L, 0L);
  
        /* Union must be at least as aligned as any field requires.  */
  
*************** layout_union (rec)
*** 618,624 ****
        else if (TREE_CODE (rec) == QUAL_UNION_TYPE)
  	var_size = fold (build (COND_EXPR, sizetype, DECL_QUALIFIER (field),
  				DECL_SIZE (field),
! 				var_size ? var_size : integer_zero_node));
        }
  
    if (TREE_CODE (rec) == QUAL_UNION_TYPE)
--- 618,624 ----
        else if (TREE_CODE (rec) == QUAL_UNION_TYPE)
  	var_size = fold (build (COND_EXPR, sizetype, DECL_QUALIFIER (field),
  				DECL_SIZE (field),
! 				var_size ? var_size : bitsize_int (0L, 0L)));
        }
  
    if (TREE_CODE (rec) == QUAL_UNION_TYPE)
*************** layout_union (rec)
*** 626,638 ****
  
    /* Determine the ultimate size of the union (in bytes).  */
    if (NULL == var_size)
!     TYPE_SIZE (rec) = size_int (CEIL (const_size, BITS_PER_UNIT)
! 				* BITS_PER_UNIT);
    else if (const_size == 0)
      TYPE_SIZE (rec) = var_size;
    else
      TYPE_SIZE (rec) = size_binop (MAX_EXPR, var_size,
! 				  round_up (size_int (const_size),
  					    BITS_PER_UNIT));
  
    /* Determine the desired alignment.  */
--- 626,638 ----
  
    /* Determine the ultimate size of the union (in bytes).  */
    if (NULL == var_size)
!     TYPE_SIZE (rec) = bitsize_int (CEIL (const_size, BITS_PER_UNIT)
! 				   * BITS_PER_UNIT, 0L);
    else if (const_size == 0)
      TYPE_SIZE (rec) = var_size;
    else
      TYPE_SIZE (rec) = size_binop (MAX_EXPR, var_size,
! 				  round_up (bitsize_int (const_size, 0L),
  					    BITS_PER_UNIT));
  
    /* Determine the desired alignment.  */
*************** layout_type (type)
*** 700,711 ****
  
        TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type),
  						 MODE_INT);
!       TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
        break;
  
      case REAL_TYPE:
        TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0);
!       TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
        break;
  
      case COMPLEX_TYPE:
--- 700,711 ----
  
        TYPE_MODE (type) = smallest_mode_for_size (TYPE_PRECISION (type),
  						 MODE_INT);
!       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)), 0L);
        break;
  
      case REAL_TYPE:
        TYPE_MODE (type) = mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0);
!       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)), 0L);
        break;
  
      case COMPLEX_TYPE:
*************** layout_type (type)
*** 715,721 ****
  			 (TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
  			  ? MODE_COMPLEX_INT : MODE_COMPLEX_FLOAT),
  			 0);
!       TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
        break;
  
      case VOID_TYPE:
--- 715,721 ----
  			 (TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
  			  ? MODE_COMPLEX_INT : MODE_COMPLEX_FLOAT),
  			 0);
!       TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)), 0L);
        break;
  
      case VOID_TYPE:
*************** layout_type (type)
*** 725,731 ****
        break;
  
      case OFFSET_TYPE:
!       TYPE_SIZE (type) = size_int (POINTER_SIZE);
        TYPE_MODE (type) = ptr_mode;
        break;
  
--- 725,731 ----
        break;
  
      case OFFSET_TYPE:
!       TYPE_SIZE (type) = bitsize_int (POINTER_SIZE, 0L);
        TYPE_MODE (type) = ptr_mode;
        break;
  
*************** layout_type (type)
*** 738,744 ****
      case POINTER_TYPE:
      case REFERENCE_TYPE:
        TYPE_MODE (type) = ptr_mode;
!       TYPE_SIZE (type) = size_int (POINTER_SIZE);
        TREE_UNSIGNED (type) = 1;
        TYPE_PRECISION (type) = POINTER_SIZE;
        break;
--- 738,744 ----
      case POINTER_TYPE:
      case REFERENCE_TYPE:
        TYPE_MODE (type) = ptr_mode;
!       TYPE_SIZE (type) = bitsize_int (POINTER_SIZE, 0L);
        TREE_UNSIGNED (type) = 1;
        TYPE_PRECISION (type) = POINTER_SIZE;
        break;
*************** layout_type (type)
*** 786,793 ****
  		&& TREE_CODE (TYPE_MAX_VALUE (index)) != INTEGER_CST)
  	      length = size_binop (MAX_EXPR, length, size_zero_node);
  
! 	    TYPE_SIZE (type) = size_binop (MULT_EXPR, length,
! 					   TYPE_SIZE (element));
  	  }
  
  	/* Now round the alignment and size,
--- 786,793 ----
  		&& 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);
  	  }
  
  	/* Now round the alignment and size,
*************** layout_type (type)
*** 971,977 ****
  	    TYPE_MODE (type) = BLKmode;
  	  else
  	    TYPE_MODE (type) = mode_for_size (alignment, MODE_INT, 1);
! 	  TYPE_SIZE (type) = size_int (rounded_size);
  	  TYPE_ALIGN (type) = alignment;
  	  TYPE_PRECISION (type) = size_in_bits;
  	}
--- 971,977 ----
  	    TYPE_MODE (type) = BLKmode;
  	  else
  	    TYPE_MODE (type) = mode_for_size (alignment, MODE_INT, 1);
! 	  TYPE_SIZE (type) = bitsize_int (rounded_size, 0L);
  	  TYPE_ALIGN (type) = alignment;
  	  TYPE_PRECISION (type) = size_in_bits;
  	}
*************** make_signed_type (precision)
*** 1067,1072 ****
--- 1067,1082 ----
    if (sizetype == 0)
      {
        sizetype = type;
+       /* The *bitsizetype types use a precision that avoids overflows when
+ 	 calculating signed sizes / offsets in bits.  */
+       precision += BITS_PER_UNIT_LOG + 1;
+       /* However, when cross-compiling from a 32 bit to a 64 bit host,
+ 	 we are limited to 64 bit precision.  */
+       if (precision > 2 * HOST_BITS_PER_WIDE_INT)
+ 	precision = 2 * HOST_BITS_PER_WIDE_INT;
+       sbitsizetype = make_signed_type (precision);
+       ubitsizetype = make_unsigned_type (precision);
+       bitsizetype = sbitsizetype;
      }
  
    /* Lay out the type: set its alignment, size, etc.  */
*************** make_unsigned_type (precision)
*** 1092,1097 ****
--- 1102,1117 ----
    if (sizetype == 0)
      {
        sizetype = type;
+       /* The *bitsizetype types use a precision that avoids overflows when
+ 	 calculating signed sizes / offsets in bits.  */
+       precision += BITS_PER_UNIT_LOG + 1;
+       /* However, when cross-compiling from a 32 bit to a 64 bit host,
+ 	 we are limited to 64 bit precision.  */
+       if (precision > 2 * HOST_BITS_PER_WIDE_INT)
+ 	precision = 2 * HOST_BITS_PER_WIDE_INT;
+       sbitsizetype = make_signed_type (precision);
+       ubitsizetype = make_unsigned_type (precision);
+       bitsizetype = ubitsizetype;
      }
  
    fixup_unsigned_type (type);
Index: tree.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/tree.h,v
retrieving revision 1.6
diff -p -r1.6 tree.h
*** tree.h	1997/10/07 16:07:42	1.6
--- tree.h	1997/10/14 23:11:05
*************** extern tree convert			PROTO((tree, tree)
*** 1387,1400 ****
  extern tree size_in_bytes		PROTO((tree));
  extern int int_size_in_bytes		PROTO((tree));
  extern tree size_binop			PROTO((enum tree_code, tree, tree));
! extern tree size_int			PROTO((unsigned HOST_WIDE_INT));
  extern tree round_up			PROTO((tree, int));
  extern tree get_pending_sizes		PROTO((void));
  extern void put_pending_sizes		PROTO((tree));
  
  /* Type for sizes of data-type.  */
  
! extern tree sizetype;
  
  /* If nonzero, an upper limit on alignment of structure fields, in bits. */
  extern int maximum_field_alignment;
--- 1387,1414 ----
  extern tree size_in_bytes		PROTO((tree));
  extern int int_size_in_bytes		PROTO((tree));
  extern tree size_binop			PROTO((enum tree_code, tree, tree));
! extern tree size_int_wide		PROTO((unsigned HOST_WIDE_INT,
! 					       unsigned HOST_WIDE_INT, int));
! #define size_int(L) size_int_2 ((L), 0, 0)
! #define bitsize_int(L, H) size_int_2 ((L), (H), 1)
! #define size_int_2(L, H, T)			\
!   size_int_wide ((unsigned HOST_WIDE_INT) (L),	\
! 		 (unsigned HOST_WIDE_INT) (H), (T))
! 
  extern tree round_up			PROTO((tree, int));
  extern tree get_pending_sizes		PROTO((void));
  extern void put_pending_sizes		PROTO((tree));
  
  /* Type for sizes of data-type.  */
  
! #define BITS_PER_UNIT_LOG \
!   ((BITS_PER_UNIT > 1) + (BITS_PER_UNIT > 2) + (BITS_PER_UNIT > 4) \
!    + (BITS_PER_UNIT > 8) + (BITS_PER_UNIT > 16) + (BITS_PER_UNIT > 32) \
!    + (BITS_PER_UNIT > 64) + (BITS_PER_UNIT > 128) + (BITS_PER_UNIT > 256))
! 
! extern tree sizetype_tab[2], sbitsizetype, ubitsizetype;
! #define sizetype sizetype_tab[0]
! #define bitsizetype sizetype_tab[1]
  
  /* If nonzero, an upper limit on alignment of structure fields, in bits. */
  extern int maximum_field_alignment;
Index: cp/class.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/cp/class.c,v
retrieving revision 1.6
diff -p -r1.6 class.c
*** class.c	1997/09/28 19:16:18	1.6
--- class.c	1997/10/14 23:11:27
*************** tree
*** 609,619 ****
  get_vfield_offset (binfo)
       tree binfo;
  {
!   return size_binop (PLUS_EXPR,
! 		     size_binop (FLOOR_DIV_EXPR,
! 				 DECL_FIELD_BITPOS (CLASSTYPE_VFIELD (BINFO_TYPE (binfo))),
! 				 size_int (BITS_PER_UNIT)),
! 		     BINFO_OFFSET (binfo));
  }
  
  /* Get the offset to the start of the original binfo that we derived
--- 609,620 ----
  get_vfield_offset (binfo)
       tree binfo;
  {
!   tree tmp
!     = size_binop (FLOOR_DIV_EXPR,
! 		  DECL_FIELD_BITPOS (CLASSTYPE_VFIELD (BINFO_TYPE (binfo))),
! 		  size_int (BITS_PER_UNIT));
!   tmp = convert (sizetype, tmp);
!   return size_binop (PLUS_EXPR, tmp, BINFO_OFFSET (binfo));
  }
  
  /* Get the offset to the start of the original binfo that we derived
Index: cp/decl.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.23
diff -p -r1.23 decl.c
*** decl.c	1997/10/08 06:04:25	1.23
--- decl.c	1997/10/14 23:11:41
*************** init_decl_processing ()
*** 4880,4901 ****
  
    /* `unsigned long' is the standard type for sizeof.
       Note that stddef.h uses `unsigned long',
!      and this must agree, even of long and int are the same size.  */
    sizetype
      = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)));
  
    ptrdiff_type_node
      = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
  
!   TREE_TYPE (TYPE_SIZE (integer_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (char_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (unsigned_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (long_unsigned_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (long_integer_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (long_long_integer_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (long_long_unsigned_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (short_integer_type_node)) = sizetype;
!   TREE_TYPE (TYPE_SIZE (short_unsigned_type_node)) = sizetype;
  
    /* Define both `signed char' and `unsigned char'.  */
    signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);
--- 4880,4901 ----
  
    /* `unsigned long' is the standard type for sizeof.
       Note that stddef.h uses `unsigned long',
!      and this must agree, even if long and int are the same size.  */
    sizetype
      = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)));
  
    ptrdiff_type_node
      = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE)));
  
!   TREE_TYPE (TYPE_SIZE (integer_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (char_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (unsigned_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (long_unsigned_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (long_integer_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (long_long_integer_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (long_long_unsigned_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (short_integer_type_node)) = bitsizetype;
!   TREE_TYPE (TYPE_SIZE (short_unsigned_type_node)) = bitsizetype;
  
    /* Define both `signed char' and `unsigned char'.  */
    signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);
Index: cp/decl2.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/cp/decl2.c,v
retrieving revision 1.15
diff -p -r1.15 decl2.c
*** decl2.c	1997/10/08 07:19:53	1.15
--- decl2.c	1997/10/14 23:11:45
*************** finish_builtin_type (type, name, fields,
*** 2356,2363 ****
     `operator new' and `operator delete' correspond to
     what compiler will be expecting.  */
  
- extern tree sizetype;
- 
  tree
  coerce_new_type (type)
       tree type;
--- 2356,2361 ----
Index: cp/rtti.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/cp/rtti.c,v
retrieving revision 1.3
diff -p -r1.3 rtti.c
*** rtti.c	1997/08/21 00:50:08	1.3
--- rtti.c	1997/10/14 23:11:56
*************** expand_class_desc (tdecl, type)
*** 788,793 ****
--- 788,794 ----
  	  field = lookup_field (type, get_identifier (name), 0, 0);
  	  offset = size_binop (FLOOR_DIV_EXPR, 
  		DECL_FIELD_BITPOS (field), size_int (BITS_PER_UNIT));
+ 	  offset = convert (sizetype, offset);
  	}
        else
  	offset = BINFO_OFFSET (binfo);
Index: cp/typeck.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.12
diff -p -r1.12 typeck.c
*** typeck.c	1997/10/08 06:04:28	1.12
--- typeck.c	1997/10/14 23:12:06
*************** c_sizeof (type)
*** 1360,1365 ****
--- 1360,1366 ----
    /* Convert in case a char is more than one unit.  */
    t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 
  		  size_int (TYPE_PRECISION (char_type_node)));
+   t = convert (sizetype, t);
    /* size_binop does not put the constant in range, so do it now.  */
    if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0))
      TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1;
*************** c_sizeof_nowarn (type)
*** 1417,1422 ****
--- 1418,1424 ----
    /* Convert in case a char is more than one unit.  */
    t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), 
  		  size_int (TYPE_PRECISION (char_type_node)));
+   t = convert (sizetype, t);
    force_fit_type (t, 0);
    return t;
  }
*************** build_binary_op_nodefault (code, orig_op
*** 3455,3460 ****
--- 3457,3463 ----
  	      delta21 = CLASSTYPE_VFIELD (TYPE_METHOD_BASETYPE (TREE_TYPE (type1)));
  	      delta21 = DECL_FIELD_BITPOS (delta21);
  	      delta21 = size_binop (FLOOR_DIV_EXPR, delta21, size_int (BITS_PER_UNIT));
+ 	      delta21 = convert (sizetype, delta21);
  	    }
  	  else
  	    index1 = integer_neg_one_node;
*************** build_component_addr (arg, argtype, msg)
*** 4006,4011 ****
--- 4009,4015 ----
        tree offset = size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (field),
  				size_int (BITS_PER_UNIT));
        int flag = TREE_CONSTANT (rval);
+       offset = convert (sizetype, offset);
        rval = fold (build (PLUS_EXPR, argtype,
  			  rval, cp_convert (argtype, offset)));
        TREE_CONSTANT (rval) = flag;
*************** unary_complex_lvalue (code, arg)
*** 4656,4664 ****
  
  	  /* Add in the offset to the field.  */
  	  offset = size_binop (PLUS_EXPR, offset,
! 			       size_binop (EASY_DIV_EXPR,
! 					   DECL_FIELD_BITPOS (t),
! 					   size_int (BITS_PER_UNIT)));
  
  	  /* We offset all pointer to data memebers by 1 so that we can
  	     distinguish between a null pointer to data member and the first
--- 4660,4669 ----
  
  	  /* Add in the offset to the field.  */
  	  offset = size_binop (PLUS_EXPR, offset,
! 			       convert (sizetype,
! 					size_binop (EASY_DIV_EXPR,
! 						    DECL_FIELD_BITPOS (t),
! 						    size_int (BITS_PER_UNIT))));
  
  	  /* We offset all pointer to data memebers by 1 so that we can
  	     distinguish between a null pointer to data member and the first



More information about the Gcc mailing list