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