This patch adds __int256 to the front-ends.  We follow the __int128 code fairly 
closely...

So, an outstanding question would be, how do I get the mangle codes allocated 
for the type?  I just choose two unused codes, for now.  All in all, the patch 
was pretty straight forward.

We have another patch underway to do N-bit constant ints, where N is defined by 
the port.  This patch is in the process of being reviewed now, and Kenny should 
be able to submit it shortly.

I tried hard to find all the __int128 bits, but, if there are any I missed, 
love to have a pointer to them.

So, I think we have to resolve which mangle codes to use in some before this 
goes in, aside from that, Ok?



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 %<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));
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 8fb9443..0fcdf33 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",
@@ -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:
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/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 ("%<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)
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/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;

Reply via email to