diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def index d8e9e56..564e5c7 100644 --- a/gcc/builtin-types.def +++ b/gcc/builtin-types.def @@ -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) diff --git a/gcc/c-decl.c b/gcc/c-decl.c index bbb437d..387105a 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -8945,6 +8945,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs, error_at (loc, ("both % and % in " "declaration specifiers")); + else if (specs->typespec_word == cts_int256) + error_at (loc, + ("both % and %<__int256%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_int128) error_at (loc, ("both % and %<__int128%> in " @@ -8989,6 +8993,10 @@ declspecs_add_type (location_t loc, struct c_declspecs *specs, error_at (loc, ("both % and % in " "declaration specifiers")); + else if (specs->typespec_word == cts_int256) + error_at (loc, + ("both % and %<__int256%> in " + "declaration specifiers")); else if (specs->typespec_word == cts_int128) error_at (loc, ("both % 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 % 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 % 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)); diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 8fb9443..f6597d5 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -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", @@ -10844,6 +10882,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: diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index ab9d0f9..90d4303 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -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, diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index 89a22a3..27f8730 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -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); diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c index d445187..3a25241 100644 --- a/gcc/c-family/c-pretty-print.c +++ b/gcc/c-family/c-pretty-print.c @@ -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"); diff --git a/gcc/c-parser.c b/gcc/c-parser.c index b4135ee..37eab46 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -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: diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 145df35..98ee22e 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -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, diff --git a/gcc/config/arm/arm-modes.def b/gcc/config/arm/arm-modes.def index 7f19ebe..697ee9c 100644 --- a/gcc/config/arm/arm-modes.def +++ b/gcc/config/arm/arm-modes.def @@ -79,6 +79,5 @@ VECTOR_MODES (UACCUM, 4); /* V2UHA */ /* Opaque integer modes for 3, 4, 6 or 8 Neon double registers (2 is TImode). */ INT_MODE (EI, 24); -INT_MODE (OI, 32); INT_MODE (CI, 48); INT_MODE (XI, 64); diff --git a/gcc/config/i386/i386-modes.def b/gcc/config/i386/i386-modes.def index c1e82cc..33e4c42 100644 --- a/gcc/config/i386/i386-modes.def +++ b/gcc/config/i386/i386-modes.def @@ -85,7 +85,5 @@ VECTOR_MODE (INT, DI, 1); /* V1DI */ VECTOR_MODE (INT, SI, 1); /* V1SI */ VECTOR_MODE (INT, QI, 2); /* V2QI */ -INT_MODE (OI, 32); - /* The symbol Pmode stands for one of the above machine modes (usually SImode). The tm.h file specifies which one. It is not a distinct mode. */ diff --git a/gcc/config/ia64/ia64-modes.def b/gcc/config/ia64/ia64-modes.def index a3d04d9..66c7291 100644 --- a/gcc/config/ia64/ia64-modes.def +++ b/gcc/config/ia64/ia64-modes.def @@ -64,9 +64,6 @@ ADJUST_ALIGNMENT (RF, (TARGET_ILP32 && !TARGET_HPUX) ? 4 : 16); ADJUST_ALIGNMENT (TF, (TARGET_ILP32 && TARGET_HPUX) ? 8 : 16); -/* 256-bit integer mode is needed for STACK_SAVEAREA_MODE. */ -INT_MODE (OI, 32); - /* Add any extra modes needed to represent the condition code. CCImode is used to mark a single predicate register instead diff --git a/gcc/config/s390/s390-modes.def b/gcc/config/s390/s390-modes.def index be2bf6e..05b9fcb 100644 --- a/gcc/config/s390/s390-modes.def +++ b/gcc/config/s390/s390-modes.def @@ -19,9 +19,6 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ -/* 256-bit integer mode is needed for STACK_SAVEAREA_MODE. */ -INT_MODE (OI, 32); - /* Define TFmode to work around reload problem PR 20927. */ FLOAT_MODE (TF, 16, ieee_quad_format); diff --git a/gcc/config/spu/spu-modes.def b/gcc/config/spu/spu-modes.def index ef21012..f5674ea 100644 --- a/gcc/config/spu/spu-modes.def +++ b/gcc/config/spu/spu-modes.def @@ -23,7 +23,3 @@ VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */ VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */ VECTOR_MODES (FLOAT, 16); /* V8HF V4SF V2DF */ - -/* cse_insn needs an INT_MODE larger than WORD_MODE, otherwise some - parts of it will go into an infinite loop. */ -INT_MODE (OI, 32); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a4b7ae3..ac92a56 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 1346f92..e55fba1 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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 ("% invalid for %qs", name); else if ((long_p || short_p) && TREE_CODE (type) != INTEGER_TYPE) error ("% or % invalid for %qs", name); + else if ((long_p || short_p || explicit_char || explicit_int) && explicit_int256) + error ("%, %, %, or % invalid for %qs", name); else if ((long_p || short_p || explicit_char || explicit_int) && explicit_int128) error ("%, %, %, or % 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) diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 5bdf020..b0a2816 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -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 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 46f1401..6981c13 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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; diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index a19a893..8e8a215 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -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, diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 9c261e4..3c31a40 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 91e7385..363e836 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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 diff --git a/gcc/fortran/iso-c-binding.def b/gcc/fortran/iso-c-binding.def index f8673b9..d0c9286 100644 --- a/gcc/fortran/iso-c-binding.def +++ b/gcc/fortran/iso-c-binding.def @@ -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) diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index aa50e3d..b2f62dc 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -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; diff --git a/gcc/gimple.c b/gcc/gimple.c index 398cb1f..f8da33b 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -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 diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c index 280d883..3d43181 100644 --- a/gcc/lto/lto-lang.c +++ b/gcc/lto/lto-lang.c @@ -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)) diff --git a/gcc/machmode.def b/gcc/machmode.def index 631015f..3c2e074 100644 --- a/gcc/machmode.def +++ b/gcc/machmode.def @@ -187,6 +187,7 @@ INT_MODE (HI, 2); INT_MODE (SI, 4); INT_MODE (DI, 8); INT_MODE (TI, 16); +INT_MODE (OI, 32); /* No partial integer modes are defined by default. */ diff --git a/gcc/optabs.c b/gcc/optabs.c index 9a549ff..f52e255 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -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; diff --git a/gcc/tree.c b/gcc/tree.c index 41790ec..adb5a9f 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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"); diff --git a/gcc/tree.h b/gcc/tree.h index be04465..6161810 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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] diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 27cc323..9b7d9e9 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -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; --- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-oimode.c.orig 2012-07-13 18:37:07.942507231 -0400 +++ a/gcc/testsuite/gcc.dg/torture/fp-int-convert-oimode.c 2012-07-13 18:39:40.934135061 -0400 @@ -0,0 +1,23 @@ +/* Test floating-point conversions. OImode types. */ +/* { dg-do run { target noneyet-*-* } } */ +/* { dg-options "" } */ + +#include +#include "fp-int-convert.h" + +typedef __int256 OItype; +typedef unsigned __int256 UOItype; + +int +main (void) +{ + TEST_I_F(OItype, UOItype, float, FLT_MANT_DIG); + TEST_I_F(OItype, UOItype, double, DBL_MANT_DIG); + /* Disable the long double tests when using IBM Extended Doubles. + They have variable precision, but constants calculated by gcc's + real.c assume fixed precision. */ +#if DBL_MANT_DIG != LDBL_MANT_DIG && LDBL_MANT_DIG != 106 + TEST_I_F(OItype, UOItype, long double, LDBL_MANT_DIG); +#endif + exit (0); +}