On Jul 13, 2012, at 6:39 AM, Joseph S. Myers wrote:
> On Fri, 13 Jul 2012, Mike Stump wrote:
> 
>> As I said, in Kenny's next patch, we add support for all constants of 
>> any size the port needs.  I don't know if you've ever tried to use the 
>> compiler with OImode, but, what I can say is the bugs are not terribly 
>> latent at times and they are not hidden very well at all, today.  The 
>> goal of course, is to improve that and make it work better.  These 
>> issues that I know about existed, prior to my patch, and we are in the 
>> process of fixing them.  Some have been fixed, others remain to be 
>> fixed.  The issues I'm thinking about exist with or without my patch to 
>> the frontend to support __int256.  Merely adding __int256 doesn't make 
>> any of the issues I'm aware of appear, and the issues I'm aware of don't 
>> appear with sizes less than 256.
> 
> I think the patches allowing constants of such a type to work should go in 
> first,

I understand the beauty of putting in the const wide int stuff first...  I 
don't think it matters much to me...  but I might ask why?  I think we have 
added support for all in-tree gcc ports for all possible testcases.  Do you 
know of a single testcase that fails on a single port?

> and the libgcc support,


I wanted to separate the patches and keep them in small well focused review 
groups, as they hit wildly different reviewers.

> before we consider the support for the type from the front ends using 
> keywords as opposed to mode attributes.

I believe that libgcc support for all existing in-tree ports of gcc is already 
complete.  We'd be happy to do any libgcc work necessary to make any testcase 
work on any existing in-tree gcc port.  If you know of any work that remains to 
be done, please provide a testcase, and I can ensure the work is complete.

> You're using OImode in target-independent code.

> But I don't see a change to machmode.def to add it as a machine-independent 
> mode.

Ah, good catch.  I've moved OImode up from the ports in the patch below.

> Nor do I think
> it *should* be a machine-independent mode; it's sufficiently specialised 
> that it should be possible to do things without it needing to be one.

Hum, how about this, if you fix __int128 to do it the way you want, then I will 
fix __int256 to copy the style that is set by __int128.  I'd rather have them 
be exactly the same, so that testing for one will more likely help the other 
one.  I don't have a good idea of a better way to do this.  Longer term, I'd 
like __int256 to be universally available, just like long is and just like long 
long is.  We can't do that yet, I think doing that is premature.

> See my comments (several messages on 1 July 2011) about 40-bit integer 
> support;

Ick, 40 / 8 is 5, and 5 isn't a power of 2, therefore, they are different cases 
to me.    I appreciate that you'd like to see HImode go, wake me up when that 
is done.

> carefully designed target hooks to specify the keywords / modes 
> for target-specific integer types are better than adding more and more 
> cases to several difference places in the target-independent compiler.

Agreed, on general principals.  And, if I waned 60 bit support, or 250 bit 
support, I'm right there with you.  However, 32 support, has, over time, proven 
to be the right answer.  Likewise, merely shifted by some years later, 64 bit 
support.  While 128 and 256 may seem to you to be as odd now as 64 bit support 
was back when 8 was all the rage...  well, I'll stop there.  Let me just say, 
these are special because they are powers of 2.

If you can sketch out a better incantation for the 128 and 256 bit support, I 
can try my hand at improving it.  I just don't know any better form for it.  
I'd argue that all powers of twos in use by any port, should be put into 
machmode.def.  I can rip out all TImode handling, leaving the int128 handling, 
the TImode code I think is redundant with the int128 code.  Would you like me 
to do that?  I just don't want to be on the hook when it doesn't work out for 
someone.

> __int128_t and __uint128_t are legacy built-in typedef names and I don't 
> think there should be any analogue for 256-bit integers; just __int256 and 
> unsigned __int256.

Ok, fixed.

>> I have put the patch through the C test suite, and it doesn't show any 
>> failures.
> 
> Certainly you should add analogues of 
> gcc.dg/torture/fp-int-convert-*timode.c for the new type and verify that 
> those tests all work for it.  It would seem advisable to add tests 
> covering pure integer operations for the new type (all the C integer 
> operations), for both constants and runtime evaluation, as well.

Ok, fixed.  I put in the portable testcase, esoteric things like 80 bit 
floating point numbers can be added by people that like such things.

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..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
 <http://www.gnu.org/licenses/>.  */
 
-/* 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 ("%<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/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 <float.h>
+#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);
+}

Reply via email to