diff --git a/src/bignum.c b/src/bignum.c index e6cef143383fd95d59211451e1a6c924241ada2c..a807e5adabe9d61dab4c1ab9437c25a7a61d2e3e 100644 --- a/src/bignum.c +++ b/src/bignum.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: bignum.c,v 1.43 2008/05/01 20:50:02 mast Exp $ +|| $Id: bignum.c,v 1.44 2008/05/01 21:14:04 mast Exp $ */ #include "global.h" @@ -135,26 +135,32 @@ static void bootstrap_push_int64 (INT64 i) } PMOD_EXPORT void (*push_int64) (INT64) = bootstrap_push_int64; -PMOD_EXPORT void (*push_uint64) (unsigned INT64) = NULL; PMOD_EXPORT int (*int64_from_bignum) (INT64 *, struct object *) = NULL; -PMOD_EXPORT int (*uint64_from_bignum) (unsigned INT64 *, struct object *)=NULL; PMOD_EXPORT void (*reduce_stack_top_bignum) (void) = NULL; +#endif + +PMOD_EXPORT void (*push_ulongest) (unsigned LONGEST) = NULL; +PMOD_EXPORT int (*ulongest_from_bignum) (unsigned LONGEST *, + struct object *) = NULL; -PMOD_EXPORT void hook_in_int64_funcs ( +PMOD_EXPORT void hook_in_gmp_funcs ( +#ifdef INT64 void (*push_int64_val)(INT64), - void (*push_uint64_val) (unsigned INT64), int (*int64_from_bignum_val) (INT64 *, struct object *), - int (*uint64_from_bignum_val) (unsigned INT64 *, struct object *), - void (*reduce_stack_top_bignum_val) (void)) + void (*reduce_stack_top_bignum_val) (void), +#endif + void (*push_ulongest_val) (unsigned LONGEST), + int (*ulongest_from_bignum_val) (unsigned LONGEST *, struct object *)) { /* Assigning the pointers above directly from the Gmp module doesn't * work in some cases, e.g. NT. */ +#ifdef INT64 push_int64 = push_int64_val ? push_int64_val : bootstrap_push_int64; - push_uint64 = push_uint64_val; int64_from_bignum = int64_from_bignum_val; - uint64_from_bignum = uint64_from_bignum_val; reduce_stack_top_bignum = reduce_stack_top_bignum_val; -} #endif + push_ulongest = push_ulongest_val; + ulongest_from_bignum = ulongest_from_bignum_val; +} #endif /* AUTO_BIGNUM */ diff --git a/src/bignum.h b/src/bignum.h index e88e7dfc59f58268a38ae7b628086743e033e4b7..e6c994f96606dd6db8b06502634b72feb8fa9ae2 100644 --- a/src/bignum.h +++ b/src/bignum.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: bignum.h,v 1.32 2008/05/01 20:49:15 mast Exp $ +|| $Id: bignum.h,v 1.33 2008/05/01 21:14:04 mast Exp $ */ #include "global.h" @@ -60,40 +60,40 @@ PMOD_EXPORT void convert_svalue_to_bignum(struct svalue *s); #ifdef INT64 PMOD_EXPORT extern void (*push_int64)(INT64 i); -PMOD_EXPORT extern void (*push_uint64) (unsigned INT64 i); /* Returns nonzero iff conversion is successful. */ PMOD_EXPORT extern int (*int64_from_bignum) (INT64 *i, struct object *bignum); -PMOD_EXPORT extern int (*uint64_from_bignum) (unsigned INT64 *i, - struct object *bignum); PMOD_EXPORT extern void (*reduce_stack_top_bignum) (void); -PMOD_EXPORT void hook_in_int64_funcs ( - void (*push_int64_val)(INT64), - void (*push_uint64_val) (unsigned INT64), - int (*int64_from_bignum_val) (INT64 *, struct object *), - int (*uint64_from_bignum_val) (unsigned INT64 *, struct object *), - void (*reduce_stack_top_bignum_val) (void)); #else #define push_int64(i) push_int((INT_TYPE)(i)) -#define push_uint64(i) push_int((INT_TYPE)(i)) #define int64_from_bignum(I,BIGNUM) 0 -#define uint64_from_bignum(I,BIGNUM) 0 #endif /* INT64 */ + +PMOD_EXPORT extern void (*push_ulongest) (unsigned LONGEST i); +PMOD_EXPORT extern int (*ulongest_from_bignum) (unsigned LONGEST *i, + struct object *bignum); +PMOD_EXPORT void hook_in_gmp_funcs ( +#ifdef INT64 + void (*push_int64_val)(INT64), + int (*int64_from_bignum_val) (INT64 *, struct object *), + void (*reduce_stack_top_bignum_val) (void), +#endif + void (*push_ulongest_val) (unsigned LONGEST), + int (*ulongest_from_bignum_val) (unsigned LONGEST *, struct object *)); /* Prototypes end here */ #else #define push_int64(i) push_int((INT_TYPE)(i)) -#define push_uint64(i) push_int((INT_TYPE)(i)) +#define push_ulongest(i) push_int((INT_TYPE)(i)) #define int64_from_bignum(I,BIGNUM) 0 -#define uint64_from_bignum(I,BIGNUM) 0 +#define ulongest_from_bignum(I,BIGNUM) 0 #endif /* AUTO_BIGNUM */ -/* Less confusing names, considering that push_int64 pushes a 32 bit +/* Less confusing name, considering that push_int64 pushes a 32 bit * int if INT64 isn't available. */ #define push_longest push_int64 -#define push_ulongest push_uint64 #endif /* BIGNUM_H */ diff --git a/src/modules/Gmp/mpz_glue.c b/src/modules/Gmp/mpz_glue.c index ed8d220d368fe7ff9a6fd6d89beaa34d1ac6fcdb..762bdd98c5e3f80c5509bb1d8ceaab888a13605b 100644 --- a/src/modules/Gmp/mpz_glue.c +++ b/src/modules/Gmp/mpz_glue.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: mpz_glue.c,v 1.175 2008/05/01 20:46:19 mast Exp $ +|| $Id: mpz_glue.c,v 1.176 2008/05/01 21:14:04 mast Exp $ */ #include "global.h" @@ -180,42 +180,6 @@ static void gmp_push_int64 (INT64 i) } } -static void gmp_push_uint64 (unsigned INT64 i) -{ - if (i <= MAX_INT_TYPE) { - push_int(DO_NOT_WARN((INT_TYPE)i)); - } - else { - MP_INT *mpz; - - push_object (fast_clone_object (bignum_program)); - mpz = OBTOMPZ (sp[-1].u.object); - -#if SIZEOF_LONG >= SIZEOF_INT64 - mpz_set_ui (mpz, i); -#else - { -#ifdef HAVE_MPZ_IMPORT - mpz_import (mpz, 1, 1, SIZEOF_INT64, 0, 0, &i); -#else - { - size_t n = - ((SIZEOF_INT64 + SIZEOF_LONG - 1) / SIZEOF_LONG - 1) - /* The above is the position of the top unsigned long in the INT64. */ - * ULONG_BITS; - mpz_set_ui (mpz, (unsigned long) (i >> n)); - while (n) { - n -= ULONG_BITS; - mpz_mul_2exp (mpz, mpz, ULONG_BITS); - mpz_add_ui (mpz, mpz, (unsigned long) (i >> n)); - } - } -#endif /* !HAVE_MPZ_IMPORT */ - } -#endif /* SIZEOF_LONG < SIZEOF_INT64 */ - } -} - static mpz_t mpz_int64_min; static int gmp_int64_from_bignum (INT64 *i, struct object *bignum) @@ -223,7 +187,7 @@ static int gmp_int64_from_bignum (INT64 *i, struct object *bignum) MP_INT *mpz = OBTOMPZ (bignum); int neg = mpz_sgn (mpz) < 0; - /* Note: Similar code in mpzmod_reduce and gmp_uint64_from_bignum. */ + /* Note: Similar code in mpzmod_reduce and gmp_ulongest_from_bignum. */ /* Get the index of the highest limb that have bits within the range * of the INT64. */ @@ -270,15 +234,36 @@ overflow: return 0; } -static int gmp_uint64_from_bignum (unsigned INT64 *i, struct object *bignum) +#endif /* INT64 */ + +static void gmp_push_ulongest (unsigned LONGEST i) +{ + if (i <= MAX_INT_TYPE) { + push_int(DO_NOT_WARN((INT_TYPE)i)); + } + else { + MP_INT *mpz; + + push_object (fast_clone_object (bignum_program)); + mpz = OBTOMPZ (sp[-1].u.object); + +#if SIZEOF_LONG >= SIZEOF_LONGEST + mpz_set_ui (mpz, i); +#else +#error LONGEST should always be at least the same size as long. +#endif + } +} + +static int gmp_ulongest_from_bignum (unsigned LONGEST *i, struct object *bignum) { MP_INT *mpz = OBTOMPZ (bignum); /* Note: Similar code in gmp_int64_from_bignum. */ /* Get the index of the highest limb that have bits within the range - * of the INT64. */ - size_t pos = (UINT64_BITS + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS - 1; + * of LONGEST. */ + size_t pos = (ULONGEST_BITS + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS - 1; #ifdef PIKE_DEBUG if ((bignum->prog != bignum_program) && @@ -290,19 +275,20 @@ static int gmp_uint64_from_bignum (unsigned INT64 *i, struct object *bignum) if (mpz_sgn (mpz) < 0) return 0; if (mpz_size (mpz) <= pos + 1) { - unsigned INT64 res; -#if UINT64_BITS == GMP_NUMB_BITS + unsigned LONGEST res; +#if ULONGEST_BITS == GMP_NUMB_BITS res = MPZ_GETLIMBN (mpz, 0) & GMP_NUMB_MASK; -#elif UINT64_BITS < GMP_NUMB_BITS +#elif ULONGEST_BITS < GMP_NUMB_BITS mp_limb_t val = MPZ_GETLIMBN (mpz, 0) & GMP_NUMB_MASK; - if (val >= (mp_limb_t) 1 << UINT64_BITS) return 0; - res = val; + res = DO_NOT_WARN ((unsigned LONGEST) val); + if (val != res) return 0; #else res = 0; for (;; pos--) { res |= MPZ_GETLIMBN (mpz, pos) & GMP_NUMB_MASK; if (pos == 0) break; - if (res >= (unsigned INT64) 1 << (UINT64_BITS - GMP_NUMB_BITS)) return 0; + if (res >= (unsigned LONGEST) 1 << (ULONGEST_BITS - GMP_NUMB_BITS)) + return 0; res <<= GMP_NUMB_BITS; } #endif @@ -314,8 +300,6 @@ static int gmp_uint64_from_bignum (unsigned INT64 *i, struct object *bignum) return 0; } -#endif /* INT64 */ - #else #define PUSH_REDUCED(o) push_object(o) #endif /* AUTO_BIGNUM */ @@ -2171,8 +2155,12 @@ PIKE_MODULE_EXIT mpz_clear (mpz_int_type_min); #ifdef INT64 mpz_clear (mpz_int64_min); - hook_in_int64_funcs (NULL, NULL, NULL, NULL, NULL); #endif + hook_in_gmp_funcs ( +#ifdef INT64 + NULL, NULL, NULL, +#endif + NULL, NULL); } #endif #endif @@ -2385,10 +2373,13 @@ PIKE_MODULE_INIT mpz_init (mpz_int64_min); mpz_setbit (mpz_int64_min, INT64_BITS); mpz_neg (mpz_int64_min, mpz_int64_min); - hook_in_int64_funcs (gmp_push_int64, gmp_push_uint64, - gmp_int64_from_bignum, gmp_uint64_from_bignum, - gmp_reduce_stack_top_bignum); #endif + hook_in_gmp_funcs ( +#ifdef INT64 + gmp_push_int64, gmp_int64_from_bignum, + gmp_reduce_stack_top_bignum, +#endif + gmp_push_ulongest, gmp_ulongest_from_bignum); #if 0 /* magic /Hubbe diff --git a/src/modules/Gmp/my_gmp.h b/src/modules/Gmp/my_gmp.h index 67147cfcc7ed3970511986d66254a6897dada99b..39a714fb9cb4c0d498794efcf4a875bd79dd4129 100644 --- a/src/modules/Gmp/my_gmp.h +++ b/src/modules/Gmp/my_gmp.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: my_gmp.h,v 1.25 2008/05/01 20:46:19 mast Exp $ +|| $Id: my_gmp.h,v 1.26 2008/05/01 21:14:04 mast Exp $ */ /* @@ -140,11 +140,11 @@ extern struct program *bignum_program; #endif /* Bits excluding the sign bit, if any. */ -#define ULONG_BITS (SIZEOF_LONG * 8) +#define ULONG_BITS (SIZEOF_LONG * CHAR_BIT) +#define ULONGEST_BITS (SIZEOF_LONGEST * CHAR_BIT) #define INT_TYPE_BITS (SIZEOF_INT_TYPE * CHAR_BIT - 1) #ifdef INT64 #define INT64_BITS (SIZEOF_INT64 * CHAR_BIT - 1) -#define UINT64_BITS (SIZEOF_INT64 * CHAR_BIT) #endif #if SIZEOF_INT_TYPE > SIZEOF_LONG