This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: proposal to make SIZE_TYPE more flexible
- From: DJ Delorie <dj at redhat dot com>
- To: "Joseph S. Myers" <joseph at codesourcery dot com>
- Cc: richard dot guenther at gmail dot com, gcc at gcc dot gnu dot org
- Date: Tue, 14 Jan 2014 17:22:18 -0500
- Subject: Re: proposal to make SIZE_TYPE more flexible
- Authentication-results: sourceware.org; auth=none
- References: <201310300422 dot r9U4M6Mx002568 at greed dot delorie dot com> <Pine dot LNX dot 4 dot 64 dot 1311221231510 dot 5029 at digraph dot polyomino dot org dot uk> <201311221933 dot rAMJXDUt031382 at greed dot delorie dot com> <Pine dot LNX dot 4 dot 64 dot 1311222046100 dot 12354 at digraph dot polyomino dot org dot uk> <201311222118 dot rAMLIxag003002 at greed dot delorie dot com> <Pine dot LNX dot 4 dot 64 dot 1311230039030 dot 12354 at digraph dot polyomino dot org dot uk> <201312100334 dot rBA3YwMq017441 at greed dot delorie dot com> <Pine dot LNX dot 4 dot 64 dot 1312101709200 dot 15324 at digraph dot polyomino dot org dot uk> <201312201947 dot rBKJlgKS003922 at greed dot delorie dot com> <Pine dot LNX dot 4 dot 64 dot 1312202151510 dot 29339 at digraph dot polyomino dot org dot uk> <201312202159 dot rBKLxmIZ007173 at greed dot delorie dot com> <Pine dot LNX dot 4 dot 64 dot 1312202215280 dot 29339 at digraph dot polyomino dot org dot uk> <201312202240 dot rBKMeVfM008400 at greed dot delorie dot com> <Pine dot LNX dot 4 dot 64 dot 1312210100330 dot 29339 at digraph dot polyomino dot org dot uk > <201401090031 dot s090VGm9003938 at greed dot delorie dot com> <Pine dot LNX dot 4 dot 64 dot 1401090214160 dot 8625 at digraph dot polyomino dot org dot uk > <201401090322 dot s093Mr4t007903 at greed dot delorie dot com> <Pine dot LNX dot 4 dot 64 dot 1401091540270 dot 21172 at digraph dot polyomino dot org dot uk>
Ok, I think I got all the features in and all the backwards
compatibility working. Big patch attached, including sample support
for msp430-elf. Tested for x86-64 and msp430.
gcc/
* machmode.h (int_n_data_t): New.
(int_n_enabled_p): New.
(int_n_data): New.
* tree.c (int_n_enabled_p): New.
(int_n_trees): New.
(make_or_reuse_type): Check for all __intN types, not just
__int128.
(build_common_tree_nodes): Likewise. Also fill in integer_typs[]
entries.
* tree.h (int128_integer_type_node): Remove.
(int128_unsigned_type_node): Remove.
(int_n_trees_t): New.
(int_n_enabled_p): New.
(int_n_trees): New.
* toplev.c (standard_type_bitsize): New.
(do_compile): Check which __intN types are enabled for the current
run.
* builtin-types.def (BT_INT128): Remove.
(BT_UINT128): Remove.
* machmode.def: Add macro to create __intN for all targets.
* stor-layout.c (mode_for_size): Support __intN types.
(smallest_mode_for_size): Likewise.
* genmodes.c (struct mode_data): Add int_n field.
(blank_mode): Likewise.
(INT_N): New.
(make_int_n): New.
(emit_insn_modes_h): Count __intN entries and define
NUM_INT_N_ENTS.
(emit_mode_int_n): New.
(emit_insn_modes_c): Call it.
* gimple.c (gimple_signed_or_unsigned_type): Check for all __intN
types, not just __int128.
* tree-core.h (integer_type_kind): Remove __int128-specific
entries, reserve spots for __intN entries.
* config/msp430/msp430.c (msp430_scalar_mode_supported_p): New.
* config/msp430/msp430-modes.def: Add __int20 macro.
gcc/c-family/
* c-pretty-print.c (pp_c_integer_constant): Check for all __intN
types, not just __int128.
* c-cppbuiltin.c (c_cpp_builtins): Add builtins for all __intN
types, not just __int128.
* c-common.c (c_common_reswords): Remove __int128 special case.
(c_common_type_for_size): Check for all __intN types, not just
__int128.
(c_common_type_for_mode): Likewise.
(c_common_signed_or_unsigned_type): Likewise.
(c_build_bitfield_integer_type): Likewise.
(c_common_nodes_and_builtins): Likewise.
(keyword_begins_type_specifier): Likewise.
* c-common.h (rid): Remove RID_INT128 and add RID_INT_N_* for all
__intN variants.
gcc/c/
* c-parser.c (c_parse_init): Add RID entries for each __intN.
(c_token_starts_typename): Check all __intN, not just __int128.
(c_token_starts_declspecs): Likewise.
(c_parser_declspecs): Likewise.
(c_parser_attribute_any_word): Likewise.
(c_parser_objc_selector): Likewise.
* c-tree.h (c_typespec_keyword): cts_int128 -> cts_int_n.
(struct c_declspecs): Add int_n_idx field to record *which* __intN
is specified.
* c-decl.c (declspecs_add_type): Check for all __intN, not just
__int128.
(finish_declspecs): Likewise.
gcc/cp/
* typeck.c (cp_common_type): Check for all __intN types, not just
__int128.
* decl.c (grokdeclarator): Likewise.
* rtti.c (emit_support_tinfos): Remove __int128-specific entries.
* parser.c (cp_lexer_next_token_is_decl_specifier_keyword): Check
for all __intN types, not just __int128.
(cp_parser_simple_type_specifier): Likewise.
* mangle.c (integer_type_codes): Remove int128-specific codes.
* cp-tree.h (cp_decl_specifier_seq): Add int_n_idx to store which
__intN was specified.
* lex.c (init_reswords): Reserve all __intN keywords.
Index: machmode.h
===================================================================
--- machmode.h (revision 206609)
+++ machmode.h (working copy)
@@ -322,7 +322,19 @@ extern void init_adjust_machine_modes (v
GET_MODE_PRECISION (MODE2))
#define HWI_COMPUTABLE_MODE_P(MODE) \
(SCALAR_INT_MODE_P (MODE) \
&& GET_MODE_PRECISION (MODE) <= HOST_BITS_PER_WIDE_INT)
+typedef struct {
+ /* These parts are initailized by genmodes output */
+ unsigned int bitsize;
+ enum machine_mode m;
+ /* RID_* is RID_INTN_BASE + index into this array */
+} int_n_data_t;
+
+/* This is also in tree.h. genmodes.c guarantees the're sorted from
+ smallest bitsize to largest bitsize. */
+extern bool int_n_enabled_p[NUM_INT_N_ENTS];
+extern const int_n_data_t int_n_data[NUM_INT_N_ENTS];
+
#endif /* not HAVE_MACHINE_MODES */
Index: c-family/c-pretty-print.c
===================================================================
--- c-family/c-pretty-print.c (revision 206609)
+++ c-family/c-pretty-print.c (working copy)
@@ -907,12 +907,14 @@ pp_c_string_literal (c_pretty_printer *p
/* Pretty-print an INTEGER literal. */
static void
pp_c_integer_constant (c_pretty_printer *pp, tree i)
{
+ int idx;
+
/* We are going to compare the type of I to other types using
pointer comparison so we need to use its canonical type. */
tree type =
TYPE_CANONICAL (TREE_TYPE (i))
? TYPE_CANONICAL (TREE_TYPE (i))
: TREE_TYPE (i);
@@ -939,15 +941,23 @@ pp_c_integer_constant (c_pretty_printer
pp_character (pp, 'u');
if (type == long_integer_type_node || type == long_unsigned_type_node)
pp_character (pp, 'l');
else if (type == long_long_integer_type_node
|| type == long_long_unsigned_type_node)
pp_string (pp, "ll");
- else if (type == int128_integer_type_node
- || type == int128_unsigned_type_node)
- pp_string (pp, "I128");
+ else for (idx = 0; idx < NUM_INT_N_ENTS; idx ++)
+ if (int_n_enabled_p[idx])
+ {
+ char buf[2+20];
+ if (type == int_n_trees[idx].signed_type
+ || type == int_n_trees[idx].unsigned_type)
+ {
+ sprintf (buf, "I%d", int_n_data[idx].bitsize);
+ pp_string (pp, buf);
+ }
+ }
}
/* Print out a CHARACTER literal. */
static void
pp_c_character_constant (c_pretty_printer *pp, tree c)
Index: c-family/c-cppbuiltin.c
===================================================================
--- c-family/c-cppbuiltin.c (revision 206609)
+++ c-family/c-cppbuiltin.c (working copy)
@@ -775,12 +775,14 @@ cpp_iec_559_complex_value (void)
}
/* Hook that registers front end and target-specific built-ins. */
void
c_cpp_builtins (cpp_reader *pfile)
{
+ int i;
+
/* -undef turns off target-specific built-ins. */
if (flag_undef)
return;
define_language_independent_builtin_macros (pfile);
@@ -993,15 +995,20 @@ c_cpp_builtins (cpp_reader *pfile)
else if (flag_stack_protect == 1)
cpp_define (pfile, "__SSP__=1");
if (flag_openmp)
cpp_define (pfile, "_OPENMP=201307");
- if (int128_integer_type_node != NULL_TREE)
- builtin_define_type_sizeof ("__SIZEOF_INT128__",
- int128_integer_type_node);
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (int_n_enabled_p[i])
+ {
+ char buf[15+20];
+ sprintf(buf, "__SIZEOF_INT%d__", int_n_data[i].bitsize);
+ builtin_define_type_sizeof (buf,
+ int_n_trees[i].signed_type);
+ }
builtin_define_type_sizeof ("__SIZEOF_WCHAR_T__", wchar_type_node);
builtin_define_type_sizeof ("__SIZEOF_WINT_T__", wint_type_node);
builtin_define_type_sizeof ("__SIZEOF_PTRDIFF_T__",
unsigned_ptrdiff_type_node);
/* A straightforward target hook doesn't work, because of problems
Index: c-family/c-common.c
===================================================================
--- c-family/c-common.c (revision 206609)
+++ c-family/c-common.c (working copy)
@@ -57,18 +57,16 @@ cpp_reader *parse_in; /* Declared in c-
INTEGER_TYPE and REAL_TYPE nodes for the standard data types.
tree short_integer_type_node;
tree long_integer_type_node;
tree long_long_integer_type_node;
- tree int128_integer_type_node;
tree short_unsigned_type_node;
tree long_unsigned_type_node;
tree long_long_unsigned_type_node;
- tree int128_unsigned_type_node;
tree truthvalue_type_node;
tree truthvalue_false_node;
tree truthvalue_true_node;
tree ptrdiff_type_node;
@@ -458,13 +456,12 @@ const struct c_common_resword c_common_r
{ "__has_trivial_destructor", RID_HAS_TRIVIAL_DESTRUCTOR, D_CXXONLY },
{ "__has_virtual_destructor", RID_HAS_VIRTUAL_DESTRUCTOR, D_CXXONLY },
{ "__imag", RID_IMAGPART, 0 },
{ "__imag__", RID_IMAGPART, 0 },
{ "__inline", RID_INLINE, 0 },
{ "__inline__", RID_INLINE, 0 },
- { "__int128", RID_INT128, 0 },
{ "__is_abstract", RID_IS_ABSTRACT, D_CXXONLY },
{ "__is_base_of", RID_IS_BASE_OF, D_CXXONLY },
{ "__is_class", RID_IS_CLASS, D_CXXONLY },
{ "__is_convertible_to", RID_IS_CONVERTIBLE_TO, D_CXXONLY },
{ "__is_empty", RID_IS_EMPTY, D_CXXONLY },
{ "__is_enum", RID_IS_ENUM, D_CXXONLY },
@@ -3385,12 +3382,14 @@ check_case_bounds (tree type, tree orig_
/* Return an integer type with BITS bits of precision,
that is unsigned if UNSIGNEDP is nonzero, otherwise signed. */
tree
c_common_type_for_size (unsigned int bits, int unsignedp)
{
+ int i;
+
if (bits == TYPE_PRECISION (integer_type_node))
return unsignedp ? unsigned_type_node : integer_type_node;
if (bits == TYPE_PRECISION (signed_char_type_node))
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
@@ -3401,16 +3400,17 @@ c_common_type_for_size (unsigned int bit
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
if (bits == TYPE_PRECISION (long_long_integer_type_node))
return (unsignedp ? long_long_unsigned_type_node
: long_long_integer_type_node);
- if (int128_integer_type_node
- && bits == TYPE_PRECISION (int128_integer_type_node))
- return (unsignedp ? int128_unsigned_type_node
- : int128_integer_type_node);
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (int_n_enabled_p[i]
+ && bits == int_n_data[i].bitsize)
+ return (unsignedp ? int_n_trees[i].unsigned_type
+ : int_n_trees[i].signed_type);
if (bits == TYPE_PRECISION (widest_integer_literal_type_node))
return (unsignedp ? widest_unsigned_literal_type_node
: widest_integer_literal_type_node);
if (bits <= TYPE_PRECISION (intQI_type_node))
@@ -3468,12 +3468,13 @@ static GTY(()) tree registered_builtin_t
then UNSIGNEDP selects between saturating and nonsaturating types. */
tree
c_common_type_for_mode (enum machine_mode mode, int unsignedp)
{
tree t;
+ int i;
if (mode == TYPE_MODE (integer_type_node))
return unsignedp ? unsigned_type_node : integer_type_node;
if (mode == TYPE_MODE (signed_char_type_node))
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
@@ -3484,15 +3485,17 @@ c_common_type_for_mode (enum machine_mod
if (mode == TYPE_MODE (long_integer_type_node))
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
if (mode == TYPE_MODE (long_long_integer_type_node))
return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
- if (int128_integer_type_node
- && mode == TYPE_MODE (int128_integer_type_node))
- return unsignedp ? int128_unsigned_type_node : int128_integer_type_node;
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (int_n_enabled_p[i]
+ && mode == int_n_data[i].m)
+ return (unsignedp ? int_n_trees[i].unsigned_type
+ : int_n_trees[i].signed_type);
if (mode == TYPE_MODE (widest_integer_literal_type_node))
return unsignedp ? widest_unsigned_literal_type_node
: widest_integer_literal_type_node;
if (mode == QImode)
@@ -3684,12 +3687,13 @@ c_common_signed_type (tree type)
signed according to UNSIGNEDP. */
tree
c_common_signed_or_unsigned_type (int unsignedp, tree type)
{
tree type1;
+ int i;
/* This block of code emulates the behavior of the old
c_common_unsigned_type. In particular, it returns
long_unsigned_type_node if passed a long, even when a int would
have the same size. This is necessary for warnings to work
correctly in archs where sizeof(int) == sizeof(long) */
@@ -3702,16 +3706,20 @@ c_common_signed_or_unsigned_type (int un
if (type1 == short_integer_type_node || type1 == short_unsigned_type_node)
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
if (type1 == long_integer_type_node || type1 == long_unsigned_type_node)
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
if (type1 == long_long_integer_type_node || type1 == long_long_unsigned_type_node)
return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
- if (int128_integer_type_node
- && (type1 == int128_integer_type_node
- || type1 == int128_unsigned_type_node))
- return unsignedp ? int128_unsigned_type_node : int128_integer_type_node;
+
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (int_n_enabled_p[i]
+ && (type1 == int_n_trees[i].unsigned_type
+ || type1 == int_n_trees[i].signed_type))
+ return (unsignedp ? int_n_trees[i].unsigned_type
+ : int_n_trees[i].signed_type);
+
if (type1 == widest_integer_literal_type_node || type1 == widest_unsigned_literal_type_node)
return unsignedp ? widest_unsigned_literal_type_node : widest_integer_literal_type_node;
#if HOST_BITS_PER_WIDE_INT >= 64
if (type1 == intTI_type_node || type1 == unsigned_intTI_type_node)
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
#endif
@@ -3820,15 +3828,20 @@ c_common_signed_or_unsigned_type (int un
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
if (TYPE_OK (long_integer_type_node))
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
if (TYPE_OK (long_long_integer_type_node))
return (unsignedp ? long_long_unsigned_type_node
: long_long_integer_type_node);
- if (int128_integer_type_node && TYPE_OK (int128_integer_type_node))
- return (unsignedp ? int128_unsigned_type_node
- : int128_integer_type_node);
+
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (int_n_enabled_p[i]
+ && TYPE_MODE (type) == int_n_data[i].m
+ && TYPE_PRECISION (type) == int_n_data[i].bitsize)
+ return (unsignedp ? int_n_trees[i].unsigned_type
+ : int_n_trees[i].signed_type);
+
if (TYPE_OK (widest_integer_literal_type_node))
return (unsignedp ? widest_unsigned_literal_type_node
: widest_integer_literal_type_node);
#if HOST_BITS_PER_WIDE_INT >= 64
if (TYPE_OK (intTI_type_node))
@@ -3849,12 +3862,14 @@ c_common_signed_or_unsigned_type (int un
/* Build a bit-field integer type for the given WIDTH and UNSIGNEDP. */
tree
c_build_bitfield_integer_type (unsigned HOST_WIDE_INT width, int unsignedp)
{
+ int i;
+
/* Extended integer types of the same width as a standard type have
lesser rank, so those of the same width as int promote to int or
unsigned int and are valid for printf formats expecting int or
unsigned int. To avoid such special cases, avoid creating
extended integer types for bit-fields if a standard integer type
is available. */
@@ -3866,16 +3881,17 @@ c_build_bitfield_integer_type (unsigned
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
if (width == TYPE_PRECISION (long_integer_type_node))
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
if (width == TYPE_PRECISION (long_long_integer_type_node))
return (unsignedp ? long_long_unsigned_type_node
: long_long_integer_type_node);
- if (int128_integer_type_node
- && width == TYPE_PRECISION (int128_integer_type_node))
- return (unsignedp ? int128_unsigned_type_node
- : int128_integer_type_node);
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (int_n_enabled_p[i]
+ && width == int_n_data[i].bitsize)
+ return (unsignedp ? int_n_trees[i].unsigned_type
+ : int_n_trees[i].signed_type);
return build_nonstandard_integer_type (width, unsignedp);
}
/* The C version of the register_builtin_type langhook. */
void
@@ -5283,12 +5299,13 @@ c_common_nodes_and_builtins (void)
int char16_type_size;
int char32_type_size;
int wchar_type_size;
tree array_domain_type;
tree va_list_ref_type_node;
tree va_list_arg_type_node;
+ int i;
build_common_tree_nodes (flag_signed_char, flag_short_double);
/* Define `int' and `char' first so that dbx will output them first. */
record_builtin_type (RID_INT, NULL, integer_type_node);
record_builtin_type (RID_CHAR, "char", char_type_node);
@@ -5299,19 +5316,25 @@ c_common_nodes_and_builtins (void)
if (c_dialect_cxx ())
record_builtin_type (RID_SIGNED, NULL, integer_type_node);
record_builtin_type (RID_LONG, "long int", long_integer_type_node);
record_builtin_type (RID_UNSIGNED, "unsigned int", unsigned_type_node);
record_builtin_type (RID_MAX, "long unsigned int",
long_unsigned_type_node);
- if (int128_integer_type_node != NULL_TREE)
+
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
{
- record_builtin_type (RID_INT128, "__int128",
- int128_integer_type_node);
- record_builtin_type (RID_MAX, "__int128 unsigned",
- int128_unsigned_type_node);
+ char name[25];
+
+ sprintf (name, "__int%d", int_n_data[i].bitsize);
+ record_builtin_type ((enum rid)(RID_FIRST_INT_N + i), name,
+ int_n_trees[i].signed_type);
+ sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
+ record_builtin_type (RID_MAX, name,
+ int_n_trees[i].unsigned_type);
}
+
if (c_dialect_cxx ())
record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node);
record_builtin_type (RID_MAX, "long long int",
long_long_integer_type_node);
record_builtin_type (RID_MAX, "long long unsigned int",
long_long_unsigned_type_node);
@@ -5341,12 +5364,14 @@ c_common_nodes_and_builtins (void)
TYPE_DECL, NULL_TREE,
intSI_type_node));
lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
TYPE_DECL, NULL_TREE,
intDI_type_node));
#if HOST_BITS_PER_WIDE_INT >= 64
+ /* Note that this is different than the __int128 type that's part of
+ the generic __intN support. */
if (targetm.scalar_mode_supported_p (TImode))
lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
TYPE_DECL,
get_identifier ("__int128_t"),
intTI_type_node));
#endif
@@ -11547,13 +11572,12 @@ keyword_begins_type_specifier (enum rid
case RID_AUTO_TYPE:
case RID_INT:
case RID_CHAR:
case RID_FLOAT:
case RID_DOUBLE:
case RID_VOID:
- case RID_INT128:
case RID_UNSIGNED:
case RID_LONG:
case RID_SHORT:
case RID_SIGNED:
case RID_DFLOAT32:
case RID_DFLOAT64:
@@ -11570,12 +11594,16 @@ keyword_begins_type_specifier (enum rid
case RID_STRUCT:
case RID_CLASS:
case RID_UNION:
case RID_ENUM:
return true;
default:
+ if (keyword >= RID_FIRST_INT_N
+ && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
+ && int_n_enabled_p[keyword-RID_FIRST_INT_N])
+ return true;
return false;
}
}
/* Return true if KEYWORD names a type qualifier. */
Index: c-family/c-common.h
===================================================================
--- c-family/c-common.h (revision 206609)
+++ c-family/c-common.h (working copy)
@@ -88,13 +88,12 @@ enum rid
/* C (reserved and imaginary types not implemented, so any use is a
syntax error) */
RID_IMAGINARY,
/* C */
RID_INT, RID_CHAR, RID_FLOAT, RID_DOUBLE, RID_VOID,
- RID_INT128,
RID_ENUM, RID_STRUCT, RID_UNION, RID_IF, RID_ELSE,
RID_WHILE, RID_DO, RID_FOR, RID_SWITCH, RID_CASE,
RID_DEFAULT, RID_BREAK, RID_CONTINUE, RID_RETURN, RID_GOTO,
RID_SIZEOF,
/* C extensions */
@@ -185,12 +184,29 @@ enum rid
RID_ADDR_SPACE_14,
RID_ADDR_SPACE_15,
RID_FIRST_ADDR_SPACE = RID_ADDR_SPACE_0,
RID_LAST_ADDR_SPACE = RID_ADDR_SPACE_15,
+ /* __intN_t keywords. The _N_M here doesn't correspond to the intN
+ in the keyword; use the bitsize in int_n_t_data_t[M] for that.
+ For example, if int_n_t_data_t[0].bitsize is 13, then RID_INT_N_0
+ is for __int13_t. */
+
+ /* Note that the range to use is RID_FIRST_INT_N through
+ RID_FIRST_INT_N + NUM_INT_N_ENTS - 1 and c-parser.c has a list of
+ all RID_INT_N_* in a case statement. */
+
+ RID_INT_N_0,
+ RID_INT_N_1,
+ RID_INT_N_2,
+ RID_INT_N_3,
+
+ RID_FIRST_INT_N = RID_INT_N_0,
+ RID_LAST_INT_N = RID_INT_N_3,
+
RID_MAX,
RID_FIRST_MODIFIER = RID_STATIC,
RID_LAST_MODIFIER = RID_ONEWAY,
RID_FIRST_CXX0X = RID_CONSTEXPR,
Index: c/c-parser.c
===================================================================
--- c/c-parser.c (revision 206609)
+++ c/c-parser.c (working copy)
@@ -109,12 +109,22 @@ c_parse_init (void)
id = get_identifier (c_common_reswords[i].word);
C_SET_RID_CODE (id, c_common_reswords[i].rid);
C_IS_RESERVED_WORD (id) = 1;
ridpointers [(int) c_common_reswords[i].rid] = id;
}
+
+ for (i = 0; i < NUM_INT_N_ENTS; i++)
+ // We always create the symbols but they aren't always supported
+ {
+ char name[50];
+ sprintf (name, "__int%d", int_n_data[i].bitsize);
+ id = get_identifier (name);
+ C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
+ C_IS_RESERVED_WORD (id) = 1;
+ }
}
/* The C lexer intermediates between the lexer in cpplib and c-lex.c
and the C parser. Unlike the C++ lexer, the parser structure
stores the lexer information instead of using a separate structure.
Identifiers are separated into ordinary identifiers, type names,
@@ -484,13 +494,12 @@ c_token_starts_typename (c_token *token)
}
case CPP_KEYWORD:
switch (token->keyword)
{
case RID_UNSIGNED:
case RID_LONG:
- case RID_INT128:
case RID_SHORT:
case RID_SIGNED:
case RID_COMPLEX:
case RID_INT:
case RID_CHAR:
case RID_FLOAT:
@@ -512,12 +521,16 @@ c_token_starts_typename (c_token *token)
case RID_FRACT:
case RID_ACCUM:
case RID_SAT:
case RID_AUTO_TYPE:
return true;
default:
+ if (token->keyword >= RID_FIRST_INT_N
+ && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
+ && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
+ return true;
return false;
}
case CPP_LESS:
if (c_dialect_objc ())
return true;
return false;
@@ -642,13 +655,12 @@ c_token_starts_declspecs (c_token *token
case RID_INLINE:
case RID_NORETURN:
case RID_AUTO:
case RID_THREAD:
case RID_UNSIGNED:
case RID_LONG:
- case RID_INT128:
case RID_SHORT:
case RID_SIGNED:
case RID_COMPLEX:
case RID_INT:
case RID_CHAR:
case RID_FLOAT:
@@ -671,12 +683,16 @@ c_token_starts_declspecs (c_token *token
case RID_SAT:
case RID_ALIGNAS:
case RID_ATOMIC:
case RID_AUTO_TYPE:
return true;
default:
+ if (token->keyword >= RID_FIRST_INT_N
+ && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
+ && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
+ return true;
return false;
}
case CPP_LESS:
if (c_dialect_objc ())
return true;
return false;
@@ -2136,13 +2152,13 @@ c_parser_static_assert_declaration_no_se
storage-class-specifier:
__thread
type-specifier:
typeof-specifier
__auto_type
- __int128
+ __intN
_Decimal32
_Decimal64
_Decimal128
_Fract
_Accum
_Sat
@@ -2290,13 +2306,12 @@ c_parser_declspecs (c_parser *parser, st
case RID_AUTO_TYPE:
if (!auto_type_ok)
goto out;
/* Fall through. */
case RID_UNSIGNED:
case RID_LONG:
- case RID_INT128:
case RID_SHORT:
case RID_SIGNED:
case RID_COMPLEX:
case RID_INT:
case RID_CHAR:
case RID_FLOAT:
@@ -2306,12 +2321,16 @@ c_parser_declspecs (c_parser *parser, st
case RID_DFLOAT64:
case RID_DFLOAT128:
case RID_BOOL:
case RID_FRACT:
case RID_ACCUM:
case RID_SAT:
+ case RID_INT_N_0:
+ case RID_INT_N_1:
+ case RID_INT_N_2:
+ case RID_INT_N_3:
if (!typespec_ok)
goto out;
attrs_ok = true;
seen_type = true;
if (c_dialect_objc ())
parser->objc_need_raw_identifier = true;
@@ -3726,13 +3745,12 @@ c_parser_attribute_any_word (c_parser *p
bool ok;
switch (c_parser_peek_token (parser)->keyword)
{
case RID_STATIC:
case RID_UNSIGNED:
case RID_LONG:
- case RID_INT128:
case RID_CONST:
case RID_EXTERN:
case RID_REGISTER:
case RID_TYPEDEF:
case RID_SHORT:
case RID_INLINE:
@@ -3756,12 +3774,16 @@ c_parser_attribute_any_word (c_parser *p
case RID_ACCUM:
case RID_SAT:
case RID_TRANSACTION_ATOMIC:
case RID_TRANSACTION_CANCEL:
case RID_ATOMIC:
case RID_AUTO_TYPE:
+ case RID_INT_N_0:
+ case RID_INT_N_1:
+ case RID_INT_N_2:
+ case RID_INT_N_3:
ok = true;
break;
default:
ok = false;
break;
}
@@ -8888,13 +8910,12 @@ c_parser_objc_selector (c_parser *parser
case RID_ASM:
case RID_SIZEOF:
case RID_TYPEOF:
case RID_ALIGNOF:
case RID_UNSIGNED:
case RID_LONG:
- case RID_INT128:
case RID_CONST:
case RID_SHORT:
case RID_VOLATILE:
case RID_SIGNED:
case RID_RESTRICT:
case RID_COMPLEX:
@@ -8909,12 +8930,16 @@ c_parser_objc_selector (c_parser *parser
case RID_FLOAT:
case RID_DOUBLE:
case RID_VOID:
case RID_BOOL:
case RID_ATOMIC:
case RID_AUTO_TYPE:
+ case RID_INT_N_0:
+ case RID_INT_N_1:
+ case RID_INT_N_2:
+ case RID_INT_N_3:
c_parser_consume_token (parser);
return value;
default:
return NULL_TREE;
}
}
Index: c/c-tree.h
===================================================================
--- c/c-tree.h (revision 206609)
+++ c/c-tree.h (working copy)
@@ -205,13 +205,13 @@ enum c_typespec_keyword {
cts_none,
cts_void,
cts_bool,
cts_char,
cts_int,
cts_float,
- cts_int128,
+ cts_int_n,
cts_double,
cts_dfloat32,
cts_dfloat64,
cts_dfloat128,
cts_fract,
cts_accum,
@@ -272,12 +272,14 @@ struct c_declspecs {
separately. */
tree attrs;
/* The base-2 log of the greatest alignment required by an _Alignas
specifier, in bytes, or -1 if no such specifiers with nonzero
alignment. */
int align_log;
+ /* For the __intN declspec, this stores the index into the int_n_* arrays. */
+ int int_n_idx;
/* The storage class specifier, or csc_none if none. */
enum c_storage_class storage_class;
/* Any type specifier keyword used such as "int", not reflecting
modifiers such as "short", or cts_none if none. */
ENUM_BITFIELD (c_typespec_keyword) typespec_word : 8;
/* The kind of type specifier if one has been seen, ctsk_none
Index: c/c-decl.c
===================================================================
--- c/c-decl.c (revision 206609)
+++ c/c-decl.c (working copy)
@@ -9147,16 +9147,17 @@ declspecs_add_type (location_t loc, stru
("both %<long%> and %<__auto_type%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_void)
error_at (loc,
("both %<long%> and %<void%> in "
"declaration specifiers"));
- else if (specs->typespec_word == cts_int128)
+ else if (specs->typespec_word == cts_int_n)
error_at (loc,
- ("both %<long%> and %<__int128%> in "
- "declaration specifiers"));
+ ("both %<long%> and %<__int%d%> in "
+ "declaration specifiers"),
+ int_n_data[specs->int_n_idx].bitsize);
else if (specs->typespec_word == cts_bool)
error_at (loc,
("both %<long%> and %<_Bool%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_char)
error_at (loc,
@@ -9195,16 +9196,17 @@ declspecs_add_type (location_t loc, stru
("both %<short%> and %<__auto_type%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_void)
error_at (loc,
("both %<short%> and %<void%> in "
"declaration specifiers"));
- else if (specs->typespec_word == cts_int128)
+ else if (specs->typespec_word == cts_int_n)
error_at (loc,
- ("both %<short%> and %<__int128%> in "
- "declaration specifiers"));
+ ("both %<short%> and %<__int%d%> in "
+ "declaration specifiers"),
+ int_n_data[specs->int_n_idx].bitsize);
else if (specs->typespec_word == cts_bool)
error_at (loc,
("both %<short%> and %<_Bool%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_char)
error_at (loc,
@@ -9372,17 +9374,18 @@ declspecs_add_type (location_t loc, stru
}
break;
case RID_SAT:
dupe = specs->saturating_p;
pedwarn (loc, OPT_Wpedantic,
"ISO C does not support saturating types");
- if (specs->typespec_word == cts_int128)
+ if (specs->typespec_word == cts_int_n)
{
error_at (loc,
- ("both %<_Sat%> and %<__int128%> in "
- "declaration specifiers"));
+ ("both %<_Sat%> and %<__int%d%> in "
+ "declaration specifiers"),
+ int_n_data[specs->int_n_idx].bitsize);
}
else if (specs->typespec_word == cts_auto_type)
error_at (loc,
("both %<_Sat%> and %<__auto_type%> in "
"declaration specifiers"));
else if (specs->typespec_word == cts_void)
@@ -9440,13 +9443,13 @@ declspecs_add_type (location_t loc, stru
return specs;
}
else
{
/* "void", "_Bool", "char", "int", "float", "double", "_Decimal32",
- "__int128", "_Decimal64", "_Decimal128", "_Fract", "_Accum" or
+ "__intN", "_Decimal64", "_Decimal128", "_Fract", "_Accum" or
"__auto_type". */
if (specs->typespec_word != cts_none)
{
error_at (loc,
"two or more data types in declaration specifiers");
return specs;
@@ -9481,37 +9484,44 @@ declspecs_add_type (location_t loc, stru
else
{
specs->typespec_word = cts_auto_type;
specs->locations[cdw_typespec] = loc;
}
return specs;
- case RID_INT128:
- if (int128_integer_type_node == NULL_TREE)
- {
- error_at (loc, "%<__int128%> is not supported for this target");
- return specs;
- }
+ case RID_INT_N_0:
+ case RID_INT_N_1:
+ case RID_INT_N_2:
+ case RID_INT_N_3:
+ specs->int_n_idx = i - RID_INT_N_0;
if (!in_system_header_at (input_location))
pedwarn (loc, OPT_Wpedantic,
- "ISO C does not support %<__int128%> type");
+ "ISO C does not support %<__int%d%> types",
+ int_n_data[specs->int_n_idx].bitsize);
if (specs->long_p)
error_at (loc,
- ("both %<__int128%> and %<long%> in "
- "declaration specifiers"));
+ ("both %<__int%d%> and %<long%> in "
+ "declaration specifiers"),
+ int_n_data[specs->int_n_idx].bitsize);
else if (specs->saturating_p)
error_at (loc,
- ("both %<_Sat%> and %<__int128%> in "
- "declaration specifiers"));
+ ("both %<_Sat%> and %<__int%d%> in "
+ "declaration specifiers"),
+ int_n_data[specs->int_n_idx].bitsize);
else if (specs->short_p)
error_at (loc,
- ("both %<__int128%> and %<short%> in "
- "declaration specifiers"));
+ ("both %<__int%d%> and %<short%> in "
+ "declaration specifiers"),
+ int_n_data[specs->int_n_idx].bitsize);
+ else if (! int_n_enabled_p [specs->int_n_idx])
+ error_at (loc,
+ "%<__int%d%> is not supported on this target",
+ int_n_data[specs->int_n_idx].bitsize);
else
{
- specs->typespec_word = cts_int128;
+ specs->typespec_word = cts_int_n;
specs->locations[cdw_typespec] = loc;
}
return specs;
case RID_VOID:
if (specs->long_p)
error_at (loc,
@@ -10070,18 +10080,18 @@ finish_declspecs (struct c_declspecs *sp
{
pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
"ISO C does not support complex integer types");
specs->type = build_complex_type (specs->type);
}
break;
- case cts_int128:
+ case cts_int_n:
gcc_assert (!specs->long_p && !specs->short_p && !specs->long_long_p);
gcc_assert (!(specs->signed_p && specs->unsigned_p));
specs->type = (specs->unsigned_p
- ? int128_unsigned_type_node
- : int128_integer_type_node);
+ ? int_n_trees[specs->int_n_idx].unsigned_type
+ : int_n_trees[specs->int_n_idx].signed_type);
if (specs->complex_p)
{
pedwarn (specs->locations[cdw_complex], OPT_Wpedantic,
"ISO C does not support complex integer types");
specs->type = build_complex_type (specs->type);
}
Index: tree.c
===================================================================
--- tree.c (revision 206609)
+++ tree.c (working copy)
@@ -236,12 +236,15 @@ static unsigned int type_hash_list (cons
static unsigned int attribute_hash_list (const_tree, hashval_t);
static bool decls_same_for_odr (tree decl1, tree decl2);
tree global_trees[TI_MAX];
tree integer_types[itk_none];
+bool int_n_enabled_p[NUM_INT_N_ENTS];
+int_n_trees_t int_n_trees[NUM_INT_N_ENTS];
+
unsigned char tree_contains_struct[MAX_TREE_CODES][64];
/* Number of operands for each OpenMP clause. */
unsigned const char omp_clause_num_ops[] =
{
0, /* OMP_CLAUSE_ERROR */
@@ -9447,26 +9450,31 @@ make_vector_type (tree innertype, int nu
return t;
}
static tree
make_or_reuse_type (unsigned size, int unsignedp)
{
+ int i;
+
if (size == INT_TYPE_SIZE)
return unsignedp ? unsigned_type_node : integer_type_node;
if (size == CHAR_TYPE_SIZE)
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
if (size == SHORT_TYPE_SIZE)
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
if (size == LONG_TYPE_SIZE)
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
if (size == LONG_LONG_TYPE_SIZE)
return (unsignedp ? long_long_unsigned_type_node
: long_long_integer_type_node);
- if (size == 128 && int128_integer_type_node)
- return (unsignedp ? int128_unsigned_type_node
- : int128_integer_type_node);
+
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (size == int_n_data[i].bitsize
+ && int_n_enabled_p[i])
+ return (unsignedp ? int_n_trees[i].unsigned_type
+ : int_n_trees[i].signed_type);
if (unsignedp)
return make_unsigned_type (size);
else
return make_signed_type (size);
}
@@ -9576,12 +9584,14 @@ build_atomic_base (tree type, unsigned i
SHORT_DOUBLE specifies whether double should be of the same precision
as float. */
void
build_common_tree_nodes (bool signed_char, bool short_double)
{
+ int i;
+
error_mark_node = make_node (ERROR_MARK);
TREE_TYPE (error_mark_node) = error_mark_node;
initialize_sizetypes ();
/* Define both `signed char' and `unsigned char'. */
@@ -9603,23 +9613,26 @@ build_common_tree_nodes (bool signed_cha
integer_type_node = make_signed_type (INT_TYPE_SIZE);
unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE);
long_integer_type_node = make_signed_type (LONG_TYPE_SIZE);
long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE);
long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE);
long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE);
-#if HOST_BITS_PER_WIDE_INT >= 64
- /* TODO: This isn't correct, but as logic depends at the moment on
- host's instead of target's wide-integer.
- If there is a target not supporting TImode, but has an 128-bit
- integer-scalar register, this target check needs to be adjusted. */
- if (targetm.scalar_mode_supported_p (TImode))
- {
- int128_integer_type_node = make_signed_type (128);
- int128_unsigned_type_node = make_unsigned_type (128);
- }
-#endif
+
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ {
+ int_n_trees[i].signed_type = make_signed_type (int_n_data[i].bitsize);
+ int_n_trees[i].unsigned_type = make_unsigned_type (int_n_data[i].bitsize);
+ TYPE_SIZE (int_n_trees[i].signed_type) = bitsize_int (int_n_data[i].bitsize);
+ TYPE_SIZE (int_n_trees[i].unsigned_type) = bitsize_int (int_n_data[i].bitsize);
+
+ if (int_n_data[i].bitsize > LONG_LONG_TYPE_SIZE)
+ {
+ integer_types[itk_intN_0 + i * 2] = int_n_trees[i].signed_type;
+ integer_types[itk_unsigned_intN_0 + i * 2] = int_n_trees[i].unsigned_type;
+ }
+ }
/* Define a boolean type. This type only represents boolean values but
may be larger than char depending on the value of BOOL_TYPE_SIZE.
Front ends which want to override this size (i.e. Java) can redefine
boolean_type_node before calling build_common_tree_nodes_2. */
boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
Index: tree.h
===================================================================
--- tree.h (revision 206609)
+++ tree.h (working copy)
@@ -3373,14 +3373,12 @@ tree_operand_check_code (const_tree __t,
#define integer_type_node integer_types[itk_int]
#define unsigned_type_node integer_types[itk_unsigned_int]
#define long_integer_type_node integer_types[itk_long]
#define long_unsigned_type_node integer_types[itk_unsigned_long]
#define long_long_integer_type_node integer_types[itk_long_long]
#define long_long_unsigned_type_node integer_types[itk_unsigned_long_long]
-#define int128_integer_type_node integer_types[itk_int128]
-#define int128_unsigned_type_node integer_types[itk_unsigned_int128]
#define NULL_TREE (tree) NULL
/* True if NODE is an erroneous expression. */
#define error_operand_p(NODE) \
@@ -4554,7 +4552,18 @@ extern unsigned int get_pointer_alignmen
extern tree fold_call_stmt (gimple, bool);
extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function);
extern void set_builtin_user_assembler_name (tree decl, const char *asmspec);
extern bool is_simple_builtin (tree);
extern bool is_inexpensive_builtin (tree);
+
+typedef struct {
+ /* These parts are initialized at runtime */
+ tree signed_type;
+ tree unsigned_type;
+} int_n_trees_t;
+
+/* This is also in machmode.h */
+extern bool int_n_enabled_p[NUM_INT_N_ENTS];
+extern int_n_trees_t int_n_trees[NUM_INT_N_ENTS];
+
#endif /* GCC_TREE_H */
Index: toplev.c
===================================================================
--- toplev.c (revision 206609)
+++ toplev.c (working copy)
@@ -1867,12 +1867,24 @@ finalize (bool no_backend)
dump_profile_report ();
/* Language-specific end of compilation actions. */
lang_hooks.finish ();
}
+static bool
+standard_type_bitsize (int bitsize)
+{
+ if (bitsize == CHAR_TYPE_SIZE
+ || bitsize == SHORT_TYPE_SIZE
+ || bitsize == INT_TYPE_SIZE
+ || bitsize == LONG_TYPE_SIZE
+ || (bitsize == LONG_LONG_TYPE_SIZE && LONG_LONG_TYPE_SIZE < GET_MODE_BITSIZE (TImode)))
+ return true;
+ return false;
+}
+
/* Initialize the compiler, and compile the input file. */
static void
do_compile (void)
{
/* Initialize timing first. The C front ends read the main file in
the post_options hook, and C++ does file timings. */
@@ -1882,19 +1894,32 @@ do_compile (void)
process_options ();
/* Don't do any more if an error has already occurred. */
if (!seen_error ())
{
+ int i;
+
timevar_start (TV_PHASE_SETUP);
/* This must be run always, because it is needed to compute the FP
predefined macros, such as __LDBL_MAX__, for targets using non
default FP formats. */
init_adjust_machine_modes ();
+ /* This must happen after the backend has a chance to process
+ command line options, but before the parsers are
+ initialized. */
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (targetm.scalar_mode_supported_p (int_n_data[i].m)
+ && ! standard_type_bitsize (int_n_data[i].bitsize)
+ && int_n_data[i].bitsize <= HOST_BITS_PER_WIDE_INT * 2)
+ int_n_enabled_p[i] = true;
+ else
+ int_n_enabled_p[i] = false;
+
/* Set up the back-end if requested. */
if (!no_backend)
backend_init ();
/* Language-dependent initialization. Returns true on success. */
if (lang_dependent_init (main_input_filename))
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 206609)
+++ cp/typeck.c (working copy)
@@ -267,12 +267,13 @@ original_type (tree t)
static tree
cp_common_type (tree t1, tree t2)
{
enum tree_code code1 = TREE_CODE (t1);
enum tree_code code2 = TREE_CODE (t2);
tree attributes;
+ int i;
/* In what follows, we slightly generalize the rules given in [expr] so
as to deal with `long long' and `complex'. First, merge the
attributes. */
attributes = (*targetm.merge_type_attributes) (t1, t2);
@@ -361,22 +362,25 @@ cp_common_type (tree t1, tree t2)
{
tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
? long_long_unsigned_type_node
: long_long_integer_type_node);
return build_type_attribute_variant (t, attributes);
}
- if (int128_integer_type_node != NULL_TREE
- && (same_type_p (TYPE_MAIN_VARIANT (t1),
- int128_integer_type_node)
- || same_type_p (TYPE_MAIN_VARIANT (t2),
- int128_integer_type_node)))
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
{
- tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
- ? int128_unsigned_type_node
- : int128_integer_type_node);
- return build_type_attribute_variant (t, attributes);
+ if (int_n_enabled_p [i]
+ && (same_type_p (TYPE_MAIN_VARIANT (t1),
+ int_n_trees[i].signed_type)
+ || same_type_p (TYPE_MAIN_VARIANT (t2),
+ int_n_trees[i].signed_type)))
+ {
+ tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
+ ? int_n_trees[i].unsigned_type
+ : int_n_trees[i].signed_type);
+ return build_type_attribute_variant (t, attributes);
+ }
}
/* Go through the same procedure, but for longs. */
if (same_type_p (TYPE_MAIN_VARIANT (t1), long_unsigned_type_node)
|| same_type_p (TYPE_MAIN_VARIANT (t2), long_unsigned_type_node))
return build_type_attribute_variant (long_unsigned_type_node,
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 206609)
+++ cp/decl.c (working copy)
@@ -8728,13 +8728,13 @@ grokdeclarator (const cp_declarator *dec
enum decl_context decl_context,
int initialized,
tree* attrlist)
{
tree type = NULL_TREE;
int longlong = 0;
- int explicit_int128 = 0;
+ int explicit_intN = 0;
int virtualp, explicitp, friendp, inlinep, staticp;
int explicit_int = 0;
int explicit_char = 0;
int defaulted_int = 0;
tree typedef_decl = NULL_TREE;
@@ -8799,13 +8799,13 @@ grokdeclarator (const cp_declarator *dec
signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed);
unsigned_p = decl_spec_seq_has_spec_p (declspecs, ds_unsigned);
short_p = decl_spec_seq_has_spec_p (declspecs, ds_short);
long_p = decl_spec_seq_has_spec_p (declspecs, ds_long);
longlong = decl_spec_seq_has_spec_p (declspecs, ds_long_long);
- explicit_int128 = declspecs->explicit_int128_p;
+ explicit_intN = declspecs->explicit_intN_p;
thread_p = decl_spec_seq_has_spec_p (declspecs, ds_thread);
if (decl_context == FUNCDEF)
funcdef_flag = true, decl_context = NORMAL;
else if (decl_context == MEMFUNCDEF)
funcdef_flag = true, decl_context = FIELD;
@@ -9140,22 +9140,24 @@ grokdeclarator (const cp_declarator *dec
type = integer_type_node;
}
ctype = NULL_TREE;
- if (explicit_int128)
+ if (explicit_intN)
{
- if (int128_integer_type_node == NULL_TREE)
- {
- error ("%<__int128%> is not supported by this target");
- explicit_int128 = false;
- }
+ if (! int_n_enabled_p[declspecs->int_n_idx])
+ {
+ error ("%<__int%d%> is not supported by this target",
+ int_n_data[declspecs->int_n_idx].bitsize);
+ explicit_intN = false;
+ }
else if (pedantic && ! in_system_header_at (input_location))
- pedwarn (input_location, OPT_Wpedantic,
- "ISO C++ does not support %<__int128%> for %qs", name);
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ does not support %<__int%d%> for %qs",
+ int_n_data[declspecs->int_n_idx].bitsize, name);
}
/* Now process the modifiers that were specified
and check for invalid combinations. */
/* Long double is a special combination. */
@@ -9181,13 +9183,13 @@ grokdeclarator (const cp_declarator *dec
else if (long_p && TREE_CODE (type) == REAL_TYPE)
error ("%<long%> invalid for %qs", name);
else if (short_p && TREE_CODE (type) == REAL_TYPE)
error ("%<short%> invalid for %qs", name);
else if ((long_p || short_p) && TREE_CODE (type) != INTEGER_TYPE)
error ("%<long%> or %<short%> invalid for %qs", name);
- else if ((long_p || short_p || explicit_char || explicit_int) && explicit_int128)
+ else if ((long_p || short_p || explicit_char || explicit_int) && explicit_intN)
error ("%<long%>, %<int%>, %<short%>, or %<char%> invalid for %qs", name);
else if ((long_p || short_p) && explicit_char)
error ("%<long%> or %<short%> specified with char for %qs", name);
else if (long_p && short_p)
error ("%<long%> and %<short%> specified together for %qs", name);
else if (type == char16_type_node || type == char32_type_node)
@@ -9197,13 +9199,13 @@ grokdeclarator (const cp_declarator *dec
else if (short_p || long_p)
error ("%<short%> or %<long%> invalid for %qs", name);
}
else
{
ok = 1;
- if (!explicit_int && !defaulted_int && !explicit_char && !explicit_int128 && pedantic)
+ if (!explicit_int && !defaulted_int && !explicit_char && !explicit_intN && pedantic)
{
pedwarn (input_location, OPT_Wpedantic,
"long, short, signed or unsigned used invalidly for %qs",
name);
if (flag_pedantic_errors)
ok = 0;
@@ -9239,14 +9241,14 @@ grokdeclarator (const cp_declarator *dec
`signed int' cannot be so controlled. */
&& !(typedef_decl
&& C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))
&& TREE_CODE (type) == INTEGER_TYPE
&& !same_type_p (TYPE_MAIN_VARIANT (type), wchar_type_node)))
{
- if (explicit_int128)
- type = int128_unsigned_type_node;
+ if (explicit_intN)
+ type = int_n_trees[declspecs->int_n_idx].unsigned_type;
else if (longlong)
type = long_long_unsigned_type_node;
else if (long_p)
type = long_unsigned_type_node;
else if (short_p)
type = short_unsigned_type_node;
@@ -9256,14 +9258,14 @@ grokdeclarator (const cp_declarator *dec
type = unsigned_type_for (type);
else
type = unsigned_type_node;
}
else if (signed_p && type == char_type_node)
type = signed_char_type_node;
- else if (explicit_int128)
- type = int128_integer_type_node;
+ else if (explicit_intN)
+ type = int_n_trees[declspecs->int_n_idx].signed_type;
else if (longlong)
type = long_long_integer_type_node;
else if (long_p)
type = long_integer_type_node;
else if (short_p)
type = short_integer_type_node;
@@ -9273,13 +9275,13 @@ grokdeclarator (const cp_declarator *dec
if (TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
error ("complex invalid for %qs", name);
/* If we just have "complex", it is equivalent to
"complex double", but if any modifiers at all are specified it is
the complex form of TYPE. E.g, "complex short" is
"complex short int". */
- else if (defaulted_int && ! longlong && ! explicit_int128
+ else if (defaulted_int && ! longlong && ! explicit_intN
&& ! (long_p || short_p || signed_p || unsigned_p))
type = complex_double_type_node;
else if (type == integer_type_node)
type = complex_integer_type_node;
else if (type == float_type_node)
type = complex_float_type_node;
Index: cp/rtti.c
===================================================================
--- cp/rtti.c (revision 206609)
+++ cp/rtti.c (working copy)
@@ -1483,13 +1483,13 @@ emit_support_tinfos (void)
&wchar_type_node, &char16_type_node, &char32_type_node,
&char_type_node, &signed_char_type_node, &unsigned_char_type_node,
&short_integer_type_node, &short_unsigned_type_node,
&integer_type_node, &unsigned_type_node,
&long_integer_type_node, &long_unsigned_type_node,
&long_long_integer_type_node, &long_long_unsigned_type_node,
- &int128_integer_type_node, &int128_unsigned_type_node,
+ // &int128_integer_type_node, &int128_unsigned_type_node,
&float_type_node, &double_type_node, &long_double_type_node,
&dfloat32_type_node, &dfloat64_type_node, &dfloat128_type_node,
&nullptr_type_node,
0
};
int ix;
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 206609)
+++ cp/parser.c (working copy)
@@ -926,13 +926,12 @@ cp_lexer_next_token_is_decl_specifier_ke
case RID_CHAR32:
case RID_WCHAR:
case RID_BOOL:
case RID_SHORT:
case RID_INT:
case RID_LONG:
- case RID_INT128:
case RID_SIGNED:
case RID_UNSIGNED:
case RID_FLOAT:
case RID_DOUBLE:
case RID_VOID:
/* GNU extensions. */
@@ -941,12 +940,16 @@ cp_lexer_next_token_is_decl_specifier_ke
/* C++0x extensions. */
case RID_DECLTYPE:
case RID_UNDERLYING_TYPE:
return true;
default:
+ if (token->keyword >= RID_FIRST_INT_N
+ && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
+ && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
+ return true;
return false;
}
}
/* Returns TRUE iff the token T begins a decltype type. */
@@ -14436,12 +14439,13 @@ static tree
cp_parser_simple_type_specifier (cp_parser* parser,
cp_decl_specifier_seq *decl_specs,
cp_parser_flags flags)
{
tree type = NULL_TREE;
cp_token *token;
+ int idx;
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
/* If we're looking at a keyword, things are easy. */
switch (token->keyword)
@@ -14469,18 +14473,25 @@ cp_parser_simple_type_specifier (cp_pars
break;
case RID_INT:
if (decl_specs)
decl_specs->explicit_int_p = true;
type = integer_type_node;
break;
- case RID_INT128:
- if (!int128_integer_type_node)
+ case RID_INT_N_0:
+ case RID_INT_N_1:
+ case RID_INT_N_2:
+ case RID_INT_N_3:
+ idx = token->keyword - RID_INT_N_0;
+ if (! int_n_enabled_p [idx])
break;
if (decl_specs)
- decl_specs->explicit_int128_p = true;
- type = int128_integer_type_node;
+ {
+ decl_specs->explicit_intN_p = true;
+ decl_specs->int_n_idx = idx;
+ }
+ type = int_n_trees [idx].signed_type;
break;
case RID_LONG:
if (decl_specs)
set_and_check_decl_spec_loc (decl_specs, ds_long, token);
type = long_integer_type_node;
break;
Index: cp/mangle.c
===================================================================
--- cp/mangle.c (revision 206609)
+++ cp/mangle.c (working copy)
@@ -149,14 +149,12 @@ integer_type_codes[itk_none] =
'i', /* itk_int */
'j', /* itk_unsigned_int */
'l', /* itk_long */
'm', /* itk_unsigned_long */
'x', /* itk_long_long */
'y', /* itk_unsigned_long_long */
- 'n', /* itk_int128 */
- 'o', /* itk_unsigned_int128 */
};
static int decl_is_template_id (const tree, tree* const);
/* Functions for handling substitutions. */
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 206609)
+++ cp/cp-tree.h (working copy)
@@ -4810,12 +4810,14 @@ typedef struct cp_decl_specifier_seq {
/* If non-NULL, a built-in type that the user attempted to redefine
to some other type. */
tree redefined_builtin_type;
/* The storage class specified -- or sc_none if no storage class was
explicitly specified. */
cp_storage_class storage_class;
+ /* For the __intN declspec, this stores the index into the int_n_* arrays. */
+ int int_n_idx;
/* True iff TYPE_SPEC defines a class or enum. */
BOOL_BITFIELD type_definition_p : 1;
/* True iff multiple types were (erroneously) specified for this
decl-specifier-seq. */
BOOL_BITFIELD multiple_types_p : 1;
/* True iff multiple storage classes were (erroneously) specified
@@ -4825,14 +4827,14 @@ typedef struct cp_decl_specifier_seq {
/* True iff at least one decl-specifier was found. */
BOOL_BITFIELD any_specifiers_p : 1;
/* True iff at least one type-specifier was found. */
BOOL_BITFIELD any_type_specifiers_p : 1;
/* True iff "int" was explicitly provided. */
BOOL_BITFIELD explicit_int_p : 1;
- /* True iff "__int128" was explicitly provided. */
- BOOL_BITFIELD explicit_int128_p : 1;
+ /* True iff "__intN" was explicitly provided. */
+ BOOL_BITFIELD explicit_intN_p : 1;
/* True iff "char" was explicitly provided. */
BOOL_BITFIELD explicit_char_p : 1;
/* True iff ds_thread is set for __thread, not thread_local. */
BOOL_BITFIELD gnu_thread_keyword_p : 1;
} cp_decl_specifier_seq;
Index: cp/lex.c
===================================================================
--- cp/lex.c (revision 206609)
+++ cp/lex.c (working copy)
@@ -190,12 +190,21 @@ init_reswords (void)
id = get_identifier (c_common_reswords[i].word);
C_SET_RID_CODE (id, c_common_reswords[i].rid);
ridpointers [(int) c_common_reswords[i].rid] = id;
if (! (c_common_reswords[i].disable & mask))
C_IS_RESERVED_WORD (id) = 1;
}
+
+ for (i = 0; i < NUM_INT_N_ENTS; i++)
+ {
+ char name[50];
+ sprintf (name, "__int%d", int_n_data[i].bitsize);
+ id = get_identifier (name);
+ C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
+ C_IS_RESERVED_WORD (id) = 1;
+ }
}
static void
init_cp_pragma (void)
{
c_register_pragma (0, "vtable", handle_pragma_vtable);
Index: builtin-types.def
===================================================================
--- builtin-types.def (revision 206609)
+++ builtin-types.def (working copy)
@@ -70,14 +70,12 @@ DEF_PRIMITIVE_TYPE (BT_BOOL, boolean_typ
DEF_PRIMITIVE_TYPE (BT_INT, integer_type_node)
DEF_PRIMITIVE_TYPE (BT_UINT, unsigned_type_node)
DEF_PRIMITIVE_TYPE (BT_LONG, long_integer_type_node)
DEF_PRIMITIVE_TYPE (BT_ULONG, long_unsigned_type_node)
DEF_PRIMITIVE_TYPE (BT_LONGLONG, long_long_integer_type_node)
DEF_PRIMITIVE_TYPE (BT_ULONGLONG, long_long_unsigned_type_node)
-DEF_PRIMITIVE_TYPE (BT_INT128, int128_integer_type_node)
-DEF_PRIMITIVE_TYPE (BT_UINT128, int128_unsigned_type_node)
DEF_PRIMITIVE_TYPE (BT_INTMAX, intmax_type_node)
DEF_PRIMITIVE_TYPE (BT_UINTMAX, uintmax_type_node)
DEF_PRIMITIVE_TYPE (BT_UINT16, uint16_type_node)
DEF_PRIMITIVE_TYPE (BT_UINT32, uint32_type_node)
DEF_PRIMITIVE_TYPE (BT_UINT64, uint64_type_node)
DEF_PRIMITIVE_TYPE (BT_WORD, (*lang_hooks.types.type_for_mode) (word_mode, 1))
Index: machmode.def
===================================================================
--- machmode.def (revision 206609)
+++ machmode.def (working copy)
@@ -189,12 +189,19 @@ INT_MODE (HI, 2);
INT_MODE (SI, 4);
INT_MODE (DI, 8);
INT_MODE (TI, 16);
/* No partial integer modes are defined by default. */
+/* The target normally defines any target-specific __intN types and
+ their modes, but __int128 for TImode is fairly common so define it
+ here. The type will not be created unless the target supports
+ TImode. */
+
+INT_N (TI, 128);
+
/* Basic floating point modes. SF and DF are the only modes provided
by default. The names QF, HF, XF, and TF are reserved for targets
that need 1-word, 2-word, 80-bit, or 128-bit float types respectively.
These are the IEEE mappings. They can be overridden with
RESET_FLOAT_FORMAT or at runtime (in TARGET_OPTION_OVERRIDE). */
Index: stor-layout.c
===================================================================
--- stor-layout.c (revision 206609)
+++ stor-layout.c (working copy)
@@ -310,22 +310,29 @@ finalize_size_functions (void)
than MAX_FIXED_MODE_SIZE will not be used. */
enum machine_mode
mode_for_size (unsigned int size, enum mode_class mclass, int limit)
{
enum machine_mode mode;
+ int i;
if (limit && size > MAX_FIXED_MODE_SIZE)
return BLKmode;
/* Get the first mode which has this size, in the specified class. */
for (mode = GET_CLASS_NARROWEST_MODE (mclass); mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
if (GET_MODE_PRECISION (mode) == size)
return mode;
+ if (mclass == MODE_INT && mode == BLKmode)
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (int_n_data[i].bitsize == size
+ && int_n_enabled_p[i])
+ return int_n_data[i].m;
+
return BLKmode;
}
/* Similar, except passed a tree node. */
enum machine_mode
@@ -346,22 +353,33 @@ mode_for_size_tree (const_tree size, enu
/* Similar, but never return BLKmode; return the narrowest mode that
contains at least the requested number of value bits. */
enum machine_mode
smallest_mode_for_size (unsigned int size, enum mode_class mclass)
{
- enum machine_mode mode;
+ enum machine_mode mode = VOIDmode;
+ int i;
/* Get the first mode which has at least this size, in the
specified class. */
for (mode = GET_CLASS_NARROWEST_MODE (mclass); mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
if (GET_MODE_PRECISION (mode) >= size)
- return mode;
+ break;
- gcc_unreachable ();
+ if (mclass == MODE_INT)
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (int_n_data[i].bitsize >= size
+ && int_n_data[i].bitsize < GET_MODE_PRECISION (mode)
+ && int_n_enabled_p[i])
+ mode = int_n_data[i].m;
+
+ if (mode == VOIDmode)
+ gcc_unreachable ();
+
+ return mode;
}
/* Find an integer mode of the exact same size, or BLKmode on failure. */
enum machine_mode
int_mode_for_mode (enum machine_mode mode)
Index: genmodes.c
===================================================================
--- genmodes.c (revision 206609)
+++ genmodes.c (working copy)
@@ -69,23 +69,25 @@ struct mode_data
const char *file; /* file and line of definition, */
unsigned int line; /* for error reporting */
unsigned int counter; /* Rank ordering of modes */
unsigned int ibit; /* the number of integral bits */
unsigned int fbit; /* the number of fractional bits */
+
+ unsigned int int_n; /* If nonzero, then __int<INT_N> will be defined */
};
static struct mode_data *modes[MAX_MODE_CLASS];
static unsigned int n_modes[MAX_MODE_CLASS];
static struct mode_data *void_mode;
static const struct mode_data blank_mode = {
0, "<unknown>", MAX_MODE_CLASS,
-1U, -1U, -1U, -1U,
0, 0, 0, 0, 0,
- "<unknown>", 0, 0, 0, 0
+ "<unknown>", 0, 0, 0, 0, 0
};
static htab_t modes_by_name;
/* Data structure for recording target-specified runtime adjustments
to a particular mode. We support varying the byte size, the
@@ -627,12 +629,40 @@ reset_float_format (const char *name, co
error ("%s:%d: mode \"%s\" is not a FLOAT class", file, line, name);
return;
}
m->format = format;
}
+/* __intN support. */
+#define INT_N(M,PREC) \
+ make_int_n (#M, PREC, __FILE__, __LINE__)
+static void ATTRIBUTE_UNUSED
+make_int_n (const char *m, int bitsize,
+ const char *file, unsigned int line)
+{
+ struct mode_data *component = find_mode (m);
+ if (!component)
+ {
+ error ("%s:%d: no mode \"%s\"", file, line, m);
+ return;
+ }
+ if (component->cl != MODE_INT
+ && component->cl != MODE_PARTIAL_INT)
+ {
+ error ("%s:%d: mode \"%s\" is not class INT or PARTIAL_INT", file, line, m);
+ return;
+ }
+ if (component->int_n != 0)
+ {
+ error ("%s:%d: mode \"%s\" already has an intN", file, line, m);
+ return;
+ }
+
+ component->int_n = bitsize;
+}
+
/* Partial integer modes are specified by relation to a full integer
mode. */
#define PARTIAL_INT_MODE(M,PREC,NAME) \
make_partial_integer_mode (#M, #NAME, PREC, __FILE__, __LINE__)
static void ATTRIBUTE_UNUSED
make_partial_integer_mode (const char *base, const char *name,
@@ -906,12 +936,13 @@ emit_max_int (void)
static void
emit_insn_modes_h (void)
{
int c;
struct mode_data *m, *first, *last;
+ int n_int_n_ents = 0;
printf ("/* Generated automatically from machmode.def%s%s\n",
HAVE_EXTRA_MODES ? " and " : "",
EXTRA_MODES_FILE);
puts ("\
@@ -966,12 +997,19 @@ enum machine_mode\n{");
#if 0 /* disabled for backward compatibility, temporary */
printf ("#define CONST_REAL_FORMAT_FOR_MODE%s\n", adj_format ? "" :" const");
#endif
printf ("#define CONST_MODE_IBIT%s\n", adj_ibit ? "" : " const");
printf ("#define CONST_MODE_FBIT%s\n", adj_fbit ? "" : " const");
emit_max_int ();
+
+ for_all_modes (c, m)
+ if (m->int_n)
+ n_int_n_ents ++;
+
+ printf ("#define NUM_INT_N_ENTS %d\n", n_int_n_ents);
+
puts ("\
\n\
#endif /* insn-modes.h */");
}
static void
@@ -1409,12 +1447,59 @@ emit_mode_fbit (void)
for_all_modes (c, m)
tagged_printf ("%u", m->fbit, m->name);
print_closer ();
}
+/* Emit __intN for all modes. */
+
+static void
+emit_mode_int_n (void)
+{
+ int c;
+ struct mode_data *m;
+ struct mode_data **mode_sort;
+ int n_modes = 0;
+ int i, j;
+
+ print_decl ("int_n_data_t", "int_n_data", "");
+
+ n_modes = 0;
+ for_all_modes (c, m)
+ if (m->int_n)
+ n_modes ++;
+ mode_sort = XALLOCAVEC (struct mode_data *, n_modes);
+
+ n_modes = 0;
+ for_all_modes (c, m)
+ if (m->int_n)
+ mode_sort[n_modes++] = m;
+
+ /* Yes, this is a bubblesort, but there are at most four (and
+ usually only 1-2) entries to sort. */
+ for (i = 0; i<n_modes - 1; i++)
+ for (j = i + 1; j < n_modes; j++)
+ if (mode_sort[i]->int_n > mode_sort[j]->int_n)
+ {
+ m = mode_sort[i];
+ mode_sort[i] = mode_sort[j];
+ mode_sort[j] = m;
+ }
+
+ for (i = 0; i < n_modes; i ++)
+ {
+ m = mode_sort[i];
+ printf(" {\n");
+ tagged_printf ("%u", m->int_n, m->name);
+ printf ("%smode,", m->name);
+ printf(" },\n");
+ }
+
+ print_closer ();
+}
+
static void
emit_insn_modes_c (void)
{
emit_insn_modes_c_header ();
emit_mode_name ();
@@ -1428,12 +1513,13 @@ emit_insn_modes_c (void)
emit_mode_base_align ();
emit_class_narrowest_mode ();
emit_real_format_for_mode ();
emit_mode_adjustments ();
emit_mode_ibit ();
emit_mode_fbit ();
+ emit_mode_int_n ();
}
static void
emit_min_insn_modes_c (void)
{
emit_min_insn_modes_c_header ();
Index: gimple.c
===================================================================
--- gimple.c (revision 206609)
+++ gimple.c (working copy)
@@ -2093,12 +2093,13 @@ gimple_compare_field_offset (tree f1, tr
signed according to UNSIGNEDP. */
static tree
gimple_signed_or_unsigned_type (bool unsignedp, tree type)
{
tree type1;
+ int i;
type1 = TYPE_MAIN_VARIANT (type);
if (type1 == signed_char_type_node
|| type1 == char_type_node
|| type1 == unsigned_char_type_node)
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
@@ -2110,16 +2111,21 @@ gimple_signed_or_unsigned_type (bool uns
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
if (type1 == long_long_integer_type_node
|| type1 == long_long_unsigned_type_node)
return unsignedp
? long_long_unsigned_type_node
: long_long_integer_type_node;
- if (int128_integer_type_node && (type1 == int128_integer_type_node || type1 == int128_unsigned_type_node))
- return unsignedp
- ? int128_unsigned_type_node
- : int128_integer_type_node;
+
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (int_n_enabled_p[i]
+ && (type1 == int_n_trees[i].unsigned_type
+ || type1 == int_n_trees[i].signed_type))
+ return unsignedp
+ ? int_n_trees[i].unsigned_type
+ : int_n_trees[i].signed_type;
+
#if HOST_BITS_PER_WIDE_INT >= 64
if (type1 == intTI_type_node || type1 == unsigned_intTI_type_node)
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
#endif
if (type1 == intDI_type_node || type1 == unsigned_intDI_type_node)
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
@@ -2226,16 +2232,20 @@ gimple_signed_or_unsigned_type (bool uns
if (TYPE_OK (long_integer_type_node))
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
if (TYPE_OK (long_long_integer_type_node))
return (unsignedp
? long_long_unsigned_type_node
: long_long_integer_type_node);
- if (int128_integer_type_node && TYPE_OK (int128_integer_type_node))
- return (unsignedp
- ? int128_unsigned_type_node
- : int128_integer_type_node);
+
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (int_n_enabled_p[i]
+ && TYPE_MODE (type) == int_n_data[i].m
+ && TYPE_PRECISION (type) == int_n_data[i].bitsize)
+ return unsignedp
+ ? int_n_trees[i].unsigned_type
+ : int_n_trees[i].signed_type;
#if HOST_BITS_PER_WIDE_INT >= 64
if (TYPE_OK (intTI_type_node))
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
#endif
if (TYPE_OK (intDI_type_node))
Index: tree-core.h
===================================================================
--- tree-core.h (revision 206609)
+++ tree-core.h (working copy)
@@ -560,14 +560,22 @@ enum integer_type_kind {
itk_int,
itk_unsigned_int,
itk_long,
itk_unsigned_long,
itk_long_long,
itk_unsigned_long_long,
- itk_int128,
- itk_unsigned_int128,
+
+ itk_intN_0,
+ itk_unsigned_intN_0,
+ itk_intN_1,
+ itk_unsigned_intN_1,
+ itk_intN_2,
+ itk_unsigned_intN_2,
+ itk_intN_3,
+ itk_unsigned_intN_3,
+
itk_none
};
/* A pointer-to-function member type looks like:
struct {
Index: config/msp430/msp430.c
===================================================================
--- config/msp430/msp430.c (revision 206609)
+++ config/msp430/msp430.c (working copy)
@@ -234,12 +234,23 @@ msp430_option_override (void)
command line and always sets -O2 in CFLAGS. Thus it is not
possible to build newlib with -Os enabled. Until now... */
if (TARGET_OPT_SPACE && optimize < 3)
optimize_size = 1;
}
+#undef TARGET_SCALAR_MODE_SUPPORTED_P
+#define TARGET_SCALAR_MODE_SUPPORTED_P msp430_scalar_mode_supported_p
+
+static bool
+msp430_scalar_mode_supported_p (enum machine_mode m)
+{
+ if (m == PSImode && msp430x)
+ return true;
+ return default_scalar_mode_supported_p (m);
+}
+
/* Storage Layout */
#undef TARGET_MS_BITFIELD_LAYOUT_P
#define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p
Index: config/msp430/msp430-modes.def
===================================================================
--- config/msp430/msp430-modes.def (revision 206609)
+++ config/msp430/msp430-modes.def (working copy)
@@ -1,3 +1,4 @@
/* 20-bit address */
PARTIAL_INT_MODE (SI, 20, PSI);
+INT_N (PSI, 20);