On x86-64-MinGW the size of long is 4. As long is used for
SCM_FIXNUM_BIT, that would mean incompatible .go files, and waste of
cell space. So we would like to use long long, but the GMP interface
uses long.
To get around this, the x86-64-MinGW port now requires the use of
mini-GMP. Mini-GMP has been changed to use intptr_t and uintptr_t.
Likewise, "integers.{h,c}" and "numbers.{h,c}" now use intptr_t instead
of scm_t_inum or long, and uintptr_t instead of unsigned long.
* configure.ac: When x86_64-w64-mingw32, require mini-GMP.
* libguile/mini-gmp.h: Use intptr_t instead of long, uintptr_t instead
of unsigned long throughout.
* libguile/mini-gmp.c: Likewise.
* libguile/scm.h (SCM_INTPTR_T_BIT): New define.
* libguile/numbers.h (SCM_FIXNUM_BIT): Use it.
* libguile/numbers.c (L1, UL1): New macros. Use them thoughout instead
of 1L, 1UL.
(verify): Use SCM_INTPTR_T_BIT.
(verify): Use SCM_INTPTR_T_MAX and SCM_INTPTR_T_MIN.
(scm_from_inum): Remove macro.
Use intptr_t and uintptr_t instead of scm_t_inum or long, and unsigned
long.
* libguile/numbers.h (scm_from_intptr, scm_from_uintptr, scm_to_intptr,
scm_to_uintptr): New defines.
* libguile/integers.h: Use intptr_t and uintptr_t instead of scm_t_inum
and unsigned long.
* libguile/integers.c (L1) : New macro. Use it thoughout instead of 1L.
Use intptr_t and uintptr_t instead of long and unsigned long.
(long_magnitude): Rename to...
(intptr_t_magnitude): ...this. Use intptr_t, uintptr_t.
(negative_long): Rename to...
(negative_t_intptr): ...this. Use uintptr_t, INTPTR_MIN.
(inum_magnitude): Use intptr_t.
(ulong_to_bignum): Rename to...
(uintptr_t_to_bignum): ...this. Use uintptr_t.
(long_to_bignum): Rename to...
(intptr_t_to_bignum): ...this. Use intptr_t.
(long_to_scm): Rename to...
(intptr_t_to_scm): ...this. Use intptr_to_bignum.
(ulong_to_scm): Rename to...
(uintptr_t_to_scm): ...this. Use uintptr_to_bignum.
(long_sign): Rename to..
(intptr_t_sign): ...this. Use SCM_SIZEOF_INTPTR_T.
(bignum_cmp_long): Rename to...
(bignum_cmp_intptr_t): ...this. Use uintptr_t.
* libguile/array-map.c (array_compare): Use uintptr_t instead of
unsigned long and intptr_t instead of long.
* libguile/arrays.c (make-shared-array): Use ssize_t instead of long.
* libguile/bytevectors.c (is_signed_int32, is_unsigned_int32)
[MINGW32 && __x86_64__]: Use ULL.
(twos_complement): Use uintptr_t instead of unsigned long.
* libguile/hash.c (JENKINS_LOOKUP3_HASHWORD2): Likewise.
(narrow_string_hash, wide_string_hash, scm_i_string_hash,
scm_i_locale_string_hash, scm_i_latin1_string_hash,
scm_i_utf8_string_hash, scm_i_struct_hash, scm_raw_ihashq,
scm_raw_ihash): Use and return uintptr_t instead of unsigned long.
(scm_hashv, scm_hash): Use SCM_UINTPTR_T_MAX.
* libguile/hash.h (scm_i_locale_string_hash, scm_i_latin1_string_hash,
scm_i_utf8_string_hash): update prototypes.
* libguile/scmsigs.c (sigaction): Use intptr_t instead of long.
* libguile/strings.c (scm_i_make_symbol, (scm_i_c_make_symbol): Use
uintptr_t instead of unsigned long.
* libguile/strings.h (scm_i_make_symbol, (scm_i_c_make_symbol): Update
declacations.
* libguile/srfi-60.c: Use scm_to_uintptr, scm_from_intptr and variants
throughout.
* libguile/symbols.c (symbol-hash): Use scm_from_uintptr.
Co-authored-by: Mike Gran <spk121@yahoo.com>
Co-authored-by: Andy Wingo <wingo@pobox.com>
* libguile/numbers.c (log_of_shifted_double, scm_log10): Avoid complex
extension when the argument is a real nan.
* test-suite/tests/numbers.test: Tests for nans of either sign.
* libguile/numbers.c (scm_abs): As stated. When x is a nan with the sign bit
set, this changes the behavior of (magnitude x) back to what it was in 3.0.7,
to clear that bit.
Calling out to Scheme was a performance regression.
* libguile/integers.h:
* libguile/integers.c (scm_integer_expt_ii, scm_integer_expt_zi): New
internal functions.
* libguile/numbers.c (scm_integer_expt): Go back to C. But, include
fast cases for inums and doubles.
* module/ice-9/boot-9.scm: Revert addition of integer-expt.
* libguile/deprecated.c (make_bignum): Move here from numbers.c, to
support scm_i_long2big etc.
(scm_i_big2dbl):
(scm_i_long2big):
(scm_i_ulong2big):
(scm_i_clonebig):
(scm_i_normbig): Deprecate.
(scm_install_gmp_memory_functions): Deprecate, happily! SCM bignums now
have digits allocated inline with the bignum itself, so they are
completely transparent to the GC already. The price is that if GMP ever
allocates digits via the MPZ API, those digits then have to be copied
back into managed memory. But we avoid having to install finalizers and
we avoid having to muck with GMP's allocator.
* libguile/numbers.c (scm_from_mpz): Use scm_integer_from_mpz.
(scm_init_numbers): Never muck with GMP's allocators.
* doc/ref/guile-invoke.texi (Environment Variables): Remove note about
GUILE_INSTALL_GMP_MEMORY_FUNCTIONS.
* meta/build-env.in: No need to set GUILE_INSTALL_GMP_MEMORY_FUNCTIONS.
* libguile/integers.c (scm_integer_to_double_z): Doubles that can't be
exactly represented as integers should round.
(bignum_frexp_z): New helper.
(scm_integer_from_mpz, scm_integer_from_double): New internal functions.
* libguile/numbers.h:
* libguile/numbers.c (scm_i_bigcmp, scm_i_dbl2big, scm_i_dbl2num):
Remove unused internal functions.
(scm_inexact_to_exact): Rework to avoid scm_i_dbl2big.
(scm_bigequal): Move here, from eq.c.
(scm_integer_to_double_z): Use the new helper.
(scm_i_big2dbl): Use scm_integer_to_double_z.
* libguile/numbers.c: We require IEEE infinities and NaN so there is no
case in which ALLOW_DIVIDE_BY_ZERO would not be defined.
(scm_divide, scm_tan, scm_tanh, scm_log, scm_log10): Always throw on
overflow for divide by exact zero, never throw for divide by inexact
zero.
* libguile/numbers.c (scm_product): Remove need for s_product defines.
Call out to product, as appropriate.
(product): New helper.
* libguile/integers.h:
* libguile/integers.c (scm_integer_mul_ii):
(scm_integer_mul_zi):
(scm_integer_mul_zz): New internal functions.
* libguile/numbers.c (scm_sum): Remove need for s_sum defines.
(negate, difference): New helpers.
(scm_difference): Call out to difference or negate, as appropriate.
* libguile/integers.h:
* libguile/integers.c (scm_integer_negate_i):
(scm_integer_negate_z):
(scm_integer_sub_ii):
(scm_integer_sub_iz):
(scm_integer_sub_zi):
(scm_integer_sub_zz): New internal functions.
* libguile/integers.h:
* libguile/integers.c (scm_integer_to_double_z):
(scm_integer_add_ii, scm_integer_add_zi, scm_integer_add_zz): New
internal functions.
* libguile/numbers.c (sum): New helper for scm_sum. Clean up to avoid
repetition. The dispatch is less optimal but the code is shorter and
more maintainable; in any case if speed is important, the compiler needs
to be involved.
(scm_sum): Adapt.
* libguile/numbers.c (scm_is_less_than, scm_is_greater_than):
(scm_is_less_than_or_equal, scm_is_greater_than_or_equal): New internal
functions.
(scm_less_p, scm_gr_p, scm_leq_p, scm_geq_p): Use new helpers. Dispatch
to generics if operands aren't real -- a tightening relative to the
previous check which was just for numbers.
* libguile/integers.h:
* libguile/integers.c (scm_is_integer_less_than_ir):
(scm_is_integer_less_than_ri):
(scm_is_integer_less_than_zz):
(scm_is_integer_less_than_zr):
(scm_is_integer_less_than_rz):
(scm_is_integer_positive_z):
(scm_is_integer_negative_z): New internal functions.
* libguile/integers.h:
* libguile/integers.c (scm_is_integer_equal_ir):
(scm_is_integer_equal_ic):
(scm_is_integer_equal_zz):
(scm_is_integer_equal_zr):
(scm_is_integer_equal_zc): New internal functions.
* libguile/numbers.c (scm_num_eq_p): Rework to tail-recurse if we need
to swap arguments, to reduce duplication, and use the new integer lib.
* libguile/numbers.c (scm_bigprint): Just convert the number to a string
and write that. Adds a copy but if we optimize scm_integer_to_string_z
then that will be fixed.
* libguile/integers.c (scm_integer_to_string_i)
(scm_integer_to_string_z): New internal functions.
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_number_to_string): Use new internal
functions.
* libguile/integers.c (scm_integer_length_i)
(scm_integer_length_z): New internal functions.
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_integer_length): Use new internal functions.
* libguile/integers.h (scm_bignum): Declare opaque struct type and a
function to cast SCM to this type. Adapt all routines that take bignums
to take a "struct scm_bignum *".
* libguile/integers.c: Adapt.
* libguile/numbers.c: Adapt all users.
* libguile/integers.c (scm_integer_logcount_i)
(scm_integer_logcount_z): New internal functions.
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_logcount): Use new internal functions.
* libguile/integers.c (scm_integer_bit_extract_i)
(scm_integer_bit_extract_z): New internal functions.
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_bit_extract): Use new internal functions.
* libguile/integers.c (scm_integer_lsh_iu, scm_integer_lsh_zu)
(scm_integer_floor_rsh_iu, scm_integer_floor_rsh_zu)
(scm_integer_round_rsh_iu, scm_integer_round_rsh_zu): New internal
functions.
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_ash): Use new internal functions.
* libguile/numbers.c (integer_expt_var): New static variable.
(init_integer_expt_var): New helper.
(scm_integer_expt): Delegate to Scheme.
* module/ice-9/boot-9.scm (integer-expt): Reimplement in Scheme. Misses
some optimizations for fractions but that is probably OK!
* libguile/integers.c (scm_integer_modulo_expt_nnn):
(integer_init_mpz): New helper.
* libguile/integers.h: Declare the new internal function.
* libguile/numbers.c (scm_modulo_expt): Use new internal function.
* libguile/integers.c (scm_integer_lognot_i, scm_integer_lognot_z):
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_lognot): Use new internal functions.
* libguile/integers.c (scm_integer_logbit_ui, scm_integer_logbit_uz):
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_logbit_p): Use new internal functions.
* libguile/integers.c (scm_integer_logtest_ii, scm_integer_logtest_zi)
(scm_integer_logtest_zz): New internal functions.
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_logtest): Use new internal functions.
* libguile/integers.c (scm_integer_logxor_ii, scm_integer_logxor_zi)
(scm_integer_logxor_zz): New internal functions.
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_logxor): Use new internal functions.
* libguile/integers.c (scm_integer_logior_ii, scm_integer_logior_zi)
(scm_integer_logior_zz): New internal functions.
* libguile/integers.h: Declare the new internal functions.
* libguile/numbers.c (scm_logior): Use new internal functions.