diff --git a/.gitignore b/.gitignore index 5aa6e0df6b..366639ffe5 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ src/config.h.in src/fft_tuning.h src/flint.h src/flint-config.h +src/gmpcompat.h build/ config/ config.log diff --git a/CMakeLists.txt b/CMakeLists.txt index 795f89035c..145e8848b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -218,6 +218,14 @@ else() set(FLINT_REENTRANT OFF) endif() +# gmpcompat.h configuration +set(CMAKE_REQUIRED_INCLUDES ${GMP_INCLUDE_DIRS}) +check_c_source_compiles([[#include + #ifndef _LONG_LONG_LIMB + # error mp_limb_t != unsigned long long limb + #endif + void main(){};]] LONG_LONG_LIMB) + # Populate headers configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/CMake/cmake_config.h.in @@ -232,6 +240,19 @@ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/src/fmpz/fmpz.c COPYONLY ) +if(LONG_LONG_LIMB) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/src/gmpcompat-longlong.h.in + ${CMAKE_CURRENT_SOURCE_DIR}/src/gmpcompat.h + COPYONLY + ) +else() + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/src/gmpcompat.h.in + ${CMAKE_CURRENT_SOURCE_DIR}/src/gmpcompat.h + COPYONLY + ) +endif() if(CMAKE_SIZEOF_VOID_P EQUAL 8) configure_file( diff --git a/Makefile.in b/Makefile.in index cb5094d2b8..408cd1e9c9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -117,7 +117,8 @@ CFG_FILES := \ $(FLINT_DIR)/config.h $(SRC_DIR)/flint-config.h \ $(FLINT_DIR)/config.log $(SRC_DIR)/flint.h \ $(SRC_DIR)/fft_tuning.h $(FLINT_DIR)/flint.pc \ - $(FLINT_DIR)/Makefile $(SRC_DIR)/fmpz/fmpz.c + $(FLINT_DIR)/Makefile $(SRC_DIR)/fmpz/fmpz.c \ + $(SRC_DIR)/gmpcompat.h ################################################################################ # directories diff --git a/configure.ac b/configure.ac index e2886034aa..afd6d4cab7 100644 --- a/configure.ac +++ b/configure.ac @@ -629,6 +629,19 @@ AC_COMPILE_IFELSE( AC_MSG_RESULT([no]) AC_MSG_ERROR(["FLINT requires GMP version 6.2.1 or later."])) +AC_MSG_CHECKING([if GMP defines mp_limb_t as unsigned long long int]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [#include ], + [#if !defined(_LONG_LONG_LIMB) + # error mp_limb_t != unsigned long long int + #endif] + )], + AC_MSG_RESULT([yes]) + gmpcompat_h_in="gmpcompat-longlong.h.in", + AC_MSG_RESULT([no]) + gmpcompat_h_in="gmpcompat.h.in") + # Check that MPFR >= 4.1.0 AC_MSG_CHECKING([if version of MPFR is greater than 4.1.0]) AC_COMPILE_IFELSE( @@ -1155,7 +1168,7 @@ fi # epilog ################################################################################ -AC_CONFIG_FILES([Makefile flint.pc src/flint.h]) +AC_CONFIG_FILES([Makefile flint.pc src/flint.h src/gmpcompat.h:src/${gmpcompat_h_in}]) AC_OUTPUT dnl Shorten the original help message diff --git a/src/gmpcompat.h b/src/gmpcompat-longlong.h.in similarity index 90% rename from src/gmpcompat.h rename to src/gmpcompat-longlong.h.in index d9836981d7..adebefe8b3 100644 --- a/src/gmpcompat.h +++ b/src/gmpcompat-longlong.h.in @@ -79,8 +79,6 @@ void flint_mpz_add_signed_uiuiui(mpz_ptr a, mpz_srcptr b, mpz_add(a, b, c); } -#if WORD_MAX != LONG_MAX - #define FLINT_MOCK_MPZ_UI(xxx, yyy) \ __mpz_struct (xxx)[1] = {{ 1, 0, NULL }}; \ do { \ @@ -831,64 +829,6 @@ int flint_mpf_fits_slong_p(mpf_srcptr f) return fl <= (fs >= 0 ? (mp_limb_t) WORD_MAX : - (mp_limb_t) WORD_MIN); } -#else - -#define flint_mpz_get_si mpz_get_si -#define flint_mpz_get_ui mpz_get_ui -#define flint_mpz_set_si mpz_set_si -#define flint_mpz_set_ui mpz_set_ui -#define flint_mpz_init_set_si mpz_init_set_si -#define flint_mpz_init_set_ui mpz_init_set_ui -#define flint_mpz_add_ui mpz_add_ui -#define flint_mpz_sub_ui mpz_sub_ui -#define flint_mpz_mul_si mpz_mul_si -#define flint_mpz_mul_ui mpz_mul_ui -#define flint_mpz_addmul_ui mpz_addmul_ui -#define flint_mpz_submul_ui mpz_submul_ui -#define flint_mpz_ui_sub mpz_ui_sub -#define flint_mpz_ui_pow_ui mpz_ui_pow_ui -#define flint_mpz_cdiv_q_ui mpz_cdiv_q_ui -#define flint_mpz_cdiv_r_ui mpz_cdiv_r_ui -#define flint_mpz_cdiv_qr_ui mpz_cdiv_qr_ui -#define flint_mpz_cdiv_ui mpz_cdiv_ui -#define flint_mpz_fdiv_q_ui mpz_fdiv_q_ui -#define flint_mpz_fdiv_r_ui mpz_fdiv_r_ui -#define flint_mpz_fdiv_qr_ui mpz_fdiv_qr_ui -#define flint_mpz_fdiv_ui mpz_fdiv_ui -#define flint_mpz_tdiv_q_ui mpz_tdiv_q_ui -#define flint_mpz_tdiv_r_ui mpz_tdiv_r_ui -#define flint_mpz_tdiv_qr_ui mpz_tdiv_qr_ui -#define flint_mpz_tdiv_ui mpz_tdiv_ui -#define flint_mpz_mod_ui mpz_mod_ui -#define flint_mpz_divexact_ui mpz_divexact_ui -#define flint_mpz_divisible_ui_p mpz_divisible_ui_p -#define flint_mpz_congruent_ui_p mpz_congruent_ui_p -#define flint_mpz_powm_ui mpz_powm_ui -#define flint_mpz_pow_ui mpz_pow_ui -#define flint_mpz_fac_ui mpz_fac_ui -#define flint_mpz_bin_uiui mpz_bin_uiui -#define flint_mpz_fib_ui mpz_fib_ui -#define flint_mpz_cmp_si mpz_cmp_si -#define flint_mpz_cmp_ui mpz_cmp_ui -#define flint_mpq_cmp_si mpq_cmp_si -#define flint_mpq_cmp_ui mpq_cmp_ui -#define flint_mpq_set_si mpq_set_si -#define flint_mpq_set_ui mpq_set_ui - -#define flint_mpf_set_si mpf_set_si -#define flint_mpf_set_ui mpf_set_ui -#define flint_mpf_get_si mpf_get_si -#define flint_mpf_cmp_ui mpf_cmp_ui -#define flint_mpf_fits_slong_p mpf_fits_slong_p - -#endif - -#if WORD_MAX == LONG_MAX - -#define flint_mpf_get_d_2exp mpf_get_d_2exp - -#else - /* defined in mpn_extras.h and used by flint_mpf_get_d_2exp below */ double flint_mpn_get_d(mp_srcptr ptr, mp_size_t size, mp_size_t sign, long exp); @@ -941,5 +881,3 @@ double flint_mpf_get_d_2exp(slong * exp2, mpf_srcptr src) } #endif - -#endif diff --git a/src/gmpcompat.h.in b/src/gmpcompat.h.in new file mode 100644 index 0000000000..7ecfe3bc33 --- /dev/null +++ b/src/gmpcompat.h.in @@ -0,0 +1,131 @@ +/* + Copyright (C) 2013 William Hart + + This file is part of FLINT. + + FLINT is free software: you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License (LGPL) as published + by the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. See . +*/ + +#ifndef GMP_COMPAT_H +#define GMP_COMPAT_H + +#include "flint.h" + +#define FLINT_MPZ_REALLOC(z, len) \ + ((len) > ((z)->_mp_alloc) \ + ? (mp_ptr) _mpz_realloc(z, len) \ + : ((z)->_mp_d)) + +static __inline__ +void flint_mpz_add_uiui(mpz_ptr a, mpz_srcptr b, ulong c1, ulong c0) +{ + ulong d[2]; + mpz_t c; + d[0] = c0; + d[1] = c1; + c->_mp_d = d; + c->_mp_alloc = 2; + c->_mp_size = d[1] != 0 ? 2 : d[0] != 0; + mpz_add(a, b, c); +} + +static __inline__ +void flint_mpz_add_signed_uiui(mpz_ptr a, mpz_srcptr b, ulong c1, ulong c0) +{ + ulong d[2]; + ulong c2 = FLINT_SIGN_EXT(c1); + mpz_t c; + sub_ddmmss(d[1], d[0], c2^c1, c2^c0, c2, c2); + c->_mp_d = d; + c->_mp_alloc = 2; + c->_mp_size = d[1] != 0 ? 2 : d[0] != 0; + if (c2 != 0) + c->_mp_size = -c->_mp_size; + mpz_add(a, b, c); +} + +static __inline__ +void flint_mpz_add_uiuiui(mpz_ptr a, mpz_srcptr b, ulong c2, ulong c1, ulong c0) +{ + ulong d[3]; + mpz_t c; + d[0] = c0; + d[1] = c1; + d[2] = c2; + c->_mp_d = d; + c->_mp_alloc = 3; + c->_mp_size = d[2] != 0 ? 3 : d[1] != 0 ? 2 : d[0] != 0; + mpz_add(a, b, c); +} + +static __inline__ +void flint_mpz_add_signed_uiuiui(mpz_ptr a, mpz_srcptr b, + ulong c2, ulong c1, ulong c0) +{ + ulong cs, d[3]; + mpz_t c; + c->_mp_d = d; + c->_mp_alloc = 3; + cs = FLINT_SIGN_EXT(c2); + sub_dddmmmsss(d[2], d[1], d[0], cs^c2, cs^c1, cs^c0, cs, cs, cs); + c->_mp_size = d[2] != 0 ? 3 : + d[1] != 0 ? 2 : + d[0] != 0; + if (cs != 0) + c->_mp_size = -c->_mp_size; + mpz_add(a, b, c); +} + +#define flint_mpz_get_si mpz_get_si +#define flint_mpz_get_ui mpz_get_ui +#define flint_mpz_set_si mpz_set_si +#define flint_mpz_set_ui mpz_set_ui +#define flint_mpz_init_set_si mpz_init_set_si +#define flint_mpz_init_set_ui mpz_init_set_ui +#define flint_mpz_add_ui mpz_add_ui +#define flint_mpz_sub_ui mpz_sub_ui +#define flint_mpz_mul_si mpz_mul_si +#define flint_mpz_mul_ui mpz_mul_ui +#define flint_mpz_addmul_ui mpz_addmul_ui +#define flint_mpz_submul_ui mpz_submul_ui +#define flint_mpz_ui_sub mpz_ui_sub +#define flint_mpz_ui_pow_ui mpz_ui_pow_ui +#define flint_mpz_cdiv_q_ui mpz_cdiv_q_ui +#define flint_mpz_cdiv_r_ui mpz_cdiv_r_ui +#define flint_mpz_cdiv_qr_ui mpz_cdiv_qr_ui +#define flint_mpz_cdiv_ui mpz_cdiv_ui +#define flint_mpz_fdiv_q_ui mpz_fdiv_q_ui +#define flint_mpz_fdiv_r_ui mpz_fdiv_r_ui +#define flint_mpz_fdiv_qr_ui mpz_fdiv_qr_ui +#define flint_mpz_fdiv_ui mpz_fdiv_ui +#define flint_mpz_tdiv_q_ui mpz_tdiv_q_ui +#define flint_mpz_tdiv_r_ui mpz_tdiv_r_ui +#define flint_mpz_tdiv_qr_ui mpz_tdiv_qr_ui +#define flint_mpz_tdiv_ui mpz_tdiv_ui +#define flint_mpz_mod_ui mpz_mod_ui +#define flint_mpz_divexact_ui mpz_divexact_ui +#define flint_mpz_divisible_ui_p mpz_divisible_ui_p +#define flint_mpz_congruent_ui_p mpz_congruent_ui_p +#define flint_mpz_powm_ui mpz_powm_ui +#define flint_mpz_pow_ui mpz_pow_ui +#define flint_mpz_fac_ui mpz_fac_ui +#define flint_mpz_bin_uiui mpz_bin_uiui +#define flint_mpz_fib_ui mpz_fib_ui +#define flint_mpz_cmp_si mpz_cmp_si +#define flint_mpz_cmp_ui mpz_cmp_ui +#define flint_mpq_cmp_si mpq_cmp_si +#define flint_mpq_cmp_ui mpq_cmp_ui +#define flint_mpq_set_si mpq_set_si +#define flint_mpq_set_ui mpq_set_ui + +#define flint_mpf_set_si mpf_set_si +#define flint_mpf_set_ui mpf_set_ui +#define flint_mpf_get_si mpf_get_si +#define flint_mpf_cmp_ui mpf_cmp_ui +#define flint_mpf_fits_slong_p mpf_fits_slong_p +#define flint_mpf_get_d_2exp mpf_get_d_2exp + +#endif