From patchwork Fri Jul 1 18:24:05 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 102942 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 57731B6F59 for ; Sat, 2 Jul 2011 04:24:53 +1000 (EST) Received: (qmail 5353 invoked by alias); 1 Jul 2011 18:24:49 -0000 Received: (qmail 5083 invoked by uid 22791); 1 Jul 2011 18:24:38 -0000 X-SWARE-Spam-Status: No, hits=0.8 required=5.0 tests=AWL, BAYES_50, SARE_BAYES_5x7, SARE_BAYES_6x7, SARE_BAYES_7x7, TW_CL, TW_IV, TW_LX, TW_PM, TW_VX, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 01 Jul 2011 18:24:15 +0000 Received: (qmail 23523 invoked from network); 1 Jul 2011 18:24:12 -0000 Received: from unknown (HELO ?84.152.209.23?) (bernds@127.0.0.2) by mail.codesourcery.com with ESMTPA; 1 Jul 2011 18:24:12 -0000 Message-ID: <4E0E10C5.3000804@codesourcery.com> Date: Fri, 01 Jul 2011 20:24:05 +0200 From: Bernd Schmidt User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110505 Lightning/1.0b3pre Thunderbird/3.1.10 MIME-Version: 1.0 To: GCC Patches Subject: RFC: 40 bit integer support Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Here's my current patch for 40 bit integer support. This requires the 11-patch GET_MODE_PRECISION series I just posted. C6X supports 40-bit integers in hardware; well enough that the old COFF ABI apparently defined "long" as a 40-bit type. Add and subtract have widening variants that can be used to synthesize 40-bit operations. Shifts and comparisons with small constants are supported directly. Other DSP-type CPUs are also likely to have a use for such operations. Blackfin has multiply-accumulate instructions with 40 bit accumulators. ARM Xscale supports this as well. I'm not really asking for approval for the patch just yet as it's untested in a 4.7 tree (4.5 c6x-elf testing shows that it basically works), and I'd like to have some more testcases first. However, it's IMO close to where it should be, and it would be good to know now if this will eventually be acceptable or not. Points that may be interesting. * Should we add an __int40_t keyword, or just do a pushdecl for it? The patch currently does the latter to match __int128_t, but decimal float and fixed-point support uses keywords. This may make a difference for (existing) code using "unsigned __int40_t". * What should be the name of the new mode? I'm using PImode, hoping to evoke the number five, but XImode by analogy with 80-bit floats might also work. * The __INT40_C macros use a cast, since using a new suffix is likely to conflict with something defined by a future standard. This means they are not usable in CPP tests. The TI compiler defines them in the same way, however, and mentions DR209. The link they give is defunct: http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_209.htm Bernd * doc/cpp.texi (__INT40_TYPE, __UINT40_TYPE__, __INT_LEAST40_TYPE__, __UINT_LEAST40_TYPE__, __INT_FAST40_TYPE__, __UINT_FAST40_TYPE__, __INT40_MAX__, __UINT40_MAX__, __INT_LEAST40_MAX__, __UINT_LEAST40_MAX__, __INT_FAST40_MAX__, __UINT_FAST40_MAX__, __INT40_C, __UINT40_C): Document. * doc/tm.texi.in (INT40_TYPE, UINT40_TYPE, INT_LEAST40_TYPE, UINT_LEAST40_TYPE, INT_FAST40_TYPE, UINT_FAST40_TYPE): Document. * doc/tm.texi: Regenerate. * defaults.h (INT40_TYPE, UINT40_TYPE, INT_LEAST40_TYPE, UINT_LEAST40_TYPE, INT_FAST40_TYPE, UINT_FAST40_TYPE): Default to NULL. * tree.h (enum tree_index): Add TI_INTPI_TYPE and TI_UINTPI_TYPE. (intPI_type-node, unsigned_intPI_type_node): New macros. * tree.c (build_common_tree_nodes): Build these nodes. * ginclude/stdint-gcc.h (int40_t, uint40_t, int_least40_t, uint_least40_t, int_fast40_t, uint_fast40_t): Define if the corresponding macro is set. (INT40_MAX, INT40_MIN, UINT40_MAX, INT_LEAST40_MAX, INT_LEAST40_MIN, UINT_LEAST40_MAX, INT_FAST40_MAX, INT_FAST40_MIN, UINT_FAST40_MAX, INT40_C, UINT40_C): Define if appropriate. * c-family/c-cppbuiltin.c (builtin_define_stdint_macros): Add 40 bit integer macros. (type_suffix): Return NULL for PImode types. (builtin_define_constants): Handle NULL suffix. (builtin_define_type_minmax): Add 40 bit constants. Handle NULL suffix. * machmode.def (PI): New mode. * varasm.c (assemble_integer): Handle modes that are wider than a word but not a multiple of the word size. * c-family/c-common.c (c_common_type_for_size): Return PImode types if appropriate. (c_common_type_for_mode): Handle PImode. (c_common_signed_or_unsigned_type): Handle PImode types. (c_common_nodes_and_builtins): Define __int40_t and __uint40_t if supported. Build 40 bit type nodes if requested. (c_stddef_cpp_builtins): Define 40 bit type macros if the types are available. * c-family/c-common.h (enum c_tree_index): Add CTI_INT40_TYPE, CTI_UINT40_TYPE, CTI_INT_LEAST40_TYPE, CTI_UINT_LEAST40_TYPE, CTI_INT_FAST40_TYPE and CTI_UINT_FAST40_TYPE. (int40_type_node, uint40_type_node, int_least40_type_node, uint_least40_type_node, int_fast40_type_node, uint_fast40_type_node): Define. * config/softp-fp/floatpisf.c: New file. * config/softp-fp/floatunpisf.c: New file. * config/softp-fp/floatpidf.c: New file. * config/softp-fp/floatunpidf.c: New file. * config/softp-fp/floatpitf.c: New file. * config/softp-fp/floatunpitf.c: New file. * config/softp-fp/fixunssfpi.c: New file. * config/softp-fp/fixsfpi.c: New file. * config/softp-fp/fixunsdfpi.c: New file. * config/softp-fp/fixdfpi.c: New file. * config/softp-fp/fixunstfpi.c: New file. * config/softp-fp/fixtfpi.c: New file. * config/soft-fp/soft-fp.h (PItype, UPItype): Declare if we have them. (PI_BITS): New macro. * libgcc2.h (PItype, UPItype0: Declare if supported. (__mulpi3, __divpi3, __modpi3, __udivpi3, __umodpi3): Define and declare. * libgcc2.c (__mulpi3, __divpi3, __modpi3, __udivpi3, __umodpi3): New functions. gcc/testsuite/ * gcc.dg/c99-stdint-1.c (test_exact, test_least, test_fsat, test_max, test_constants): Add tests and comments for 40 bit integers. * gcc.dg/c99-stdint-3.c (check_corresponding): Add tests for 40 bit integers. * gcc.dg/c99-stdint-7.c: Add comments about 40 bit integers. * gcc.dg/shift-pi.c: New test. * gcc.dg/arith-rand-40.c: New test. * gcc.dg/arith40.c: New test. * lib/target-supports.exp (check_effective_target_int40): New function. libgcc/ * Makefile.in (lib2funcs): Add LIB2_PI_FUNCS. * config/t-pimode: New file. 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 + +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);