machmode.h (int_n_data_t): New.

* 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 __int128 for all targets.
	* stor-layout.c (mode_for_size): Support __intN types.
	(smallest_mode_for_size): Likewise.
	(initialize_sizetypes): Support __intN types.
	* 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.

libstdc++-v3/
	* src/c++11/limits.cc: Add support for __intN types.
	* include/std/type_traits: Likewise.
	* include/std/limits: Likewise.
	* include/c_std/cstdlib: Likewise.
	* include/bits/cpp_type_traits.h: Likewise.
	* include/c_global/cstdlib: Likewise.

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.
	(cpp_atomic_builtins): Round pointer sizes up.
	(type_suffix): Use type precision, not specific types.
	* 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.

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.

testsuite/
	* g++.dg/abi/mangle64.C: New.

cp/
	* typeck.c (cp_common_type): Check for all __intN types, not just
	__int128.
	* decl.c (grokdeclarator): Likewise.
	* rtti.c (emit_support_tinfos): Check for all __intN types, not just
	__int128.
	* 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.

lto/
	* lto-lang.c (lto_build_c_type_nodes): Check intN types for
	size-type as well.
	(lto_init): Initialize all intN types, not just int128.

From-SVN: r216220
This commit is contained in:
DJ Delorie 2014-10-14 15:44:36 -04:00 committed by DJ Delorie
parent df3e34938d
commit 78a7c3172f
39 changed files with 1041 additions and 353 deletions

View File

@ -1,3 +1,43 @@
2014-10-14 DJ Delorie <dj@redhat.com>
* 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 __int128 for all targets.
* stor-layout.c (mode_for_size): Support __intN types.
(smallest_mode_for_size): Likewise.
(initialize_sizetypes): Support __intN types.
* 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-modes.def (PSI): Add.
2014-10-14 Kito Cheng <kito@0xlab.org>
* ira.c: Fix typo in comment.

View File

@ -65,8 +65,6 @@ 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)

View File

@ -1,3 +1,22 @@
2014-10-14 DJ Delorie <dj@redhat.com>
* 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.
(cpp_atomic_builtins): Round pointer sizes up.
(type_suffix): Use type precision, not specific types.
* 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.
2014-10-12 Trevor Saunders <tsaunders@mozilla.com>
* c-common.c: Use hash_table instead of hashtab.

View File

@ -61,12 +61,10 @@ cpp_reader *parse_in; /* Declared in c-pragma.h. */
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;
@ -468,7 +466,6 @@ const struct c_common_resword c_common_reswords[] =
{ "__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 },
@ -3449,6 +3446,8 @@ check_case_bounds (location_t loc, tree type, tree orig_type,
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;
@ -3465,10 +3464,11 @@ c_common_type_for_size (unsigned int bits, int unsignedp)
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
@ -3532,6 +3532,7 @@ 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;
@ -3548,9 +3549,11 @@ c_common_type_for_mode (enum machine_mode mode, int unsignedp)
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
@ -3748,6 +3751,7 @@ 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
@ -3766,10 +3770,14 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type)
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
@ -3884,9 +3892,14 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type)
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);
@ -3913,6 +3926,8 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type)
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
@ -3930,10 +3945,11 @@ c_build_bitfield_integer_type (unsigned HOST_WIDE_INT width, int unsignedp)
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);
}
@ -5338,6 +5354,7 @@ c_common_nodes_and_builtins (void)
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);
@ -5354,13 +5371,19 @@ c_common_nodes_and_builtins (void)
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), xstrdup (name),
int_n_trees[i].signed_type);
sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
record_builtin_type (RID_MAX, xstrdup (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",
@ -5396,6 +5419,8 @@ c_common_nodes_and_builtins (void)
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,
@ -11762,7 +11787,6 @@ keyword_begins_type_specifier (enum rid keyword)
case RID_FLOAT:
case RID_DOUBLE:
case RID_VOID:
case RID_INT128:
case RID_UNSIGNED:
case RID_LONG:
case RID_SHORT:
@ -11785,6 +11809,10 @@ keyword_begins_type_specifier (enum rid keyword)
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;
}
}

View File

@ -91,7 +91,6 @@ enum rid
/* 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,
@ -190,6 +189,23 @@ enum rid
RID_FIRST_ADDR_SPACE = RID_ADDR_SPACE_0,
RID_LAST_ADDR_SPACE = RID_ADDR_SPACE_15,
/* __intN 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. */
/* 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,

View File

@ -771,6 +771,8 @@ cpp_iec_559_complex_value (void)
void
c_cpp_builtins (cpp_reader *pfile)
{
int i;
/* -undef turns off target-specific built-ins. */
if (flag_undef)
return;
@ -889,6 +891,23 @@ c_cpp_builtins (cpp_reader *pfile)
builtin_define_type_max ("__PTRDIFF_MAX__", ptrdiff_type_node);
builtin_define_type_max ("__SIZE_MAX__", size_type_node);
for (i = 0; i < NUM_INT_N_ENTS; i ++)
if (int_n_enabled_p[i])
{
char buf[35+20+20];
/* These are used to configure the C++ library. */
if (!flag_iso || int_n_data[i].bitsize == POINTER_SIZE)
{
sprintf (buf, "__GLIBCXX_TYPE_INT_N_%d=__int%d", i, int_n_data[i].bitsize);
cpp_define (parse_in, buf);
sprintf (buf, "__GLIBCXX_BITSIZE_INT_N_%d=%d", i, int_n_data[i].bitsize);
cpp_define (parse_in, buf);
}
}
/* stdint.h and the testsuite need to know these. */
builtin_define_stdint_macros ();
@ -1169,9 +1188,14 @@ c_cpp_builtins (cpp_reader *pfile)
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__",
@ -1445,12 +1469,15 @@ type_suffix (tree type)
static const char *const suffixes[] = { "", "U", "L", "UL", "LL", "ULL" };
int unsigned_suffix;
int is_long;
int tp = TYPE_PRECISION (type);
if (type == long_long_integer_type_node
|| type == long_long_unsigned_type_node)
|| type == long_long_unsigned_type_node
|| tp > TYPE_PRECISION (long_integer_type_node))
is_long = 2;
else if (type == long_integer_type_node
|| type == long_unsigned_type_node)
|| type == long_unsigned_type_node
|| tp > TYPE_PRECISION (integer_type_node))
is_long = 1;
else if (type == integer_type_node
|| type == unsigned_type_node

View File

@ -920,6 +920,8 @@ pp_c_void_constant (c_pretty_printer *pp)
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 =
@ -950,9 +952,17 @@ pp_c_integer_constant (c_pretty_printer *pp, tree i)
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. */

View File

@ -1,3 +1,18 @@
2014-10-14 DJ Delorie <dj@redhat.com>
* 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.
2014-10-13 Anthony Brandon <anthony.brandon@gmail.com>
* c-parser.c (c_parser_all_labels): New function to replace

View File

@ -9369,10 +9369,11 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
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 "
@ -9417,10 +9418,11 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
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 "
@ -9594,11 +9596,12 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
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,
@ -9662,7 +9665,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *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)
{
@ -9703,31 +9706,41 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
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;
}
if (!in_system_header_at (input_location))
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)
/* As a special exception, allow a type that's used
for __SIZE_TYPE__. */
&& int_n_data[specs->int_n_idx].bitsize != POINTER_SIZE)
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;
@ -10295,12 +10308,12 @@ finish_declspecs (struct c_declspecs *specs)
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,

View File

@ -113,6 +113,16 @@ c_parse_init (void)
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 (xstrdup (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
@ -483,7 +493,6 @@ c_token_starts_typename (c_token *token)
{
case RID_UNSIGNED:
case RID_LONG:
case RID_INT128:
case RID_SHORT:
case RID_SIGNED:
case RID_COMPLEX:
@ -511,6 +520,10 @@ c_token_starts_typename (c_token *token)
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:
@ -641,7 +654,6 @@ c_token_starts_declspecs (c_token *token)
case RID_THREAD:
case RID_UNSIGNED:
case RID_LONG:
case RID_INT128:
case RID_SHORT:
case RID_SIGNED:
case RID_COMPLEX:
@ -670,6 +682,10 @@ c_token_starts_declspecs (c_token *token)
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:
@ -2158,7 +2174,7 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser)
type-specifier:
typeof-specifier
__auto_type
__int128
__intN
_Decimal32
_Decimal64
_Decimal128
@ -2312,7 +2328,6 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
/* Fall through. */
case RID_UNSIGNED:
case RID_LONG:
case RID_INT128:
case RID_SHORT:
case RID_SIGNED:
case RID_COMPLEX:
@ -2328,6 +2343,10 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
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;
@ -3738,7 +3757,6 @@ c_parser_attribute_any_word (c_parser *parser)
case RID_STATIC:
case RID_UNSIGNED:
case RID_LONG:
case RID_INT128:
case RID_CONST:
case RID_EXTERN:
case RID_REGISTER:
@ -3768,6 +3786,10 @@ c_parser_attribute_any_word (c_parser *parser)
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:
@ -8992,7 +9014,6 @@ c_parser_objc_selector (c_parser *parser)
case RID_ALIGNOF:
case RID_UNSIGNED:
case RID_LONG:
case RID_INT128:
case RID_CONST:
case RID_SHORT:
case RID_VOLATILE:
@ -9013,6 +9034,10 @@ c_parser_objc_selector (c_parser *parser)
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:

View File

@ -202,7 +202,7 @@ enum c_typespec_keyword {
cts_char,
cts_int,
cts_float,
cts_int128,
cts_int_n,
cts_double,
cts_dfloat32,
cts_dfloat64,
@ -269,6 +269,8 @@ struct c_declspecs {
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

View File

@ -1,3 +1,18 @@
2014-10-14 DJ Delorie <dj@redhat.com>
* typeck.c (cp_common_type): Check for all __intN types, not just
__int128.
* decl.c (grokdeclarator): Likewise.
* rtti.c (emit_support_tinfos): Check for all __intN types, not just
__int128.
* 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.
2014-10-14 Marc Glisse <marc.glisse@inria.fr>
* typeck.c (cp_build_unary_op) [TRUTH_NOT_EXPR]: Accept float vectors.

View File

@ -4899,6 +4899,8 @@ typedef struct cp_decl_specifier_seq {
/* 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
@ -4914,8 +4916,8 @@ typedef struct cp_decl_specifier_seq {
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. */

View File

@ -8802,7 +8802,7 @@ grokdeclarator (const cp_declarator *declarator,
{
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;
@ -8875,7 +8875,7 @@ grokdeclarator (const cp_declarator *declarator,
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)
@ -9221,16 +9221,18 @@ grokdeclarator (const cp_declarator *declarator,
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
@ -9262,7 +9264,7 @@ grokdeclarator (const cp_declarator *declarator,
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);
@ -9278,7 +9280,7 @@ grokdeclarator (const cp_declarator *declarator,
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",
@ -9320,8 +9322,8 @@ grokdeclarator (const cp_declarator *declarator,
&& 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)
@ -9337,8 +9339,8 @@ grokdeclarator (const cp_declarator *declarator,
}
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)
@ -9354,7 +9356,7 @@ grokdeclarator (const cp_declarator *declarator,
"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)

View File

@ -193,6 +193,15 @@ init_reswords (void)
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

View File

@ -154,8 +154,8 @@ integer_type_codes[itk_none] =
'm', /* itk_unsigned_long */
'x', /* itk_long_long */
'y', /* itk_unsigned_long_long */
'n', /* itk_int128 */
'o', /* itk_unsigned_int128 */
/* __intN types are handled separately */
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
};
static int decl_is_template_id (const tree, tree* const);
@ -2215,6 +2215,7 @@ write_builtin_type (tree type)
iagain:
for (itk = 0; itk < itk_none; ++itk)
if (integer_types[itk] != NULL_TREE
&& integer_type_codes[itk] != '\0'
&& type == integer_types[itk])
{
/* Print the corresponding single-letter code. */

View File

@ -947,7 +947,6 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
case RID_SHORT:
case RID_INT:
case RID_LONG:
case RID_INT128:
case RID_SIGNED:
case RID_UNSIGNED:
case RID_FLOAT:
@ -962,6 +961,10 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
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;
}
}
@ -14664,6 +14667,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
{
tree type = NULL_TREE;
cp_token *token;
int idx;
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
@ -14697,12 +14701,19 @@ cp_parser_simple_type_specifier (cp_parser* parser,
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)

View File

@ -1520,7 +1520,6 @@ emit_support_tinfos (void)
&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,
&float_type_node, &double_type_node, &long_double_type_node,
&dfloat32_type_node, &dfloat64_type_node, &dfloat128_type_node,
&nullptr_type_node,
@ -1542,6 +1541,12 @@ emit_support_tinfos (void)
doing_runtime = 1;
for (ix = 0; fundamentals[ix]; ix++)
emit_support_tinfo_1 (*fundamentals[ix]);
for (ix = 0; ix < NUM_INT_N_ENTS; ix ++)
if (int_n_enabled_p[ix])
{
emit_support_tinfo_1 (int_n_trees[ix].signed_type);
emit_support_tinfo_1 (int_n_trees[ix].unsigned_type);
}
}
/* Finish a type info decl. DECL_PTR is a pointer to an unemitted

View File

@ -270,6 +270,7 @@ 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
@ -364,16 +365,19 @@ cp_common_type (tree t1, tree t2)
: 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. */

View File

@ -74,6 +74,7 @@ struct mode_data
unsigned int fbit; /* the number of fractional bits */
bool need_bytesize_adj; /* true if this mode need dynamic size
adjustment */
unsigned int int_n; /* If nonzero, then __int<INT_N> will be defined */
};
static struct mode_data *modes[MAX_MODE_CLASS];
@ -84,7 +85,7 @@ 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, false
"<unknown>", 0, 0, 0, 0, false, 0
};
static htab_t modes_by_name;
@ -632,6 +633,34 @@ reset_float_format (const char *name, const char *format,
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) \
@ -1010,6 +1039,7 @@ 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 " : "",
@ -1071,6 +1101,13 @@ enum machine_mode\n{");
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#if GCC_VERSION >= 4001\n");
emit_mode_size_inline ();
emit_mode_nunits_inline ();
@ -1520,6 +1557,53 @@ emit_mode_fbit (void)
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)
@ -1539,6 +1623,7 @@ emit_insn_modes_c (void)
emit_mode_adjustments ();
emit_mode_ibit ();
emit_mode_fbit ();
emit_mode_int_n ();
}
static void

View File

@ -2113,6 +2113,7 @@ 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
@ -2130,10 +2131,15 @@ gimple_signed_or_unsigned_type (bool unsignedp, tree type)
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;
@ -2246,10 +2252,14 @@ gimple_signed_or_unsigned_type (bool unsignedp, tree type)
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))

View File

@ -1,3 +1,9 @@
2014-10-14 DJ Delorie <dj@redhat.com>
* lto-lang.c (lto_build_c_type_nodes): Check intN types for
size-type as well.
(lto_init): Initialize all intN types, not just int128.
2014-10-06 Martin Liska <mliska@suse.cz>
* lto.c (stream_out): ARG_UNUSED added for last argument.

View File

@ -1150,7 +1150,26 @@ lto_build_c_type_nodes (void)
signed_size_type_node = long_long_integer_type_node;
}
else
gcc_unreachable ();
{
int i;
signed_size_type_node = NULL_TREE;
for (i = 0; i < NUM_INT_N_ENTS; i++)
if (int_n_enabled_p[i])
{
char name[50];
sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
if (strcmp (name, SIZE_TYPE) == 0)
{
intmax_type_node = int_n_trees[i].signed_type;
uintmax_type_node = int_n_trees[i].unsigned_type;
signed_size_type_node = int_n_trees[i].signed_type;
}
}
if (signed_size_type_node == NULL_TREE)
gcc_unreachable ();
}
wint_type_node = unsigned_type_node;
pid_type_node = integer_type_node;
@ -1161,6 +1180,8 @@ lto_build_c_type_nodes (void)
static bool
lto_init (void)
{
int i;
/* We need to generate LTO if running in WPA mode. */
flag_generate_lto = (flag_wpa != NULL);
@ -1232,8 +1253,13 @@ lto_init (void)
NAME_TYPE (complex_float_type_node, "complex float");
NAME_TYPE (complex_double_type_node, "complex double");
NAME_TYPE (complex_long_double_type_node, "complex long double");
if (int128_integer_type_node)
NAME_TYPE (int128_integer_type_node, "__int128");
for (i = 0; i < NUM_INT_N_ENTS; i++)
if (int_n_enabled_p[i])
{
char name[50];
sprintf (name, "__int%d", int_n_data[i].bitsize);
NAME_TYPE (int_n_trees[i].signed_type, name);
}
#undef NAME_TYPE
/* Initialize LTO-specific data structures. */

View File

@ -192,6 +192,13 @@ 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.

View File

@ -345,4 +345,16 @@ extern void init_adjust_machine_modes (void);
(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 */

View File

@ -313,6 +313,7 @@ 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;
@ -323,6 +324,12 @@ mode_for_size (unsigned int size, enum mode_class mclass, int limit)
if (GET_MODE_PRECISION (mode) == size)
return mode;
if (mclass == MODE_INT || mclass == MODE_PARTIAL_INT)
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;
}
@ -349,16 +356,27 @@ mode_for_size_tree (const_tree size, enum mode_class mclass, int limit)
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 || mclass == MODE_PARTIAL_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. */
@ -2550,7 +2568,24 @@ initialize_sizetypes (void)
else if (strcmp (SIZETYPE, "short unsigned int") == 0)
precision = SHORT_TYPE_SIZE;
else
gcc_unreachable ();
{
int i;
precision = -1;
for (i = 0; i < NUM_INT_N_ENTS; i++)
if (int_n_enabled_p[i])
{
char name[50];
sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
if (strcmp (name, SIZETYPE) == 0)
{
precision = int_n_data[i].bitsize;
}
}
if (precision == -1)
gcc_unreachable ();
}
bprecision
= MIN (precision + BITS_PER_UNIT_LOG + 1, MAX_FIXED_MODE_SIZE);

View File

@ -1,3 +1,7 @@
2014-10-14 DJ Delorie <dj@redhat.com>
* g++.dg/abi/mangle64.C: New.
2014-10-14 Marc Glisse <marc.glisse@inria.fr>
* g++.dg/ext/vector9.C: Test ! with float vectors.

View File

@ -0,0 +1,13 @@
// { dg-do compile { target msp430*-*-* } }
// { dg-options "-std=gnu++11" }
// { dg-skip-if "" { msp430*-*-* } { "-mcpu=msp430" } { "" } }
__int20 x;
__int20 foo (__int20 a, unsigned __int20 b)
{
return a + b;
}
// { dg-final { scan-assembler "\n_?_Z3foou5int20u6uint20\[: \t\n\]" } }

View File

@ -1901,6 +1901,21 @@ finalize (bool no_backend)
lang_hooks.finish ();
}
static bool
standard_type_bitsize (int bitsize)
{
/* As a special exception, we always want __int128 enabled if possible. */
if (bitsize == 128)
return false;
if (bitsize == CHAR_TYPE_SIZE
|| bitsize == SHORT_TYPE_SIZE
|| bitsize == INT_TYPE_SIZE
|| bitsize == LONG_TYPE_SIZE
|| bitsize == LONG_LONG_TYPE_SIZE)
return true;
return false;
}
/* Initialize the compiler, and compile the input file. */
static void
do_compile (void)
@ -1916,6 +1931,8 @@ do_compile (void)
/* 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
@ -1924,6 +1941,16 @@ do_compile (void)
init_adjust_machine_modes ();
init_derived_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_enabled_p[i] = true;
else
int_n_enabled_p[i] = false;
/* Set up the back-end if requested. */
if (!no_backend)
backend_init ();

View File

@ -570,8 +570,16 @@ enum integer_type_kind {
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
};

View File

@ -236,6 +236,9 @@ static void attribute_hash_list (const_tree, inchash::hash &);
tree global_trees[TI_MAX];
tree integer_types[itk_none];
bool int_n_enabled_p[NUM_INT_N_ENTS];
struct 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. */
@ -9445,6 +9448,8 @@ make_vector_type (tree innertype, int nunits, enum machine_mode mode)
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)
@ -9456,9 +9461,12 @@ make_or_reuse_type (unsigned size, int unsignedp)
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);
@ -9574,6 +9582,8 @@ build_atomic_base (tree type, unsigned int align)
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;
@ -9601,17 +9611,20 @@ build_common_tree_nodes (bool signed_char, bool short_double)
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. */
@ -9630,7 +9643,24 @@ build_common_tree_nodes (bool signed_char, bool short_double)
else if (strcmp (SIZE_TYPE, "short unsigned int") == 0)
size_type_node = short_unsigned_type_node;
else
gcc_unreachable ();
{
int i;
size_type_node = NULL_TREE;
for (i = 0; i < NUM_INT_N_ENTS; i++)
if (int_n_enabled_p[i])
{
char name[50];
sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
if (strcmp (name, SIZE_TYPE) == 0)
{
size_type_node = int_n_trees[i].unsigned_type;
}
}
if (size_type_node == NULL_TREE)
gcc_unreachable ();
}
/* Fill in the rest of the sized types. Reuse existing type nodes
when possible. */

View File

@ -3426,8 +3426,6 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i,
#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]
/* True if NODE is an erroneous expression. */
@ -4800,6 +4798,17 @@ extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
extern tree array_ref_low_bound (tree);
struct GTY(()) int_n_trees_t {
/* These parts are initialized at runtime */
tree signed_type;
tree unsigned_type;
};
/* This is also in machmode.h */
extern bool int_n_enabled_p[NUM_INT_N_ENTS];
extern GTY(()) struct int_n_trees_t int_n_trees[NUM_INT_N_ENTS];
/* Like bit_position, but return as an integer. It must be representable in
that way (since it could be a signed value, we don't have the
option of returning -1 like int_size_in_byte can. */

View File

@ -1,3 +1,12 @@
2014-10-14 DJ Delorie <dj@redhat.com>
* src/c++11/limits.cc: Add support for __intN types.
* include/std/type_traits: Likewise.
* include/std/limits: Likewise.
* include/c_std/cstdlib: Likewise.
* include/bits/cpp_type_traits.h: Likewise.
* include/c_global/cstdlib: Likewise.
2014-10-14 Jonathan Wakely <jwakely@redhat.com>
* testsuite/20_util/align/1.cc: Add dg-require-stdint.

View File

@ -141,7 +141,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Thirteen specializations (yes there are eleven standard integer
// types; <em>long long</em> and <em>unsigned long long</em> are
// supported as extensions)
// supported as extensions). Up to four target-specific __int<N>
// types are supported as well.
template<>
struct __is_integer<bool>
{
@ -251,6 +252,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef __true_type __type;
};
#define __INT_N(TYPE) \
template<> \
struct __is_integer<TYPE> \
{ \
enum { __value = 1 }; \
typedef __true_type __type; \
}; \
template<> \
struct __is_integer<unsigned TYPE> \
{ \
enum { __value = 1 }; \
typedef __true_type __type; \
};
#ifdef __GLIBCXX_TYPE_INT_N_0
__INT_N(__GLIBCXX_TYPE_INT_N_0)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_1
__INT_N(__GLIBCXX_TYPE_INT_N_1)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_2
__INT_N(__GLIBCXX_TYPE_INT_N_2)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_3
__INT_N(__GLIBCXX_TYPE_INT_N_3)
#endif
#undef __INT_N
//
// Floating point types
//

View File

@ -174,10 +174,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
abs(long long __x) { return __builtin_llabs (__x); }
#endif
#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
inline __int128
abs(__int128 __x) { return __x >= 0 ? __x : -__x; }
#if defined(__GLIBCXX_TYPE_INT_N_0)
inline __GLIBCXX_TYPE_INT_N_0
abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_1)
inline __GLIBCXX_TYPE_INT_N_1
abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_2)
inline __GLIBCXX_TYPE_INT_N_2
abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_3)
inline __GLIBCXX_TYPE_INT_N_3
abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; }
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

View File

@ -169,9 +169,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
abs(long long __x) { return __builtin_llabs (__x); }
#endif
#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
inline __int128
abs(__int128 __x) { return __x >= 0 ? __x : -__x; }
#if defined(__GLIBCXX_TYPE_INT_N_0)
inline __GLIBCXX_TYPE_INT_N_0
abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_1)
inline __GLIBCXX_TYPE_INT_N_1
abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_2)
inline __GLIBCXX_TYPE_INT_N_2
abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_3)
inline __GLIBCXX_TYPE_INT_N_3
abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; }
#endif
inline ldiv_t

View File

@ -125,21 +125,32 @@
// You should not need to define any macros below this point.
#define __glibcxx_signed(T) ((T)(-1) < 0)
#define __glibcxx_signed_b(T,B) ((T)(-1) < 0)
#define __glibcxx_min(T) \
(__glibcxx_signed (T) ? -__glibcxx_max (T) - 1 : (T)0)
#define __glibcxx_min_b(T,B) \
(__glibcxx_signed_b (T,B) ? -__glibcxx_max_b (T,B) - 1 : (T)0)
#define __glibcxx_max(T) \
(__glibcxx_signed (T) ? \
(((((T)1 << (__glibcxx_digits (T) - 1)) - 1) << 1) + 1) : ~(T)0)
#define __glibcxx_max_b(T,B) \
(__glibcxx_signed_b (T,B) ? \
(((((T)1 << (__glibcxx_digits_b (T,B) - 1)) - 1) << 1) + 1) : ~(T)0)
#define __glibcxx_digits(T) \
(sizeof(T) * __CHAR_BIT__ - __glibcxx_signed (T))
#define __glibcxx_digits_b(T,B) \
(B - __glibcxx_signed_b (T,B))
// The fraction 643/2136 approximates log10(2) to 7 significant digits.
#define __glibcxx_digits10_b(T,B) \
(__glibcxx_digits_b (T,B) * 643L / 2136)
#define __glibcxx_signed(T) \
__glibcxx_signed_b (T, sizeof(T) * __CHAR_BIT__)
#define __glibcxx_min(T) \
__glibcxx_min_b (T, sizeof(T) * __CHAR_BIT__)
#define __glibcxx_max(T) \
__glibcxx_max_b (T, sizeof(T) * __CHAR_BIT__)
#define __glibcxx_digits(T) \
__glibcxx_digits_b (T, sizeof(T) * __CHAR_BIT__)
#define __glibcxx_digits10(T) \
(__glibcxx_digits (T) * 643L / 2136)
__glibcxx_digits10_b (T, sizeof(T) * __CHAR_BIT__)
#define __glibcxx_max_digits10(T) \
(2 + (T) * 643L / 2136)
@ -1399,153 +1410,181 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
= round_toward_zero;
};
#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
/// numeric_limits<__int128> specialization.
template<>
struct numeric_limits<__int128>
{
static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;
#if !defined(__STRICT_ANSI__)
static _GLIBCXX_CONSTEXPR __int128
min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min (__int128); }
static _GLIBCXX_CONSTEXPR __int128
max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max (__int128); }
#if __cplusplus >= 201103L
static constexpr __int128
lowest() noexcept { return min(); }
#endif
static _GLIBCXX_USE_CONSTEXPR int digits
= __glibcxx_digits (__int128);
static _GLIBCXX_USE_CONSTEXPR int digits10
= __glibcxx_digits10 (__int128);
#if __cplusplus >= 201103L
static constexpr int max_digits10 = 0;
#endif
static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
static _GLIBCXX_USE_CONSTEXPR int radix = 2;
static _GLIBCXX_CONSTEXPR __int128
epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }
static _GLIBCXX_CONSTEXPR __int128
round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }
static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;
static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
= denorm_absent;
static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;
static _GLIBCXX_CONSTEXPR __int128
infinity() _GLIBCXX_USE_NOEXCEPT
{ return static_cast<__int128>(0); }
static _GLIBCXX_CONSTEXPR __int128
quiet_NaN() _GLIBCXX_USE_NOEXCEPT
{ return static_cast<__int128>(0); }
static _GLIBCXX_CONSTEXPR __int128
signaling_NaN() _GLIBCXX_USE_NOEXCEPT
{ return static_cast<__int128>(0); }
static _GLIBCXX_CONSTEXPR __int128
denorm_min() _GLIBCXX_USE_NOEXCEPT
{ return static_cast<__int128>(0); }
static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;
static _GLIBCXX_USE_CONSTEXPR bool traps
= __glibcxx_integral_traps;
static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
= round_toward_zero;
#define __INT_N(TYPE, BITSIZE, EXT, UEXT) \
template<> \
struct numeric_limits<TYPE> \
{ \
static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; \
\
static _GLIBCXX_CONSTEXPR TYPE \
min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min_b (TYPE, BITSIZE); } \
\
static _GLIBCXX_CONSTEXPR TYPE \
max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max_b (TYPE, BITSIZE);; } \
\
static _GLIBCXX_USE_CONSTEXPR int digits \
= BITSIZE - 1; \
static _GLIBCXX_USE_CONSTEXPR int digits10 \
= (BITSIZE - 1) * 643L / 2136; \
\
static _GLIBCXX_USE_CONSTEXPR bool is_signed = true; \
static _GLIBCXX_USE_CONSTEXPR bool is_integer = true; \
static _GLIBCXX_USE_CONSTEXPR bool is_exact = true; \
static _GLIBCXX_USE_CONSTEXPR int radix = 2; \
\
static _GLIBCXX_CONSTEXPR TYPE \
epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; } \
\
static _GLIBCXX_CONSTEXPR TYPE \
round_error() _GLIBCXX_USE_NOEXCEPT { return 0; } \
\
EXT \
\
static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0; \
static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0; \
static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0; \
static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0; \
\
static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false; \
static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false; \
static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false; \
static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm \
= denorm_absent; \
static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; \
\
static _GLIBCXX_CONSTEXPR TYPE \
infinity() _GLIBCXX_USE_NOEXCEPT \
{ return static_cast<TYPE>(0); } \
\
static _GLIBCXX_CONSTEXPR TYPE \
quiet_NaN() _GLIBCXX_USE_NOEXCEPT \
{ return static_cast<TYPE>(0); } \
\
static _GLIBCXX_CONSTEXPR TYPE \
signaling_NaN() _GLIBCXX_USE_NOEXCEPT \
{ return static_cast<TYPE>(0); } \
\
static _GLIBCXX_CONSTEXPR TYPE \
denorm_min() _GLIBCXX_USE_NOEXCEPT \
{ return static_cast<TYPE>(0); } \
\
static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false; \
static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; \
static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; \
\
static _GLIBCXX_USE_CONSTEXPR bool traps \
= __glibcxx_integral_traps; \
static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; \
static _GLIBCXX_USE_CONSTEXPR float_round_style round_style \
= round_toward_zero; \
}; \
\
template<> \
struct numeric_limits<unsigned TYPE> \
{ \
static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; \
\
static _GLIBCXX_CONSTEXPR unsigned TYPE \
min() _GLIBCXX_USE_NOEXCEPT { return 0; } \
\
static _GLIBCXX_CONSTEXPR unsigned TYPE \
max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max_b (TYPE, BITSIZE); } \
\
UEXT \
\
static _GLIBCXX_USE_CONSTEXPR int digits \
= BITSIZE; \
static _GLIBCXX_USE_CONSTEXPR int digits10 \
= BITSIZE * 643L / 2136; \
static _GLIBCXX_USE_CONSTEXPR bool is_signed = false; \
static _GLIBCXX_USE_CONSTEXPR bool is_integer = true; \
static _GLIBCXX_USE_CONSTEXPR bool is_exact = true; \
static _GLIBCXX_USE_CONSTEXPR int radix = 2; \
\
static _GLIBCXX_CONSTEXPR unsigned TYPE \
epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; } \
\
static _GLIBCXX_CONSTEXPR unsigned TYPE \
round_error() _GLIBCXX_USE_NOEXCEPT { return 0; } \
\
static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0; \
static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0; \
static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0; \
static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0; \
\
static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false; \
static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false; \
static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false; \
static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm \
= denorm_absent; \
static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; \
\
static _GLIBCXX_CONSTEXPR unsigned TYPE \
infinity() _GLIBCXX_USE_NOEXCEPT \
{ return static_cast<unsigned TYPE>(0); } \
\
static _GLIBCXX_CONSTEXPR unsigned TYPE \
quiet_NaN() _GLIBCXX_USE_NOEXCEPT \
{ return static_cast<unsigned TYPE>(0); } \
\
static _GLIBCXX_CONSTEXPR unsigned TYPE \
signaling_NaN() _GLIBCXX_USE_NOEXCEPT \
{ return static_cast<unsigned TYPE>(0); } \
\
static _GLIBCXX_CONSTEXPR unsigned TYPE \
denorm_min() _GLIBCXX_USE_NOEXCEPT \
{ return static_cast<unsigned TYPE>(0); } \
\
static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false; \
static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; \
static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true; \
\
static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps; \
static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; \
static _GLIBCXX_USE_CONSTEXPR float_round_style round_style \
= round_toward_zero; \
};
/// numeric_limits<unsigned __int128> specialization.
template<>
struct numeric_limits<unsigned __int128>
{
static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;
static _GLIBCXX_CONSTEXPR unsigned __int128
min() _GLIBCXX_USE_NOEXCEPT { return 0; }
static _GLIBCXX_CONSTEXPR unsigned __int128
max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max (unsigned __int128); }
#if __cplusplus >= 201103L
static constexpr unsigned __int128
lowest() noexcept { return min(); }
#endif
static _GLIBCXX_USE_CONSTEXPR int digits
= __glibcxx_digits (unsigned __int128);
static _GLIBCXX_USE_CONSTEXPR int digits10
= __glibcxx_digits10 (unsigned __int128);
#if __cplusplus >= 201103L
#define __INT_N_201103(TYPE) \
static constexpr TYPE \
lowest() noexcept { return min(); } \
static constexpr int max_digits10 = 0;
#define __INT_N_U201103(TYPE) \
static constexpr unsigned TYPE \
lowest() noexcept { return min(); } \
static constexpr int max_digits10 = 0;
#else
#define __INT_N_201103(TYPE)
#define __INT_N_U201103(TYPE)
#endif
static _GLIBCXX_USE_CONSTEXPR bool is_signed = false;
static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
static _GLIBCXX_USE_CONSTEXPR int radix = 2;
static _GLIBCXX_CONSTEXPR unsigned __int128
epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }
#ifdef __GLIBCXX_TYPE_INT_N_0
__INT_N(__GLIBCXX_TYPE_INT_N_0, __GLIBCXX_BITSIZE_INT_N_0,
__INT_N_201103 (__GLIBCXX_TYPE_INT_N_0), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_0))
#endif
#ifdef __GLIBCXX_TYPE_INT_N_1
__INT_N (__GLIBCXX_TYPE_INT_N_1, __GLIBCXX_BITSIZE_INT_N_1,
__INT_N_201103 (__GLIBCXX_TYPE_INT_N_1), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_1))
#endif
#ifdef __GLIBCXX_TYPE_INT_N_2
__INT_N (__GLIBCXX_TYPE_INT_N_2, __GLIBCXX_BITSIZE_INT_N_2,
__INT_N_201103 (__GLIBCXX_TYPE_INT_N_2), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_2))
#endif
#ifdef __GLIBCXX_TYPE_INT_N_3
__INT_N (__GLIBCXX_TYPE_INT_N_3, __GLIBCXX_BITSIZE_INT_N_3,
__INT_N_201103 (__GLIBCXX_TYPE_INT_N_3), __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_3))
#endif
static _GLIBCXX_CONSTEXPR unsigned __int128
round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }
#undef __INT_N
#undef __INT_N_201103
#undef __INT_N_U201103
static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;
static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
= denorm_absent;
static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;
static _GLIBCXX_CONSTEXPR unsigned __int128
infinity() _GLIBCXX_USE_NOEXCEPT
{ return static_cast<unsigned __int128>(0); }
static _GLIBCXX_CONSTEXPR unsigned __int128
quiet_NaN() _GLIBCXX_USE_NOEXCEPT
{ return static_cast<unsigned __int128>(0); }
static _GLIBCXX_CONSTEXPR unsigned __int128
signaling_NaN() _GLIBCXX_USE_NOEXCEPT
{ return static_cast<unsigned __int128>(0); }
static _GLIBCXX_CONSTEXPR unsigned __int128
denorm_min() _GLIBCXX_USE_NOEXCEPT
{ return static_cast<unsigned __int128>(0); }
static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;
static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
= round_toward_zero;
};
#endif
/// numeric_limits<float> specialization.

View File

@ -242,13 +242,42 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __is_integral_helper<unsigned long long>
: public true_type { };
#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
// Conditionalizing on __STRICT_ANSI__ here will break any port that
// uses one of these types for size_t.
#if defined(__GLIBCXX_TYPE_INT_N_0)
template<>
struct __is_integral_helper<__int128>
struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_0>
: public true_type { };
template<>
struct __is_integral_helper<unsigned __int128>
struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_0>
: public true_type { };
#endif
#if defined(__GLIBCXX_TYPE_INT_N_1)
template<>
struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_1>
: public true_type { };
template<>
struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_1>
: public true_type { };
#endif
#if defined(__GLIBCXX_TYPE_INT_N_2)
template<>
struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_2>
: public true_type { };
template<>
struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_2>
: public true_type { };
#endif
#if defined(__GLIBCXX_TYPE_INT_N_3)
template<>
struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_3>
: public true_type { };
template<>
struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_3>
: public true_type { };
#endif
@ -1661,10 +1690,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
#endif
#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
#if defined(__GLIBCXX_TYPE_INT_N_0)
template<>
struct __make_unsigned<__int128>
{ typedef unsigned __int128 __type; };
struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0>
{ typedef unsigned __GLIBCXX_TYPE_INT_N_0 __type; };
#endif
#if defined(__GLIBCXX_TYPE_INT_N_1)
template<>
struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1>
{ typedef unsigned __GLIBCXX_TYPE_INT_N_1 __type; };
#endif
#if defined(__GLIBCXX_TYPE_INT_N_2)
template<>
struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2>
{ typedef unsigned __GLIBCXX_TYPE_INT_N_2 __type; };
#endif
#if defined(__GLIBCXX_TYPE_INT_N_3)
template<>
struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3>
{ typedef unsigned __GLIBCXX_TYPE_INT_N_3 __type; };
#endif
// Select between integral and enum: not possible to be both.
@ -1758,10 +1802,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
#endif
#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
#if defined(__GLIBCXX_TYPE_INT_N_0)
template<>
struct __make_signed<unsigned __int128>
{ typedef __int128 __type; };
struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_0>
{ typedef __GLIBCXX_TYPE_INT_N_0 __type; };
#endif
#if defined(__GLIBCXX_TYPE_INT_N_1)
template<>
struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_1>
{ typedef __GLIBCXX_TYPE_INT_N_1 __type; };
#endif
#if defined(__GLIBCXX_TYPE_INT_N_2)
template<>
struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_2>
{ typedef __GLIBCXX_TYPE_INT_N_2 __type; };
#endif
#if defined(__GLIBCXX_TYPE_INT_N_3)
template<>
struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_3>
{ typedef __GLIBCXX_TYPE_INT_N_3 __type; };
#endif
// Select between integral and enum: not possible to be both.

View File

@ -388,54 +388,66 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const bool numeric_limits<unsigned long long>::tinyness_before;
const float_round_style numeric_limits<unsigned long long>::round_style;
#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
const bool numeric_limits<__int128>::is_specialized;
const int numeric_limits<__int128>::digits;
const int numeric_limits<__int128>::digits10;
const int numeric_limits<__int128>::max_digits10;
const bool numeric_limits<__int128>::is_signed;
const bool numeric_limits<__int128>::is_integer;
const bool numeric_limits<__int128>::is_exact;
const int numeric_limits<__int128>::radix;
const int numeric_limits<__int128>::min_exponent;
const int numeric_limits<__int128>::min_exponent10;
const int numeric_limits<__int128>::max_exponent;
const int numeric_limits<__int128>::max_exponent10;
const bool numeric_limits<__int128>::has_infinity;
const bool numeric_limits<__int128>::has_quiet_NaN;
const bool numeric_limits<__int128>::has_signaling_NaN;
const float_denorm_style numeric_limits<__int128>::has_denorm;
const bool numeric_limits<__int128>::has_denorm_loss;
const bool numeric_limits<__int128>::is_iec559;
const bool numeric_limits<__int128>::is_bounded;
const bool numeric_limits<__int128>::is_modulo;
const bool numeric_limits<__int128>::traps;
const bool numeric_limits<__int128>::tinyness_before;
const float_round_style numeric_limits<__int128>::round_style;
#define INT_N(__INT_N_TYPE) \
const bool numeric_limits<__INT_N_TYPE>::is_specialized; \
const int numeric_limits<__INT_N_TYPE>::digits; \
const int numeric_limits<__INT_N_TYPE>::digits10; \
const int numeric_limits<__INT_N_TYPE>::max_digits10; \
const bool numeric_limits<__INT_N_TYPE>::is_signed; \
const bool numeric_limits<__INT_N_TYPE>::is_integer; \
const bool numeric_limits<__INT_N_TYPE>::is_exact; \
const int numeric_limits<__INT_N_TYPE>::radix; \
const int numeric_limits<__INT_N_TYPE>::min_exponent; \
const int numeric_limits<__INT_N_TYPE>::min_exponent10; \
const int numeric_limits<__INT_N_TYPE>::max_exponent; \
const int numeric_limits<__INT_N_TYPE>::max_exponent10; \
const bool numeric_limits<__INT_N_TYPE>::has_infinity; \
const bool numeric_limits<__INT_N_TYPE>::has_quiet_NaN; \
const bool numeric_limits<__INT_N_TYPE>::has_signaling_NaN; \
const float_denorm_style numeric_limits<__INT_N_TYPE>::has_denorm; \
const bool numeric_limits<__INT_N_TYPE>::has_denorm_loss; \
const bool numeric_limits<__INT_N_TYPE>::is_iec559; \
const bool numeric_limits<__INT_N_TYPE>::is_bounded; \
const bool numeric_limits<__INT_N_TYPE>::is_modulo; \
const bool numeric_limits<__INT_N_TYPE>::traps; \
const bool numeric_limits<__INT_N_TYPE>::tinyness_before; \
const float_round_style numeric_limits<__INT_N_TYPE>::round_style; \
\
const bool numeric_limits<unsigned __INT_N_TYPE>::is_specialized; \
const int numeric_limits<unsigned __INT_N_TYPE>::digits; \
const int numeric_limits<unsigned __INT_N_TYPE>::digits10; \
const int numeric_limits<unsigned __INT_N_TYPE>::max_digits10; \
const bool numeric_limits<unsigned __INT_N_TYPE>::is_signed; \
const bool numeric_limits<unsigned __INT_N_TYPE>::is_integer; \
const bool numeric_limits<unsigned __INT_N_TYPE>::is_exact; \
const int numeric_limits<unsigned __INT_N_TYPE>::radix; \
const int numeric_limits<unsigned __INT_N_TYPE>::min_exponent; \
const int numeric_limits<unsigned __INT_N_TYPE>::min_exponent10; \
const int numeric_limits<unsigned __INT_N_TYPE>::max_exponent; \
const int numeric_limits<unsigned __INT_N_TYPE>::max_exponent10; \
const bool numeric_limits<unsigned __INT_N_TYPE>::has_infinity; \
const bool numeric_limits<unsigned __INT_N_TYPE>::has_quiet_NaN; \
const bool numeric_limits<unsigned __INT_N_TYPE>::has_signaling_NaN; \
const float_denorm_style numeric_limits<unsigned __INT_N_TYPE>::has_denorm; \
const bool numeric_limits<unsigned __INT_N_TYPE>::has_denorm_loss; \
const bool numeric_limits<unsigned __INT_N_TYPE>::is_iec559; \
const bool numeric_limits<unsigned __INT_N_TYPE>::is_bounded; \
const bool numeric_limits<unsigned __INT_N_TYPE>::is_modulo; \
const bool numeric_limits<unsigned __INT_N_TYPE>::traps; \
const bool numeric_limits<unsigned __INT_N_TYPE>::tinyness_before; \
const float_round_style numeric_limits<unsigned __INT_N_TYPE>::round_style;
const bool numeric_limits<unsigned __int128>::is_specialized;
const int numeric_limits<unsigned __int128>::digits;
const int numeric_limits<unsigned __int128>::digits10;
const int numeric_limits<unsigned __int128>::max_digits10;
const bool numeric_limits<unsigned __int128>::is_signed;
const bool numeric_limits<unsigned __int128>::is_integer;
const bool numeric_limits<unsigned __int128>::is_exact;
const int numeric_limits<unsigned __int128>::radix;
const int numeric_limits<unsigned __int128>::min_exponent;
const int numeric_limits<unsigned __int128>::min_exponent10;
const int numeric_limits<unsigned __int128>::max_exponent;
const int numeric_limits<unsigned __int128>::max_exponent10;
const bool numeric_limits<unsigned __int128>::has_infinity;
const bool numeric_limits<unsigned __int128>::has_quiet_NaN;
const bool numeric_limits<unsigned __int128>::has_signaling_NaN;
const float_denorm_style numeric_limits<unsigned __int128>::has_denorm;
const bool numeric_limits<unsigned __int128>::has_denorm_loss;
const bool numeric_limits<unsigned __int128>::is_iec559;
const bool numeric_limits<unsigned __int128>::is_bounded;
const bool numeric_limits<unsigned __int128>::is_modulo;
const bool numeric_limits<unsigned __int128>::traps;
const bool numeric_limits<unsigned __int128>::tinyness_before;
const float_round_style numeric_limits<unsigned __int128>::round_style;
#ifdef __GLIBCXX_TYPE_INT_N_0
INT_N (__GLIBCXX_TYPE_INT_N_0)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_1
INT_N (__GLIBCXX_TYPE_INT_N_1)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_2
INT_N (__GLIBCXX_TYPE_INT_N_2)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_3
INT_N (__GLIBCXX_TYPE_INT_N_3)
#endif
// float