@@ -72,6 +72,8 @@ 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_INT256, int256_integer_type_node)
+DEF_PRIMITIVE_TYPE (BT_UINT256, int256_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)
@@ -8945,6 +8945,10 @@ 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_int256)
+ error_at (loc,
+ ("both %<long%> and %<__int256%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_int128)
error_at (loc,
("both %<long%> and %<__int128%> in "
@@ -8989,6 +8993,10 @@ 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_int256)
+ error_at (loc,
+ ("both %<short%> and %<__int256%> in "
+ "declaration specifiers"));
else if (specs->typespec_word == cts_int128)
error_at (loc,
("both %<short%> and %<__int128%> in "
@@ -9154,7 +9162,13 @@ 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_int256)
+ {
+ error_at (loc,
+ ("both %<_Sat%> and %<__int256%> in "
+ "declaration specifiers"));
+ }
+ else if (specs->typespec_word == cts_int128)
{
error_at (loc,
("both %<_Sat%> and %<__int128%> in "
@@ -9218,7 +9232,7 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
else
{
/* "void", "_Bool", "char", "int", "float", "double", "_Decimal32",
- "__int128", "_Decimal64", "_Decimal128", "_Fract" or "_Accum". */
+ "__int256", "__int128", "_Decimal64", "_Decimal128", "_Fract" or "_Accum". */
if (specs->typespec_word != cts_none)
{
error_at (loc,
@@ -9227,6 +9241,34 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs,
}
switch (i)
{
+ case RID_INT256:
+ if (int256_integer_type_node == NULL_TREE)
+ {
+ error_at (loc, "%<__int256%> is not supported for this target");
+ return specs;
+ }
+ if (!in_system_header)
+ pedwarn (loc, OPT_Wpedantic,
+ "ISO C does not support %<__int256%> type");
+
+ if (specs->long_p)
+ error_at (loc,
+ ("both %<__int256%> and %<long%> in "
+ "declaration specifiers"));
+ else if (specs->saturating_p)
+ error_at (loc,
+ ("both %<_Sat%> and %<__int256%> in "
+ "declaration specifiers"));
+ else if (specs->short_p)
+ error_at (loc,
+ ("both %<__int256%> and %<short%> in "
+ "declaration specifiers"));
+ else
+ {
+ specs->typespec_word = cts_int256;
+ specs->locations[cdw_typespec] = loc;
+ }
+ return specs;
case RID_INT128:
if (int128_integer_type_node == NULL_TREE)
{
@@ -9788,6 +9830,19 @@ finish_declspecs (struct c_declspecs *specs)
specs->type = build_complex_type (specs->type);
}
break;
+ case cts_int256:
+ 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
+ ? int256_unsigned_type_node
+ : int256_integer_type_node);
+ 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);
+ }
+ break;
case cts_int128:
gcc_assert (!specs->long_p && !specs->short_p && !specs->long_long_p);
gcc_assert (!(specs->signed_p && specs->unsigned_p));
@@ -59,11 +59,13 @@ 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 int256_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 int256_unsigned_type_node;
tree int128_unsigned_type_node;
tree truthvalue_type_node;
@@ -97,12 +99,14 @@ cpp_reader *parse_in; /* Declared in c-pragma.h. */
tree intSI_type_node;
tree intDI_type_node;
tree intTI_type_node;
+ tree intOI_type_node;
tree unsigned_intQI_type_node;
tree unsigned_intHI_type_node;
tree unsigned_intSI_type_node;
tree unsigned_intDI_type_node;
tree unsigned_intTI_type_node;
+ tree unsigned_intOI_type_node;
tree widest_integer_literal_type_node;
tree widest_unsigned_literal_type_node;
@@ -456,6 +460,7 @@ const struct c_common_resword c_common_reswords[] =
{ "__imag__", RID_IMAGPART, 0 },
{ "__inline", RID_INLINE, 0 },
{ "__inline__", RID_INLINE, 0 },
+ { "__int256", RID_INT256, 0 },
{ "__int128", RID_INT128, 0 },
{ "__is_abstract", RID_IS_ABSTRACT, D_CXXONLY },
{ "__is_base_of", RID_IS_BASE_OF, D_CXXONLY },
@@ -3047,6 +3052,11 @@ c_common_type_for_size (unsigned int bits, int unsignedp)
return (unsignedp ? long_long_unsigned_type_node
: long_long_integer_type_node);
+ if (int256_integer_type_node
+ && bits == TYPE_PRECISION (int256_integer_type_node))
+ return (unsignedp ? int256_unsigned_type_node
+ : int256_integer_type_node);
+
if (int128_integer_type_node
&& bits == TYPE_PRECISION (int128_integer_type_node))
return (unsignedp ? int128_unsigned_type_node
@@ -3130,6 +3140,10 @@ 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 (int256_integer_type_node
+ && mode == TYPE_MODE (int256_integer_type_node))
+ return unsignedp ? int256_unsigned_type_node : int256_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;
@@ -3151,6 +3165,8 @@ c_common_type_for_mode (enum machine_mode mode, int unsignedp)
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
#if HOST_BITS_PER_WIDE_INT >= 64
+ if (mode == TYPE_MODE (intOI_type_node))
+ return unsignedp ? unsigned_intOI_type_node : intOI_type_node;
if (mode == TYPE_MODE (intTI_type_node))
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
#endif
@@ -3348,6 +3364,10 @@ 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 (int256_integer_type_node
+ && (type1 == int256_integer_type_node
+ || type1 == int256_unsigned_type_node))
+ return unsignedp ? int256_unsigned_type_node : int256_integer_type_node;
if (int128_integer_type_node
&& (type1 == int128_integer_type_node
|| type1 == int128_unsigned_type_node))
@@ -3355,6 +3375,8 @@ c_common_signed_or_unsigned_type (int unsignedp, tree 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 == intOI_type_node || type1 == unsigned_intOI_type_node)
+ return unsignedp ? unsigned_intOI_type_node : intOI_type_node;
if (type1 == intTI_type_node || type1 == unsigned_intTI_type_node)
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
#endif
@@ -3469,11 +3491,16 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type)
if (int128_integer_type_node && TYPE_OK (int128_integer_type_node))
return (unsignedp ? int128_unsigned_type_node
: int128_integer_type_node);
+ if (int256_integer_type_node && TYPE_OK (int256_integer_type_node))
+ return (unsignedp ? int256_unsigned_type_node
+ : int256_integer_type_node);
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 (intOI_type_node))
+ return unsignedp ? unsigned_intOI_type_node : intOI_type_node;
if (TYPE_OK (intTI_type_node))
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
#endif
@@ -3512,6 +3539,10 @@ 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 (int256_integer_type_node
+ && width == TYPE_PRECISION (int256_integer_type_node))
+ return (unsignedp ? int256_unsigned_type_node
+ : int256_integer_type_node);
if (int128_integer_type_node
&& width == TYPE_PRECISION (int128_integer_type_node))
return (unsignedp ? int128_unsigned_type_node
@@ -4920,6 +4951,13 @@ 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 (int256_integer_type_node != NULL_TREE)
+ {
+ record_builtin_type (RID_INT256, "__int256",
+ int256_integer_type_node);
+ record_builtin_type (RID_MAX, "__int256 unsigned",
+ int256_unsigned_type_node);
+ }
if (int128_integer_type_node != NULL_TREE)
{
record_builtin_type (RID_INT128, "__int128",
@@ -4962,6 +5000,11 @@ c_common_nodes_and_builtins (void)
TYPE_DECL, NULL_TREE,
intDI_type_node));
#if HOST_BITS_PER_WIDE_INT >= 64
+ if (targetm.scalar_mode_supported_p (OImode))
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL,
+ get_identifier ("__int256_t"),
+ intOI_type_node));
if (targetm.scalar_mode_supported_p (TImode))
lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
TYPE_DECL,
@@ -4981,6 +5024,11 @@ c_common_nodes_and_builtins (void)
TYPE_DECL, NULL_TREE,
unsigned_intDI_type_node));
#if HOST_BITS_PER_WIDE_INT >= 64
+ if (targetm.scalar_mode_supported_p (OImode))
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL,
+ get_identifier ("__uint256_t"),
+ unsigned_intOI_type_node));
if (targetm.scalar_mode_supported_p (TImode))
lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
TYPE_DECL,
@@ -10844,6 +10892,7 @@ keyword_begins_type_specifier (enum rid keyword)
case RID_FLOAT:
case RID_DOUBLE:
case RID_VOID:
+ case RID_INT256:
case RID_INT128:
case RID_UNSIGNED:
case RID_LONG:
@@ -93,7 +93,7 @@ enum rid
/* C */
RID_INT, RID_CHAR, RID_FLOAT, RID_DOUBLE, RID_VOID,
- RID_INT128,
+ RID_INT256, 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,
@@ -897,6 +897,9 @@ c_cpp_builtins (cpp_reader *pfile)
if (flag_openmp)
cpp_define (pfile, "_OPENMP=201107");
+ if (int256_integer_type_node != NULL_TREE)
+ builtin_define_type_sizeof ("__SIZEOF_INT256__",
+ int256_integer_type_node);
if (int128_integer_type_node != NULL_TREE)
builtin_define_type_sizeof ("__SIZEOF_INT128__",
int128_integer_type_node);
@@ -937,6 +937,9 @@ 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 == int256_integer_type_node
+ || type == int256_unsigned_type_node)
+ pp_string (pp, "I256");
else if (type == int128_integer_type_node
|| type == int128_unsigned_type_node)
pp_string (pp, "I128");
@@ -473,6 +473,7 @@ c_token_starts_typename (c_token *token)
{
case RID_UNSIGNED:
case RID_LONG:
+ case RID_INT256:
case RID_INT128:
case RID_SHORT:
case RID_SIGNED:
@@ -628,6 +629,7 @@ c_token_starts_declspecs (c_token *token)
case RID_THREAD:
case RID_UNSIGNED:
case RID_LONG:
+ case RID_INT256:
case RID_INT128:
case RID_SHORT:
case RID_SIGNED:
@@ -1964,6 +1966,7 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser)
type-specifier:
typeof-specifier
+ __int256
__int128
_Decimal32
_Decimal64
@@ -2110,6 +2113,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
break;
case RID_UNSIGNED:
case RID_LONG:
+ case RID_INT256:
case RID_INT128:
case RID_SHORT:
case RID_SIGNED:
@@ -3439,6 +3443,7 @@ c_parser_attribute_any_word (c_parser *parser)
case RID_STATIC:
case RID_UNSIGNED:
case RID_LONG:
+ case RID_INT256:
case RID_INT128:
case RID_CONST:
case RID_EXTERN:
@@ -8029,6 +8034,7 @@ c_parser_objc_selector (c_parser *parser)
case RID_ALIGNOF:
case RID_UNSIGNED:
case RID_LONG:
+ case RID_INT256:
case RID_INT128:
case RID_CONST:
case RID_SHORT:
@@ -204,6 +204,7 @@ enum c_storage_class {
};
/* A type specifier keyword "void", "_Bool", "char", "int", "float",
+ "__int256", "__int128",
"double", "_Decimal32", "_Decimal64", "_Decimal128", "_Fract", "_Accum",
or none of these. */
enum c_typespec_keyword {
@@ -213,6 +214,7 @@ enum c_typespec_keyword {
cts_char,
cts_int,
cts_float,
+ cts_int256,
cts_int128,
cts_double,
cts_dfloat32,
@@ -4712,6 +4712,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 "__int256" was explicitly provided. */
+ BOOL_BITFIELD explicit_int256_p : 1;
/* True iff "__int128" was explicitly provided. */
BOOL_BITFIELD explicit_int128_p : 1;
/* True iff "char" was explicitly provided. */
@@ -8366,6 +8366,7 @@ grokdeclarator (const cp_declarator *declarator,
{
tree type = NULL_TREE;
int longlong = 0;
+ int explicit_int256 = 0;
int explicit_int128 = 0;
int virtualp, explicitp, friendp, inlinep, staticp;
int explicit_int = 0;
@@ -8433,6 +8434,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_int256 = declspecs->explicit_int256_p;
explicit_int128 = declspecs->explicit_int128_p;
thread_p = decl_spec_seq_has_spec_p (declspecs, ds_thread);
@@ -8774,6 +8776,17 @@ grokdeclarator (const cp_declarator *declarator,
ctype = NULL_TREE;
+ if (explicit_int256)
+ {
+ if (int256_integer_type_node == NULL_TREE)
+ {
+ error ("%<__int256%> is not supported by this target");
+ explicit_int256 = false;
+ }
+ else if (pedantic && ! in_system_header)
+ pedwarn (input_location, OPT_Wpedantic,
+ "ISO C++ does not support %<__int256%> for %qs", name);
+ }
if (explicit_int128)
{
if (int128_integer_type_node == NULL_TREE)
@@ -8815,6 +8828,8 @@ 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_int256)
+ error ("%<long%>, %<int%>, %<short%>, or %<char%> invalid for %qs", name);
else if ((long_p || short_p || explicit_char || explicit_int) && explicit_int128)
error ("%<long%>, %<int%>, %<short%>, or %<char%> invalid for %qs", name);
else if ((long_p || short_p) && explicit_char)
@@ -8831,7 +8846,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_int128 && !explicit_int256 && pedantic)
{
pedwarn (input_location, OPT_Wpedantic,
"long, short, signed or unsigned used invalidly for %qs",
@@ -8873,7 +8888,9 @@ grokdeclarator (const cp_declarator *declarator,
&& TREE_CODE (type) == INTEGER_TYPE
&& !same_type_p (TYPE_MAIN_VARIANT (type), wchar_type_node)))
{
- if (explicit_int128)
+ if (explicit_int256)
+ type = int256_unsigned_type_node;
+ else if (explicit_int128)
type = int128_unsigned_type_node;
else if (longlong)
type = long_long_unsigned_type_node;
@@ -8890,6 +8907,8 @@ grokdeclarator (const cp_declarator *declarator,
}
else if (signed_p && type == char_type_node)
type = signed_char_type_node;
+ else if (explicit_int256)
+ type = int256_integer_type_node;
else if (explicit_int128)
type = int128_integer_type_node;
else if (longlong)
@@ -8907,7 +8926,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_int256 && ! explicit_int128
&& ! (long_p || short_p || signed_p || unsigned_p))
type = complex_double_type_node;
else if (type == integer_type_node)
@@ -151,6 +151,8 @@ integer_type_codes[itk_none] =
'm', /* itk_unsigned_long */
'x', /* itk_long_long */
'y', /* itk_unsigned_long_long */
+ 'q', /* itk_int256 */
+ 'k', /* itk_unsigned_int256 */
'n', /* itk_int128 */
'o', /* itk_unsigned_int128 */
};
@@ -2105,6 +2107,8 @@ write_CV_qualifiers_for_type (const tree type)
::= m # unsigned long
::= x # long long, __int64
::= y # unsigned long long, __int64
+ ::= q # __int256
+ ::= k # unsigned __int256
::= n # __int128
::= o # unsigned __int128
::= f # float
@@ -884,6 +884,7 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
case RID_SHORT:
case RID_INT:
case RID_LONG:
+ case RID_INT256:
case RID_INT128:
case RID_SIGNED:
case RID_UNSIGNED:
@@ -13496,6 +13497,7 @@ cp_parser_type_specifier (cp_parser* parser,
GNU Extension:
simple-type-specifier:
+ __int256
__int128
__typeof__ unary-expression
__typeof__ ( type-id )
@@ -13543,6 +13545,13 @@ cp_parser_simple_type_specifier (cp_parser* parser,
decl_specs->explicit_int_p = true;
type = integer_type_node;
break;
+ case RID_INT256:
+ if (!int256_integer_type_node)
+ break;
+ if (decl_specs)
+ decl_specs->explicit_int256_p = true;
+ type = int256_integer_type_node;
+ break;
case RID_INT128:
if (!int128_integer_type_node)
break;
@@ -1483,6 +1483,7 @@ 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,
+ &int256_integer_type_node, &int256_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,
@@ -364,6 +364,17 @@ cp_common_type (tree t1, tree t2)
: long_long_integer_type_node);
return build_type_attribute_variant (t, attributes);
}
+ if (int256_integer_type_node != NULL_TREE
+ && (same_type_p (TYPE_MAIN_VARIANT (t1),
+ int256_integer_type_node)
+ || same_type_p (TYPE_MAIN_VARIANT (t2),
+ int256_integer_type_node)))
+ {
+ tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
+ ? int256_unsigned_type_node
+ : int256_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)
@@ -34,6 +34,7 @@ extensions, accepted by GCC in C90 mode and in C++.
* Conditionals:: Omitting the middle operand of a @samp{?:} expression.
* Long Long:: Double-word integers---@code{long long int}.
* __int128:: 128-bit integers---@code{__int128}.
+* __int256:: 256-bit integers---@code{__int256}.
* Complex:: Data types for complex numbers.
* Floating Types:: Additional Floating Types.
* Half-Precision:: Half-Precision Floating Point.
@@ -818,6 +819,17 @@ Simply write @code{__int128} for a signed 128-bit integer, or
support in GCC to express an integer constant of type @code{__int128}
for targets having @code{long long} integer with less then 128 bit width.
+@node __int256
+@section 256-bits integers
+@cindex @code{__int256} data types
+
+As an extension the integer scalar type @code{__int256} is supported for
+targets having an integer mode wide enough to hold 256-bit.
+Simply write @code{__int256} for a signed 256-bit integer, or
+@code{unsigned __int256} for an unsigned 256-bit integer. There is no
+support in GCC to express an integer constant of type @code{__int256}
+for targets having @code{long long} integer with less then 256 bit width.
+
@node Long Long
@section Double-Word Integers
@cindex @code{long long} data types
@@ -75,6 +75,8 @@ NAMED_INTCST (ISOCBINDING_INT32_T, "c_int32_t", \
NAMED_INTCST (ISOCBINDING_INT64_T, "c_int64_t", \
get_int_kind_from_name (INT64_TYPE), GFC_STD_F2003)
/* GNU Extension. */
+NAMED_INTCST (ISOCBINDING_INT256_T, "c_int256_t", \
+ get_int_kind_from_width (256), GFC_STD_GNU)
NAMED_INTCST (ISOCBINDING_INT128_T, "c_int128_t", \
get_int_kind_from_width (128), GFC_STD_GNU)
@@ -758,6 +758,8 @@ gfc_build_int_type (gfc_integer_info *info)
return intDI_type_node;
if (TYPE_PRECISION (intTI_type_node) == mode_precision)
return intTI_type_node;
+ if (TYPE_PRECISION (intOI_type_node) == mode_precision)
+ return intOI_type_node;
return make_signed_type (mode_precision);
}
@@ -2860,6 +2862,8 @@ gfc_type_for_size (unsigned bits, int unsignedp)
#if HOST_BITS_PER_WIDE_INT >= 64
if (bits == TYPE_PRECISION (intTI_type_node))
return intTI_type_node;
+ if (bits == TYPE_PRECISION (intOI_type_node))
+ return intOI_type_node;
#endif
if (bits <= TYPE_PRECISION (intQI_type_node))
@@ -2872,6 +2876,8 @@ gfc_type_for_size (unsigned bits, int unsignedp)
return intDI_type_node;
if (bits <= TYPE_PRECISION (intTI_type_node))
return intTI_type_node;
+ if (bits <= TYPE_PRECISION (intOI_type_node))
+ return intOI_type_node;
}
else
{
@@ -2885,6 +2891,8 @@ gfc_type_for_size (unsigned bits, int unsignedp)
return unsigned_intDI_type_node;
if (bits <= TYPE_PRECISION (unsigned_intTI_type_node))
return unsigned_intTI_type_node;
+ if (bits <= TYPE_PRECISION (unsigned_intOI_type_node))
+ return unsigned_intOI_type_node;
}
return NULL_TREE;
@@ -4739,11 +4739,17 @@ gimple_signed_or_unsigned_type (bool unsignedp, tree type)
return unsignedp
? long_long_unsigned_type_node
: long_long_integer_type_node;
+ if (int256_integer_type_node && (type1 == int256_integer_type_node || type1 == int256_unsigned_type_node))
+ return unsignedp
+ ? int256_unsigned_type_node
+ : int256_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;
#if HOST_BITS_PER_WIDE_INT >= 64
+ if (type1 == intOI_type_node || type1 == unsigned_intOI_type_node)
+ return unsignedp ? unsigned_intOI_type_node : intOI_type_node;
if (type1 == intTI_type_node || type1 == unsigned_intTI_type_node)
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
#endif
@@ -4855,12 +4861,18 @@ gimple_signed_or_unsigned_type (bool unsignedp, tree type)
return (unsignedp
? long_long_unsigned_type_node
: long_long_integer_type_node);
+ if (int256_integer_type_node && TYPE_OK (int256_integer_type_node))
+ return (unsignedp
+ ? int256_unsigned_type_node
+ : int256_integer_type_node);
if (int128_integer_type_node && TYPE_OK (int128_integer_type_node))
return (unsignedp
? int128_unsigned_type_node
: int128_integer_type_node);
#if HOST_BITS_PER_WIDE_INT >= 64
+ if (TYPE_OK (intOI_type_node))
+ return unsignedp ? unsigned_intOI_type_node : intOI_type_node;
if (TYPE_OK (intTI_type_node))
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
#endif
@@ -811,6 +811,9 @@ lto_type_for_size (unsigned precision, int unsignedp)
if (precision <= TYPE_PRECISION (intTI_type_node))
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+ if (precision <= TYPE_PRECISION (intOI_type_node))
+ return unsignedp ? unsigned_intOI_type_node : intOI_type_node;
+
return NULL_TREE;
}
@@ -856,6 +859,8 @@ lto_type_for_mode (enum machine_mode mode, int unsigned_p)
#if HOST_BITS_PER_WIDE_INT >= 64
if (mode == TYPE_MODE (intTI_type_node))
return unsigned_p ? unsigned_intTI_type_node : intTI_type_node;
+ if (mode == TYPE_MODE (intOI_type_node))
+ return unsigned_p ? unsigned_intOI_type_node : intOI_type_node;
#endif
if (mode == TYPE_MODE (float_type_node))
@@ -5488,7 +5488,8 @@ static void
gen_int_libfunc (optab optable, const char *opname, char suffix,
enum machine_mode mode)
{
- int maxsize = 2 * BITS_PER_WORD;
+ /* TODO: Add OImode support in libgcc. */
+ int maxsize = 4 * BITS_PER_WORD;
if (GET_MODE_CLASS (mode) != MODE_INT)
return;
@@ -9178,6 +9178,9 @@ 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 == 256 && int256_integer_type_node)
+ return (unsignedp ? int256_unsigned_type_node
+ : int256_integer_type_node);
if (size == 128 && int128_integer_type_node)
return (unsignedp ? int128_unsigned_type_node
: int128_integer_type_node);
@@ -9300,6 +9303,15 @@ build_common_tree_nodes (bool signed_char, bool short_double)
#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 OImode, but has an 256-bit
+ integer-scalar register, this target check needs to be adjusted. */
+ if (targetm.scalar_mode_supported_p (OImode))
+ {
+ int256_integer_type_node = make_signed_type (256);
+ int256_unsigned_type_node = make_unsigned_type (256);
+ }
+ /* 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))
@@ -9337,12 +9349,14 @@ build_common_tree_nodes (bool signed_char, bool short_double)
intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 0);
intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 0);
intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 0);
+ intOI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (OImode), 0);
unsigned_intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 1);
unsigned_intHI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (HImode), 1);
unsigned_intSI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (SImode), 1);
unsigned_intDI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (DImode), 1);
unsigned_intTI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (TImode), 1);
+ unsigned_intOI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (OImode), 1);
access_public_node = get_identifier ("public");
access_protected_node = get_identifier ("protected");
@@ -3725,12 +3725,14 @@ enum tree_index
TI_INTSI_TYPE,
TI_INTDI_TYPE,
TI_INTTI_TYPE,
+ TI_INTOI_TYPE,
TI_UINTQI_TYPE,
TI_UINTHI_TYPE,
TI_UINTSI_TYPE,
TI_UINTDI_TYPE,
TI_UINTTI_TYPE,
+ TI_UINTOI_TYPE,
TI_UINT16_TYPE,
TI_UINT32_TYPE,
@@ -3881,12 +3883,14 @@ extern GTY(()) tree global_trees[TI_MAX];
#define intSI_type_node global_trees[TI_INTSI_TYPE]
#define intDI_type_node global_trees[TI_INTDI_TYPE]
#define intTI_type_node global_trees[TI_INTTI_TYPE]
+#define intOI_type_node global_trees[TI_INTOI_TYPE]
#define unsigned_intQI_type_node global_trees[TI_UINTQI_TYPE]
#define unsigned_intHI_type_node global_trees[TI_UINTHI_TYPE]
#define unsigned_intSI_type_node global_trees[TI_UINTSI_TYPE]
#define unsigned_intDI_type_node global_trees[TI_UINTDI_TYPE]
#define unsigned_intTI_type_node global_trees[TI_UINTTI_TYPE]
+#define unsigned_intOI_type_node global_trees[TI_UINTOI_TYPE]
#define uint16_type_node global_trees[TI_UINT16_TYPE]
#define uint32_type_node global_trees[TI_UINT32_TYPE]
@@ -4070,6 +4074,8 @@ enum integer_type_kind
itk_unsigned_long,
itk_long_long,
itk_unsigned_long_long,
+ itk_int256,
+ itk_unsigned_int256,
itk_int128,
itk_unsigned_int128,
itk_none
@@ -4092,6 +4098,8 @@ extern GTY(()) tree integer_types[itk_none];
#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 int256_integer_type_node integer_types[itk_int256]
+#define int256_unsigned_type_node integer_types[itk_unsigned_int256]
#define int128_integer_type_node integer_types[itk_int128]
#define int128_unsigned_type_node integer_types[itk_unsigned_int128]
@@ -2059,14 +2059,15 @@ cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT] =
/* h */ { NL ("unsigned char"), NL ("unsigned char"), D_PRINT_DEFAULT },
/* i */ { NL ("int"), NL ("int"), D_PRINT_INT },
/* j */ { NL ("unsigned int"), NL ("unsigned"), D_PRINT_UNSIGNED },
- /* k */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
+ /* k */ { NL ("unsigned __int256"), NL ("unsigned __int256"),
+ D_PRINT_DEFAULT },
/* l */ { NL ("long"), NL ("long"), D_PRINT_LONG },
/* m */ { NL ("unsigned long"), NL ("unsigned long"), D_PRINT_UNSIGNED_LONG },
/* n */ { NL ("__int128"), NL ("__int128"), D_PRINT_DEFAULT },
/* o */ { NL ("unsigned __int128"), NL ("unsigned __int128"),
D_PRINT_DEFAULT },
/* p */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
- /* q */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
+ /* q */ { NL ("__int256"), NL ("__int256"), D_PRINT_DEFAULT },
/* r */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
/* s */ { NL ("short"), NL ("short"), D_PRINT_DEFAULT },
/* t */ { NL ("unsigned short"), NL ("unsigned short"), D_PRINT_DEFAULT },
@@ -2132,6 +2133,8 @@ cplus_demangle_type (struct d_info *di)
case 'h': case 'i': case 'j': case 'l': case 'm': case 'n':
case 'o': case 's': case 't':
case 'v': case 'w': case 'x': case 'y': case 'z':
+ case 'k': /* unsigned __int256 */
+ case 'q': /* __int256 */
ret = d_make_builtin_type (di,
&cplus_demangle_builtin_types[peek - 'a']);
di->expansion += ret->u.s_builtin.type->len;