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);
+}
