> > > Maybe you need to refactor __glibcxx_digits so there is a version taking 
> > > the bitsize as an argument rather than using sizeof(T) * __CHAR_BIT__, 
> > > but 
> > > that should be the only change needed to handle such types with the 
> > > existing macros.  The bitsize macros should be the only ones needing 
> > > predefining to pass information to libstdc++.
> > 
> > Like this?
> 
> Yes (well, the libstdc++ changes will need to go to the libstdc++ mailing 
> list for review there, but this is the sort of thing I'd expect to keep 
> the way libstdc++ defines these limits as consistent as possible between 
> different types).

Ok, here's the updated c-cppbuiltins.c and all the libstdc++-v3
changes, cross-posted to the libstdc++ list.  I tested the macros on
x86-64 (before and after) and msp430 (after) with __int128 and __int20
and get the right values in all cases.


Index: gcc/c-family/c-cppbuiltin.c
===================================================================
--- gcc/c-family/c-cppbuiltin.c (revision 213886)
+++ gcc/c-family/c-cppbuiltin.c (working copy)
@@ -775,12 +775,14 @@ cpp_iec_559_complex_value (void)
 }
 
 /* Hook that registers front end and target-specific built-ins.  */
 void
 c_cpp_builtins (cpp_reader *pfile)
 {
+  int i;
+
   /* -undef turns off target-specific built-ins.  */
   if (flag_undef)
     return;
 
   define_language_independent_builtin_macros (pfile);
 
@@ -845,12 +847,29 @@ c_cpp_builtins (cpp_reader *pfile)
   builtin_define_type_minmax ("__WCHAR_MIN__", "__WCHAR_MAX__",
                              underlying_wchar_type_node);
   builtin_define_type_minmax ("__WINT_MIN__", "__WINT_MAX__", wint_type_node);
   builtin_define_type_max ("__PTRDIFF_MAX__", ptrdiff_type_node);
   builtin_define_type_max ("__SIZE_MAX__", size_type_node);
 
+  for (i = 0; i < NUM_INT_N_ENTS; i ++)
+    if (int_n_enabled_p[i])
+      {
+       char buf[35+20+20];
+
+       /* These are used to configure the C++ library.  */
+
+       if (!flag_iso || int_n_data[i].bitsize == POINTER_SIZE)
+         {
+           sprintf (buf, "__GLIBCXX_TYPE_INT_N_%d=__int%d", i, 
int_n_data[i].bitsize);
+           cpp_define (parse_in, buf);
+
+           sprintf (buf, "__GLIBCXX_BITSIZE_INT_N_%d=%d", i, 
int_n_data[i].bitsize);
+           cpp_define (parse_in, buf);
+         }
+      }
+
   /* stdint.h and the testsuite need to know these.  */
   builtin_define_stdint_macros ();
 
   /* Provide information for library headers to determine whether to
      define macros such as __STDC_IEC_559__ and
      __STDC_IEC_559_COMPLEX__.  */
@@ -993,15 +1012,20 @@ c_cpp_builtins (cpp_reader *pfile)
   else if (flag_stack_protect == 1)
     cpp_define (pfile, "__SSP__=1");
 
   if (flag_openmp)
     cpp_define (pfile, "_OPENMP=201307");
 
-  if (int128_integer_type_node != NULL_TREE)
-    builtin_define_type_sizeof ("__SIZEOF_INT128__",
-                               int128_integer_type_node);
+  for (i = 0; i < NUM_INT_N_ENTS; i ++)
+    if (int_n_enabled_p[i])
+      {
+       char buf[15+20];
+       sprintf(buf, "__SIZEOF_INT%d__", int_n_data[i].bitsize);
+       builtin_define_type_sizeof (buf,
+                                   int_n_trees[i].signed_type);
+      }
   builtin_define_type_sizeof ("__SIZEOF_WCHAR_T__", wchar_type_node);
   builtin_define_type_sizeof ("__SIZEOF_WINT_T__", wint_type_node);
   builtin_define_type_sizeof ("__SIZEOF_PTRDIFF_T__",
                              unsigned_ptrdiff_type_node);
 
   /* A straightforward target hook doesn't work, because of problems
Index: libstdc++-v3/src/c++11/limits.cc
===================================================================
--- libstdc++-v3/src/c++11/limits.cc    (revision 213886)
+++ libstdc++-v3/src/c++11/limits.cc    (working copy)
@@ -385,60 +385,72 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const bool numeric_limits<unsigned long long>::is_bounded;
   const bool numeric_limits<unsigned long long>::is_modulo;
   const bool numeric_limits<unsigned long long>::traps;
   const bool numeric_limits<unsigned long long>::tinyness_before;
   const float_round_style numeric_limits<unsigned long long>::round_style;
 
-#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
-  const bool numeric_limits<__int128>::is_specialized;
-  const int  numeric_limits<__int128>::digits;
-  const int  numeric_limits<__int128>::digits10;
-  const int  numeric_limits<__int128>::max_digits10;
-  const bool numeric_limits<__int128>::is_signed;
-  const bool numeric_limits<__int128>::is_integer;
-  const bool numeric_limits<__int128>::is_exact;
-  const int  numeric_limits<__int128>::radix;
-  const int  numeric_limits<__int128>::min_exponent;
-  const int  numeric_limits<__int128>::min_exponent10;
-  const int  numeric_limits<__int128>::max_exponent;
-  const int  numeric_limits<__int128>::max_exponent10;
-  const bool numeric_limits<__int128>::has_infinity;
-  const bool numeric_limits<__int128>::has_quiet_NaN;
-  const bool numeric_limits<__int128>::has_signaling_NaN;
-  const float_denorm_style numeric_limits<__int128>::has_denorm;
-  const bool numeric_limits<__int128>::has_denorm_loss;
-  const bool numeric_limits<__int128>::is_iec559;
-  const bool numeric_limits<__int128>::is_bounded;
-  const bool numeric_limits<__int128>::is_modulo;
-  const bool numeric_limits<__int128>::traps;
-  const bool numeric_limits<__int128>::tinyness_before;
-  const float_round_style numeric_limits<__int128>::round_style;
-
-  const bool numeric_limits<unsigned __int128>::is_specialized;
-  const int  numeric_limits<unsigned __int128>::digits;
-  const int  numeric_limits<unsigned __int128>::digits10;
-  const int  numeric_limits<unsigned __int128>::max_digits10;
-  const bool numeric_limits<unsigned __int128>::is_signed;
-  const bool numeric_limits<unsigned __int128>::is_integer;
-  const bool numeric_limits<unsigned __int128>::is_exact;
-  const int  numeric_limits<unsigned __int128>::radix;
-  const int  numeric_limits<unsigned __int128>::min_exponent;
-  const int  numeric_limits<unsigned __int128>::min_exponent10;
-  const int  numeric_limits<unsigned __int128>::max_exponent;
-  const int  numeric_limits<unsigned __int128>::max_exponent10;
-  const bool numeric_limits<unsigned __int128>::has_infinity;
-  const bool numeric_limits<unsigned __int128>::has_quiet_NaN;
-  const bool numeric_limits<unsigned __int128>::has_signaling_NaN;
-  const float_denorm_style numeric_limits<unsigned __int128>::has_denorm;
-  const bool numeric_limits<unsigned __int128>::has_denorm_loss;
-  const bool numeric_limits<unsigned __int128>::is_iec559;
-  const bool numeric_limits<unsigned __int128>::is_bounded;
-  const bool numeric_limits<unsigned __int128>::is_modulo;
-  const bool numeric_limits<unsigned __int128>::traps;
-  const bool numeric_limits<unsigned __int128>::tinyness_before;
-  const float_round_style numeric_limits<unsigned __int128>::round_style;
+#define INT_N(__INT_N_TYPE)                                                    
\
+  const bool numeric_limits<__INT_N_TYPE>::is_specialized;                     
\
+  const int  numeric_limits<__INT_N_TYPE>::digits;                             
\
+  const int  numeric_limits<__INT_N_TYPE>::digits10;                           
\
+  const int  numeric_limits<__INT_N_TYPE>::max_digits10;                       
\
+  const bool numeric_limits<__INT_N_TYPE>::is_signed;                          
\
+  const bool numeric_limits<__INT_N_TYPE>::is_integer;                         
\
+  const bool numeric_limits<__INT_N_TYPE>::is_exact;                           
\
+  const int  numeric_limits<__INT_N_TYPE>::radix;                              
\
+  const int  numeric_limits<__INT_N_TYPE>::min_exponent;                       
\
+  const int  numeric_limits<__INT_N_TYPE>::min_exponent10;                     
\
+  const int  numeric_limits<__INT_N_TYPE>::max_exponent;                       
\
+  const int  numeric_limits<__INT_N_TYPE>::max_exponent10;                     
\
+  const bool numeric_limits<__INT_N_TYPE>::has_infinity;                       
\
+  const bool numeric_limits<__INT_N_TYPE>::has_quiet_NaN;                      
\
+  const bool numeric_limits<__INT_N_TYPE>::has_signaling_NaN;                  
\
+  const float_denorm_style numeric_limits<__INT_N_TYPE>::has_denorm;           
\
+  const bool numeric_limits<__INT_N_TYPE>::has_denorm_loss;                    
\
+  const bool numeric_limits<__INT_N_TYPE>::is_iec559;                          
\
+  const bool numeric_limits<__INT_N_TYPE>::is_bounded;                         
\
+  const bool numeric_limits<__INT_N_TYPE>::is_modulo;                          
\
+  const bool numeric_limits<__INT_N_TYPE>::traps;                              
\
+  const bool numeric_limits<__INT_N_TYPE>::tinyness_before;                    
\
+  const float_round_style numeric_limits<__INT_N_TYPE>::round_style;           
\
+                                                                       \
+  const bool numeric_limits<unsigned __INT_N_TYPE>::is_specialized;            
\
+  const int  numeric_limits<unsigned __INT_N_TYPE>::digits;                    
\
+  const int  numeric_limits<unsigned __INT_N_TYPE>::digits10;                  
\
+  const int  numeric_limits<unsigned __INT_N_TYPE>::max_digits10;              
\
+  const bool numeric_limits<unsigned __INT_N_TYPE>::is_signed;                 
\
+  const bool numeric_limits<unsigned __INT_N_TYPE>::is_integer;                
        \
+  const bool numeric_limits<unsigned __INT_N_TYPE>::is_exact;                  
\
+  const int  numeric_limits<unsigned __INT_N_TYPE>::radix;                     
\
+  const int  numeric_limits<unsigned __INT_N_TYPE>::min_exponent;              
\
+  const int  numeric_limits<unsigned __INT_N_TYPE>::min_exponent10;            
\
+  const int  numeric_limits<unsigned __INT_N_TYPE>::max_exponent;              
\
+  const int  numeric_limits<unsigned __INT_N_TYPE>::max_exponent10;            
\
+  const bool numeric_limits<unsigned __INT_N_TYPE>::has_infinity;              
\
+  const bool numeric_limits<unsigned __INT_N_TYPE>::has_quiet_NaN;             
\
+  const bool numeric_limits<unsigned __INT_N_TYPE>::has_signaling_NaN;         
\
+  const float_denorm_style numeric_limits<unsigned __INT_N_TYPE>::has_denorm;  
\
+  const bool numeric_limits<unsigned __INT_N_TYPE>::has_denorm_loss;           
\
+  const bool numeric_limits<unsigned __INT_N_TYPE>::is_iec559;                 
\
+  const bool numeric_limits<unsigned __INT_N_TYPE>::is_bounded;                
        \
+  const bool numeric_limits<unsigned __INT_N_TYPE>::is_modulo;                 
\
+  const bool numeric_limits<unsigned __INT_N_TYPE>::traps;                     
\
+  const bool numeric_limits<unsigned __INT_N_TYPE>::tinyness_before;           
\
+  const float_round_style numeric_limits<unsigned __INT_N_TYPE>::round_style;
+
+#ifdef __GLIBCXX_TYPE_INT_N_0
+  INT_N (__GLIBCXX_TYPE_INT_N_0)
+#endif
+#ifdef __GLIBCXX_TYPE_INT_N_1
+  INT_N (__GLIBCXX_TYPE_INT_N_1)
+#endif
+#ifdef __GLIBCXX_TYPE_INT_N_2
+  INT_N (__GLIBCXX_TYPE_INT_N_2)
+#endif
+#ifdef __GLIBCXX_TYPE_INT_N_3
+  INT_N (__GLIBCXX_TYPE_INT_N_3)
 #endif
 
   // float
   const bool numeric_limits<float>::is_specialized;
   const int  numeric_limits<float>::digits;
   const int  numeric_limits<float>::digits10;
Index: libstdc++-v3/include/std/type_traits
===================================================================
--- libstdc++-v3/include/std/type_traits        (revision 213886)
+++ libstdc++-v3/include/std/type_traits        (working copy)
@@ -236,19 +236,48 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     : public true_type { };
 
   template<>
     struct __is_integral_helper<unsigned long long>
     : public true_type { };
 
-#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
+  // Conditionalizing on __STRICT_ANSI__ here will break any port that
+  // uses one of these types for size_t.
+#if defined(__GLIBCXX_TYPE_INT_N_0)
   template<>
-    struct __is_integral_helper<__int128>
+    struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_0>
     : public true_type { };
 
   template<>
-    struct __is_integral_helper<unsigned __int128>
+    struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_0>
+    : public true_type { };
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_1)
+  template<>
+    struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_1>
+    : public true_type { };
+
+  template<>
+    struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_1>
+    : public true_type { };
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_2)
+  template<>
+    struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_2>
+    : public true_type { };
+
+  template<>
+    struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_2>
+    : public true_type { };
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_3)
+  template<>
+    struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_3>
+    : public true_type { };
+
+  template<>
+    struct __is_integral_helper<unsigned __GLIBCXX_TYPE_INT_N_3>
     : public true_type { };
 #endif
 
   /// is_integral
   template<typename _Tp>
     struct is_integral
@@ -1598,16 +1627,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if defined(_GLIBCXX_USE_WCHAR_T) && !defined(__WCHAR_UNSIGNED__)
   template<>
     struct __make_unsigned<wchar_t> : __make_unsigned<__WCHAR_TYPE__>
     { };
 #endif
 
-#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
+#if defined(__GLIBCXX_TYPE_INT_N_0)
+  template<>
+    struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0>
+    { typedef unsigned __GLIBCXX_TYPE_INT_N_0 __type; };
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_1)
+  template<>
+    struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1>
+    { typedef unsigned __GLIBCXX_TYPE_INT_N_1 __type; };
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_2)
   template<>
-    struct __make_unsigned<__int128>
-    { typedef unsigned __int128 __type; };
+    struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2>
+    { typedef unsigned __GLIBCXX_TYPE_INT_N_2 __type; };
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_3)
+  template<>
+    struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3>
+    { typedef unsigned __GLIBCXX_TYPE_INT_N_3 __type; };
 #endif
 
   // Select between integral and enum: not possible to be both.
   template<typename _Tp, 
           bool _IsInt = is_integral<_Tp>::value,
           bool _IsEnum = is_enum<_Tp>::value>
@@ -1695,16 +1739,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { };
   template<>
     struct __make_signed<char32_t> : __make_signed<uint_least32_t>
     { };
 #endif
 
-#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
+#if defined(__GLIBCXX_TYPE_INT_N_0)
+  template<>
+    struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_0>
+    { typedef __GLIBCXX_TYPE_INT_N_0 __type; };
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_1)
+  template<>
+    struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_1>
+    { typedef __GLIBCXX_TYPE_INT_N_1 __type; };
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_2)
+  template<>
+    struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_2>
+    { typedef __GLIBCXX_TYPE_INT_N_2 __type; };
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_3)
   template<>
-    struct __make_signed<unsigned __int128>
-    { typedef __int128 __type; };
+    struct __make_signed<unsigned __GLIBCXX_TYPE_INT_N_3>
+    { typedef __GLIBCXX_TYPE_INT_N_3 __type; };
 #endif
 
   // Select between integral and enum: not possible to be both.
   template<typename _Tp, 
           bool _IsInt = is_integral<_Tp>::value,
           bool _IsEnum = is_enum<_Tp>::value>
Index: libstdc++-v3/include/std/limits
===================================================================
--- libstdc++-v3/include/std/limits     (revision 213886)
+++ libstdc++-v3/include/std/limits     (working copy)
@@ -122,27 +122,38 @@
 #ifndef __glibcxx_long_double_tinyness_before
 #  define __glibcxx_long_double_tinyness_before false
 #endif
 
 // You should not need to define any macros below this point.
 
-#define __glibcxx_signed(T)    ((T)(-1) < 0)
+#define __glibcxx_signed_b(T,B)        ((T)(-1) < 0)
 
-#define __glibcxx_min(T) \
-  (__glibcxx_signed (T) ? -__glibcxx_max (T) - 1 : (T)0)
+#define __glibcxx_min_b(T,B)                                   \
+  (__glibcxx_signed_b (T,B) ? -__glibcxx_max_b (T,B) - 1 : (T)0)
 
-#define __glibcxx_max(T) \
-  (__glibcxx_signed (T) ? \
-   (((((T)1 << (__glibcxx_digits (T) - 1)) - 1) << 1) + 1) : ~(T)0)
+#define __glibcxx_max_b(T,B)                                           \
+  (__glibcxx_signed_b (T,B) ?                                          \
+   (((((T)1 << (__glibcxx_digits_b (T,B) - 1)) - 1) << 1) + 1) : ~(T)0)
 
-#define __glibcxx_digits(T) \
-  (sizeof(T) * __CHAR_BIT__ - __glibcxx_signed (T))
+#define __glibcxx_digits_b(T,B)                                \
+  (B - __glibcxx_signed_b (T,B))
 
 // The fraction 643/2136 approximates log10(2) to 7 significant digits.
+#define __glibcxx_digits10_b(T,B)              \
+  (__glibcxx_digits_b (T,B) * 643L / 2136)
+
+#define __glibcxx_signed(T) \
+  __glibcxx_signed_b (T, sizeof(T) * __CHAR_BIT__)
+#define __glibcxx_min(T) \
+  __glibcxx_min_b (T, sizeof(T) * __CHAR_BIT__)
+#define __glibcxx_max(T) \
+  __glibcxx_max_b (T, sizeof(T) * __CHAR_BIT__)
+#define __glibcxx_digits(T) \
+  __glibcxx_digits_b (T, sizeof(T) * __CHAR_BIT__)
 #define __glibcxx_digits10(T) \
-  (__glibcxx_digits (T) * 643L / 2136)
+  __glibcxx_digits10_b (T, sizeof(T) * __CHAR_BIT__)
 
 #define __glibcxx_max_digits10(T) \
   (2 + (T) * 643L / 2136)
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -1396,159 +1407,187 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
       static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
       static _GLIBCXX_USE_CONSTEXPR float_round_style round_style 
        = round_toward_zero;
     };
 
-#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
-  /// numeric_limits<__int128> specialization.
-  template<>
-    struct numeric_limits<__int128>
-    {
-      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;
+#if !defined(__STRICT_ANSI__)
 
-      static _GLIBCXX_CONSTEXPR __int128
-      min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min (__int128); }
+#define __INT_N(TYPE, BITSIZE, EXT, UEXT)                      \
+  template<>                                                                   
\
+    struct numeric_limits<TYPE>                                                
\
+    {                                                                          
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;                
\
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR TYPE                                           
\
+       min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min_b (TYPE, BITSIZE); } 
\
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR TYPE                                           
\
+      max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max_b (TYPE, BITSIZE);; } 
        \       
+                                                                               
\
+      static _GLIBCXX_USE_CONSTEXPR int digits                                 
        \
+       = BITSIZE - 1;                                                          
\
+      static _GLIBCXX_USE_CONSTEXPR int digits10                               
\
+       = (BITSIZE - 1) * 643L / 2136;                                          
\
+                                                                               
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;                     
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;                    
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;                      
\
+      static _GLIBCXX_USE_CONSTEXPR int radix = 2;                             
\
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR TYPE                                           
\
+      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }                            
\
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR TYPE                                           
\
+      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }                        
\
+                                                                               
\
+      EXT                                                                      
\
+                                                                               
\
+      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;                      
\
+      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;                    
\
+      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;                      
\
+      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;                    
\
+                                                                               
\
+      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;                 
        \
+      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;                
\
+      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;            
\
+      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm              
\
+       = denorm_absent;                                                        
\
+      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;              
\
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR TYPE                                           
\
+      infinity() _GLIBCXX_USE_NOEXCEPT                                         
        \
+      { return static_cast<TYPE>(0); }                                         
        \
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR TYPE                                           
\
+      quiet_NaN() _GLIBCXX_USE_NOEXCEPT                                        
\
+      { return static_cast<TYPE>(0); }                                         
        \
+                                                                               
        \
+      static _GLIBCXX_CONSTEXPR TYPE                                           
\
+      signaling_NaN() _GLIBCXX_USE_NOEXCEPT                                    
\
+      { return static_cast<TYPE>(0); }                                         
        \
+                                                                               
        \
+      static _GLIBCXX_CONSTEXPR TYPE                                           
\
+      denorm_min() _GLIBCXX_USE_NOEXCEPT                                       
\
+      { return static_cast<TYPE>(0); }                                         
        \
+                                                                               
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;                    
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;                    
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;                    
\
+                                                                               
\
+      static _GLIBCXX_USE_CONSTEXPR bool traps                                 
        \
+       = __glibcxx_integral_traps;                                             
\
+      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;              
\
+      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style              
\
+       = round_toward_zero;                                                    
\
+    };                                                                         
        \
+                                                                               
\
+  template<>                                                                   
\
+    struct numeric_limits<unsigned TYPE>                                       
\
+    {                                                                          
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;                
\
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR unsigned TYPE                                  
\
+      min() _GLIBCXX_USE_NOEXCEPT { return 0; }                                
\
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR unsigned TYPE                                  
\
+      max() _GLIBCXX_USE_NOEXCEPT { return  __glibcxx_max_b (TYPE, BITSIZE); } 
 \
+                                                                               
\
+      UEXT                                                                     
\
+                                                                               
\
+      static _GLIBCXX_USE_CONSTEXPR int digits                                 
        \
+       = BITSIZE;                                                              
\
+      static _GLIBCXX_USE_CONSTEXPR int digits10                               
\
+       = BITSIZE * 643L / 2136;                                                
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_signed = false;                    
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;                    
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;                      
\
+      static _GLIBCXX_USE_CONSTEXPR int radix = 2;                             
\
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR unsigned TYPE                                  
\
+      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }                            
\
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR unsigned TYPE                                  
\
+      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }                        
\
+                                                                               
\
+      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;                      
\
+      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;                    
\
+      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;                      
\
+      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;                    
\
+                                                                               
\
+      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;                 
        \
+      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;                
\
+      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;            
\
+      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm              
\
+       = denorm_absent;                                                        
\
+      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;              
\
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR unsigned TYPE                                  
\
+      infinity() _GLIBCXX_USE_NOEXCEPT                                         
        \
+      { return static_cast<unsigned TYPE>(0); }                                
\
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR unsigned TYPE                                  
\
+      quiet_NaN() _GLIBCXX_USE_NOEXCEPT                                        
\
+      { return static_cast<unsigned TYPE>(0); }                                
\
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR unsigned TYPE                                  
\
+      signaling_NaN() _GLIBCXX_USE_NOEXCEPT                                    
\
+      { return static_cast<unsigned TYPE>(0); }                                
\
+                                                                               
\
+      static _GLIBCXX_CONSTEXPR unsigned TYPE                                  
\
+      denorm_min() _GLIBCXX_USE_NOEXCEPT                                       
\
+      { return static_cast<unsigned TYPE>(0); }                                
\
+                                                                               
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;                    
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;                    
\
+      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;                     
\
+                                                                               
\
+      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;     
\
+      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;              
\
+      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style              
\
+       = round_toward_zero;                                                    
\
+    };
+
+#if __cplusplus >= 201103L
+
+#define __INT_N_201103(TYPE)                                                   
\
+      static constexpr TYPE                                                    
\
+      lowest() noexcept { return min(); }                                      
\
+      static constexpr int max_digits10 = 0;
 
-      static _GLIBCXX_CONSTEXPR __int128
-      max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max (__int128); }
+#define __INT_N_U201103(TYPE)                                                  
\
+      static constexpr unsigned TYPE                                           
\
+      lowest() noexcept { return min(); }                                      
\
+      static constexpr int max_digits10 = 0;
 
-#if __cplusplus >= 201103L
-      static constexpr __int128
-      lowest() noexcept { return min(); }
+#else
+#define __INT_N_201103(TYPE)
+#define __INT_N_U201103(TYPE)
 #endif
 
-      static _GLIBCXX_USE_CONSTEXPR int digits
-       = __glibcxx_digits (__int128);
-      static _GLIBCXX_USE_CONSTEXPR int digits10
-       = __glibcxx_digits10 (__int128);
-#if __cplusplus >= 201103L
-      static constexpr int max_digits10 = 0;
+#ifdef __GLIBCXX_TYPE_INT_N_0
+  __INT_N(__GLIBCXX_TYPE_INT_N_0, __GLIBCXX_BITSIZE_INT_N_0,
+         __INT_N_201103 (__GLIBCXX_TYPE_INT_N_0), __INT_N_U201103 
(__GLIBCXX_TYPE_INT_N_0))
 #endif
-      static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
-      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
-      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
-      static _GLIBCXX_USE_CONSTEXPR int radix = 2;
-
-      static _GLIBCXX_CONSTEXPR __int128
-      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }
-
-      static _GLIBCXX_CONSTEXPR __int128
-      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }
-
-      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
-      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
-      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
-      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;
-
-      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
-      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
-      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
-      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
-       = denorm_absent;
-      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;
-
-      static _GLIBCXX_CONSTEXPR __int128
-      infinity() _GLIBCXX_USE_NOEXCEPT
-      { return static_cast<__int128>(0); }
-
-      static _GLIBCXX_CONSTEXPR __int128
-      quiet_NaN() _GLIBCXX_USE_NOEXCEPT
-      { return static_cast<__int128>(0); }
-      
-      static _GLIBCXX_CONSTEXPR __int128
-      signaling_NaN() _GLIBCXX_USE_NOEXCEPT
-      { return static_cast<__int128>(0); }
-      
-      static _GLIBCXX_CONSTEXPR __int128
-      denorm_min() _GLIBCXX_USE_NOEXCEPT
-      { return static_cast<__int128>(0); }
-
-      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
-      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
-      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;
-
-      static _GLIBCXX_USE_CONSTEXPR bool traps
-       = __glibcxx_integral_traps;
-      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
-      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
-       = round_toward_zero;
-    };
-
-  /// numeric_limits<unsigned __int128> specialization.
-  template<>
-    struct numeric_limits<unsigned __int128>
-    {
-      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;
-
-      static _GLIBCXX_CONSTEXPR unsigned __int128
-      min() _GLIBCXX_USE_NOEXCEPT { return 0; }
-
-      static _GLIBCXX_CONSTEXPR unsigned __int128
-      max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max (unsigned __int128); }
-
-#if __cplusplus >= 201103L
-      static constexpr unsigned __int128
-      lowest() noexcept { return min(); }
+#ifdef __GLIBCXX_TYPE_INT_N_1
+  __INT_N (__GLIBCXX_TYPE_INT_N_1, __GLIBCXX_BITSIZE_INT_N_1,
+         __INT_N_201103 (__GLIBCXX_TYPE_INT_N_1), __INT_N_U201103 
(__GLIBCXX_TYPE_INT_N_1))
 #endif
-
-      static _GLIBCXX_USE_CONSTEXPR int digits
-       = __glibcxx_digits (unsigned __int128);
-      static _GLIBCXX_USE_CONSTEXPR int digits10
-       = __glibcxx_digits10 (unsigned __int128);
-#if __cplusplus >= 201103L
-      static constexpr int max_digits10 = 0;
+#ifdef __GLIBCXX_TYPE_INT_N_2
+  __INT_N (__GLIBCXX_TYPE_INT_N_2, __GLIBCXX_BITSIZE_INT_N_2,
+         __INT_N_201103 (__GLIBCXX_TYPE_INT_N_2), __INT_N_U201103 
(__GLIBCXX_TYPE_INT_N_2))
+#endif
+#ifdef __GLIBCXX_TYPE_INT_N_3
+  __INT_N (__GLIBCXX_TYPE_INT_N_3, __GLIBCXX_BITSIZE_INT_N_3,
+         __INT_N_201103 (__GLIBCXX_TYPE_INT_N_3), __INT_N_U201103 
(__GLIBCXX_TYPE_INT_N_3))
 #endif
-      static _GLIBCXX_USE_CONSTEXPR bool is_signed = false;
-      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
-      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
-      static _GLIBCXX_USE_CONSTEXPR int radix = 2;
-
-      static _GLIBCXX_CONSTEXPR unsigned __int128
-      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }
-
-      static _GLIBCXX_CONSTEXPR unsigned __int128
-      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }
-
-      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
-      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
-      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
-      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;
-
-      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
-      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
-      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
-      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
-       = denorm_absent;
-      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;
-
-      static _GLIBCXX_CONSTEXPR unsigned __int128
-      infinity() _GLIBCXX_USE_NOEXCEPT
-      { return static_cast<unsigned __int128>(0); }
-
-      static _GLIBCXX_CONSTEXPR unsigned __int128
-      quiet_NaN() _GLIBCXX_USE_NOEXCEPT
-      { return static_cast<unsigned __int128>(0); }
-
-      static _GLIBCXX_CONSTEXPR unsigned __int128
-      signaling_NaN() _GLIBCXX_USE_NOEXCEPT
-      { return static_cast<unsigned __int128>(0); }
-
-      static _GLIBCXX_CONSTEXPR unsigned __int128
-      denorm_min() _GLIBCXX_USE_NOEXCEPT
-      { return static_cast<unsigned __int128>(0); }
 
-      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
-      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
-      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;
+#undef __INT_N
+#undef __INT_N_201103
+#undef __INT_N_U201103
 
-      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
-      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
-      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
-       = round_toward_zero;
-    };
 #endif
 
   /// numeric_limits<float> specialization.
   template<>
     struct numeric_limits<float>
     {
Index: libstdc++-v3/include/c_std/cstdlib
===================================================================
--- libstdc++-v3/include/c_std/cstdlib  (revision 213886)
+++ libstdc++-v3/include/c_std/cstdlib  (working copy)
@@ -166,15 +166,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #ifdef _GLIBCXX_USE_LONG_LONG
   inline long long
   abs(long long __x) { return __builtin_llabs (__x); }
 #endif
 
-#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
-  inline __int128
-  abs(__int128 __x) { return __x >= 0 ? __x : -__x; }
+#if defined(__GLIBCXX_TYPE_INT_N_0)
+  inline __GLIBCXX_TYPE_INT_N_0
+  abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_1)
+  inline __GLIBCXX_TYPE_INT_N_1
+  abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_2)
+  inline __GLIBCXX_TYPE_INT_N_2
+  abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_3)
+  inline __GLIBCXX_TYPE_INT_N_3
+  abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; }
 #endif
 
   inline ldiv_t
   div(long __i, long __j) { return ldiv(__i, __j); }
 
 _GLIBCXX_END_NAMESPACE_VERSION
Index: libstdc++-v3/include/bits/cpp_type_traits.h
===================================================================
--- libstdc++-v3/include/bits/cpp_type_traits.h (revision 213886)
+++ libstdc++-v3/include/bits/cpp_type_traits.h (working copy)
@@ -138,13 +138,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       enum { __value = 0 };
       typedef __false_type __type;
     };
 
   // Thirteen specializations (yes there are eleven standard integer
   // types; <em>long long</em> and <em>unsigned long long</em> are
-  // supported as extensions)
+  // supported as extensions).  Up to four target-specific __int<N>
+  // types are supported as well.
   template<>
     struct __is_integer<bool>
     {
       enum { __value = 1 };
       typedef __true_type __type;
     };
@@ -248,12 +249,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct __is_integer<unsigned long long>
     {
       enum { __value = 1 };
       typedef __true_type __type;
     };
 
+#define __INT_N(TYPE)                  \
+  template<>                           \
+    struct __is_integer<TYPE>          \
+    {                                  \
+      enum { __value = 1 };            \
+      typedef __true_type __type;      \
+    };                                 \
+  template<>                           \
+    struct __is_integer<unsigned TYPE> \
+    {                                  \
+      enum { __value = 1 };            \
+      typedef __true_type __type;      \
+    };
+
+#ifdef __GLIBCXX_TYPE_INT_N_0
+__INT_N(__GLIBCXX_TYPE_INT_N_0)
+#endif
+#ifdef __GLIBCXX_TYPE_INT_N_1
+__INT_N(__GLIBCXX_TYPE_INT_N_1)
+#endif
+#ifdef __GLIBCXX_TYPE_INT_N_2
+__INT_N(__GLIBCXX_TYPE_INT_N_2)
+#endif
+#ifdef __GLIBCXX_TYPE_INT_N_3
+__INT_N(__GLIBCXX_TYPE_INT_N_3)
+#endif
+
+#undef __INT_N
+
   //
   // Floating point types
   //
   template<typename _Tp>
     struct __is_floating
     {
Index: libstdc++-v3/include/c_global/cstdlib
===================================================================
--- libstdc++-v3/include/c_global/cstdlib       (revision 213886)
+++ libstdc++-v3/include/c_global/cstdlib       (working copy)
@@ -171,17 +171,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #ifdef _GLIBCXX_USE_LONG_LONG
   inline long long
   abs(long long __x) { return __builtin_llabs (__x); }
 #endif
 
-#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
-  inline __int128
-  abs(__int128 __x) { return __x >= 0 ? __x : -__x; }
+#if defined(__GLIBCXX_TYPE_INT_N_0)
+  inline __GLIBCXX_TYPE_INT_N_0
+  abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_1)
+  inline __GLIBCXX_TYPE_INT_N_1
+  abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_2)
+  inline __GLIBCXX_TYPE_INT_N_2
+  abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_3)
+  inline __GLIBCXX_TYPE_INT_N_3
+  abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; }
 #endif
 
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
 #if _GLIBCXX_USE_C99
 
 #undef _Exit

Reply via email to