Index: gcc/doc/cpp.texi
===================================================================
--- gcc/doc/cpp.texi	(revision 325327)
+++ gcc/doc/cpp.texi	(working copy)
@@ -2122,46 +2122,55 @@ OSF/rose @option{-mno-underscores} optio
 @itemx __INT8_TYPE__
 @itemx __INT16_TYPE__
 @itemx __INT32_TYPE__
+@itemx __INT40_TYPE__
 @itemx __INT64_TYPE__
 @itemx __UINT8_TYPE__
 @itemx __UINT16_TYPE__
 @itemx __UINT32_TYPE__
+@itemx __UINT40_TYPE__
 @itemx __UINT64_TYPE__
 @itemx __INT_LEAST8_TYPE__
 @itemx __INT_LEAST16_TYPE__
 @itemx __INT_LEAST32_TYPE__
+@itemx __INT_LEAST40_TYPE__
 @itemx __INT_LEAST64_TYPE__
 @itemx __UINT_LEAST8_TYPE__
 @itemx __UINT_LEAST16_TYPE__
 @itemx __UINT_LEAST32_TYPE__
+@itemx __UINT_LEAST40_TYPE__
 @itemx __UINT_LEAST64_TYPE__
 @itemx __INT_FAST8_TYPE__
 @itemx __INT_FAST16_TYPE__
 @itemx __INT_FAST32_TYPE__
+@itemx __INT_FAST40_TYPE__
 @itemx __INT_FAST64_TYPE__
 @itemx __UINT_FAST8_TYPE__
 @itemx __UINT_FAST16_TYPE__
 @itemx __UINT_FAST32_TYPE__
+@itemx __UINT_FAST40_TYPE__
 @itemx __UINT_FAST64_TYPE__
 @itemx __INTPTR_TYPE__
 @itemx __UINTPTR_TYPE__
+
 These macros are defined to the correct underlying types for the
 @code{size_t}, @code{ptrdiff_t}, @code{wchar_t}, @code{wint_t},
 @code{intmax_t}, @code{uintmax_t}, @code{sig_atomic_t}, @code{int8_t},
-@code{int16_t}, @code{int32_t}, @code{int64_t}, @code{uint8_t},
-@code{uint16_t}, @code{uint32_t}, @code{uint64_t},
-@code{int_least8_t}, @code{int_least16_t}, @code{int_least32_t},
-@code{int_least64_t}, @code{uint_least8_t}, @code{uint_least16_t},
+@code{int16_t}, @code{int32_t}, @code{int32_t}, @code{int64_t},
+@code{uint8_t}, @code{uint16_t}, @code{uint32_t}, @code{uint32_t},
+@code{uint64_t}, @code{int_least8_t}, @code{int_least16_t},
+@code{int_least32_t}, @code{int_least32_t}, @code{int_least64_t},
+@code{uint_least8_t}, @code{uint_least16_t}, @code{uint_least32_t},
 @code{uint_least32_t}, @code{uint_least64_t}, @code{int_fast8_t},
-@code{int_fast16_t}, @code{int_fast32_t}, @code{int_fast64_t},
-@code{uint_fast8_t}, @code{uint_fast16_t}, @code{uint_fast32_t},
-@code{uint_fast64_t}, @code{intptr_t}, and @code{uintptr_t} typedefs,
-respectively.  They exist to make the standard header files
-@file{stddef.h}, @file{stdint.h}, and @file{wchar.h} work correctly.
-You should not use these macros directly; instead, include the
-appropriate headers and use the typedefs.  Some of these macros may
-not be defined on particular systems if GCC does not provide a
-@file{stdint.h} header on those systems.
+@code{int_fast16_t}, @code{int_fast32_t}, @code{int_fast32_t},
+@code{int_fast64_t}, @code{uint_fast8_t}, @code{uint_fast16_t},
+@code{uint_fast32_t}, @code{uint_fast32_t}, @code{uint_fast64_t},
+@code{intptr_t}, and @code{uintptr_t} typedefs, respectively.  They
+exist to make the standard header files @file{stddef.h},
+@file{stdint.h}, and @file{wchar.h} work correctly.  You should not use
+these macros directly; instead, include the appropriate headers and use
+the typedefs.  Some of these macros may not be defined on particular
+systems if GCC does not provide a @file{stdint.h} header on those
+systems.
 
 @item __CHAR_BIT__
 Defined to the number of bits used in the representation of the
@@ -2184,26 +2193,32 @@ this macro directly; instead, include th
 @itemx __INT8_MAX__
 @itemx __INT16_MAX__
 @itemx __INT32_MAX__
+@itemx __INT40_MAX__
 @itemx __INT64_MAX__
 @itemx __UINT8_MAX__
 @itemx __UINT16_MAX__
 @itemx __UINT32_MAX__
+@itemx __UINT40_MAX__
 @itemx __UINT64_MAX__
 @itemx __INT_LEAST8_MAX__
 @itemx __INT_LEAST16_MAX__
 @itemx __INT_LEAST32_MAX__
+@itemx __INT_LEAST40_MAX__
 @itemx __INT_LEAST64_MAX__
 @itemx __UINT_LEAST8_MAX__
 @itemx __UINT_LEAST16_MAX__
 @itemx __UINT_LEAST32_MAX__
+@itemx __UINT_LEAST40_MAX__
 @itemx __UINT_LEAST64_MAX__
 @itemx __INT_FAST8_MAX__
 @itemx __INT_FAST16_MAX__
 @itemx __INT_FAST32_MAX__
+@itemx __INT_FAST40_MAX__
 @itemx __INT_FAST64_MAX__
 @itemx __UINT_FAST8_MAX__
 @itemx __UINT_FAST16_MAX__
 @itemx __UINT_FAST32_MAX__
+@itemx __UINT_FAST40_MAX__
 @itemx __UINT_FAST64_MAX__
 @itemx __INTPTR_MAX__
 @itemx __UINTPTR_MAX__
@@ -2215,13 +2230,13 @@ Defined to the maximum value of the @cod
 @code{signed int}, @code{signed long}, @code{signed long long},
 @code{wint_t}, @code{size_t}, @code{ptrdiff_t},
 @code{intmax_t}, @code{uintmax_t}, @code{sig_atomic_t}, @code{int8_t},
-@code{int16_t}, @code{int32_t}, @code{int64_t}, @code{uint8_t},
-@code{uint16_t}, @code{uint32_t}, @code{uint64_t},
-@code{int_least8_t}, @code{int_least16_t}, @code{int_least32_t},
-@code{int_least64_t}, @code{uint_least8_t}, @code{uint_least16_t},
-@code{uint_least32_t}, @code{uint_least64_t}, @code{int_fast8_t},
-@code{int_fast16_t}, @code{int_fast32_t}, @code{int_fast64_t},
-@code{uint_fast8_t}, @code{uint_fast16_t}, @code{uint_fast32_t},
+@code{int16_t}, @code{int32_t},  @code{int40_t}, @code{int64_t}, @code{uint8_t},
+@code{uint16_t}, @code{uint32_t}, @code{uint40_t}, @code{uint64_t},
+@code{int_least8_t}, @code{int_least16_t}, @code{int_least32_t}, @code{int_least40_t},
+@code{int_least64_t}, @code{uint_least8_t}, @code{uint_least16_t}, @code{uint_least32_t},
+@code{uint_least40_t}, @code{uint_least64_t}, @code{int_fast8_t},
+@code{int_fast16_t}, @code{int_fast32_t}, @code{int_fast40_t}, @code{int_fast64_t},
+@code{uint_fast8_t}, @code{uint_fast16_t}, @code{uint_fast32_t}, @code{uint_fast40_t},
 @code{uint_fast64_t}, @code{intptr_t}, and @code{uintptr_t} types and
 to the minimum value of the @code{wchar_t}, @code{wint_t}, and
 @code{sig_atomic_t} types respectively.  They exist to make the
@@ -2233,9 +2248,11 @@ does not provide a @file{stdint.h} heade
 @item __INT8_C
 @itemx __INT16_C
 @itemx __INT32_C
+@itemx __INT40_C
 @itemx __INT64_C
 @itemx __UINT8_C
 @itemx __UINT16_C
+@itemx __UINT40_C
 @itemx __UINT32_C
 @itemx __UINT64_C
 @itemx __INTMAX_C
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 327382)
+++ gcc/doc/tm.texi	(working copy)
@@ -1820,39 +1820,47 @@ int}.
 @defmacx INT8_TYPE
 @defmacx INT16_TYPE
 @defmacx INT32_TYPE
+@defmacx INT40_TYPE
 @defmacx INT64_TYPE
 @defmacx UINT8_TYPE
 @defmacx UINT16_TYPE
 @defmacx UINT32_TYPE
+@defmacx UINT40_TYPE
 @defmacx UINT64_TYPE
 @defmacx INT_LEAST8_TYPE
 @defmacx INT_LEAST16_TYPE
 @defmacx INT_LEAST32_TYPE
+@defmacx INT_LEAST40_TYPE
 @defmacx INT_LEAST64_TYPE
 @defmacx UINT_LEAST8_TYPE
 @defmacx UINT_LEAST16_TYPE
 @defmacx UINT_LEAST32_TYPE
+@defmacx UINT_LEAST40_TYPE
 @defmacx UINT_LEAST64_TYPE
 @defmacx INT_FAST8_TYPE
 @defmacx INT_FAST16_TYPE
 @defmacx INT_FAST32_TYPE
+@defmacx INT_FAST40_TYPE
 @defmacx INT_FAST64_TYPE
 @defmacx UINT_FAST8_TYPE
 @defmacx UINT_FAST16_TYPE
 @defmacx UINT_FAST32_TYPE
+@defmacx UINT_FAST40_TYPE
 @defmacx UINT_FAST64_TYPE
 @defmacx INTPTR_TYPE
 @defmacx UINTPTR_TYPE
-C expressions for the standard types @code{sig_atomic_t},
-@code{int8_t}, @code{int16_t}, @code{int32_t}, @code{int64_t},
-@code{uint8_t}, @code{uint16_t}, @code{uint32_t}, @code{uint64_t},
-@code{int_least8_t}, @code{int_least16_t}, @code{int_least32_t},
-@code{int_least64_t}, @code{uint_least8_t}, @code{uint_least16_t},
-@code{uint_least32_t}, @code{uint_least64_t}, @code{int_fast8_t},
-@code{int_fast16_t}, @code{int_fast32_t}, @code{int_fast64_t},
-@code{uint_fast8_t}, @code{uint_fast16_t}, @code{uint_fast32_t},
-@code{uint_fast64_t}, @code{intptr_t}, and @code{uintptr_t}.  See
-@code{SIZE_TYPE} above for more information.
+C expressions for the standard types @code{sig_atomic_t}, @code{int8_t},
+@code{int16_t}, @code{int32_t}, @code{int40_t}, @code{int64_t},
+@code{uint8_t}, @code{uint16_t}, @code{uint32_t}, @code{uint40_t},
+@code{uint64_t}, @code{int_least8_t}, @code{int_least16_t},
+@code{int_least32_t}, @code{int_least40_t}, @code{int_least64_t},
+@code{uint_least8_t}, @code{uint_least16_t}, @code{uint_least32_t},
+@code{uint_least40_t}, @code{uint_least64_t}, @code{int_fast8_t},
+@code{int_fast16_t}, @code{int_fast32_t}, @code{int_fast40_t},
+@code{int_fast64_t}, @code{uint_fast8_t}, @code{uint_fast16_t},
+@code{uint_fast32_t}, @code{uint_fast40_t}, @code{uint_fast64_t},
+@code{intptr_t}, and @code{uintptr_t}.  See @code{SIZE_TYPE} above for
+more information.
 
 If any of these macros evaluates to a null pointer, the corresponding
 type is not supported; if GCC is configured to provide
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 327382)
+++ gcc/doc/tm.texi.in	(working copy)
@@ -1820,39 +1820,47 @@ int}.
 @defmacx INT8_TYPE
 @defmacx INT16_TYPE
 @defmacx INT32_TYPE
+@defmacx INT40_TYPE
 @defmacx INT64_TYPE
 @defmacx UINT8_TYPE
 @defmacx UINT16_TYPE
 @defmacx UINT32_TYPE
+@defmacx UINT40_TYPE
 @defmacx UINT64_TYPE
 @defmacx INT_LEAST8_TYPE
 @defmacx INT_LEAST16_TYPE
 @defmacx INT_LEAST32_TYPE
+@defmacx INT_LEAST40_TYPE
 @defmacx INT_LEAST64_TYPE
 @defmacx UINT_LEAST8_TYPE
 @defmacx UINT_LEAST16_TYPE
 @defmacx UINT_LEAST32_TYPE
+@defmacx UINT_LEAST40_TYPE
 @defmacx UINT_LEAST64_TYPE
 @defmacx INT_FAST8_TYPE
 @defmacx INT_FAST16_TYPE
 @defmacx INT_FAST32_TYPE
+@defmacx INT_FAST40_TYPE
 @defmacx INT_FAST64_TYPE
 @defmacx UINT_FAST8_TYPE
 @defmacx UINT_FAST16_TYPE
 @defmacx UINT_FAST32_TYPE
+@defmacx UINT_FAST40_TYPE
 @defmacx UINT_FAST64_TYPE
 @defmacx INTPTR_TYPE
 @defmacx UINTPTR_TYPE
-C expressions for the standard types @code{sig_atomic_t},
-@code{int8_t}, @code{int16_t}, @code{int32_t}, @code{int64_t},
-@code{uint8_t}, @code{uint16_t}, @code{uint32_t}, @code{uint64_t},
-@code{int_least8_t}, @code{int_least16_t}, @code{int_least32_t},
-@code{int_least64_t}, @code{uint_least8_t}, @code{uint_least16_t},
-@code{uint_least32_t}, @code{uint_least64_t}, @code{int_fast8_t},
-@code{int_fast16_t}, @code{int_fast32_t}, @code{int_fast64_t},
-@code{uint_fast8_t}, @code{uint_fast16_t}, @code{uint_fast32_t},
-@code{uint_fast64_t}, @code{intptr_t}, and @code{uintptr_t}.  See
-@code{SIZE_TYPE} above for more information.
+C expressions for the standard types @code{sig_atomic_t}, @code{int8_t},
+@code{int16_t}, @code{int32_t}, @code{int40_t}, @code{int64_t},
+@code{uint8_t}, @code{uint16_t}, @code{uint32_t}, @code{uint40_t},
+@code{uint64_t}, @code{int_least8_t}, @code{int_least16_t},
+@code{int_least32_t}, @code{int_least40_t}, @code{int_least64_t},
+@code{uint_least8_t}, @code{uint_least16_t}, @code{uint_least32_t},
+@code{uint_least40_t}, @code{uint_least64_t}, @code{int_fast8_t},
+@code{int_fast16_t}, @code{int_fast32_t}, @code{int_fast40_t},
+@code{int_fast64_t}, @code{uint_fast8_t}, @code{uint_fast16_t},
+@code{uint_fast32_t}, @code{uint_fast40_t}, @code{uint_fast64_t},
+@code{intptr_t}, and @code{uintptr_t}.  See @code{SIZE_TYPE} above for
+more information.
 
 If any of these macros evaluates to a null pointer, the corresponding
 type is not supported; if GCC is configured to provide
Index: gcc/defaults.h
===================================================================
--- gcc/defaults.h	(revision 325327)
+++ gcc/defaults.h	(working copy)
@@ -589,6 +589,10 @@ see the files COPYING3 and COPYING.RUNTI
 #define INT32_TYPE ((const char *) NULL)
 #endif
 
+#ifndef INT40_TYPE
+#define INT40_TYPE ((const char *) NULL)
+#endif
+
 #ifndef INT64_TYPE
 #define INT64_TYPE ((const char *) NULL)
 #endif
@@ -605,6 +609,10 @@ see the files COPYING3 and COPYING.RUNTI
 #define UINT32_TYPE ((const char *) NULL)
 #endif
 
+#ifndef UINT40_TYPE
+#define UINT40_TYPE ((const char *) NULL)
+#endif
+
 #ifndef UINT64_TYPE
 #define UINT64_TYPE ((const char *) NULL)
 #endif
@@ -621,6 +629,10 @@ see the files COPYING3 and COPYING.RUNTI
 #define INT_LEAST32_TYPE ((const char *) NULL)
 #endif
 
+#ifndef INT_LEAST40_TYPE
+#define INT_LEAST40_TYPE ((const char *) NULL)
+#endif
+
 #ifndef INT_LEAST64_TYPE
 #define INT_LEAST64_TYPE ((const char *) NULL)
 #endif
@@ -637,6 +649,10 @@ see the files COPYING3 and COPYING.RUNTI
 #define UINT_LEAST32_TYPE ((const char *) NULL)
 #endif
 
+#ifndef UINT_LEAST40_TYPE
+#define UINT_LEAST40_TYPE ((const char *) NULL)
+#endif
+
 #ifndef UINT_LEAST64_TYPE
 #define UINT_LEAST64_TYPE ((const char *) NULL)
 #endif
@@ -653,6 +669,10 @@ see the files COPYING3 and COPYING.RUNTI
 #define INT_FAST32_TYPE ((const char *) NULL)
 #endif
 
+#ifndef INT_FAST40_TYPE
+#define INT_FAST40_TYPE ((const char *) NULL)
+#endif
+
 #ifndef INT_FAST64_TYPE
 #define INT_FAST64_TYPE ((const char *) NULL)
 #endif
@@ -669,6 +689,10 @@ see the files COPYING3 and COPYING.RUNTI
 #define UINT_FAST32_TYPE ((const char *) NULL)
 #endif
 
+#ifndef UINT_FAST40_TYPE
+#define UINT_FAST40_TYPE ((const char *) NULL)
+#endif
+
 #ifndef UINT_FAST64_TYPE
 #define UINT_FAST64_TYPE ((const char *) NULL)
 #endif
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 327382)
+++ gcc/tree.c	(working copy)
@@ -8822,12 +8822,14 @@ build_common_tree_nodes (bool signed_cha
   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);
+  intPI_type_node = build_nonstandard_integer_type (40, false);
 
   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_intPI_type_node = build_nonstandard_integer_type (40, true);
 
   access_public_node = get_identifier ("public");
   access_protected_node = get_identifier ("protected");
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 325327)
+++ gcc/tree.h	(working copy)
@@ -3415,12 +3415,14 @@ enum tree_index
   TI_INTSI_TYPE,
   TI_INTDI_TYPE,
   TI_INTTI_TYPE,
+  TI_INTPI_TYPE,
 
   TI_UINTQI_TYPE,
   TI_UINTHI_TYPE,
   TI_UINTSI_TYPE,
   TI_UINTDI_TYPE,
   TI_UINTTI_TYPE,
+  TI_UINTPI_TYPE,
 
   TI_UINT32_TYPE,
   TI_UINT64_TYPE,
@@ -3569,12 +3571,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 intPI_type_node			global_trees[TI_INTPI_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_intPI_type_node	global_trees[TI_UINTPI_TYPE]
 
 #define uint32_type_node		global_trees[TI_UINT32_TYPE]
 #define uint64_type_node		global_trees[TI_UINT64_TYPE]
Index: gcc/ginclude/stdint-gcc.h
===================================================================
--- gcc/ginclude/stdint-gcc.h	(revision 325327)
+++ gcc/ginclude/stdint-gcc.h	(working copy)
@@ -39,6 +39,9 @@ typedef __INT16_TYPE__ int16_t;
 #ifdef __INT32_TYPE__
 typedef __INT32_TYPE__ int32_t;
 #endif
+#ifdef __INT40_TYPE__
+typedef __INT40_TYPE__ int40_t;
+#endif
 #ifdef __INT64_TYPE__
 typedef __INT64_TYPE__ int64_t;
 #endif
@@ -51,6 +54,9 @@ typedef __UINT16_TYPE__ uint16_t;
 #ifdef __UINT32_TYPE__
 typedef __UINT32_TYPE__ uint32_t;
 #endif
+#ifdef __UINT40_TYPE__
+typedef __UINT40_TYPE__ uint40_t;
+#endif
 #ifdef __UINT64_TYPE__
 typedef __UINT64_TYPE__ uint64_t;
 #endif
@@ -66,6 +72,14 @@ typedef __UINT_LEAST16_TYPE__ uint_least
 typedef __UINT_LEAST32_TYPE__ uint_least32_t;
 typedef __UINT_LEAST64_TYPE__ uint_least64_t;
 
+
+#ifdef __INT_LEAST40_TYPE__
+typedef __INT_LEAST40_TYPE__ int_least40_t;
+#endif
+#ifdef __UINT_LEAST40_TYPE__
+typedef __UINT_LEAST40_TYPE__ uint_least40_t;
+#endif
+
 /* 7.8.1.3 Fastest minimum-width integer types */
 
 typedef __INT_FAST8_TYPE__ int_fast8_t;
@@ -77,6 +91,13 @@ typedef __UINT_FAST16_TYPE__ uint_fast16
 typedef __UINT_FAST32_TYPE__ uint_fast32_t;
 typedef __UINT_FAST64_TYPE__ uint_fast64_t;
 
+#ifdef __INT_FAST40_TYPE__
+typedef __INT_FAST40_TYPE__ int_fast40_t;
+#endif
+#ifdef __UINT_FAST40_TYPE__
+typedef __UINT_FAST40_TYPE__ uint_fast40_t;
+#endif
+
 /* 7.8.1.4 Integer types capable of holding object pointers */
 
 #ifdef __INTPTR_TYPE__
@@ -125,6 +146,16 @@ typedef __UINTMAX_TYPE__ uintmax_t;
 # undef UINT32_MAX
 # define UINT32_MAX __UINT32_MAX__
 #endif
+#ifdef __INT40_MAX__
+# undef INT40_MAX
+# define INT40_MAX __INT40_MAX__
+# undef INT40_MIN
+# define INT40_MIN (-INT40_MAX - 1)
+#endif
+#ifdef __UINT40_MAX__
+# undef UINT40_MAX
+# define UINT40_MAX __UINT40_MAX__
+#endif
 #ifdef __INT64_MAX__
 # undef INT64_MAX
 # define INT64_MAX __INT64_MAX__
@@ -154,6 +185,16 @@ typedef __UINTMAX_TYPE__ uintmax_t;
 #define INT_LEAST32_MIN (-INT_LEAST32_MAX - 1)
 #undef UINT_LEAST32_MAX
 #define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
+#ifdef __INT40_TYPE__
+#undef INT_LEAST40_MAX
+#define INT_LEAST40_MAX __INT40_MAX__
+#undef INT_LEAST40_MIN
+#define INT_LEAST40_MIN (-INT40_MAX - 1)
+#endif
+#ifdef __UINT40_TYPE__
+#undef UINT_LEAST40_MAX
+#define UINT_LEAST40_MAX __UINT40_MAX__
+#endif
 #undef INT_LEAST64_MAX
 #define INT_LEAST64_MAX __INT_LEAST64_MAX__
 #undef INT_LEAST64_MIN
@@ -179,6 +220,16 @@ typedef __UINTMAX_TYPE__ uintmax_t;
 #define INT_FAST32_MIN (-INT_FAST32_MAX - 1)
 #undef UINT_FAST32_MAX
 #define UINT_FAST32_MAX __UINT_FAST32_MAX__
+#ifdef __INT40_TYPE__
+#undef INT_FAST40_MAX
+#define INT_FAST40_MAX __INT40_MAX__
+#undef INT_FAST40_MIN
+#define INT_FAST40_MIN (-INT40_MAX - 1)
+#endif
+#ifdef __UINT40_TYPE__
+#undef UINT_FAST40_MAX
+#define UINT_FAST40_MAX __UINT40_MAX__
+#endif
 #undef INT_FAST64_MAX
 #define INT_FAST64_MAX __INT_FAST64_MAX__
 #undef INT_FAST64_MIN
@@ -239,6 +290,10 @@ typedef __UINTMAX_TYPE__ uintmax_t;
 #define INT16_C(c) __INT16_C(c)
 #undef INT32_C
 #define INT32_C(c) __INT32_C(c)
+#undef INT40_C
+#ifdef __INT40_TYPE__
+#define INT40_C(c) __INT40_C(c)
+#endif
 #undef INT64_C
 #define INT64_C(c) __INT64_C(c)
 #undef UINT8_C
@@ -247,6 +302,10 @@ typedef __UINTMAX_TYPE__ uintmax_t;
 #define UINT16_C(c) __UINT16_C(c)
 #undef UINT32_C
 #define UINT32_C(c) __UINT32_C(c)
+#undef UINT40_C
+#ifdef __UINT40_TYPE__
+#define UINT40_C(c) __UINT40_C(c)
+#endif
 #undef UINT64_C
 #define UINT64_C(c) __UINT64_C(c)
 #undef INTMAX_C
Index: gcc/c-family/c-cppbuiltin.c
===================================================================
--- gcc/c-family/c-cppbuiltin.c	(revision 325327)
+++ gcc/c-family/c-cppbuiltin.c	(working copy)
@@ -413,6 +413,8 @@ builtin_define_stdint_macros (void)
     builtin_define_type_max ("__INT16_MAX__", int16_type_node);
   if (int32_type_node)
     builtin_define_type_max ("__INT32_MAX__", int32_type_node);
+  if (int40_type_node)
+    builtin_define_type_max ("__INT40_MAX__", int40_type_node);
   if (int64_type_node)
     builtin_define_type_max ("__INT64_MAX__", int64_type_node);
   if (uint8_type_node)
@@ -421,6 +423,8 @@ builtin_define_stdint_macros (void)
     builtin_define_type_max ("__UINT16_MAX__", uint16_type_node);
   if (c_uint32_type_node)
     builtin_define_type_max ("__UINT32_MAX__", c_uint32_type_node);
+  if (uint40_type_node)
+    builtin_define_type_max ("__UINT40_MAX__", uint40_type_node);
   if (c_uint64_type_node)
     builtin_define_type_max ("__UINT64_MAX__", c_uint64_type_node);
   if (int_least8_type_node)
@@ -438,6 +442,11 @@ builtin_define_stdint_macros (void)
       builtin_define_type_max ("__INT_LEAST32_MAX__", int_least32_type_node);
       builtin_define_constants ("__INT32_C", int_least32_type_node);
     }
+  if (int_least40_type_node)
+    {
+      builtin_define_type_max ("__INT_LEAST40_MAX__", int_least40_type_node);
+      builtin_define_constants ("__INT40_C", int_least40_type_node);
+    }
   if (int_least64_type_node)
     {
       builtin_define_type_max ("__INT_LEAST64_MAX__", int_least64_type_node);
@@ -458,6 +467,11 @@ builtin_define_stdint_macros (void)
       builtin_define_type_max ("__UINT_LEAST32_MAX__", uint_least32_type_node);
       builtin_define_constants ("__UINT32_C", uint_least32_type_node);
     }
+  if (uint_least40_type_node)
+    {
+      builtin_define_type_max ("__UINT_LEAST40_MAX__", uint_least40_type_node);
+      builtin_define_constants ("__UINT40_C", uint_least40_type_node);
+    }
   if (uint_least64_type_node)
     {
       builtin_define_type_max ("__UINT_LEAST64_MAX__", uint_least64_type_node);
@@ -469,6 +483,8 @@ builtin_define_stdint_macros (void)
     builtin_define_type_max ("__INT_FAST16_MAX__", int_fast16_type_node);
   if (int_fast32_type_node)
     builtin_define_type_max ("__INT_FAST32_MAX__", int_fast32_type_node);
+  if (int_fast40_type_node)
+    builtin_define_type_max ("__INT_FAST40_MAX__", int_fast40_type_node);
   if (int_fast64_type_node)
     builtin_define_type_max ("__INT_FAST64_MAX__", int_fast64_type_node);
   if (uint_fast8_type_node)
@@ -477,6 +493,8 @@ builtin_define_stdint_macros (void)
     builtin_define_type_max ("__UINT_FAST16_MAX__", uint_fast16_type_node);
   if (uint_fast32_type_node)
     builtin_define_type_max ("__UINT_FAST32_MAX__", uint_fast32_type_node);
+  if (uint_fast40_type_node)
+    builtin_define_type_max ("__UINT_FAST40_MAX__", uint_fast40_type_node);
   if (uint_fast64_type_node)
     builtin_define_type_max ("__UINT_FAST64_MAX__", uint_fast64_type_node);
   if (intptr_type_node)
@@ -976,6 +994,10 @@ type_suffix (tree type)
   int unsigned_suffix;
   int is_long;
 
+  if (type == intPI_type_node
+      || type == unsigned_intPI_type_node)
+    return NULL;
+
   if (type == long_long_integer_type_node
       || type == long_long_unsigned_type_node)
     is_long = 2;
@@ -1011,7 +1033,14 @@ builtin_define_constants (const char *ma
 
   suffix = type_suffix (type);
 
-  if (suffix[0] == 0)
+  if (suffix == NULL)
+    {
+      const char *name = type == intTI_type_node ? "__int40_t" : "__uint40_t";
+      buf = (char *) alloca (strlen (macro) + 2 + strlen (name)
+			     + 9 + 1);
+      sprintf (buf, "%s(c)=(%s)(c)", macro, name);
+    }
+  else if (suffix[0] == 0)
     {
       buf = (char *) alloca (strlen (macro) + 6);
       sprintf (buf, "%s(c)=c", macro);
@@ -1044,6 +1073,7 @@ builtin_define_type_minmax (const char *
     = { "127", "255",
 	"32767", "65535",
 	"2147483647", "4294967295",
+	"549755813887", "1099511627775",
 	"9223372036854775807", "18446744073709551615",
 	"170141183460469231731687303715884105727",
 	"340282366920938463463374607431768211455" };
@@ -1060,17 +1090,27 @@ builtin_define_type_minmax (const char *
     case 8:	idx = 0; break;
     case 16:	idx = 2; break;
     case 32:	idx = 4; break;
-    case 64:	idx = 6; break;
-    case 128:	idx = 8; break;
+    case 40:	idx = 6; break;
+    case 64:	idx = 8; break;
+    case 128:	idx = 10; break;
     default:    gcc_unreachable ();
     }
 
   value = values[idx + TYPE_UNSIGNED (type)];
   suffix = type_suffix (type);
 
-  buf = (char *) alloca (strlen (max_macro) + 1 + strlen (value)
-                         + strlen (suffix) + 1);
-  sprintf (buf, "%s=%s%s", max_macro, value, suffix);
+  if (suffix != NULL)
+    {
+      buf = (char *) alloca (strlen (max_macro) + 1 + strlen (value)
+			     + strlen (suffix) + 1);
+      sprintf (buf, "%s=%s%s", max_macro, value, suffix);
+    }
+  else
+    {
+      buf = (char *) alloca (strlen (max_macro) + 10 + 3 + strlen (value) + 1);
+      sprintf (buf, "%s=__INT%d_C(%s)", max_macro, TYPE_PRECISION (type),
+	       value);
+    }
 
   cpp_define (parse_in, buf);
 
@@ -1078,8 +1118,18 @@ builtin_define_type_minmax (const char *
     {
       if (TYPE_UNSIGNED (type))
 	{
-	  buf = (char *) alloca (strlen (min_macro) + 2 + strlen (suffix) + 1);
-	  sprintf (buf, "%s=0%s", min_macro, suffix);
+	  if (suffix != NULL)
+	    {
+	      buf = (char *) alloca (strlen (min_macro) + 2 + strlen (suffix)
+				     + 1);
+	      sprintf (buf, "%s=0%s", min_macro, suffix);
+	    }
+	  else
+	    {
+	      buf = (char *) alloca (strlen (min_macro) + 12 + 3 + 1);
+	      sprintf (buf, "%s=__UINT%d_C(0)", min_macro,
+		       TYPE_PRECISION (type));
+	    }
 	}
       else
 	{
Index: gcc/testsuite/gcc.dg/c99-stdint-3.c
===================================================================
--- gcc/testsuite/gcc.dg/c99-stdint-3.c	(revision 325327)
+++ gcc/testsuite/gcc.dg/c99-stdint-3.c	(working copy)
@@ -21,16 +21,25 @@ check_corresponding (void)
 #if defined(INT32_MAX) && defined(UINT32_MAX)
   CHECK_CORRESPONDING(int32_t, uint32_t);
 #endif
+#if defined(INT40_MAX) && defined(UINT40_MAX)
+  CHECK_CORRESPONDING(int40_t, uint40_t);
+#endif
 #if defined(INT64_MAX) && defined(UINT64_MAX)
   CHECK_CORRESPONDING(int64_t, uint64_t);
 #endif
   CHECK_CORRESPONDING(int_least8_t, uint_least8_t);
   CHECK_CORRESPONDING(int_least16_t, uint_least16_t);
   CHECK_CORRESPONDING(int_least32_t, uint_least32_t);
+#if defined(INT40_MAX) && defined(UINT40_MAX)
+  CHECK_CORRESPONDING(int_least40_t, uint_least40_t);
+#endif
   CHECK_CORRESPONDING(int_least64_t, uint_least64_t);
   CHECK_CORRESPONDING(int_fast8_t, uint_fast8_t);
   CHECK_CORRESPONDING(int_fast16_t, uint_fast16_t);
   CHECK_CORRESPONDING(int_fast32_t, uint_fast32_t);
+#if defined(INT40_MAX) && defined(UINT40_MAX)
+  CHECK_CORRESPONDING(int_fast40_t, uint_fast40_t);
+#endif
   CHECK_CORRESPONDING(int_fast64_t, uint_fast64_t);
 #if defined(INTPTR_MAX) && defined(UINTPTR_MAX)
   CHECK_CORRESPONDING(intptr_t, uintptr_t);
Index: gcc/testsuite/gcc.dg/c99-stdint-7.c
===================================================================
--- gcc/testsuite/gcc.dg/c99-stdint-7.c	(revision 325327)
+++ gcc/testsuite/gcc.dg/c99-stdint-7.c	(working copy)
@@ -34,6 +34,7 @@
 #if defined(UINT32_MAX) != defined(__UINT32_TYPE__)
 #error "Unexpected UINT32_MAX definedness"
 #endif
+/* 40 bit macros are known not to be usable in this way.  */
 #if defined(INT64_MIN) != defined(__INT64_TYPE__)
 #error "Unexpected INT64_MIN definedness"
 #endif
@@ -80,6 +81,7 @@
 #if defined(UINT32_MAX) && UINT32_MAX != __UINT32_MAX__
 #error "UINT32_MAX not usable in #if or wrong value"
 #endif
+/* 40 bit macros are known not to be usable in this way.  */
 #if defined(INT64_MIN) && INT64_MIN != -__INT64_MAX__-1
 #error "INT64_MIN not usable in #if or wrong value"
 #endif
@@ -117,6 +119,7 @@
 #if UINT_LEAST32_MAX != __UINT_LEAST32_MAX__
 #error "UINT_LEAST32_MAX not usable in #if or wrong value"
 #endif
+/* 40 bit macros are known not to be usable in this way.  */
 #if INT_LEAST64_MIN != -__INT_LEAST64_MAX__-1
 #error "INT_LEAST64_MIN not usable in #if or wrong value"
 #endif
@@ -154,6 +157,7 @@
 #if UINT_FAST32_MAX != __UINT_FAST32_MAX__
 #error "UINT_FAST32_MAX not usable in #if or wrong value"
 #endif
+/* 40 bit macros are known not to be usable in this way.  */
 #if INT_FAST64_MIN != -__INT_FAST64_MAX__-1
 #error "INT_FAST64_MIN not usable in #if or wrong value"
 #endif
Index: gcc/testsuite/gcc.dg/shift-pi.c
===================================================================
--- gcc/testsuite/gcc.dg/shift-pi.c	(revision 0)
+++ gcc/testsuite/gcc.dg/shift-pi.c	(revision 0)
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target int40 } */
+/* { dg-options "-std=gnu89" } */
+
+__int40_t a;
+__uint40_t b;
+
+void foo ()
+{
+  a <<= 39; /* { dg-bogus "shift count" } */
+  a <<= 40; /* { dg-warning "shift count" } */
+  a >>= 39; /* { dg-bogus "shift count" } */
+  a >>= 40; /* { dg-warning "shift count" } */
+  b <<= 39; /* { dg-bogus "shift count" } */
+  b <<= 40; /* { dg-warning "shift count" } */
+  b >>= 39; /* { dg-bogus "shift count" } */
+  b >>= 40; /* { dg-warning "shift count" } */
+}
Index: gcc/testsuite/gcc.dg/c99-stdint-1.c
===================================================================
--- gcc/testsuite/gcc.dg/c99-stdint-1.c	(revision 325327)
+++ gcc/testsuite/gcc.dg/c99-stdint-1.c	(working copy)
@@ -99,6 +99,10 @@ test_exact (void)
 #else
   CHECK_WIDTH_AT_LEAST(int_least32_t, 33);
 #endif
+#ifdef INT40_MIN
+  CHECK_WIDTH_EQUALS(int40_t, 40);
+  CHECK_SIGNED_LIMITS(int40_t, INT40_MIN, INT40_MAX);
+#endif
 #ifdef INT64_MIN
   CHECK_WIDTH_EQUALS(int64_t, 64);
   CHECK_SIGNED_LIMITS(int64_t, INT64_MIN, INT64_MAX);
@@ -123,6 +127,10 @@ test_exact (void)
 #else
   CHECK_WIDTH_AT_LEAST(uint_least32_t, 33);
 #endif
+#ifdef UINT40_MAX
+  CHECK_WIDTH_EQUALS(uint40_t, 40);
+  CHECK_UNSIGNED_LIMITS(uint40_t, UINT40_MAX);
+#endif
 #ifdef UINT64_MAX
   CHECK_WIDTH_EQUALS(uint64_t, 64);
   CHECK_UNSIGNED_LIMITS(uint64_t, UINT64_MAX);
@@ -143,6 +151,11 @@ test_least (void)
   CHECK_WIDTH_AT_LEAST(int_least32_t, 32);
   CHECK_WIDTH_ORDER(int_least32_t, int_fast32_t);
   CHECK_SIGNED_LIMITS(int_least32_t, INT_LEAST32_MIN, INT_LEAST32_MAX);
+#ifdef INT40_MIN
+  CHECK_WIDTH_AT_LEAST(int_least40_t, 40);
+  CHECK_WIDTH_ORDER(int_least40_t, int_fast40_t);
+  CHECK_SIGNED_LIMITS(int_least40_t, INT_LEAST40_MIN, INT_LEAST40_MAX);
+#endif
   CHECK_WIDTH_AT_LEAST(int_least64_t, 64);
   CHECK_WIDTH_ORDER(int_least64_t, int_fast64_t);
   CHECK_SIGNED_LIMITS(int_least64_t, INT_LEAST64_MIN, INT_LEAST64_MAX);
@@ -155,6 +168,11 @@ test_least (void)
   CHECK_WIDTH_AT_LEAST(uint_least32_t, 32);
   CHECK_WIDTH_ORDER(uint_least32_t, uint_fast32_t);
   CHECK_UNSIGNED_LIMITS(uint_least32_t, UINT_LEAST32_MAX);
+#ifdef INT40_MIN
+  CHECK_WIDTH_AT_LEAST(uint_least40_t, 40);
+  CHECK_WIDTH_ORDER(uint_least40_t, uint_fast40_t);
+  CHECK_UNSIGNED_LIMITS(uint_least40_t, UINT_LEAST40_MAX);
+#endif
   CHECK_WIDTH_AT_LEAST(uint_least64_t, 64);
   CHECK_WIDTH_ORDER(uint_least64_t, uint_fast64_t);
   CHECK_UNSIGNED_LIMITS(uint_least64_t, UINT_LEAST64_MAX);
@@ -169,6 +187,10 @@ test_fast (void)
   CHECK_SIGNED_LIMITS(int_fast16_t, INT_FAST16_MIN, INT_FAST16_MAX);
   CHECK_WIDTH_AT_LEAST(int_fast32_t, 32);
   CHECK_SIGNED_LIMITS(int_fast32_t, INT_FAST32_MIN, INT_FAST32_MAX);
+#ifdef INT40_MIN
+  CHECK_WIDTH_AT_LEAST(int_fast40_t, 40);
+  CHECK_SIGNED_LIMITS(int_fast40_t, INT_FAST40_MIN, INT_FAST40_MAX);
+#endif
   CHECK_WIDTH_AT_LEAST(int_fast64_t, 64);
   CHECK_SIGNED_LIMITS(int_fast64_t, INT_FAST64_MIN, INT_FAST64_MAX);
   CHECK_WIDTH_AT_LEAST(uint_fast8_t, 8);
@@ -177,6 +199,10 @@ test_fast (void)
   CHECK_UNSIGNED_LIMITS(uint_fast16_t, UINT_FAST16_MAX);
   CHECK_WIDTH_AT_LEAST(uint_fast32_t, 32);
   CHECK_UNSIGNED_LIMITS(uint_fast32_t, UINT_FAST32_MAX);
+#ifdef UINT40_MIN
+  CHECK_WIDTH_AT_LEAST(uint_fast40_t, 40);
+  CHECK_UNSIGNED_LIMITS(uint_fast40_t, UINT_FAST40_MAX);
+#endif
   CHECK_WIDTH_AT_LEAST(uint_fast64_t, 64);
   CHECK_UNSIGNED_LIMITS(uint_fast64_t, UINT_FAST64_MAX);
 }
@@ -200,6 +226,9 @@ test_max (void)
   CHECK_WIDTH_ORDER(int_fast8_t, intmax_t);
   CHECK_WIDTH_ORDER(int_fast16_t, intmax_t);
   CHECK_WIDTH_ORDER(int_fast32_t, intmax_t);
+#ifdef INT40_MIN
+  CHECK_WIDTH_ORDER(int_fast40_t, intmax_t);
+#endif
   CHECK_WIDTH_ORDER(int_fast64_t, intmax_t);
   CHECK_SIGNED_LIMITS(intmax_t, INTMAX_MIN, INTMAX_MAX);
   CHECK_WIDTH_AT_LEAST(uintmax_t, 64);
@@ -207,6 +236,9 @@ test_max (void)
   CHECK_WIDTH_ORDER(uint_fast8_t, uintmax_t);
   CHECK_WIDTH_ORDER(uint_fast16_t, uintmax_t);
   CHECK_WIDTH_ORDER(uint_fast32_t, uintmax_t);
+#ifdef UINT40_MIN
+  CHECK_WIDTH_ORDER(uint_fast40_t, intmax_t);
+#endif
   CHECK_WIDTH_ORDER(uint_fast64_t, uintmax_t);
   CHECK_UNSIGNED_LIMITS(uintmax_t, UINTMAX_MAX);
 }
@@ -230,11 +262,17 @@ test_constants (void)
   CHECK_CONSTS(int_least8_t, INT8_C);
   CHECK_CONSTS(int_least16_t, INT16_C);
   CHECK_CONSTS(int_least32_t, INT32_C);
+#ifdef INT40_MIN
+  CHECK_CONSTS(int_least40_t, INT40_C);
+#endif
   CHECK_CONSTS(int_least64_t, INT64_C);
   CHECK_CONSTS(intmax_t, INTMAX_C);
   CHECK_CONSTS(uint_least8_t, UINT8_C);
   CHECK_CONSTS(uint_least16_t, UINT16_C);
   CHECK_CONSTS(uint_least32_t, UINT32_C);
+#ifdef UINT40_MIN
+  CHECK_CONSTS(uint_least40_t, UINT40_C);
+#endif
   CHECK_CONSTS(uint_least64_t, UINT64_C);
   CHECK_CONSTS(uintmax_t, UINTMAX_C);
 #if INT8_C(12) != 12
@@ -246,6 +284,7 @@ test_constants (void)
 #if INT32_C(12) != 12
 #error "INT32_C not usable in #if"
 #endif
+  /* INT40_C is known not to be usable in #if.  */
 #if INT64_C(12) != 12
 #error "INT64_C not usable in #if"
 #endif
@@ -261,6 +300,7 @@ test_constants (void)
 #if UINT32_C(12) != 12
 #error "UINT32_C not usable in #if"
 #endif
+  /* UINT40_C is known not to be usable in #if.  */
 #if UINT64_C(12) != 12
 #error "UINT64_C not usable in #if"
 #endif
Index: gcc/testsuite/gcc.dg/torture/arith-rand-40.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/arith-rand-40.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/arith-rand-40.c	(revision 0)
@@ -0,0 +1,74 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int40 } */
+
+#include <stdlib.h>
+
+long
+simple_rand ()
+{
+  static __uint40_t seed = 47114711;
+  __uint40_t this = seed * 1103515245 + 12345;
+  seed = this;
+  return this >> 8;
+}
+
+__uint40_t
+random_bitstring ()
+{
+  __uint40_t x;
+  int n_bits;
+  long ran;
+  int tot_bits = 0;
+
+  x = 0;
+  for (;;)
+    {
+      ran = simple_rand ();
+      n_bits = (ran >> 1) % 16;
+      tot_bits += n_bits;
+
+      if (n_bits == 0)
+	return x;
+      else
+	{
+	  x <<= n_bits;
+	  if (ran & 1)
+	    x |= (1 << n_bits) - 1;
+
+	  if (tot_bits > 8 * sizeof (long) + 6)
+	    return x;
+	}
+    }
+}
+
+#define ABS(x) ((x) >= 0 ? (x) : -(x))
+
+main ()
+{
+  long int i;
+
+  for (i = 0; i < 1000; i++)
+    {
+      __uint40_t x, y;
+      x = random_bitstring ();
+      y = random_bitstring ();
+
+      { __uint40_t xx = x, yy = y, r1, r2;
+	if (yy == 0) continue;
+	r1 = xx / yy;
+	r2 = xx % yy;
+	if (r2 >= yy || r1 * yy + r2 != xx)
+	  abort ();
+      }
+      { __int40_t xx = x, yy = y, r1, r2;
+	if ((__uint40_t) xx << 1 == 0 && yy == -1)
+	  continue;
+	r1 = xx / yy;
+	r2 = xx % yy;
+	if (ABS (r2) >= (__uint40_t) ABS (yy) || (__int40_t) (r1 * yy + r2) != xx)
+	  abort ();
+      }
+    }
+
+  exit (0);
+}
Index: gcc/testsuite/gcc.dg/torture/arith40.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/arith40.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/arith40.c	(revision 0)
@@ -0,0 +1,207 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target int40 } */
+__int40_t add (__int40_t a, __int40_t b)
+{
+  return a + b;
+}
+__int40_t sub (__int40_t a, __int40_t b)
+{
+  return a - b;
+}
+__int40_t mul (__int40_t a, __int40_t b)
+{
+  return a * b;
+}
+__int40_t div (__int40_t a, __int40_t b)
+{
+  return a / b;
+}
+__int40_t mod (__int40_t a, __int40_t b)
+{
+  return a % b;
+}
+
+int lt (__int40_t a, __int40_t b)
+{
+  return a < b;
+}
+int le (__int40_t a, __int40_t b)
+{
+  return a <= b;
+}
+int gt (__int40_t a, __int40_t b)
+{
+  return a > b;
+}
+int ge (__int40_t a, __int40_t b)
+{
+  return a >= b;
+}
+int eq (__int40_t a, __int40_t b)
+{
+  return a == b;
+}
+int ne (__int40_t a, __int40_t b)
+{
+  return a != b;
+}
+
+__int40_t ext_int (int a)
+{
+  return (__int40_t)a;
+}
+long long ext_ll (__int40_t a)
+{
+  return (long long)a;
+}
+float conv_float (__int40_t a)
+{
+  return (float)a;
+}
+double conv_double (__int40_t a)
+{
+  return (double)a;
+}
+__int40_t fix_float (float a)
+{
+  return (__int40_t)a;
+}
+__int40_t fix_double (double a)
+{
+  return (__int40_t)a;
+}
+
+__int40_t abs40 (__int40_t a)
+{
+  return a < 0 ? -a : a;
+}
+__int40_t neg (__int40_t a)
+{
+  return -a;
+}
+__int40_t not (__int40_t a)
+{
+  return ~a;
+}
+
+__int40_t shl (__int40_t a, int b)
+{
+  return a << b;
+}
+__int40_t shr (__int40_t a, int b)
+{
+  return a >> b;
+}
+
+__int40_t rotr8 (__int40_t a)
+{
+  return ((a >> 8) & 0xffffffff) | (a << 32);
+}
+__int40_t rotl8 (__int40_t a)
+{
+  return (a << 8) | ((a >> 32) & 0xff);
+}
+
+
+__uint40_t uadd (__uint40_t a, __uint40_t b)
+{
+  return a + b;
+}
+__uint40_t usub (__uint40_t a, __uint40_t b)
+{
+  return a - b;
+}
+__uint40_t umul (__uint40_t a, __uint40_t b)
+{
+  return a * b;
+}
+__uint40_t udiv (__uint40_t a, __uint40_t b)
+{
+  return a / b;
+}
+__uint40_t umod (__uint40_t a, __uint40_t b)
+{
+  return a % b;
+}
+
+int ult (__uint40_t a, __uint40_t b)
+{
+  return a < b;
+}
+int ule (__uint40_t a, __uint40_t b)
+{
+  return a <= b;
+}
+int ugt (__uint40_t a, __uint40_t b)
+{
+  return a > b;
+}
+int uge (__uint40_t a, __uint40_t b)
+{
+  return a >= b;
+}
+int ueq (__uint40_t a, __uint40_t b)
+{
+  return a == b;
+}
+int une (__uint40_t a, __uint40_t b)
+{
+  return a != b;
+}
+
+__uint40_t uext_int (int a)
+{
+  return (__uint40_t)a;
+}
+long long uext_ll (__uint40_t a)
+{
+  return (long long)a;
+}
+float uconv_float (__uint40_t a)
+{
+  return (float)a;
+}
+double uconv_double (__uint40_t a)
+{
+  return (double)a;
+}
+__uint40_t ufix_float (float a)
+{
+  return (__uint40_t)a;
+}
+__uint40_t ufix_double (double a)
+{
+  return (__uint40_t)a;
+}
+
+__uint40_t uabs (__uint40_t a)
+{
+  return a < 0 ? -a : a;
+}
+__uint40_t uneg (__uint40_t a)
+{
+  return -a;
+}
+__uint40_t unot (__uint40_t a)
+{
+  return ~a;
+}
+
+__uint40_t ushl (__uint40_t a, int b)
+{
+  return a << b;
+}
+__uint40_t ushr (__uint40_t a, int b)
+{
+  return a >> b;
+}
+
+__uint40_t urotr8 (__uint40_t a)
+{
+  return (a >> 8) | (a << 32);
+}
+__uint40_t urotl8 (__uint40_t a)
+{
+  return (a << 8) | (a >> 32);
+}
+
Index: gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc/testsuite/lib/target-supports.exp	(revision 325327)
+++ gcc/testsuite/lib/target-supports.exp	(working copy)
@@ -1449,6 +1449,15 @@ proc check_effective_target_dfprt { } {
     }]
 }
 
+# Return 1 if the target supports 40-bit integers as __int40_t,
+# 0 otherwise.
+
+proc check_effective_target_int40 { } {
+    return [check_no_compiler_messages in40 object {
+        __int40_t x; __uint40_t y;
+    }]
+}
+
 # Return 1 if the target supports compiling and assembling UCN, 0 otherwise.
 
 proc check_effective_target_ucn_nocache { } {
Index: gcc/machmode.def
===================================================================
--- gcc/machmode.def	(revision 325327)
+++ gcc/machmode.def	(working copy)
@@ -184,6 +184,10 @@ INT_MODE (SI, 4);
 INT_MODE (DI, 8);
 INT_MODE (TI, 16);
 
+/* A mode used for int40_t on machines that support operations on such a
+   type.  */
+FRACTIONAL_INT_MODE (PI, 40, 8);
+
 /* No partial integer modes are defined by default.  */
 
 /* Basic floating point modes.  SF and DF are the only modes provided
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	(revision 325327)
+++ gcc/varasm.c	(working copy)
@@ -2753,12 +2753,12 @@ assemble_integer (rtx x, unsigned int si
      it into words it if is multi-word, otherwise split it into bytes.  */
   if (size > 1)
     {
-      enum machine_mode omode, imode;
+      enum machine_mode omode, imode, hmode;
       unsigned int subalign;
       unsigned int subsize, i;
       enum mode_class mclass;
 
-      subsize = size > UNITS_PER_WORD? UNITS_PER_WORD : 1;
+      subsize = size > UNITS_PER_WORD ? UNITS_PER_WORD : 1;
       subalign = MIN (align, subsize * BITS_PER_UNIT);
       if (GET_CODE (x) == CONST_FIXED)
 	mclass = GET_MODE_CLASS (GET_MODE (x));
@@ -2767,19 +2767,29 @@ assemble_integer (rtx x, unsigned int si
 
       omode = mode_for_size (subsize * BITS_PER_UNIT, mclass, 0);
       imode = mode_for_size (size * BITS_PER_UNIT, mclass, 0);
+      hmode = omode;
+      if (size > UNITS_PER_WORD && size % subsize != 0)
+	hmode = mode_for_size ((size % subsize) * BITS_PER_UNIT, mclass, 0);
 
       for (i = 0; i < size; i += subsize)
 	{
-	  rtx partial = simplify_subreg (omode, x, imode, i);
-	  if (!partial || !assemble_integer (partial, subsize, subalign, 0))
-	    break;
-	}
-      if (i == size)
-	return true;
+	  enum machine_mode this_mode;
+	  rtx partial;
 
-      /* If we've printed some of it, but not all of it, there's no going
-	 back now.  */
-      gcc_assert (!i);
+	  this_mode = omode;
+	  if (size > UNITS_PER_WORD
+	      && ((i == 0 && WORDS_BIG_ENDIAN)
+		  || (i + subsize >= size && !WORDS_BIG_ENDIAN)))
+	    {
+	      this_mode = hmode;
+	    }
+	  partial = simplify_subreg (this_mode, x, imode, i);
+	  gcc_assert (partial);
+	  if (!assemble_integer (partial, GET_MODE_SIZE (this_mode),
+				 subalign, 0))
+	    gcc_unreachable ();
+	}
+      return true;
     }
 
   gcc_assert (!force);
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 325327)
+++ gcc/c-family/c-common.c	(working copy)
@@ -2832,6 +2832,8 @@ check_case_bounds (tree type, tree orig_
 tree
 c_common_type_for_size (unsigned int bits, int unsignedp)
 {
+  tree retval;
+
   if (bits == TYPE_PRECISION (integer_type_node))
     return unsignedp ? unsigned_type_node : integer_type_node;
 
@@ -2853,18 +2855,23 @@ c_common_type_for_size (unsigned int bit
 	    : widest_integer_literal_type_node);
 
   if (bits <= TYPE_PRECISION (intQI_type_node))
-    return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
+    retval = unsignedp ? unsigned_intQI_type_node : intQI_type_node;
 
-  if (bits <= TYPE_PRECISION (intHI_type_node))
-    return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
+  else if (bits <= TYPE_PRECISION (intHI_type_node))
+    retval = unsignedp ? unsigned_intHI_type_node : intHI_type_node;
 
-  if (bits <= TYPE_PRECISION (intSI_type_node))
-    return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
+  else if (bits <= TYPE_PRECISION (intSI_type_node))
+    retval = unsignedp ? unsigned_intSI_type_node : intSI_type_node;
 
-  if (bits <= TYPE_PRECISION (intDI_type_node))
-    return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
+  else if (bits <= TYPE_PRECISION (intDI_type_node))
+    retval = unsignedp ? unsigned_intDI_type_node : intDI_type_node;
 
-  return 0;
+  if (targetm.scalar_mode_supported_p (PImode)
+      && bits <= TYPE_PRECISION (intPI_type_node)
+      && TYPE_PRECISION (intPI_type_node) <= TYPE_PRECISION (retval))
+    return unsignedp ? unsigned_intPI_type_node : intPI_type_node;
+
+  return retval;
 }
 
 /* Return a fixed-point type that has at least IBIT ibits and FBIT fbits
@@ -2942,6 +2949,9 @@ c_common_type_for_mode (enum machine_mod
   if (mode == DImode)
     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
 
+  if (mode == PImode)
+    return unsignedp ? unsigned_intPI_type_node : intPI_type_node;
+  
 #if HOST_BITS_PER_WIDE_INT >= 64
   if (mode == TYPE_MODE (intTI_type_node))
     return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
@@ -3145,6 +3155,8 @@ c_common_signed_or_unsigned_type (int un
   if (type1 == intTI_type_node || type1 == unsigned_intTI_type_node)
     return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
 #endif
+  if (type1 == intPI_type_node || type1 == unsigned_intPI_type_node)
+    return unsignedp ? unsigned_intPI_type_node : intPI_type_node;
   if (type1 == intDI_type_node || type1 == unsigned_intDI_type_node)
     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
   if (type1 == intSI_type_node || type1 == unsigned_intSI_type_node)
@@ -4700,6 +4712,11 @@ c_common_nodes_and_builtins (void)
   lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
 					 TYPE_DECL, NULL_TREE,
 					 intDI_type_node));
+  if (targetm.scalar_mode_supported_p (PImode))
+    lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+					   TYPE_DECL,
+					   get_identifier ("__int40_t"),
+					   intPI_type_node));
 #if HOST_BITS_PER_WIDE_INT >= 64
   if (targetm.scalar_mode_supported_p (TImode))
     lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
@@ -4719,6 +4736,11 @@ c_common_nodes_and_builtins (void)
   lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
 					 TYPE_DECL, NULL_TREE,
 					 unsigned_intDI_type_node));
+  if (targetm.scalar_mode_supported_p (PImode))
+    lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+					   TYPE_DECL,
+					   get_identifier ("__uint40_t"),
+					   unsigned_intPI_type_node));
 #if HOST_BITS_PER_WIDE_INT >= 64
   if (targetm.scalar_mode_supported_p (TImode))
     lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
@@ -4985,6 +5007,9 @@ c_common_nodes_and_builtins (void)
   if (INT_LEAST32_TYPE)
     int_least32_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (INT_LEAST32_TYPE)));
+  if (INT_LEAST40_TYPE)
+    int_least40_type_node =
+      TREE_TYPE (identifier_global_value (c_get_ident (INT_LEAST40_TYPE)));
   if (INT_LEAST64_TYPE)
     int_least64_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (INT_LEAST64_TYPE)));
@@ -4997,6 +5022,9 @@ c_common_nodes_and_builtins (void)
   if (UINT_LEAST32_TYPE)
     uint_least32_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT_LEAST32_TYPE)));
+  if (UINT_LEAST40_TYPE)
+    uint_least40_type_node =
+      TREE_TYPE (identifier_global_value (c_get_ident (UINT_LEAST40_TYPE)));
   if (UINT_LEAST64_TYPE)
     uint_least64_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT_LEAST64_TYPE)));
@@ -5009,6 +5037,9 @@ c_common_nodes_and_builtins (void)
   if (INT_FAST32_TYPE)
     int_fast32_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (INT_FAST32_TYPE)));
+  if (INT_FAST40_TYPE)
+    int_fast40_type_node =
+      TREE_TYPE (identifier_global_value (c_get_ident (INT_FAST40_TYPE)));
   if (INT_FAST64_TYPE)
     int_fast64_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (INT_FAST64_TYPE)));
@@ -5021,6 +5052,9 @@ c_common_nodes_and_builtins (void)
   if (UINT_FAST32_TYPE)
     uint_fast32_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT_FAST32_TYPE)));
+  if (UINT_FAST40_TYPE)
+    uint_fast40_type_node =
+      TREE_TYPE (identifier_global_value (c_get_ident (UINT_FAST40_TYPE)));
   if (UINT_FAST64_TYPE)
     uint_fast64_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT_FAST64_TYPE)));
@@ -5717,6 +5751,8 @@ c_stddef_cpp_builtins(void)
     builtin_define_with_value ("__INT16_TYPE__", INT16_TYPE, 0);
   if (INT32_TYPE)
     builtin_define_with_value ("__INT32_TYPE__", INT32_TYPE, 0);
+  if (INT40_TYPE)
+    builtin_define_with_value ("__INT40_TYPE__", INT40_TYPE, 0);
   if (INT64_TYPE)
     builtin_define_with_value ("__INT64_TYPE__", INT64_TYPE, 0);
   if (UINT8_TYPE)
@@ -5725,6 +5761,8 @@ c_stddef_cpp_builtins(void)
     builtin_define_with_value ("__UINT16_TYPE__", UINT16_TYPE, 0);
   if (UINT32_TYPE)
     builtin_define_with_value ("__UINT32_TYPE__", UINT32_TYPE, 0);
+  if (UINT40_TYPE)
+    builtin_define_with_value ("__UINT40_TYPE__", UINT40_TYPE, 0);
   if (UINT64_TYPE)
     builtin_define_with_value ("__UINT64_TYPE__", UINT64_TYPE, 0);
   if (INT_LEAST8_TYPE)
@@ -5733,6 +5771,8 @@ c_stddef_cpp_builtins(void)
     builtin_define_with_value ("__INT_LEAST16_TYPE__", INT_LEAST16_TYPE, 0);
   if (INT_LEAST32_TYPE)
     builtin_define_with_value ("__INT_LEAST32_TYPE__", INT_LEAST32_TYPE, 0);
+  if (INT_LEAST40_TYPE)
+    builtin_define_with_value ("__INT_LEAST40_TYPE__", INT_LEAST40_TYPE, 0);
   if (INT_LEAST64_TYPE)
     builtin_define_with_value ("__INT_LEAST64_TYPE__", INT_LEAST64_TYPE, 0);
   if (UINT_LEAST8_TYPE)
@@ -5741,6 +5781,8 @@ c_stddef_cpp_builtins(void)
     builtin_define_with_value ("__UINT_LEAST16_TYPE__", UINT_LEAST16_TYPE, 0);
   if (UINT_LEAST32_TYPE)
     builtin_define_with_value ("__UINT_LEAST32_TYPE__", UINT_LEAST32_TYPE, 0);
+  if (UINT_LEAST40_TYPE)
+    builtin_define_with_value ("__UINT_LEAST40_TYPE__", UINT_LEAST40_TYPE, 0);
   if (UINT_LEAST64_TYPE)
     builtin_define_with_value ("__UINT_LEAST64_TYPE__", UINT_LEAST64_TYPE, 0);
   if (INT_FAST8_TYPE)
@@ -5749,6 +5791,8 @@ c_stddef_cpp_builtins(void)
     builtin_define_with_value ("__INT_FAST16_TYPE__", INT_FAST16_TYPE, 0);
   if (INT_FAST32_TYPE)
     builtin_define_with_value ("__INT_FAST32_TYPE__", INT_FAST32_TYPE, 0);
+  if (INT_FAST40_TYPE)
+    builtin_define_with_value ("__INT_FAST40_TYPE__", INT_FAST40_TYPE, 0);
   if (INT_FAST64_TYPE)
     builtin_define_with_value ("__INT_FAST64_TYPE__", INT_FAST64_TYPE, 0);
   if (UINT_FAST8_TYPE)
@@ -5757,6 +5801,8 @@ c_stddef_cpp_builtins(void)
     builtin_define_with_value ("__UINT_FAST16_TYPE__", UINT_FAST16_TYPE, 0);
   if (UINT_FAST32_TYPE)
     builtin_define_with_value ("__UINT_FAST32_TYPE__", UINT_FAST32_TYPE, 0);
+  if (UINT_FAST40_TYPE)
+    builtin_define_with_value ("__UINT_FAST40_TYPE__", UINT_FAST40_TYPE, 0);
   if (UINT_FAST64_TYPE)
     builtin_define_with_value ("__UINT_FAST64_TYPE__", UINT_FAST64_TYPE, 0);
   if (INTPTR_TYPE)
Index: gcc/c-family/c-common.h
===================================================================
--- gcc/c-family/c-common.h	(revision 325327)
+++ gcc/c-family/c-common.h	(working copy)
@@ -197,26 +197,32 @@ enum c_tree_index
     CTI_INT8_TYPE,
     CTI_INT16_TYPE,
     CTI_INT32_TYPE,
+    CTI_INT40_TYPE,
     CTI_INT64_TYPE,
     CTI_UINT8_TYPE,
     CTI_UINT16_TYPE,
     CTI_UINT32_TYPE,
+    CTI_UINT40_TYPE,
     CTI_UINT64_TYPE,
     CTI_INT_LEAST8_TYPE,
     CTI_INT_LEAST16_TYPE,
     CTI_INT_LEAST32_TYPE,
+    CTI_INT_LEAST40_TYPE,
     CTI_INT_LEAST64_TYPE,
     CTI_UINT_LEAST8_TYPE,
     CTI_UINT_LEAST16_TYPE,
     CTI_UINT_LEAST32_TYPE,
+    CTI_UINT_LEAST40_TYPE,
     CTI_UINT_LEAST64_TYPE,
     CTI_INT_FAST8_TYPE,
     CTI_INT_FAST16_TYPE,
     CTI_INT_FAST32_TYPE,
+    CTI_INT_FAST40_TYPE,
     CTI_INT_FAST64_TYPE,
     CTI_UINT_FAST8_TYPE,
     CTI_UINT_FAST16_TYPE,
     CTI_UINT_FAST32_TYPE,
+    CTI_UINT_FAST40_TYPE,
     CTI_UINT_FAST64_TYPE,
     CTI_INTPTR_TYPE,
     CTI_UINTPTR_TYPE,
@@ -313,26 +319,32 @@ extern const unsigned int num_c_common_r
 #define int8_type_node			c_global_trees[CTI_INT8_TYPE]
 #define int16_type_node			c_global_trees[CTI_INT16_TYPE]
 #define int32_type_node			c_global_trees[CTI_INT32_TYPE]
+#define int40_type_node			c_global_trees[CTI_INT40_TYPE]
 #define int64_type_node			c_global_trees[CTI_INT64_TYPE]
 #define uint8_type_node			c_global_trees[CTI_UINT8_TYPE]
 #define uint16_type_node		c_global_trees[CTI_UINT16_TYPE]
 #define c_uint32_type_node		c_global_trees[CTI_UINT32_TYPE]
+#define uint40_type_node		c_global_trees[CTI_UINT40_TYPE]
 #define c_uint64_type_node		c_global_trees[CTI_UINT64_TYPE]
 #define int_least8_type_node		c_global_trees[CTI_INT_LEAST8_TYPE]
 #define int_least16_type_node		c_global_trees[CTI_INT_LEAST16_TYPE]
 #define int_least32_type_node		c_global_trees[CTI_INT_LEAST32_TYPE]
+#define int_least40_type_node		c_global_trees[CTI_INT_LEAST40_TYPE]
 #define int_least64_type_node		c_global_trees[CTI_INT_LEAST64_TYPE]
 #define uint_least8_type_node		c_global_trees[CTI_UINT_LEAST8_TYPE]
 #define uint_least16_type_node		c_global_trees[CTI_UINT_LEAST16_TYPE]
 #define uint_least32_type_node		c_global_trees[CTI_UINT_LEAST32_TYPE]
+#define uint_least40_type_node		c_global_trees[CTI_UINT_LEAST40_TYPE]
 #define uint_least64_type_node		c_global_trees[CTI_UINT_LEAST64_TYPE]
 #define int_fast8_type_node		c_global_trees[CTI_INT_FAST8_TYPE]
 #define int_fast16_type_node		c_global_trees[CTI_INT_FAST16_TYPE]
 #define int_fast32_type_node		c_global_trees[CTI_INT_FAST32_TYPE]
+#define int_fast40_type_node		c_global_trees[CTI_INT_FAST40_TYPE]
 #define int_fast64_type_node		c_global_trees[CTI_INT_FAST64_TYPE]
 #define uint_fast8_type_node		c_global_trees[CTI_UINT_FAST8_TYPE]
 #define uint_fast16_type_node		c_global_trees[CTI_UINT_FAST16_TYPE]
 #define uint_fast32_type_node		c_global_trees[CTI_UINT_FAST32_TYPE]
+#define uint_fast40_type_node		c_global_trees[CTI_UINT_FAST40_TYPE]
 #define uint_fast64_type_node		c_global_trees[CTI_UINT_FAST64_TYPE]
 #define intptr_type_node		c_global_trees[CTI_INTPTR_TYPE]
 #define uintptr_type_node		c_global_trees[CTI_UINTPTR_TYPE]
Index: gcc/config/soft-fp/floatpisf.c
===================================================================
--- gcc/config/soft-fp/floatpisf.c	(revision 325327)
+++ gcc/config/soft-fp/floatpisf.c	(working copy)
@@ -31,13 +31,13 @@
 #include "soft-fp.h"
 #include "single.h"
 
-SFtype __floattisf(TItype i)
+SFtype __floatpisf(PItype i)
 {
   FP_DECL_EX;
   FP_DECL_S(A);
   SFtype a;
 
-  FP_FROM_INT_S(A, i, TI_BITS, UTItype);
+  FP_FROM_INT_S(A, i, PI_BITS, UPItype);
   FP_PACK_RAW_S(a, A);
   FP_HANDLE_EXCEPTIONS;
 
Index: gcc/config/soft-fp/floatunpidf.c
===================================================================
--- gcc/config/soft-fp/floatunpidf.c	(revision 325327)
+++ gcc/config/soft-fp/floatunpidf.c	(working copy)
@@ -31,13 +31,13 @@
 #include "soft-fp.h"
 #include "double.h"
 
-DFtype __floatuntidf(UTItype i)
+DFtype __floatunpidf(UPItype i)
 {
   FP_DECL_EX;
   FP_DECL_D(A);
   DFtype a;
 
-  FP_FROM_INT_D(A, i, TI_BITS, UTItype);
+  FP_FROM_INT_D(A, i, PI_BITS, UPItype);
   FP_PACK_RAW_D(a, A);
   FP_HANDLE_EXCEPTIONS;
 
Index: gcc/config/soft-fp/floatunpitf.c
===================================================================
--- gcc/config/soft-fp/floatunpitf.c	(revision 325327)
+++ gcc/config/soft-fp/floatunpitf.c	(working copy)
@@ -31,13 +31,13 @@
 #include "soft-fp.h"
 #include "quad.h"
 
-TFtype __floatuntitf(UTItype i)
+TFtype __floatunpitf(UPItype i)
 {
   FP_DECL_EX;
   FP_DECL_Q(A);
   TFtype a;
 
-  FP_FROM_INT_Q(A, i, TI_BITS, UTItype);
+  FP_FROM_INT_Q(A, i, PI_BITS, UPItype);
   FP_PACK_RAW_Q(a, A);
   FP_HANDLE_EXCEPTIONS;
 
Index: gcc/config/soft-fp/fixunssfpi.c
===================================================================
--- gcc/config/soft-fp/fixunssfpi.c	(revision 325327)
+++ gcc/config/soft-fp/fixunssfpi.c	(working copy)
@@ -31,14 +31,14 @@
 #include "soft-fp.h"
 #include "single.h"
 
-UTItype __fixunssfti(SFtype a)
+UPItype __fixunssfpi(SFtype a)
 {
   FP_DECL_EX;
   FP_DECL_S(A);
-  UTItype r;
+  UPItype r;
 
   FP_UNPACK_RAW_S(A, a);
-  FP_TO_INT_S(r, A, TI_BITS, 0);
+  FP_TO_INT_S(r, A, PI_BITS, 0);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
Index: gcc/config/soft-fp/fixsfpi.c
===================================================================
--- gcc/config/soft-fp/fixsfpi.c	(revision 325327)
+++ gcc/config/soft-fp/fixsfpi.c	(working copy)
@@ -31,14 +31,14 @@
 #include "soft-fp.h"
 #include "single.h"
 
-TItype __fixsfti(SFtype a)
+PItype __fixsfpi(SFtype a)
 {
   FP_DECL_EX;
   FP_DECL_S(A);
-  UTItype r;
+  UPItype r;
 
   FP_UNPACK_RAW_S(A, a);
-  FP_TO_INT_S(r, A, TI_BITS, 1);
+  FP_TO_INT_S(r, A, PI_BITS, 1);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
Index: gcc/config/soft-fp/fixunsdfpi.c
===================================================================
--- gcc/config/soft-fp/fixunsdfpi.c	(revision 325327)
+++ gcc/config/soft-fp/fixunsdfpi.c	(working copy)
@@ -31,14 +31,14 @@
 #include "soft-fp.h"
 #include "double.h"
 
-UTItype __fixunsdfti(DFtype a)
+UPItype __fixunsdfpi(DFtype a)
 {
   FP_DECL_EX;
   FP_DECL_D(A);
-  UTItype r;
+  UPItype r;
 
   FP_UNPACK_RAW_D(A, a);
-  FP_TO_INT_D(r, A, TI_BITS, 0);
+  FP_TO_INT_D(r, A, PI_BITS, 0);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
Index: gcc/config/soft-fp/fixdfpi.c
===================================================================
--- gcc/config/soft-fp/fixdfpi.c	(revision 325327)
+++ gcc/config/soft-fp/fixdfpi.c	(working copy)
@@ -31,14 +31,14 @@
 #include "soft-fp.h"
 #include "double.h"
 
-TItype __fixdfti(DFtype a)
+PItype __fixdfpi(DFtype a)
 {
   FP_DECL_EX;
   FP_DECL_D(A);
-  UTItype r;
+  UPItype r;
 
   FP_UNPACK_RAW_D(A, a);
-  FP_TO_INT_D(r, A, TI_BITS, 1);
+  FP_TO_INT_D(r, A, PI_BITS, 1);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
Index: gcc/config/soft-fp/floatunpisf.c
===================================================================
--- gcc/config/soft-fp/floatunpisf.c	(revision 325327)
+++ gcc/config/soft-fp/floatunpisf.c	(working copy)
@@ -31,13 +31,13 @@
 #include "soft-fp.h"
 #include "single.h"
 
-SFtype __floatuntisf(UTItype i)
+SFtype __floatunpisf(UPItype i)
 {
   FP_DECL_EX;
   FP_DECL_S(A);
   SFtype a;
 
-  FP_FROM_INT_S(A, i, TI_BITS, UTItype);
+  FP_FROM_INT_S(A, i, PI_BITS, UPItype);
   FP_PACK_RAW_S(a, A);
   FP_HANDLE_EXCEPTIONS;
 
Index: gcc/config/soft-fp/fixunstfpi.c
===================================================================
--- gcc/config/soft-fp/fixunstfpi.c	(revision 325327)
+++ gcc/config/soft-fp/fixunstfpi.c	(working copy)
@@ -31,14 +31,14 @@
 #include "soft-fp.h"
 #include "quad.h"
 
-UTItype __fixunstfti(TFtype a)
+UPItype __fixunstfpi(TFtype a)
 {
   FP_DECL_EX;
   FP_DECL_Q(A);
-  UTItype r;
+  UPItype r;
 
   FP_UNPACK_RAW_Q(A, a);
-  FP_TO_INT_Q(r, A, TI_BITS, 0);
+  FP_TO_INT_Q(r, A, PI_BITS, 0);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
Index: gcc/config/soft-fp/floatpidf.c
===================================================================
--- gcc/config/soft-fp/floatpidf.c	(revision 325327)
+++ gcc/config/soft-fp/floatpidf.c	(working copy)
@@ -31,13 +31,13 @@
 #include "soft-fp.h"
 #include "double.h"
 
-DFtype __floattidf(TItype i)
+DFtype __floatpidf(PItype i)
 {
   FP_DECL_EX;
   FP_DECL_D(A);
   DFtype a;
 
-  FP_FROM_INT_D(A, i, TI_BITS, UTItype);
+  FP_FROM_INT_D(A, i, PI_BITS, UPItype);
   FP_PACK_RAW_D(a, A);
   FP_HANDLE_EXCEPTIONS;
 
Index: gcc/config/soft-fp/fixtfpi.c
===================================================================
--- gcc/config/soft-fp/fixtfpi.c	(revision 325327)
+++ gcc/config/soft-fp/fixtfpi.c	(working copy)
@@ -31,14 +31,14 @@
 #include "soft-fp.h"
 #include "quad.h"
 
-TItype __fixtfti(TFtype a)
+PItype __fixtfpi(TFtype a)
 {
   FP_DECL_EX;
   FP_DECL_Q(A);
-  UTItype r;
+  UPItype r;
 
   FP_UNPACK_RAW_Q(A, a);
-  FP_TO_INT_Q(r, A, TI_BITS, 1);
+  FP_TO_INT_Q(r, A, PI_BITS, 1);
   FP_HANDLE_EXCEPTIONS;
 
   return r;
Index: gcc/config/soft-fp/soft-fp.h
===================================================================
--- gcc/config/soft-fp/soft-fp.h	(revision 325327)
+++ gcc/config/soft-fp/soft-fp.h	(working copy)
@@ -180,6 +180,9 @@ do {						\
 typedef int QItype __attribute__((mode(QI)));
 typedef int SItype __attribute__((mode(SI)));
 typedef int DItype __attribute__((mode(DI)));
+#ifdef __INT40_TYPE__
+typedef __int40_t PItype;
+#endif
 typedef unsigned int UQItype __attribute__((mode(QI)));
 typedef unsigned int USItype __attribute__((mode(SI)));
 typedef unsigned int UDItype __attribute__((mode(DI)));
@@ -188,6 +191,9 @@ typedef unsigned int UHWtype __attribute
 #elif _FP_W_TYPE_SIZE == 64
 typedef USItype UHWtype;
 #endif
+#ifdef __INT40_TYPE__
+typedef __uint40_t UPItype;
+#endif
 
 #ifndef CMPtype
 #define CMPtype		int
@@ -195,6 +201,7 @@ typedef USItype UHWtype;
 
 #define SI_BITS		(__CHAR_BIT__ * (int)sizeof(SItype))
 #define DI_BITS		(__CHAR_BIT__ * (int)sizeof(DItype))
+#define PI_BITS		40
 
 #ifndef umul_ppmm
 #ifdef _LIBC
Index: gcc/config/soft-fp/floatpitf.c
===================================================================
--- gcc/config/soft-fp/floatpitf.c	(revision 325327)
+++ gcc/config/soft-fp/floatpitf.c	(working copy)
@@ -31,13 +31,13 @@
 #include "soft-fp.h"
 #include "quad.h"
 
-TFtype __floattitf(TItype i)
+TFtype __floatpitf(PItype i)
 {
   FP_DECL_EX;
   FP_DECL_Q(A);
   TFtype a;
 
-  FP_FROM_INT_Q(A, i, TI_BITS, UTItype);
+  FP_FROM_INT_Q(A, i, PI_BITS, UPItype);
   FP_PACK_RAW_Q(a, A);
   FP_HANDLE_EXCEPTIONS;
 
Index: libgcc/Makefile.in
===================================================================
--- libgcc/Makefile.in  (revision 329707)
+++ libgcc/Makefile.in  (working copy)
@@ -315,6 +315,8 @@ lib2funcs = _muldi3 _negdi2 _lshrdi3 _as
            _mulsc3 _muldc3 _mulxc3 _multc3 _divsc3 _divdc3 _divxc3        \
            _divtc3 _bswapsi2 _bswapdi2 _clrsbsi2 _clrsbdi2
 
+lib2funcs += $(LIB2_PI_FUNCS)
+
 # The floating-point conversion routines that involve a single-word integer.
 # XX stands for the integer mode.
 swfloatfuncs = $(patsubst %,_fixuns%XX,sf df xf)
Index: libgcc/config/t-pimode
===================================================================
--- libgcc/config/t-pimode      (revision 0)
+++ libgcc/config/t-pimode      (revision 0)
@@ -0,0 +1,2 @@
+LIB2_PI_FUNCS = _mulpi3 _divpi3 _udivpi3 _modpi3 _umodpi3
+
Index: gcc/libgcc2.c
===================================================================
--- gcc/libgcc2.c	(revision 329707)
+++ gcc/libgcc2.c	(working copy)
@@ -561,6 +561,21 @@ __muldi3 (DWtype u, DWtype v)
   return w.ll;
 }
 #endif
+
+#ifdef L_mulpi3
+PItype
+__mulpi3 (PItype u, PItype v)
+{
+  const DWunion uu = {.ll = u};
+  const DWunion vv = {.ll = v};
+  DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
+
+  w.s.high += ((UHWtype) uu.s.low * (UHWtype) vv.s.high
+	       + (UHWtype) uu.s.high * (UHWtype) vv.s.low);
+
+  return w.ll;
+}
+#endif
 

 #if (defined (L_udivdi3) || defined (L_divdi3) || \
      defined (L_umoddi3) || defined (L_moddi3))
@@ -1182,6 +1197,73 @@ __udivdi3 (UDWtype n, UDWtype d)
 {
   return __udivmoddi4 (n, d, (UDWtype *) 0);
 }
+#endif
+
+#ifdef L_divpi3
+PItype
+__divpi3 (PItype u, PItype v)
+{
+  Wtype c = 0;
+  DWunion uu = {.ll = u};
+  DWunion vv = {.ll = v};
+  PItype w;
+
+  if (uu.s.high < 0)
+    c = ~c,
+    uu.ll = -uu.ll;
+  if (vv.s.high < 0)
+    c = ~c,
+    vv.ll = -vv.ll;
+
+  w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
+  if (c)
+    w = -w;
+
+  return w;
+}
+#endif
+
+#ifdef L_modpi3
+PItype
+__modpi3 (PItype u, PItype v)
+{
+  Wtype c = 0;
+  DWunion uu = {.ll = u};
+  DWunion vv = {.ll = v};
+  DWtype w;
+
+  if (uu.s.high < 0)
+    c = ~c,
+    uu.ll = -uu.ll;
+  if (vv.s.high < 0)
+    vv.ll = -vv.ll;
+
+  (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w);
+  if (c)
+    w = -w;
+
+  return w;
+}
+#endif
+
+#ifdef L_umodpi3
+UPItype
+__umodpi3 (UPItype u, UPItype v)
+{
+  UDWtype w;
+
+  (void) __udivmoddi4 (u, v, &w);
+
+  return w;
+}
+#endif
+
+#ifdef L_udivpi3
+UPItype
+__udivpi3 (UPItype n, UPItype d)
+{
+  return __udivmoddi4 (n, d, (UDWtype *) 0);
+}
 #endif
 

 #ifdef L_cmpdi2
Index: gcc/libgcc2.h
===================================================================
--- gcc/libgcc2.h	(revision 329707)
+++ gcc/libgcc2.h	(working copy)
@@ -152,6 +152,11 @@ typedef unsigned int UTItype	__attribute
 #endif
 #endif
 
+#ifdef __INT40_TYPE__
+typedef		 int PItype	__attribute__ ((mode (PI)));
+typedef unsigned int UPItype	__attribute__ ((mode (PI)));
+#endif
+
 #if LIBGCC2_HAS_SF_MODE
 typedef 	float SFtype	__attribute__ ((mode (SF)));
 typedef _Complex float SCtype	__attribute__ ((mode (SC)));
@@ -336,6 +341,11 @@ typedef int shift_count_type __attribute
 #define __popcountDI2	__NDW(popcount,2)
 #define __parityDI2	__NDW(parity,2)
 
+#define __mulpi3		__N(mulpi3)
+#define __divpi3		__N(divpi3)
+#define __modpi3		__N(modpi3)
+#define __udivpi3		__N(udivpi3)
+#define __umodpi3		__N(umodpi3)
 #define __clz_tab		__N(clz_tab)
 #define __bswapsi2		__N(bswapsi2)
 #define __bswapdi2		__N(bswapdi2)
@@ -392,6 +402,14 @@ extern DWtype __moddi3 (DWtype, DWtype);
 extern UDWtype __udivmoddi4 (UDWtype, UDWtype, UDWtype *);
 #endif
 
+#ifdef L_mulpi3
+extern PItype __mulpi3 (PItype, PItype);
+extern PItype __divpi3 (PItype, PItype);
+extern UPItype __udivpi3 (UPItype, UPItype);
+extern UPItype __umodpi3 (UPItype, UPItype);
+extern PItype __modpi3 (PItype, PItype);
+#endif
+
 /* __negdi2 is static inline when building other libgcc2 portions.  */
 #if !defined(L_divdi3) && !defined(L_moddi3)
 extern DWtype __negdi2 (DWtype);
