diff --git a/.gitattributes b/.gitattributes
index 82a1b7eb0e61a84d2cbe0ae28a46620d1f0c79f1..05a10a9edd01b076d954eb871fa75497c0350ef6 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -183,6 +183,7 @@ testfont binary
 /src/modules/Gmp/gmp_machine.h.in foreign_ident
 /src/modules/Gmp/mpz_glue.c foreign_ident
 /src/modules/Gmp/my_gmp.h foreign_ident
+/src/modules/Gmp/my_mpz_xor.c foreign_ident
 /src/modules/Gmp/next_prime.c foreign_ident
 /src/modules/Gmp/prime_table.c foreign_ident
 /src/modules/Gmp/testsuite.in foreign_ident
diff --git a/src/modules/Gmp/Makefile.in b/src/modules/Gmp/Makefile.in
index 50c74675fd0ec69bb468bb197ff258b7d92060b9..63947e5cbedfc507a348d38afba076ce10eec579 100644
--- a/src/modules/Gmp/Makefile.in
+++ b/src/modules/Gmp/Makefile.in
@@ -1,8 +1,8 @@
-# $Id: Makefile.in,v 1.9 1999/04/24 12:56:47 grubba Exp $
+# $Id: Makefile.in,v 1.10 1999/11/01 16:53:36 mirar Exp $
 SRCDIR=@srcdir@
 VPATH=@srcdir@:@srcdir@/../..:../..
 MODULE_LDFLAGS=@LDFLAGS@ @LIBS@
-OBJS=mpz_glue.o next_prime.o
+OBJS=mpz_glue.o next_prime.o my_mpz_xor.o
 
 PRIME_LIMIT=1024
 
diff --git a/src/modules/Gmp/mpz_glue.c b/src/modules/Gmp/mpz_glue.c
index 042fd4d4cbdfd43fe493624ccc47d66d560fae90..b898f4d91688f1115a54e6aed545cb3d7d48228f 100644
--- a/src/modules/Gmp/mpz_glue.c
+++ b/src/modules/Gmp/mpz_glue.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: mpz_glue.c,v 1.64 1999/11/01 15:21:57 mirar Exp $");
+RCSID("$Id: mpz_glue.c,v 1.65 1999/11/01 16:53:37 mirar Exp $");
 #include "gmp_machine.h"
 
 #if defined(HAVE_GMP2_GMP_H) && defined(HAVE_LIBGMP2)
@@ -901,6 +901,7 @@ static void name(INT32 args)				\
 
 BINFUN(mpzmod_and,mpz_and)
 BINFUN(mpzmod_or,mpz_ior)
+BINFUN(mpzmod_xor,my_mpz_xor)
 
 static void mpzmod_compl(INT32 args)
 {
@@ -1263,6 +1264,8 @@ void pike_module_exit(void)
   ADD_FUNCTION("``&",mpzmod_and,tMpz_binop_type,0);			\
   ADD_FUNCTION("`|",mpzmod_or,tMpz_binop_type,0);			\
   ADD_FUNCTION("``|",mpzmod_or,tMpz_binop_type,0);			\
+  ADD_FUNCTION("`^",mpzmod_xor,tMpz_binop_type,0);			\
+  ADD_FUNCTION("``^",mpzmod_xor,tMpz_binop_type,0);			\
   ADD_FUNCTION("`~",mpzmod_compl,tFunc(tNone,tObj),0);			\
 									\
   add_function("`<<",mpzmod_lsh,MPZ_SHIFT_TYPE,0);			\
diff --git a/src/modules/Gmp/my_gmp.h b/src/modules/Gmp/my_gmp.h
index d9ce549843f4d485af25043345fd3a9ecb95291f..69211674d30bd871362c41afc544966b6c301ab4 100644
--- a/src/modules/Gmp/my_gmp.h
+++ b/src/modules/Gmp/my_gmp.h
@@ -1,4 +1,4 @@
-/* $Id: my_gmp.h,v 1.5 1999/08/08 13:06:58 grubba Exp $
+/* $Id: my_gmp.h,v 1.6 1999/11/01 16:53:38 mirar Exp $
  *
  * These functions or something similar will hopefully be included
  * with Gmp-2.1 .
@@ -23,5 +23,6 @@
 unsigned long mpz_small_factor(mpz_t n, int limit);
 
 void mpz_next_prime(mpz_t p, mpz_t n, int count, int prime_limit);
+void my_mpz_xor _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
 
 #endif /* MY_GMP_H_INCLUDED */
diff --git a/src/modules/Gmp/my_mpz_xor.c b/src/modules/Gmp/my_mpz_xor.c
new file mode 100644
index 0000000000000000000000000000000000000000..e1ac0b606626c2adccf251f4076adf4dfbf79c59
--- /dev/null
+++ b/src/modules/Gmp/my_mpz_xor.c
@@ -0,0 +1,54 @@
+/* $Id: my_mpz_xor.c,v 1.1 1999/11/01 16:53:39 mirar Exp $
+ *
+ * since xor isn't implemented by gmp (for some odd reason)
+ */
+
+#include "global.h"
+
+RCSID("$Id: my_mpz_xor.c,v 1.1 1999/11/01 16:53:39 mirar Exp $");
+
+#include "gmp_machine.h"
+
+#if defined(HAVE_GMP2_GMP_H) && defined(HAVE_LIBGMP2)
+#define USE_GMP2
+#else /* !HAVE_GMP2_GMP_H || !HAVE_LIBGMP2 */
+#if defined(HAVE_GMP_H) && defined(HAVE_LIBGMP)
+#define USE_GMP
+#endif /* HAVE_GMP_H && HAVE_LIBGMP */
+#endif /* HAVE_GMP2_GMP_H && HAVE_LIBGMP2 */
+
+#if defined(USE_GMP) || defined(USE_GMP2)
+
+#include "gmp.h"
+
+void my_mpz_xor (mpz_ptr res, mpz_srcptr a, mpz_srcptr b)
+{
+   /* (a&~b)|(~a&b) for now */
+
+   mpz_t t1;
+   mpz_t t2;
+   mpz_t not;
+   
+   mpz_init(t1);
+   mpz_init(t2);
+   mpz_init(not);
+   
+   /* t1=(a&~b) */
+   mpz_com(not,b);
+   mpz_and(t1,a,not);
+
+   /* t2=(~a&b) */
+   mpz_com(not,a);
+   mpz_and(t2,not,b);
+
+   /* res=t1|t2 */
+   mpz_ior(res,t1,t2);
+
+   /* bye bye */
+   mpz_clear(t1);
+   mpz_clear(t2);
+   mpz_clear(not);
+}
+
+
+#endif