Index: test/Preprocessor/init.c
===================================================================
--- test/Preprocessor/init.c	(revision 86695)
+++ test/Preprocessor/init.c	(working copy)
@@ -378,7 +378,7 @@
 // MSP430:#define __FLT_MIN__ 1.17549435e-38F
 // MSP430:#define __FLT_RADIX__ 2
 // MSP430:#define __INT16_TYPE__ short
-// MSP430:#define __INT32_TYPE__ long long
+// MSP430:#define __INT32_TYPE__ long int
 // MSP430:#define __INT8_TYPE__ char
 // MSP430:#define __INTMAX_MAX__ 2147483647L
 // MSP430:#define __INTMAX_TYPE__ long int
@@ -447,7 +447,7 @@
 // PIC16:#define __FLT_MIN__ 1.17549435e-38F
 // PIC16:#define __FLT_RADIX__ 2
 // PIC16:#define __INT16_TYPE__ short
-// PIC16:#define __INT32_TYPE__ long long
+// PIC16:#define __INT32_TYPE__ long int
 // PIC16:#define __INT8_TYPE__ char
 // PIC16:#define __INTMAX_MAX__ 2147483647L
 // PIC16:#define __INTMAX_TYPE__ long int
@@ -679,7 +679,7 @@
 // S390X:#define __FLT_RADIX__ 2
 // S390X:#define __INT16_TYPE__ short
 // S390X:#define __INT32_TYPE__ int
-// S390X:#define __INT64_TYPE__ long long int
+// S390X:#define __INT64_TYPE__ long int
 // S390X:#define __INT8_TYPE__ char
 // S390X:#define __INTMAX_MAX__ 9223372036854775807LL
 // S390X:#define __INTMAX_TYPE__ long long int
Index: test/Preprocessor/stdint.c
===================================================================
--- test/Preprocessor/stdint.c	(revision 86695)
+++ test/Preprocessor/stdint.c	(working copy)
@@ -1,20 +1,20 @@
 // RUN: clang-cc -E -ffreestanding -triple=arm-none-none %s | FileCheck -check-prefix ARM %s
 //
-// ARM:typedef long long int int64_t;
+// ARM:typedef signed long long int int64_t;
 // ARM:typedef unsigned long long int uint64_t;
 // ARM:typedef int64_t int_least64_t;
 // ARM:typedef uint64_t uint_least64_t;
 // ARM:typedef int64_t int_fast64_t;
 // ARM:typedef uint64_t uint_fast64_t;
 //
-// ARM:typedef int int32_t;
+// ARM:typedef signed int int32_t;
 // ARM:typedef unsigned int uint32_t;
 // ARM:typedef int32_t int_least32_t;
 // ARM:typedef uint32_t uint_least32_t;
 // ARM:typedef int32_t int_fast32_t;
 // ARM:typedef uint32_t uint_fast32_t;
 // 
-// ARM:typedef short int16_t;
+// ARM:typedef signed short int16_t;
 // ARM:typedef unsigned short uint16_t;
 // ARM:typedef int16_t int_least16_t;
 // ARM:typedef uint16_t uint_least16_t;
@@ -108,21 +108,21 @@
 //
 // RUN: clang-cc -E -ffreestanding -triple=bfin-none-none %s | FileCheck -check-prefix BFIN %s
 //
-// BFIN:typedef long long int int64_t;
+// BFIN:typedef signed long long int int64_t;
 // BFIN:typedef unsigned long long int uint64_t;
 // BFIN:typedef int64_t int_least64_t;
 // BFIN:typedef uint64_t uint_least64_t;
 // BFIN:typedef int64_t int_fast64_t;
 // BFIN:typedef uint64_t uint_fast64_t;
 //
-// BFIN:typedef int int32_t;
+// BFIN:typedef signed int int32_t;
 // BFIN:typedef unsigned int uint32_t;
 // BFIN:typedef int32_t int_least32_t;
 // BFIN:typedef uint32_t uint_least32_t;
 // BFIN:typedef int32_t int_fast32_t;
 // BFIN:typedef uint32_t uint_fast32_t;
 //
-// BFIN:typedef short int16_t;
+// BFIN:typedef signed short int16_t;
 // BFIN:typedef unsigned short uint16_t;
 // BFIN:typedef int16_t int_least16_t;
 // BFIN:typedef uint16_t uint_least16_t;
@@ -216,21 +216,21 @@
 //
 // RUN: clang-cc -E -ffreestanding -triple=i386-none-none %s | FileCheck -check-prefix I386 %s
 //
-// I386:typedef long long int int64_t;
+// I386:typedef signed long long int int64_t;
 // I386:typedef unsigned long long int uint64_t;
 // I386:typedef int64_t int_least64_t;
 // I386:typedef uint64_t uint_least64_t;
 // I386:typedef int64_t int_fast64_t;
 // I386:typedef uint64_t uint_fast64_t;
 //
-// I386:typedef int int32_t;
+// I386:typedef signed int int32_t;
 // I386:typedef unsigned int uint32_t;
 // I386:typedef int32_t int_least32_t;
 // I386:typedef uint32_t uint_least32_t;
 // I386:typedef int32_t int_fast32_t;
 // I386:typedef uint32_t uint_fast32_t;
 //
-// I386:typedef short int16_t;
+// I386:typedef signed short int16_t;
 // I386:typedef unsigned short uint16_t;
 // I386:typedef int16_t int_least16_t;
 // I386:typedef uint16_t uint_least16_t;
@@ -323,14 +323,14 @@
 //
 // RUN: clang-cc -E -ffreestanding -triple=msp430-none-none %s | FileCheck -check-prefix MSP430 %s
 //
-// MSP430:typedef long long int int32_t;
-// MSP430:typedef unsigned long long int uint32_t;
+// MSP430:typedef signed long int int32_t;
+// MSP430:typedef unsigned long int uint32_t;
 // MSP430:typedef int32_t int_least32_t;
 // MSP430:typedef uint32_t uint_least32_t;
 // MSP430:typedef int32_t int_fast32_t;
 // MSP430:typedef uint32_t uint_fast32_t;
 //
-// MSP430:typedef short int16_t;
+// MSP430:typedef signed short int16_t;
 // MSP430:typedef unsigned short uint16_t;
 // MSP430:typedef int16_t int_least16_t;
 // MSP430:typedef uint16_t uint_least16_t;
@@ -423,14 +423,14 @@
 //
 // RUN: clang-cc -E -ffreestanding -triple=pic16-none-none %s | FileCheck -check-prefix PIC16 %s
 // 
-// PIC16:typedef long long int int32_t;
-// PIC16:typedef unsigned long long int uint32_t;
+// PIC16:typedef signed long int int32_t;
+// PIC16:typedef unsigned long int uint32_t;
 // PIC16:typedef int32_t int_least32_t;
 // PIC16:typedef uint32_t uint_least32_t;
 // PIC16:typedef int32_t int_fast32_t;
 // PIC16:typedef uint32_t uint_fast32_t;
 //
-// PIC16:typedef short int16_t;
+// PIC16:typedef signed short int16_t;
 // PIC16:typedef unsigned short uint16_t;
 // PIC16:typedef int16_t int_least16_t;
 // PIC16:typedef uint16_t uint_least16_t;
@@ -523,21 +523,21 @@
 //
 // RUN: clang-cc -E -ffreestanding -triple=powerpc64-none-none %s | FileCheck -check-prefix PPC64 %s
 //
-// PPC64:typedef long int int64_t;
+// PPC64:typedef signed long int int64_t;
 // PPC64:typedef unsigned long int uint64_t;
 // PPC64:typedef int64_t int_least64_t;
 // PPC64:typedef uint64_t uint_least64_t;
 // PPC64:typedef int64_t int_fast64_t;
 // PPC64:typedef uint64_t uint_fast64_t;
 //
-// PPC64:typedef int int32_t;
+// PPC64:typedef signed int int32_t;
 // PPC64:typedef unsigned int uint32_t;
 // PPC64:typedef int32_t int_least32_t;
 // PPC64:typedef uint32_t uint_least32_t;
 // PPC64:typedef int32_t int_fast32_t;
 // PPC64:typedef uint32_t uint_fast32_t;
 //
-// PPC64:typedef short int16_t;
+// PPC64:typedef signed short int16_t;
 // PPC64:typedef unsigned short uint16_t;
 // PPC64:typedef int16_t int_least16_t;
 // PPC64:typedef uint16_t uint_least16_t;
@@ -631,21 +631,21 @@
 // RUN: clang-cc -E -ffreestanding -triple=powerpc-none-none %s | FileCheck -check-prefix PPC %s
 //
 //
-// PPC:typedef long long int int64_t;
+// PPC:typedef signed long long int int64_t;
 // PPC:typedef unsigned long long int uint64_t;
 // PPC:typedef int64_t int_least64_t;
 // PPC:typedef uint64_t uint_least64_t;
 // PPC:typedef int64_t int_fast64_t;
 // PPC:typedef uint64_t uint_fast64_t;
 //
-// PPC:typedef int int32_t;
+// PPC:typedef signed int int32_t;
 // PPC:typedef unsigned int uint32_t;
 // PPC:typedef int32_t int_least32_t;
 // PPC:typedef uint32_t uint_least32_t;
 // PPC:typedef int32_t int_fast32_t;
 // PPC:typedef uint32_t uint_fast32_t;
 //
-// PPC:typedef short int16_t;
+// PPC:typedef signed short int16_t;
 // PPC:typedef unsigned short uint16_t;
 // PPC:typedef int16_t int_least16_t;
 // PPC:typedef uint16_t uint_least16_t;
@@ -738,21 +738,21 @@
 //
 // RUN: clang-cc -E -ffreestanding -triple=s390x-none-none %s | FileCheck -check-prefix S390X %s
 //
-// S390X:typedef long long int int64_t;
-// S390X:typedef unsigned long long int uint64_t;
+// S390X:typedef signed long int int64_t;
+// S390X:typedef unsigned long int uint64_t;
 // S390X:typedef int64_t int_least64_t;
 // S390X:typedef uint64_t uint_least64_t;
 // S390X:typedef int64_t int_fast64_t;
 // S390X:typedef uint64_t uint_fast64_t;
 //
-// S390X:typedef int int32_t;
+// S390X:typedef signed int int32_t;
 // S390X:typedef unsigned int uint32_t;
 // S390X:typedef int32_t int_least32_t;
 // S390X:typedef uint32_t uint_least32_t;
 // S390X:typedef int32_t int_fast32_t;
 // S390X:typedef uint32_t uint_fast32_t;
 //
-// S390X:typedef short int16_t;
+// S390X:typedef signed short int16_t;
 // S390X:typedef unsigned short uint16_t;
 // S390X:typedef int16_t int_least16_t;
 // S390X:typedef uint16_t uint_least16_t;
@@ -845,21 +845,21 @@
 //
 // RUN: clang-cc -E -ffreestanding -triple=sparc-none-none %s | FileCheck -check-prefix SPARC %s
 //
-// SPARC:typedef long long int int64_t;
+// SPARC:typedef signed long long int int64_t;
 // SPARC:typedef unsigned long long int uint64_t;
 // SPARC:typedef int64_t int_least64_t;
 // SPARC:typedef uint64_t uint_least64_t;
 // SPARC:typedef int64_t int_fast64_t;
 // SPARC:typedef uint64_t uint_fast64_t;
 //
-// SPARC:typedef int int32_t;
+// SPARC:typedef signed int int32_t;
 // SPARC:typedef unsigned int uint32_t;
 // SPARC:typedef int32_t int_least32_t;
 // SPARC:typedef uint32_t uint_least32_t;
 // SPARC:typedef int32_t int_fast32_t;
 // SPARC:typedef uint32_t uint_fast32_t;
 //
-// SPARC:typedef short int16_t;
+// SPARC:typedef signed short int16_t;
 // SPARC:typedef unsigned short uint16_t;
 // SPARC:typedef int16_t int_least16_t;
 // SPARC:typedef uint16_t uint_least16_t;
@@ -952,14 +952,14 @@
 //
 // RUN: clang-cc -E -ffreestanding -triple=tce-none-none %s | FileCheck -check-prefix TCE %s
 //
-// TCE:typedef int int32_t;
+// TCE:typedef signed int int32_t;
 // TCE:typedef unsigned int uint32_t;
 // TCE:typedef int32_t int_least32_t;
 // TCE:typedef uint32_t uint_least32_t;
 // TCE:typedef int32_t int_fast32_t;
 // TCE:typedef uint32_t uint_fast32_t;
 //
-// TCE:typedef short int16_t;
+// TCE:typedef signed short int16_t;
 // TCE:typedef unsigned short uint16_t;
 // TCE:typedef int16_t int_least16_t;
 // TCE:typedef uint16_t uint_least16_t;
@@ -1053,21 +1053,21 @@
 // RUN: clang-cc -E -ffreestanding -triple=x86_64-none-none %s | FileCheck -check-prefix X86_64 %s
 //
 //
-// X86_64:typedef long int int64_t;
+// X86_64:typedef signed long int int64_t;
 // X86_64:typedef unsigned long int uint64_t;
 // X86_64:typedef int64_t int_least64_t;
 // X86_64:typedef uint64_t uint_least64_t;
 // X86_64:typedef int64_t int_fast64_t;
 // X86_64:typedef uint64_t uint_fast64_t;
 //
-// X86_64:typedef int int32_t;
+// X86_64:typedef signed int int32_t;
 // X86_64:typedef unsigned int uint32_t;
 // X86_64:typedef int32_t int_least32_t;
 // X86_64:typedef uint32_t uint_least32_t;
 // X86_64:typedef int32_t int_fast32_t;
 // X86_64:typedef uint32_t uint_fast32_t;
 //
-// X86_64:typedef short int16_t;
+// X86_64:typedef signed short int16_t;
 // X86_64:typedef unsigned short uint16_t;
 // X86_64:typedef int16_t int_least16_t;
 // X86_64:typedef uint16_t uint_least16_t;
Index: lib/Frontend/InitPreprocessor.cpp
===================================================================
--- lib/Frontend/InitPreprocessor.cpp	(revision 86695)
+++ lib/Frontend/InitPreprocessor.cpp	(working copy)
@@ -232,6 +232,12 @@
   DefineBuiltinMacro(Buf, MacroBuf);
 }
 
+static void DefineExactWidthIntType(TargetInfo::IntType Ty, 
+                               const TargetInfo &TI, std::vector<char> &Buf) {
+  char MacroBuf[60];
+  sprintf(MacroBuf, "__INT%d_TYPE__", TI.getTypeWidth(Ty));
+  DefineType(MacroBuf, Ty, Buf);
+}
 
 static void InitializePredefinedMacros(const TargetInfo &TI,
                                        const LangOptions &LangOpts,
@@ -385,25 +391,22 @@
   if (!LangOpts.CharIsSigned)
     DefineBuiltinMacro(Buf, "__CHAR_UNSIGNED__");
 
-  // Define fixed-sized integer types for stdint.h
-  assert(TI.getCharWidth() == 8 && "unsupported target types");
-  assert(TI.getShortWidth() == 16 && "unsupported target types");
-  DefineBuiltinMacro(Buf, "__INT8_TYPE__=char");
-  DefineType("__INT16_TYPE__", TargetInfo::SignedShort, Buf);
+  // Define exact-width integer types for stdint.h
+  sprintf(MacroBuf, "__INT%d_TYPE__=char", TI.getCharWidth());
+  DefineBuiltinMacro(Buf, MacroBuf);
 
-  TargetInfo::IntType Int32Type;
-  if (TI.getIntWidth() == 32)
-    Int32Type = TargetInfo::SignedInt;
-  else {
-    assert(TI.getLongLongWidth() == 32 && "unsupported target types");
-    Int32Type = TargetInfo::SignedLongLong;
-  }
-  DefineType("__INT32_TYPE__", Int32Type, Buf);
-
-  // 16-bit targets doesn't necessarily have a 64-bit type.
-  if (TI.getLongLongWidth() == 64)
-    DefineType("__INT64_TYPE__", TI.getInt64Type(), Buf);
-
+  if (TI.getShortWidth() > TI.getCharWidth())
+    DefineExactWidthIntType(TargetInfo::SignedShort, TI, Buf);
+                      
+  if (TI.getIntWidth() > TI.getShortWidth())
+    DefineExactWidthIntType(TargetInfo::SignedInt, TI, Buf);
+                              
+  if (TI.getLongWidth() > TI.getIntWidth())
+    DefineExactWidthIntType(TargetInfo::SignedLong, TI, Buf);
+                                      
+  if (TI.getLongLongWidth() > TI.getLongWidth())
+    DefineExactWidthIntType(TargetInfo::SignedLongLong, TI, Buf);
+  
   // Add __builtin_va_list typedef.
   {
     const char *VAList = TI.getVAListDeclaration();
Index: lib/Headers/stdint.h
===================================================================
--- lib/Headers/stdint.h	(revision 86695)
+++ lib/Headers/stdint.h	(working copy)
@@ -33,61 +33,179 @@
 # include_next <stdint.h>
 #else
 
-/* We currently only support targets with power of two, 2s complement integers.
- */
-
 /* C99 7.18.1.1 Exact-width integer types.
  * C99 7.18.1.2 Minimum-width integer types.
  * C99 7.18.1.3 Fastest minimum-width integer types.
- * Since we only support pow-2 targets, these map directly to exact width types.
+ *
+ * The standard requires that exact-width type be defined for 8-, 16-, 32-, and 
+ * 64-bit types if they are implemented. Other exact width types are optional.
+ * This implementation defines an exact-width types for every integer width
+ * that is represented in the standard integer types.
+ *
+ * The standard also requires minimum-width types be defined for 8-, 16-, 32-,
+ * and 64-bit widths regardless of whether there are corresponding exact-width
+ * types. 
+ *
+ * To accomodate targets that are missing types that are exactly 8, 16, 32, or
+ * 64 bits wide, this implementation takes an approach of cascading
+ * redefintions, redefining __int_leastN_t to successively smaller exact-width
+ * types. It is therefore important that the types are defined in order of
+ * descending widths.
+ *
+ * We currently assume that the minimum-width types and the fastest
+ * minimum-width types are the same. This is allowed by the standard, but is
+ * suboptimal.
+ *
+ * In violation of the standard, some targets do not implement a type that is
+ * wide enough to represent all of the required widths (8-, 16-, 32-, 64-bit).  
+ * To accomodate these targets, a required minimum-width type is only
+ * defined if there exists an exact-width type of equal or greater width.
  */
 
-/* Some 16-bit targets do not have a 64-bit datatype.  Only define the 64-bit
- * typedefs if there is something to typedef them to.
- */
 #ifdef __INT64_TYPE__
-#ifndef __int8_t_defined  /* glibc does weird things with sys/types.h */
-typedef __INT64_TYPE__ int64_t;
-#endif
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int64_t*/
+typedef signed __INT64_TYPE__ int64_t;
+# endif /* __int8_t_defined */
 typedef unsigned __INT64_TYPE__ uint64_t;
-typedef int64_t   int_least64_t;
-typedef uint64_t uint_least64_t;
-typedef int64_t   int_fast64_t;
-typedef uint64_t uint_fast64_t;
-#endif
+# define __int_least64_t int64_t
+# define __uint_least64_t uint64_t
+# define __int_least32_t int64_t
+# define __uint_least32_t uint64_t
+# define __int_least16_t int64_t
+# define __uint_least16_t uint64_t
+# define __int_least8_t int64_t
+# define __uint_least8_t uint64_t
+#endif /* __INT64_TYPE__ */
 
-#ifndef __int8_t_defined  /* glibc does weird things with sys/types.h */
-typedef __INT32_TYPE__ int32_t;
-#endif
-#ifndef __uint32_t_defined  /* more glibc compatibility */
-#define __uint32_t_defined
+#ifdef __int_least64_t
+typedef __int_least64_t int_least64_t;
+typedef __uint_least64_t uint_least64_t;
+typedef __int_least64_t int_fast64_t;
+typedef __uint_least64_t uint_fast64_t;
+#endif /* __int_least64_t */
+
+#ifdef __INT56_TYPE__
+typedef signed __INT56_TYPE__ int56_t;
+typedef unsigned __INT56_TYPE__ uint56_t;
+typedef int56_t int_least56_t;
+typedef uint56_t uint_least56_t;
+typedef int56_t int_fast56_t;
+typedef uint56_t uint_fast56_t;
+# define __int_least32_t int56_t
+# define __uint_least32_t uint56_t
+# define __int_least16_t int56_t
+# define __uint_least16_t uint56_t
+# define __int_least8_t int56_t
+# define __uint_least8_t uint56_t
+#endif /* __INT56_TYPE__ */
+
+
+#ifdef __INT48_TYPE__
+typedef signed __INT48_TYPE__ int48_t;
+typedef unsigned __INT48_TYPE__ uint48_t;
+typedef int48_t int_least48_t;
+typedef uint48_t uint_least48_t;
+typedef int48_t int_fast48_t;
+typedef uint48_t uint_fast48_t;
+# define __int_least32_t int48_t
+# define __uint_least32_t uint48_t
+# define __int_least16_t int48_t
+# define __uint_least16_t uint48_t
+# define __int_least8_t int48_t
+# define __uint_least8_t uint48_t
+#endif /* __INT48_TYPE__ */
+
+
+#ifdef __INT40_TYPE__
+typedef signed __INT40_TYPE__ int40_t;
+typedef unsigned __INT40_TYPE__ uint40_t;
+typedef int40_t int_least40_t;
+typedef uint40_t uint_least40_t;
+typedef int40_t int_fast40_t;
+typedef uint40_t uint_fast40_t;
+# define __int_least32_t int40_t
+# define __uint_least32_t uint40_t
+# define __int_least16_t int40_t
+# define __uint_least16_t uint40_t
+# define __int_least8_t int40_t
+# define __uint_least8_t uint40_t
+#endif /* __INT40_TYPE__ */
+
+
+#ifdef __INT32_TYPE__
+
+# ifndef __int8_t_defined /* glibc sys/types.h also defines int32_t*/
+typedef signed __INT32_TYPE__ int32_t;
+# endif /* __int8_t_defined */
+
+# ifndef __uint32_t_defined  /* more glibc compatibility */
+# define __uint32_t_defined
 typedef unsigned __INT32_TYPE__ uint32_t;
-#endif
-typedef int32_t   int_least32_t;
-typedef uint32_t uint_least32_t;
-typedef int32_t   int_fast32_t;
-typedef uint32_t uint_fast32_t;
+# endif /* __uint32_t_defined */
 
+# define __int_least32_t int32_t
+# define __uint_least32_t uint32_t
+# define __int_least16_t int32_t
+# define __uint_least16_t uint32_t
+# define __int_least8_t int32_t
+# define __uint_least8_t uint32_t
+#endif /* __INT32_TYPE__ */
 
-#ifndef __int8_t_defined  /* glibc does weird things with sys/types.h */
-typedef __INT16_TYPE__ int16_t;
-#endif
+#ifdef __int_least32_t
+typedef __int_least32_t int_least32_t;
+typedef __uint_least32_t uint_least32_t;
+typedef __int_least32_t int_fast32_t;
+typedef __uint_least32_t uint_fast32_t;
+#endif /* __int_least32_t */
+
+#ifdef __INT24_TYPE__
+typedef signed __INT24_TYPE__ int24_t;
+typedef unsigned __INT24_TYPE__ uint24_t;
+typedef int24_t int_least24_t;
+typedef uint24_t uint_least24_t;
+typedef int24_t int_fast24_t;
+typedef uint24_t uint_fast24_t;
+# define __int_least16_t int24_t
+# define __uint_least16_t uint24_t
+# define __int_least8_t int24_t
+# define __uint_least8_t uint24_t
+#endif /* __INT24_TYPE__ */
+
+#ifdef __INT16_TYPE__
+#ifndef __int8_t_defined /* glibc sys/types.h also defines int16_t*/
+typedef signed __INT16_TYPE__ int16_t;
+#endif /* __int8_t_defined */
 typedef unsigned __INT16_TYPE__ uint16_t;
-typedef int16_t   int_least16_t;
-typedef uint16_t uint_least16_t;
-typedef int16_t   int_fast16_t;
-typedef uint16_t uint_fast16_t;
+# define __int_least16_t int16_t
+# define __uint_least16_t uint16_t
+# define __int_least8_t int16_t
+# define __uint_least8_t uint16_t
+#endif /* __INT16_TYPE__ */
 
+#ifdef __int_least16_t
+typedef __int_least16_t int_least16_t;
+typedef __uint_least16_t uint_least16_t;
+typedef __int_least16_t int_fast16_t;
+typedef __uint_least16_t uint_fast16_t;
+#endif /* __int_least16_t */
 
-#ifndef __int8_t_defined  /* glibc does weird things with sys/types.h */
+
+#ifdef __INT8_TYPE__
+#ifndef __int8_t_defined  /* glibc sys/types.h also defines int8_t*/
 typedef signed __INT8_TYPE__ int8_t;
-#endif
+#endif /* __int8_t_defined */
 typedef unsigned __INT8_TYPE__ uint8_t;
-typedef int8_t     int_least8_t;
-typedef uint8_t   uint_least8_t;
-typedef int8_t     int_fast8_t;
-typedef uint8_t   uint_fast8_t;
+# define __int_least8_t int8_t
+# define __uint_least8_t uint8_t
+#endif /* __INT8_TYPE__ */
 
+#ifdef __int_least8_t
+typedef __int_least8_t int_least8_t;
+typedef __uint_least8_t uint_least8_t;
+typedef __int_least8_t int_fast8_t;
+typedef __uint_least8_t uint_fast8_t;
+#endif /* __int_least8_t */
+
 /* prevent glibc sys/types.h from defining conflicting types */
 #ifndef __int8_t_defined  
 # define __int8_t_defined
@@ -108,76 +226,385 @@
 
 /* C99 7.18.4 Macros for minimum-width integer constants.
  *
+ * The standard requires that integer constant macros be defined for all the
+ * minimum-width types defined above. As 8-, 16-, 32-, and 64-bit minimum-width
+ * types are required, the corresponding integer constant macros are defined 
+ * here. This implementation also defines minimum-width types for every other
+ * integer width that the target implements, so corresponding macros are 
+ * defined below, too.
+ *
+ * These macros are defined using the same successive-shrinking approach as
+ * the type definitions above. It is likewise important that macros are defined
+ * in order of decending width.
+ *
  * Note that C++ should not check __STDC_CONSTANT_MACROS here, contrary to the
  * claims of the C standard (see C++ 18.3.1p2, [cstdint.syn]).
  */
 
-/* Only define the 64-bit size macros if we have 64-bit support. */
+#define __int_c_join(a, b) a ## b
+#define __int_c(v, suffix) (__int_c_join(v, suffix))
+#define __uint_c(v, suffix) (__int_c_join(v##U, suffix))
+
+
 #ifdef __INT64_TYPE__
-#define INT64_C(v)  (v##LL)
-#define UINT64_C(v) (v##ULL)
-#endif
+/* FIXME: predefine suffix based on type*/
+# define __INT64_C_SUFFIX__ LL
+# ifdef __INT64_C_SUFFIX__
+#  define __int64_c_suffix __INT64_C_SUFFIX__
+#  define __int32_c_suffix __INT64_C_SUFFIX__
+#  define __int16_c_suffix __INT64_C_SUFFIX__
+#  define  __int8_c_suffix __INT64_C_SUFFIX__
+# else
+#  undef __int64_c_suffix
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT64_C_SUFFIX__ */
+#endif /* __INT64_TYPE__ */
 
-#define INT32_C(v)  (v)
-#define UINT32_C(v) (v##U)
-#define INT16_C(v)  (v)
-#define UINT16_C(v) (v##U)
-#define INT8_C(v)   (v)
-#define UINT8_C(v)  (v##U)
+#ifdef __int_least64_t
+# ifdef __int64_c_suffix
+#  define INT64_C(v) __int_c(v, __int64_c_suffix)
+#  define UINT64_C(v) __uint_c(v, __int64_c_suffix)
+# else
+#  define INT64_C(v) (v)
+#  define UINT64_C(v) (v ## U)
+# endif /* __int64_c_suffix */
+#endif /* __int_least64_t */
 
+
+#ifdef __INT56_TYPE__
+/* FIXME: predefine suffix based on type */
+# define __INT56_C_SUFFIX__ L
+# ifdef __INT56_C_SUFFIX__
+#  define INT56_C(v) __int_c(v, __INT56_C_SUFFIX__)
+#  define UINT56_C(v) __uint_c(v, __INT56_C_SUFFIX__)
+#  define __int32_c_suffix __INT56_C_SUFFIX__
+#  define __int16_c_suffix __INT56_C_SUFFIX__
+#  define __int8_c_suffix  __INT56_C_SUFFIX__
+# else
+#  define INT56_C(v) (v)
+#  define UINT56_C(v) (v ## U)
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT56_C_SUFFIX__ */
+#endif /* __INT56_TYPE__ */
+
+
+#ifdef __INT48_TYPE__
+/* FIXME: predefine suffix based on type */
+# define __INT48_C_SUFFIX__ L
+# ifdef __INT48_C_SUFFIX__
+#  define INT48_C(v) __int_c(v, __INT48_C_SUFFIX__)
+#  define UINT48_C(v) __uint_c(v, __INT48_C_SUFFIX__)
+#  define __int32_c_suffix __INT48_C_SUFFIX__
+#  define __int16_c_suffix __INT48_C_SUFFIX__
+#  define __int8_c_suffix  __INT48_C_SUFFIX__
+# else
+#  define INT48_C(v) (v)
+#  define UINT48_C(v) (v ## U)
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT48_C_SUFFIX__ */
+#endif /* __INT48_TYPE__ */
+
+
+#ifdef __INT40_TYPE__
+/* FIXME: predefine suffix based on type */
+# define __INT40_C_SUFFIX__ L
+# ifdef __INT40_C_SUFFIX__
+#  define INT40_C(v) __int_c(v, __INT40_C_SUFFIX__)
+#  define UINT40_C(v) __uint_c(v, __INT40_C_SUFFIX__)
+#  define __int32_c_suffix __INT40_C_SUFFIX__
+#  define __int16_c_suffix __INT40_C_SUFFIX__
+#  define __int8_c_suffix  __INT40_C_SUFFIX__
+# else
+#  define INT40_C(v) (v)
+#  define UINT40_C(v) (v ## U)
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT40_C_SUFFIX__ */
+#endif /* __INT40_TYPE__ */
+
+
+#ifdef __INT32_TYPE__
+# ifdef __INT32_C_SUFFIX__
+#  define __int32_c_suffix __INT32_C_SUFFIX__
+#  define __int16_c_suffix __INT32_C_SUFFIX__
+#  define __int8_c_suffix  __INT32_C_SUFFIX__
+#else
+#  undef __int32_c_suffix
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT32_C_SUFFIX__ */
+#endif /* __INT32_TYPE__ */
+
+#ifdef __int_least32_t
+# ifdef __int32_c_suffix
+#  define INT32_C(v) __int_c(v, __int32_c_suffix)
+#  define UINT32_C(v) __uint_c(v, __int32_c_suffix)
+# else
+#  define INT32_C(v) (v)
+#  define UINT32_C(v) (v ## U)
+# endif /* __int32_c_suffix */
+#endif /* __int_least32_t */
+
+
+#ifdef __INT24_TYPE__
+# ifdef __INT24_C_SUFFIX__
+#  define INT24_C(v) __int_c(v, __INT24_C_SUFFIX__)
+#  define UINT24_C(v) __uint_c(v, __INT24_C_SUFFIX__)
+#  define __int16_c_suffix __INT24_C_SUFFIX__
+#  define __int8_c_suffix  __INT24_C_SUFFIX__
+# else
+#  define INT24_C(v) (v)
+#  define UINT24_C(v) (v ## U)
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT24_C_SUFFIX__ */
+#endif /* __INT24_TYPE__ */
+
+
+#ifdef __INT16_TYPE__
+# ifdef __INT16_C_SUFFIX__
+#  define __int16_c_suffix __INT16_C_SUFFIX__
+#  define __int8_c_suffix  __INT16_C_SUFFIX__
+#else
+#  undef __int16_c_suffix
+#  undef  __int8_c_suffix
+# endif /* __INT16_C_SUFFIX__ */
+#endif /* __INT16_TYPE__ */
+
+#ifdef __int_least16_t
+# ifdef __int16_c_suffix
+#  define INT16_C(v) __int_c(v, __int16_c_suffix)
+#  define UINT16_C(v) __uint_c(v, __int16_c_suffix)
+# else
+#  define INT16_C(v) (v)
+#  define UINT16_C(v) (v ## U)
+# endif /* __int16_c_suffix */
+#endif /* __int_least16_t */
+
+
+#ifdef __INT8_TYPE__
+# ifdef __INT8_C_SUFFIX__
+#  define __int8_c_suffix __INT8_C_SUFFIX__
+#else
+#  undef  __int8_c_suffix
+# endif /* __INT8_C_SUFFIX__ */
+#endif /* __INT8_TYPE__ */
+
+#ifdef __int_least8_t
+# ifdef __int8_c_suffix
+#  define INT8_C(v) __int_c(v, __int8_c_suffix)
+#  define UINT8_C(v) __uint_c(v, __int8_c_suffix)
+# else
+#  define INT8_C(v) (v)
+#  define UINT8_C(v) (v ## U)
+# endif /* __int8_c_suffix */
+#endif /* __int_least8_t */
+
+
 /* C99 7.18.2.1 Limits of exact-width integer types. 
- * Fixed sized values have fixed size max/min.
  * C99 7.18.2.2 Limits of minimum-width integer types.
- * Since we map these directly onto fixed-sized types, these values the same.
  * C99 7.18.2.3 Limits of fastest minimum-width integer types.
  *
+ * The presence of limit macros are completely optional in C99.  This
+ * implementation defines limits for all of the types (exact- and
+ * minimum-width) that it defines above, using the limits of the minimum-width
+ * type for any types that do not have exact-width representations.
+ *
+ * As in the type definitions, this section takes an approach of
+ * successive-shrinking to determine which limits to use for the standard (8,
+ * 16, 32, 64) bit widths when they don't have exact representations. It is
+ * therefore important that the defintions be kept in order of decending
+ * widths.
+ *
  * Note that C++ should not check __STDC_LIMIT_MACROS here, contrary to the
  * claims of the C standard (see C++ 18.3.1p2, [cstdint.syn]).
  */
 
-/* If we do not have 64-bit support, don't define the 64-bit size macros. */
 #ifdef __INT64_TYPE__
-#define INT64_MAX      9223372036854775807LL
-#define INT64_MIN    (-9223372036854775807LL-1)
-#define UINT64_MAX    18446744073709551615ULL
-#define INT_LEAST64_MIN  INT64_MIN
-#define INT_LEAST64_MAX  INT64_MAX
-#define UINT_LEAST64_MAX UINT64_MAX
-#define INT_FAST64_MIN    INT64_MIN
-#define INT_FAST64_MAX    INT64_MAX
-#define UINT_FAST64_MAX  UINT64_MAX
-#endif
+# define INT64_MAX     9223372036854775807LL
+# define INT64_MIN   (-9223372036854775807LL-1)
+# define UINT64_MAX   18446744073709551615ULL
+# define __INT_LEAST64_MIN   INT64_MIN
+# define __INT_LEAST64_MAX   INT64_MAX
+# define __UINT_LEAST64_MAX UINT64_MAX
+# define __INT_LEAST32_MIN   INT64_MIN
+# define __INT_LEAST32_MAX   INT64_MAX
+# define __UINT_LEAST32_MAX UINT64_MAX
+# define __INT_LEAST16_MIN   INT64_MIN
+# define __INT_LEAST16_MAX   INT64_MAX
+# define __UINT_LEAST16_MAX UINT64_MAX
+# define __INT_LEAST8_MIN    INT64_MIN
+# define __INT_LEAST8_MAX    INT64_MAX
+# define __UINT_LEAST8_MAX  UINT64_MAX
+#endif /* __INT64_TYPE__ */
 
-#define INT32_MAX         2147483647
-#define INT32_MIN        (-2147483647-1)
-#define UINT32_MAX        4294967295U
-#define INT_LEAST32_MIN  INT32_MIN
-#define INT_LEAST32_MAX  INT32_MAX
-#define UINT_LEAST32_MAX UINT32_MAX
-#define INT_FAST32_MIN   INT32_MIN
-#define INT_FAST32_MAX   INT32_MAX
-#define UINT_FAST32_MAX  UINT32_MAX
+#ifdef __INT_LEAST64_MIN
+# define INT_LEAST64_MIN   __INT_LEAST64_MIN
+# define INT_LEAST64_MAX   __INT_LEAST64_MAX
+# define UINT_LEAST64_MAX __UINT_LEAST64_MAX
+# define INT_FAST64_MIN    __INT_LEAST64_MIN
+# define INT_FAST64_MAX    __INT_LEAST64_MAX
+# define UINT_FAST64_MAX  __UINT_LEAST64_MAX
+#endif /* __INT_LEAST64_MIN */
 
-#define INT16_MAX    32767
-#define INT16_MIN  (-32768)
-#define UINT16_MAX   65535
-#define INT_LEAST16_MIN   INT16_MIN
-#define INT_LEAST16_MAX   INT16_MAX
-#define UINT_LEAST16_MAX UINT16_MAX
-#define INT_FAST16_MIN    INT16_MIN
-#define INT_FAST16_MAX    INT16_MAX
-#define UINT_FAST16_MAX  UINT16_MAX
 
-#define INT8_MAX    127
-#define INT8_MIN  (-128)
-#define UINT8_MAX   255
-#define INT_LEAST8_MIN   INT8_MIN
-#define INT_LEAST8_MAX   INT8_MAX
-#define UINT_LEAST8_MAX UINT8_MAX
-#define INT_FAST8_MIN    INT8_MIN
-#define INT_FAST8_MAX    INT8_MAX
-#define UINT_FAST8_MAX  UINT8_MAX
+#ifdef __INT56_TYPE__
+# define INT56_MAX   36028797018963967L
+# define INT56_MIN (-36028797018963967L-1)
+# define UINT56_MAX  72057594037927935UL
+# define INT_LEAST56_MIN     INT56_MIN
+# define INT_LEAST56_MAX     INT56_MAX
+# define UINT_LEAST56_MAX   UINT56_MAX
+# define INT_FAST56_MIN      INT56_MIN
+# define INT_FAST56_MAX      INT56_MAX
+# define UINT_FAST56_MAX    UINT56_MAX
+# define __INT_LEAST32_MIN   INT56_MIN
+# define __INT_LEAST32_MAX   INT56_MAX
+# define __UINT_LEAST32_MAX UINT56_MAX
+# define __INT_LEAST16_MIN   INT56_MIN
+# define __INT_LEAST16_MAX   INT56_MAX
+# define __UINT_LEAST16_MAX UINT56_MAX
+# define __INT_LEAST8_MIN    INT56_MIN
+# define __INT_LEAST8_MAX    INT56_MAX
+# define __UINT_LEAST8_MAX  UINT56_MAX
+#endif /* __INT56_TYPE__ */
 
+
+#ifdef __INT48_TYPE__
+# define INT48_MAX     140737488355327L
+# define INT48_MIN   (-140737488355327L-1)
+# define UINT48_MAX    281474976710655UL
+# define INT_LEAST48_MIN     INT48_MIN
+# define INT_LEAST48_MAX     INT48_MAX
+# define UINT_LEAST48_MAX   UINT48_MAX
+# define INT_FAST48_MIN      INT48_MIN
+# define INT_FAST48_MAX      INT48_MAX
+# define UINT_FAST48_MAX    UINT48_MAX
+# define __INT_LEAST32_MIN   INT48_MIN
+# define __INT_LEAST32_MAX   INT48_MAX
+# define __UINT_LEAST32_MAX UINT48_MAX
+# define __INT_LEAST16_MIN   INT48_MIN
+# define __INT_LEAST16_MAX   INT48_MAX
+# define __UINT_LEAST16_MAX UINT48_MAX
+# define __INT_LEAST8_MIN    INT48_MIN
+# define __INT_LEAST8_MAX    INT48_MAX
+# define __UINT_LEAST8_MAX  UINT48_MAX
+#endif /* __INT48_TYPE__ */
+
+
+#ifdef __INT40_TYPE__
+# define INT40_MAX        549755813887L
+# define INT40_MIN      (-549755813887L-1)
+# define UINT40_MAX      1099511627775UL
+# define INT_LEAST40_MIN     INT40_MIN
+# define INT_LEAST40_MAX     INT40_MAX
+# define UINT_LEAST40_MAX   UINT40_MAX
+# define INT_FAST40_MIN      INT40_MIN
+# define INT_FAST40_MAX      INT40_MAX
+# define UINT_FAST40_MAX    UINT40_MAX
+# define __INT_LEAST32_MIN   INT40_MIN
+# define __INT_LEAST32_MAX   INT40_MAX
+# define __UINT_LEAST32_MAX UINT40_MAX
+# define __INT_LEAST16_MIN   INT40_MIN
+# define __INT_LEAST16_MAX   INT40_MAX
+# define __UINT_LEAST16_MAX UINT40_MAX
+# define __INT_LEAST8_MIN    INT40_MIN
+# define __INT_LEAST8_MAX    INT40_MAX
+# define __UINT_LEAST8_MAX  UINT40_MAX
+#endif /* __INT40_TYPE__ */
+
+
+#ifdef __INT32_TYPE__
+# define INT32_MAX          2147483647
+# define INT32_MIN        (-2147483647-1)
+# define UINT32_MAX         4294967295U
+# define __INT_LEAST32_MIN   INT32_MIN
+# define __INT_LEAST32_MAX   INT32_MAX
+# define __UINT_LEAST32_MAX UINT32_MAX
+# define __INT_LEAST16_MIN   INT32_MIN
+# define __INT_LEAST16_MAX   INT32_MAX
+# define __UINT_LEAST16_MAX UINT32_MAX
+# define __INT_LEAST8_MIN    INT32_MIN
+# define __INT_LEAST8_MAX    INT32_MAX
+# define __UINT_LEAST8_MAX  UINT32_MAX
+#endif /* __INT32_TYPE__ */
+
+#ifdef __INT_LEAST32_MIN
+# define INT_LEAST32_MIN   __INT_LEAST32_MIN
+# define INT_LEAST32_MAX   __INT_LEAST32_MAX
+# define UINT_LEAST32_MAX __UINT_LEAST32_MAX
+# define INT_FAST32_MIN    __INT_LEAST32_MIN
+# define INT_FAST32_MAX    __INT_LEAST32_MAX
+# define UINT_FAST32_MAX  __UINT_LEAST32_MAX
+#endif /* __INT_LEAST32_MIN */
+
+
+#ifdef __INT24_TYPE__
+# define INT24_MAX             8388607
+# define INT24_MIN           (-8388608)
+# define UINT24_MAX           16777215
+# define INT_LEAST24_MIN     INT24_MIN
+# define INT_LEAST24_MAX     INT24_MAX
+# define UINT_LEAST24_MAX   UINT24_MAX
+# define INT_FAST24_MIN      INT24_MIN
+# define INT_FAST24_MAX      INT24_MAX
+# define UINT_FAST24_MAX    UINT24_MAX
+# define __INT_LEAST16_MIN   INT24_MIN
+# define __INT_LEAST16_MAX   INT24_MAX
+# define __UINT_LEAST16_MAX UINT24_MAX
+# define __INT_LEAST8_MIN    INT24_MIN
+# define __INT_LEAST8_MAX    INT24_MAX
+# define __UINT_LEAST8_MAX  UINT24_MAX
+#endif /* __INT24_TYPE__ */
+
+
+#ifdef __INT16_TYPE__
+#define INT16_MAX                32767
+#define INT16_MIN              (-32768)
+#define UINT16_MAX               65535
+# define __INT_LEAST16_MIN   INT16_MIN
+# define __INT_LEAST16_MAX   INT16_MAX
+# define __UINT_LEAST16_MAX UINT16_MAX
+# define __INT_LEAST8_MIN    INT16_MIN
+# define __INT_LEAST8_MAX    INT16_MAX
+# define __UINT_LEAST8_MAX  UINT16_MAX
+#endif /* __INT16_TYPE__ */
+
+#ifdef __INT_LEAST16_MIN
+# define INT_LEAST16_MIN   __INT_LEAST16_MIN
+# define INT_LEAST16_MAX   __INT_LEAST16_MAX
+# define UINT_LEAST16_MAX __UINT_LEAST16_MAX
+# define INT_FAST16_MIN    __INT_LEAST16_MIN
+# define INT_FAST16_MAX    __INT_LEAST16_MAX
+# define UINT_FAST16_MAX  __UINT_LEAST16_MAX
+#endif /* __INT_LEAST16_MIN */
+
+
+#ifdef __INT8_TYPE__
+# define INT8_MAX                 127
+# define INT8_MIN               (-128)
+# define UINT8_MAX                255
+# define __INT_LEAST8_MIN    INT8_MIN
+# define __INT_LEAST8_MAX    INT8_MAX
+# define __UINT_LEAST8_MAX  UINT8_MAX
+#endif /* __INT8_TYPE__ */
+
+#ifdef __INT_LEAST8_MIN
+# define INT_LEAST8_MIN   __INT_LEAST8_MIN
+# define INT_LEAST8_MAX   __INT_LEAST8_MAX
+# define UINT_LEAST8_MAX __UINT_LEAST8_MAX
+# define INT_FAST8_MIN    __INT_LEAST8_MIN
+# define INT_FAST8_MAX    __INT_LEAST8_MAX
+# define UINT_FAST8_MAX  __UINT_LEAST8_MAX
+#endif /* __INT_LEAST8_MIN */
+
 /* C99 7.18.2.4 Limits of integer types capable of holding object pointers. */
 /* C99 7.18.3 Limits of other integer types. */
 
