commit 34f930afff6aaba910800d55a58c580ff2046b03
Author: Jason Merrill <jason@redhat.com>
Date: Mon Feb 11 15:02:05 2013 -0500
* glimits.h (__INT128_MIN__, __UINT128_MAX__): Define.
* c-cppbuiltin.c (type_suffix): Handle __int128_t.
(c_cpp_builtins): Define __INT128_MAX__.
(cpp_atomic_builtins): Define __GCC_ATOMIC_INT128_LOCK_FREE.
* c-opts.c (c_common_init): Set cpp max precision to that of the
largest integer, not intmax_t.
* c-lex.c (interpret_integer): Restrict C++11 user-defined literal
precision to unsigned long long.
@@ -668,6 +668,10 @@ cpp_atomic_builtins (cpp_reader *pfile)
(have_swap[SWAP_INDEX (long_integer_type_node)]? 2 : 1));
builtin_define_with_int_value ("__GCC_ATOMIC_LLONG_LOCK_FREE",
(have_swap[SWAP_INDEX (long_long_integer_type_node)]? 2 : 1));
+ if (int128_integer_type_node != NULL_TREE)
+ builtin_define_with_int_value
+ ("__GCC_ATOMIC_INT128_LOCK_FREE",
+ have_swap[SWAP_INDEX (int128_integer_type_node)]? 2 : 1);
/* If we're dealing with a "set" value that doesn't exactly correspond
to a boolean truth value, let the library work around that. */
@@ -751,6 +755,8 @@ c_cpp_builtins (cpp_reader *pfile)
builtin_define_type_max ("__INT_MAX__", integer_type_node);
builtin_define_type_max ("__LONG_MAX__", long_integer_type_node);
builtin_define_type_max ("__LONG_LONG_MAX__", long_long_integer_type_node);
+ if (int128_integer_type_node)
+ builtin_define_type_max ("__INT128_MAX__", int128_integer_type_node);
builtin_define_type_minmax ("__WCHAR_MIN__", "__WCHAR_MAX__",
underlying_wchar_type_node);
builtin_define_type_minmax ("__WINT_MIN__", "__WINT_MAX__", wint_type_node);
@@ -1132,7 +1138,10 @@ type_suffix (tree type)
int is_long;
if (type == long_long_integer_type_node
- || type == long_long_unsigned_type_node)
+ || type == long_long_unsigned_type_node
+ /* int128_t doesn't have its own suffix. */
+ || type == int128_integer_type_node
+ || type == int128_unsigned_type_node)
is_long = 2;
else if (type == long_integer_type_node
|| type == long_unsigned_type_node)
@@ -596,11 +596,20 @@ interpret_integer (const cpp_token *token, unsigned int flags,
enum integer_type_kind itk;
cpp_num integer;
cpp_options *options = cpp_get_options (parse_in);
+ unsigned int precision = options->precision;
*overflow = OT_NONE;
+ if (flags & CPP_N_USERDEF)
+ /* A C++11 user-defined literal wants a long long unsigned value even
+ if normal literals can be larger. */
+ options->precision = TYPE_PRECISION (long_long_unsigned_type_node);
+
integer = cpp_interpret_integer (parse_in, token, flags);
integer = cpp_num_sign_extend (integer, options->precision);
+
+ options->precision = precision;
+
if (integer.overflow)
*overflow = OT_OVERFLOW;
@@ -987,7 +987,19 @@ c_common_init (void)
{
/* Set up preprocessor arithmetic. Must be done after call to
c_common_nodes_and_builtins for type nodes to be good. */
- cpp_opts->precision = TYPE_PRECISION (intmax_type_node);
+
+ /* Set cpp precision to be the precision of the largest integer type,
+ which might be larger than intmax_t (i.e. __int128_t). */
+ for (unsigned int itk = itk_none - 1; ; itk--)
+ {
+ tree type = integer_types[itk];
+ if (type)
+ {
+ cpp_opts->precision = TYPE_PRECISION (type);
+ break;
+ }
+ }
+
cpp_opts->char_precision = TYPE_PRECISION (char_type_node);
cpp_opts->int_precision = TYPE_PRECISION (integer_type_node);
cpp_opts->wchar_precision = TYPE_PRECISION (wchar_type_node);
@@ -123,4 +123,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1ULL)
#endif
+#ifdef __INT128_MAX__
+/* Minimum value a 'signed __int128_t' can hold. */
+#define __INT128_MIN__ (-__INT128_MAX__ - 1)
+/* Maximum value an 'unsigned __int128_t' can hold. */
+#define __UINT128_MAX__ (__INT128_MAX__ * 2ULL + 1ULL)
+#endif
+
#endif /* _LIMITS_H___ */
new file mode 100644
@@ -0,0 +1,7 @@
+/* Test for int128 literals. */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-std=gnu99" { target c } } */
+/* { dg-options "" { target c++ } } */
+
+unsigned __int128 i = 0xfffffffffffffffff;
+/* 12345678901234567 */
@@ -3,6 +3,6 @@
/* { dg-do compile } */
/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
-#if 9223372036854775808LL /* { dg-error "integer constant is so large that it is unsigned" } */
-unsigned long long l = 9223372036854775808LL; /* { dg-error "integer constant is so large that it is unsigned" } */
+#if 9223372036854775808LL /* { dg-error "integer constant is so large that it is unsigned" "" { target { ! int128 } } } */
+unsigned long long l = 9223372036854775808LL; /* { dg-error "integer constant is so large that it is unsigned" "" { target { ! int128 } } } */
#endif
@@ -16,7 +16,11 @@
#define APPEND2(NUM, SUFF) NUM ## SUFF
#define APPEND(NUM, SUFF) APPEND2(NUM, SUFF)
+#if __UINT128_MAX__ > ULLONG_MAX
+#define TARGET_UTYPE_MAX __UINT128_MAX__
+#else
#define TARGET_UTYPE_MAX ULLONG_MAX
+#endif
/* The tests in this file depend only on the macros defined in this
#if block. Note that it is no good calculating these values, as
@@ -118,6 +122,38 @@
# define LONG_SMODULO -234582345927345L % 12345678901L
# define LONG_SMODULO_ANSWER -2101129444L
+#elif TARGET_UTYPE_MAX == 340282366920938463463374607431768211455ULL
+
+# define TARG_PRECISION 128
+# define MAX_INT 170141183460469231731687303715884105727
+# define MAX_UINT 340282366920938463463374607431768211455
+
+# define TARG_MAX_HEX 0x7fffffffffffffffffffffffffffffff
+# define TARG_MAX_OCT 01777777777777777777777777777777777777777777
+# define TARG_MAX_PLUS_1 170141183460469231731687303715884105728L
+# define TARG_MAX_PLUS_1_U 170141183460469231731687303715884105728UL
+# define TARG_MAX_PLUS_1_HEX 0x80000000000000000000000000000000
+# define TARG_MAX_PLUS_1_OCT 02000000000000000000000000000000000000000000
+# define UTARG_MAX_HEX 0xffffffffffffffffffffffffffffffff
+# define UTARG_MAX_OCT 03777777777777777777777777777777777777777777
+# define UTARG_MAX_PLUS_1 340282366920938463463374607431768211456L
+# define UTARG_MAX_PLUS_1_HEX 0x100000000000000000000000000000000
+# define UTARG_MAX_PLUS_1_OCT 04000000000000000000000000000000000000000000
+
+# define TARG_LOWPART_PLUS_1 18446744073709551616
+# define TARG_LOWPART_PLUS_1_U 18446744073709551616U
+
+ /* Division and modulo; anything that uses the high half in both
+ dividend and divisor. */
+# define LONG_UDIVISION 7577378169271152754952UL / 4346979189724050067L
+# define LONG_UDIVISION_ANSWER 1743
+# define LONG_SDIVISION -7298376219237659121371L / 4932087234986723097L
+# define LONG_SDIVISION_ANSWER -1479
+# define LONG_UMODULO 7577378169271152754952UL % 4346979189724050067L
+# define LONG_UMODULO_ANSWER 593441582133488171L
+# define LONG_SMODULO -7298376219237659121371L % 4932087234986723097L
+# define LONG_SMODULO_ANSWER -3819198692295660908
+
#else
# error Please extend the macros here so that this file tests your target
@@ -37,5 +37,5 @@
#if 099 /* { dg-error "invalid digit" "decimal in octal constant" } */
#endif
-#if 0xfffffffffffffffff /* { dg-error "integer constant" "range error" } */
+#if 0xfffffffffffffffff /* { dg-error "integer constant" "range error" { target { ! int128 } } } */
#endif
@@ -25,7 +25,7 @@ testfunc ()
/* But this one should, since it doesn't fit in long (long), but
does fit in unsigned long (long). */
- i = 18446744073709551615; /* { dg-warning "integer constant is so large that it is unsigned" "so large" } */
+ i = 18446744073709551615; /* { dg-warning "integer constant is so large that it is unsigned" "so large" { target { ! int128 } } }*/
/* { dg-warning "this decimal constant would be unsigned in ISO C90" "ISO C90" { target *-*-* } 28 } */
# 29 "sys-header.h" 3