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