Various changes. Kinda in the middle of it here, but it seems to work.
[catacomb-perl] / mp.xs
diff --git a/mp.xs b/mp.xs
index 56c8756..28c22f9 100644 (file)
--- a/mp.xs
+++ b/mp.xs
@@ -1,6 +1,6 @@
 # ---?---
 #
-# $Id: mp.xs,v 1.2 2004/04/08 01:36:21 mdw Exp $
+# $Id$
 #
 # Multiprecision interface
 #
@@ -34,13 +34,18 @@ new(me, sv = 0, radix = 0)
        SV *sv
        int radix
        CODE:
-       RETVAL = sv ? mp_fromsv(sv, "sv", radix, 1) : MP_ZERO;
+       RETVAL = sv ? mp_fromsv(sv, "sv", 
+                               "Catacomb::MP", radix, 1) : MP_ZERO;
        OUTPUT:
        RETVAL
 
 mp *
-mp_copy(x)
+copy(x)
        mp *x
+       CODE:
+       RETVAL = MP_COPY(x);
+       OUTPUT:
+       RETVAL
 
 mp *
 loadb(me, sv)
@@ -147,7 +152,7 @@ mp *
 neg(a)
        mp *a
        CODE:
-       mp_copy(a);
+       MP_COPY(a);
        RETVAL = mp_split(a);
        if (RETVAL->v < RETVAL->vl)
          RETVAL->f ^= MP_NEG;
@@ -171,7 +176,7 @@ binop(a, b)
        XSINTERFACE_FUNC
        XSINTERFACE_FUNC_SETMP
        INTERFACE:
-       add sub mul and or xor
+       add sub mul and2c or2c nand2c nor2c xor2c and or nand nor xor
 
 mp *
 shiftop(a, n)
@@ -183,7 +188,29 @@ shiftop(a, n)
        XSINTERFACE_FUNC
        XSINTERFACE_FUNC_SETMP
        INTERFACE:
-       lsl lsr
+       lsl lsr lsl2c lsr2c
+
+bool
+testbitop(a, n)
+       mp *a
+       unsigned long n
+       INTERFACE_MACRO:
+       XSINTERFACE_FUNC
+       XSINTERFACE_FUNC_SETMP
+       INTERFACE:
+       testbit testbit2c
+
+mp *
+flipbits(a, n)
+       mp *a
+       unsigned long n
+       C_ARGS:
+       MP_NEW, a, n
+       INTERFACE_MACRO:
+       XSINTERFACE_FUNC
+       XSINTERFACE_FUNC_SETMP
+       INTERFACE:
+       setbit clearbit setbit2c clearbit2c
 
 int
 mp_cmp(a, b)
@@ -284,13 +311,24 @@ smallfactor(x)
        OUTPUT:
        RETVAL
 
+MP_Reduce *
+makereduce(x)
+       mp *x
+       CODE:
+       if (!MP_POSP(x))
+         croak("Argument to Catacomb::MP::makereduce must be positive");
+       RETVAL = CREATE(MP_Reduce);     
+       mpreduce_create(RETVAL, x);
+       OUTPUT:
+       RETVAL
+
 MP_Mont *
 mont(x)
        mp *x
        CODE:
-       if (x->f & MP_NEG)
+       if (!MP_POSP(x))
          croak("Argument to Catacomb::MP::mont must be positive");
-       if (x->v == x->vl || !(x->v[0] & 1u))
+       if (!MP_ODDP(x))
          croak("Argument to Catacomb::MP::mont must be odd");
        RETVAL = CREATE(MP_Mont);       
        mpmont_create(RETVAL, x);
@@ -301,7 +339,7 @@ MP_Barrett *
 barrett(x)
        mp *x
        CODE:
-       if (x->f & MP_NEG)
+       if (!MP_POSP(x))
          croak("Argument to Catacomb::MP::barrett must be positive");
        RETVAL = CREATE(mpbarrett);
        mpbarrett_create(RETVAL, x);
@@ -312,9 +350,9 @@ MP_Prime_Rabin *
 rabin(x)
        mp *x
        CODE:
-       if (x->f & MP_NEG)
+       if (!MP_POSP(x))
          croak("Argument to Catacomb::MP::rabin must be positive");
-       if (x->v == x->vl || !(x->v[0] & 1u))
+       if (!MP_ODDP(x))
          croak("Argument to Catacomb::MP::rabin must be odd");
        RETVAL = CREATE(MP_Prime_Rabin);
        rabin_create(RETVAL, x);
@@ -328,9 +366,9 @@ new(me, x)
        SV *me
        mp *x
        CODE:
-       if (x->f & MP_NEG)
+       if (!MP_POSP(x))
          croak("Argument to Catacomb::MP::Mont::new must be positive");
-       if (x->v == x->vl || !(x->v[0] & 1u))
+       if (!MP_ODDP(x))
          croak("Argument to Catacomb::MP::Mont::new must be odd");
        RETVAL = CREATE(MP_Mont);       
        mpmont_create(RETVAL, x);
@@ -390,8 +428,8 @@ mpmont_mexpr(mm, ...)
        n = (items - 1)/2;
        v = xmalloc(n * sizeof(mp_expfactor));
        for (i = 1, j = 0; i < items; i += 2, j++) {
-         v[j].base = mp_fromsv(ST(i), "g_i", 0, 0);
-         v[j].exp = mp_fromsv(ST(i + 1), "x_i", 0, 0);
+         v[j].base = mp_fromsv(ST(i), "g_i", "Catacomb::MP", 0, 0);
+         v[j].exp = mp_fromsv(ST(i + 1), "x_i", "Catacomb::MP", 0, 0);
        }
        RETVAL = mpmont_mexpr(mm, MP_NEW, v, n);
        xfree(v);
@@ -412,8 +450,10 @@ mpmont_mexp(mm, ...)
        n = (items - 1)/2;
        v = xmalloc(n * sizeof(mp_expfactor));
        for (i = 1, j = 0; i < items; i += 2, j++) {
-         v[j].base = mp_fromsv(ST(i), "g_%lu", 0, 0, (unsigned long)i);
-         v[j].exp = mp_fromsv(ST(i + 1), "x_%lu", 0, 0, (unsigned long)i);
+         v[j].base = mp_fromsv(ST(i), "g_%lu",
+                               "Catacomb::MP", 0, 0, (unsigned long)i);
+         v[j].exp = mp_fromsv(ST(i + 1), "x_%lu",
+                              "Catacomb::MP", 0, 0, (unsigned long)i);
        }
        RETVAL = mpmont_mexp(mm, MP_NEW, v, n);
        xfree(v);
@@ -424,7 +464,7 @@ mp *
 r(mm)
        MP_Mont *mm
        CODE:
-       RETVAL = mp_copy(mm->r);
+       RETVAL = MP_COPY(mm->r);
        OUTPUT:
        RETVAL
 
@@ -432,7 +472,7 @@ mp *
 r2(mm)
        MP_Mont *mm
        CODE:
-       RETVAL = mp_copy(mm->r2);
+       RETVAL = MP_COPY(mm->r2);
        OUTPUT:
        RETVAL
 
@@ -440,7 +480,7 @@ mp *
 m(mm)
        MP_Mont *mm
        CODE:
-       RETVAL = mp_copy(mm->m);
+       RETVAL = MP_COPY(mm->m);
        OUTPUT:
        RETVAL
 
@@ -451,7 +491,7 @@ new(me, x)
        SV *me
        mp *x
        CODE:
-       if (x->f & MP_NEG)
+       if (!MP_POSP(x))
          croak("Argument to Catacomb::MP::Barrett::new must be positive");
        RETVAL = CREATE(mpbarrett);
        mpbarrett_create(RETVAL, x);
@@ -485,7 +525,54 @@ mp *
 m(mb)
        MP_Barrett *mb
        CODE:
-       RETVAL = mp_copy(mb->m);
+       RETVAL = MP_COPY(mb->m);
+       OUTPUT:
+       RETVAL
+
+MODULE = Catacomb PACKAGE = Catacomb::MP::Reduce PREFIX = mpreduce_
+
+MP_Reduce *
+new(me, x)
+       SV *me
+       mp *x
+       CODE:
+       if (!MP_POSP(x))
+         croak("Argument to Catacomb::MP::Reduce::new must be positive");
+       RETVAL = CREATE(mpreduce);
+       mpreduce_create(RETVAL, x);
+       OUTPUT:
+       RETVAL
+
+SV *
+DESTROY(r)
+       MP_Reduce *r
+       CODE:
+       mpreduce_destroy(r);
+       DESTROY(r);
+       XSRETURN_UNDEF;
+
+mp *
+reduce(r, x)
+       MP_Reduce *r
+       mp *x
+       CODE:
+       RETVAL = mpreduce_do(r, MP_NEW, x);
+       OUTPUT:
+       RETVAL
+
+mp *
+mpreduce_exp(r, x, y)
+       MP_Reduce *r
+       mp *x
+       mp *y
+       C_ARGS:
+       r, MP_NEW, x, y
+
+mp *
+m(r)
+       MP_Reduce *r
+       CODE:
+       RETVAL = MP_COPY(r->p);
        OUTPUT:
        RETVAL
 
@@ -503,7 +590,8 @@ new(me, ...)
        n = items - 1;
        v = xmalloc(n * sizeof(mpcrt_mod));
        for (i = 0; i < n; i++) {
-         v[i].m = mp_copy(mp_fromsv(ST(i + 1), "n_%lu", 0, 0, 
+         v[i].m = mp_copy(mp_fromsv(ST(i + 1), "n_%lu", 
+                          "Catacomb::MP", 0, 0, 
                           (unsigned long)i));
        }
        RETVAL = CREATE(MP_CRT);
@@ -530,8 +618,10 @@ solve(mc, ...)
        n = mc->k;
        if (items - 1 != n)
          croak("Wrong number of residues for this CRT context");
-       for (i = 0; i < n; i++)
-         v[i] = mp_fromsv(ST(i + 1), "r_%lu", 0, 0, (unsigned long)i);
+       for (i = 0; i < n; i++) {
+         v[i] = mp_fromsv(ST(i + 1), "r_%lu", "Catacomb::MP", 
+                          0, 0, (unsigned long)i);
+       }
        RETVAL = mpcrt_solve(mc, MP_NEW, v);
        xfree(v);
        OUTPUT: