This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Make HOST_WIDE_INT underlying type match int64_t, adjust printing macros again


This computes the underlying type of int64_t in a configure check and
uses that for HOST_WIDE_INT.  This makes sure we can use the PRI?64
macros from inttypes.h for HOST_WIDE_INT_PRINT_*, which the following
patch re-instantiates.

The patch also makes sure inttypes.h defines PRId64 and if not,
provides replacements in hwint.h (like previously), matching
int64_t.

Built on i586-linux-gnu and x86_64-linux-gnu (to verify both
'long' and 'long long' choices).  A bootstrap and regtest on
x86_64-unknown-linux-gnu is pending.

Ok?

Thanks,
Richard.

2014-06-02  Richard Biener  <rguenther@suse.de>

	* configure.ac: Check whether the underlying type of int64_t
	is long or long long.
	* configure: Regenerate.
	* config.in: Likewise.
	* hwint.h (HOST_WIDE_INT): Match the underlying type of int64_t.
	(HOST_WIDE_INT_PRINT_*): Define in terms of PRI*64.

Index: gcc/configure.ac
===================================================================
*** gcc/configure.ac	(revision 211125)
--- gcc/configure.ac	(working copy)
*************** if test x"$ac_cv_c_uint64_t" = x"no" -o
*** 316,321 ****
--- 316,350 ----
    AC_MSG_ERROR([uint64_t or int64_t not found])
  fi
  
+ # check what underlying integer type int64_t uses
+ AC_LANG_PUSH(C++)
+ AC_CACHE_CHECK(for int64_t underlying type, ac_cv_int64_t_type, [
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #ifdef HAVE_STDINT_H
+ #include <stdint.h>
+ #endif
+ template <typename T> struct X { };
+ template <>
+ struct X<long> { typedef long t; };
+ ]], [[typename X<int64_t>::t x;]])],[ac_cv_int64_t_type=long],[ac_cv_int64_t_type="long long"])])
+ if test x$ac_cv_int64_t_type = xlong; then
+   AC_DEFINE(INT64_T_IS_LONG, 1,
+   [Define if int64_t uses long as underlying type.])
+ else
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #ifdef HAVE_STDINT_H
+ #include <stdint.h>
+ #endif
+ template <typename T> struct X { };
+ template <>
+ struct X<long long> { typedef long long t; };
+ ]], [[typename X<int64_t>::t x;]])],[],[AC_MSG_ERROR([error verifying int64_t uses long long])])
+ fi
+ AC_LANG_POP(C++)
+ 
+ 
+ 
+ 
  # ---------------------
  # Warnings and checking
  # ---------------------
*************** LIBS="$save_LIBS"
*** 1055,1067 ****
  AC_SUBST(LDEXP_LIB)
  
  # Use <inttypes.h> only if it exists,
! # doesn't clash with <sys/types.h>, and declares intmax_t.
  AC_MSG_CHECKING(for inttypes.h)
  AC_CACHE_VAL(gcc_cv_header_inttypes_h,
  [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
! [[#include <sys/types.h>
  #include <inttypes.h>]],
!   [[intmax_t i = -1;]])],
    [gcc_cv_header_inttypes_h=yes],
    [gcc_cv_header_inttypes_h=no])])
  AC_MSG_RESULT($gcc_cv_header_inttypes_h)
--- 1084,1101 ----
  AC_SUBST(LDEXP_LIB)
  
  # Use <inttypes.h> only if it exists,
! # doesn't clash with <sys/types.h>, declares intmax_t and defines
! # PRId64
  AC_MSG_CHECKING(for inttypes.h)
  AC_CACHE_VAL(gcc_cv_header_inttypes_h,
  [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
! [[#define __STDC_FORMAT_MACROS
! #include <sys/types.h>
  #include <inttypes.h>]],
!   [[intmax_t i = -1;
! #ifndef PRId64
! choke me
! #endif]])],
    [gcc_cv_header_inttypes_h=yes],
    [gcc_cv_header_inttypes_h=no])])
  AC_MSG_RESULT($gcc_cv_header_inttypes_h)
Index: gcc/hwint.h
===================================================================
*** gcc/hwint.h	(revision 211125)
--- gcc/hwint.h	(working copy)
*************** extern char sizeof_long_long_must_be_8[s
*** 46,58 ****
  #endif
  
  /* Set HOST_WIDE_INT, this should be always 64 bits.
! 
!    With a sane ABI, 'long' is the largest efficient host integer type.
!    Thus, we use that unless we have to use 'long long'
!    because we're on a 32-bit host.  */
  
  #define HOST_BITS_PER_WIDE_INT 64
! #if HOST_BITS_PER_LONG == 64
  #   define HOST_WIDE_INT long
  #   define HOST_WIDE_INT_C(X) X ## L
  #else
--- 46,56 ----
  #endif
  
  /* Set HOST_WIDE_INT, this should be always 64 bits.
!    The underlying type is matched to that of int64_t and assumed
!    to be either long or long long.  */
  
  #define HOST_BITS_PER_WIDE_INT 64
! #if INT64_T_IS_LONG   
  #   define HOST_WIDE_INT long
  #   define HOST_WIDE_INT_C(X) X ## L
  #else
*************** extern char sizeof_long_long_must_be_8[s
*** 75,122 ****
     typedef before using the __asm_fprintf__ format attribute.  */
  typedef HOST_WIDE_INT __gcc_host_wide_int__;
  
- /* Various printf format strings for HOST_WIDE_INT.  */
- 
- #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
- # define HOST_WIDE_INT_PRINT HOST_LONG_FORMAT
- # define HOST_WIDE_INT_PRINT_C "L"
-   /* HOST_BITS_PER_WIDE_INT is 64 bits.  */
- # define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
-     "0x%" HOST_LONG_FORMAT "x%016" HOST_LONG_FORMAT "x"
- # define HOST_WIDE_INT_PRINT_PADDED_HEX \
-     "%016" HOST_LONG_FORMAT "x"
- #else
- # define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT
- # define HOST_WIDE_INT_PRINT_C "LL"
-   /* HOST_BITS_PER_WIDE_INT is 64 bits.  */
- # define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
-     "0x%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x"
- # define HOST_WIDE_INT_PRINT_PADDED_HEX \
-     "%016" HOST_LONG_LONG_FORMAT "x"
- #endif /* HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG */
- 
- #define HOST_WIDE_INT_PRINT_DEC "%" HOST_WIDE_INT_PRINT "d"
- #define HOST_WIDE_INT_PRINT_DEC_C HOST_WIDE_INT_PRINT_DEC HOST_WIDE_INT_PRINT_C
- #define HOST_WIDE_INT_PRINT_UNSIGNED "%" HOST_WIDE_INT_PRINT "u"
- #define HOST_WIDE_INT_PRINT_HEX "%#" HOST_WIDE_INT_PRINT "x"
- #define HOST_WIDE_INT_PRINT_HEX_PURE "%" HOST_WIDE_INT_PRINT "x"
- 
  /* Provide C99 <inttypes.h> style format definitions for 64bits.  */
  #ifndef HAVE_INTTYPES_H
  #undef PRId64
! #define PRId64 HOST_WIDE_INT_PRINT "d"
  #undef PRIi64
! #define PRIi64 HOST_WIDE_INT_PRINT "i"
  #undef PRIo64
! #define PRIo64 HOST_WIDE_INT_PRINT "o"
  #undef PRIu64
! #define PRIu64 HOST_WIDE_INT_PRINT "u"
  #undef PRIx64
! #define PRIx64 HOST_WIDE_INT_PRINT "x"
  #undef PRIX64
! #define PRIX64 HOST_WIDE_INT_PRINT "X"
  #endif
  
  /* Define HOST_WIDEST_FAST_INT to the widest integer type supported
     efficiently in hardware.  (That is, the widest integer type that fits
     in a hardware register.)  Normally this is "long" but on some hosts it
--- 73,117 ----
     typedef before using the __asm_fprintf__ format attribute.  */
  typedef HOST_WIDE_INT __gcc_host_wide_int__;
  
  /* Provide C99 <inttypes.h> style format definitions for 64bits.  */
  #ifndef HAVE_INTTYPES_H
+ #if INT64_T_IS_LONG
+ # define GCC_PRI64 HOST_LONG_FORMAT
+ #else
+ # define GCC_PRI64 HOST_LONG_LONG_FORMAT
+ #endif
  #undef PRId64
! #define PRId64 GCC_PRI64 "d"
  #undef PRIi64
! #define PRIi64 GCC_PRI64 "i"
  #undef PRIo64
! #define PRIo64 GCC_PRI64 "o"
  #undef PRIu64
! #define PRIu64 GCC_PRI64 "u"
  #undef PRIx64
! #define PRIx64 GCC_PRI64 "x"
  #undef PRIX64
! #define PRIX64 GCC_PRI64 "X"
  #endif
  
+ /* Various printf format strings for HOST_WIDE_INT.  */
+ 
+ #if INT64_T_IS_LONG
+ # define HOST_WIDE_INT_PRINT HOST_LONG_FORMAT
+ # define HOST_WIDE_INT_PRINT_C "L"
+ #else
+ # define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT
+ # define HOST_WIDE_INT_PRINT_C "LL"
+ #endif
+ 
+ #define HOST_WIDE_INT_PRINT_DEC "%" PRId64
+ #define HOST_WIDE_INT_PRINT_DEC_C "%" PRId64 HOST_WIDE_INT_PRINT_C
+ #define HOST_WIDE_INT_PRINT_UNSIGNED "%" PRIu64
+ #define HOST_WIDE_INT_PRINT_HEX "%#" PRIx64
+ #define HOST_WIDE_INT_PRINT_HEX_PURE "%" PRIx64
+ #define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%" PRIx64 "%016" PRIx64
+ #define HOST_WIDE_INT_PRINT_PADDED_HEX "%016" PRIx64
+ 
  /* Define HOST_WIDEST_FAST_INT to the widest integer type supported
     efficiently in hardware.  (That is, the widest integer type that fits
     in a hardware register.)  Normally this is "long" but on some hosts it


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]