public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* full 16 bit addressing support for 16 bit targets
@ 1997-09-30 12:47 Joern Rennecke
  1997-09-30 22:36 ` Jim Wilson
  0 siblings, 1 reply; 4+ messages in thread
From: Joern Rennecke @ 1997-09-30 12:47 UTC (permalink / raw)
  To: Richard Kenner; +Cc: egcs

When compiling the following function for the h8300 target:

int f()
{
  int a[4097];

  a[0] = 0;
  a[4096] = 1;
  return a[0];
}

cc1 complains with an error 'size of array `a' is too large' and emits
incorrect code.  This happens because size_t is just 16 bit wide, and
gcc truncates bit sizes and offsets within arrays to size_t.

Here is a fix:

Tue Sep 30 19:56:37 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_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.

Tue Sep 30 19:57:59 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, c_sizeof_nowarn): Convert result to sizetype.

diff -p ../ss-970926/c-decl.c ./c-decl.c
*** ../ss-970926/c-decl.c	Mon Sep 29 19:33:15 1997
--- ./c-decl.c	Tue Sep 30 16:41:24 1997
*************** 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;
diff -p ../ss-970926/expr.c ./expr.c
*** ../ss-970926/expr.c	Mon Sep 29 18:12:19 1997
--- ./expr.c	Tue Sep 30 18:13:38 1997
*************** get_inner_reference (exp, pbitsize, pbit
*** 4385,4399 ****
  	  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
--- 4385,4404 ----
  	  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
diff -p ../ss-970926/fold-const.c ./fold-const.c
*** ../ss-970926/fold-const.c	Mon Sep 29 18:12:20 1997
--- ./fold-const.c	Mon Sep 29 21:13:58 1997
*************** 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)
*** 1419,1451 ****
    return 0;
  }
  \f
! /* 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;
--- 1419,1453 ----
    return 0;
  }
  \f
! /* 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
*** 2329,2335 ****
       int unsignedp;
  {
    tree result = build (BIT_FIELD_REF, type, inner,
! 		       size_int (bitsize), size_int (bitpos));
  
    TREE_UNSIGNED (result) = unsignedp;
  
--- 2331,2337 ----
       int unsignedp;
  {
    tree result = build (BIT_FIELD_REF, type, inner,
! 		       size_int (bitsize), bitsize_int (bitpos, 0L));
  
    TREE_UNSIGNED (result) = unsignedp;
  
diff -p ../ss-970926/stor-layout.c ./stor-layout.c
*** ../ss-970926/stor-layout.c	Tue Sep 16 15:59:06 1997
--- ./stor-layout.c	Tue Sep 30 16:35:07 1997
*************** 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_union (rec)
*** 630,637 ****
  
    /* 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
--- 630,637 ----
  
    /* 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
*************** layout_type (type)
*** 709,720 ****
  
        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:
--- 709,720 ----
  
        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)
*** 724,730 ****
  			 (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:
--- 724,730 ----
  			 (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)
*** 734,740 ****
        break;
  
      case OFFSET_TYPE:
!       TYPE_SIZE (type) = size_int (POINTER_SIZE);
        TYPE_MODE (type) = ptr_mode;
        break;
  
--- 734,740 ----
        break;
  
      case OFFSET_TYPE:
!       TYPE_SIZE (type) = bitsize_int (POINTER_SIZE, 0L);
        TYPE_MODE (type) = ptr_mode;
        break;
  
*************** layout_type (type)
*** 747,753 ****
      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;
--- 747,753 ----
      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)
*** 795,802 ****
  		&& 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,
--- 795,802 ----
  		&& 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)
*** 969,975 ****
  	    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;
  	}
--- 969,975 ----
  	    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)
*** 1065,1070 ****
--- 1065,1080 ----
    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)
*** 1090,1095 ****
--- 1100,1108 ----
    if (sizetype == 0)
      {
        sizetype = type;
+       sbitsizetype = make_signed_type (precision + BITS_PER_UNIT_LOG + 1);
+       ubitsizetype = make_unsigned_type (precision + BITS_PER_UNIT_LOG + 1);
+       bitsizetype = ubitsizetype;
      }
  
    fixup_unsigned_type (type);
diff -p ../ss-970926/tree.h ./tree.h
*** ../ss-970926/tree.h	Tue Sep 16 15:59:06 1997
--- ./tree.h	Mon Sep 29 22:23:31 1997
*************** 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;
diff -p ../ss-970926/c-typeck.c ./c-typeck.c
*** ../ss-970926/c-typeck.c	Mon Sep 29 19:33:15 1997
--- ./c-typeck.c	Tue Sep 30 19:56:37 1997
*************** c_sizeof (type)
*** 834,839 ****
--- 834,840 ----
    /* 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)
*** 857,862 ****
--- 858,864 ----
    /* 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)
*** 885,890 ****
--- 887,893 ----
    /* 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;
  }
diff -p ../ss-970926/cp/decl.c cp/decl.c
*** ../ss-970926/cp/decl.c	Mon Sep 29 18:12:16 1997
--- cp/decl.c	Tue Sep 30 16:16:31 1997
*************** init_decl_processing ()
*** 4848,4869 ****
  
    /* `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);
--- 4848,4869 ----
  
    /* `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);
diff -p ../ss-970926/cp/decl2.c cp/decl2.c
*** ../ss-970926/cp/decl2.c	Mon Sep 29 18:12:16 1997
--- cp/decl2.c	Tue Sep 30 15:38:15 1997
*************** finish_builtin_type (type, name, fields,
*** 2312,2319 ****
     `operator new' and `operator delete' correspond to
     what compiler will be expecting.  */
  
- extern tree sizetype;
- 
  tree
  coerce_new_type (type)
       tree type;
--- 2312,2317 ----
*** ../ss-970926/cp/typeck.c	Mon Sep 29 18:12:18 1997
--- cp/typeck.c	Tue Sep 30 19:57:59 1997
*************** c_sizeof (type)
*** 1359,1364 ****
--- 1359,1365 ----
    /* 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)
*** 1416,1421 ****
--- 1417,1423 ----
    /* 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;
  }

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: full 16 bit addressing support for 16 bit targets
  1997-09-30 12:47 full 16 bit addressing support for 16 bit targets Joern Rennecke
@ 1997-09-30 22:36 ` Jim Wilson
  0 siblings, 0 replies; 4+ messages in thread
From: Jim Wilson @ 1997-09-30 22:36 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: Richard Kenner, egcs

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?

Jim

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: full 16 bit addressing support for 16 bit targets
  1997-10-24  9:35 ` Joern Rennecke
@ 1998-01-03 11:28   ` Jeffrey A Law
  0 siblings, 0 replies; 4+ messages in thread
From: Jeffrey A Law @ 1998-01-03 11:28 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: egcs

Joern -- I'd like to go ahead and get this installed.  However, I see two minor
problems that need to be addressed:

  * The get_inner_reference code has a changed somewhat since you wrote your
  patch, and as a result your patch doesn't apply correctly to expr.c.  I
  suspect your patch only needs minor updating.

  * Don't we also need a patch for the Fortran front end?


I think once we get those issues addressed we can install the patch.

jeff

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: full 16 bit addressing support for 16 bit targets
       [not found] <9710020111.AA15326@vlsi1.ultra.nyu.edu>
@ 1997-10-24  9:35 ` Joern Rennecke
  1998-01-03 11:28   ` Jeffrey A Law
  0 siblings, 1 reply; 4+ messages in thread
From: Joern Rennecke @ 1997-10-24  9:35 UTC (permalink / raw)
  To: egcs

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;
  }
  \f
! /* 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;
  }
  \f
! /* 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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~1998-01-03 11:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-09-30 12:47 full 16 bit addressing support for 16 bit targets Joern Rennecke
1997-09-30 22:36 ` Jim Wilson
     [not found] <9710020111.AA15326@vlsi1.ultra.nyu.edu>
1997-10-24  9:35 ` Joern Rennecke
1998-01-03 11:28   ` Jeffrey A Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).