summaryrefslogtreecommitdiff
path: root/sys/src/libmp/port/mpfield.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-12-16 21:18:20 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2015-12-16 21:18:20 +0100
commitefd3ac8a2328d1baf55c296a00807052473d549e (patch)
tree3e0851312267fee156a3cfb67aea5b4faebbfb76 /sys/src/libmp/port/mpfield.c
parentb6f04b77e3d11699d664d0ca7d0ba991f9599acc (diff)
libmp: add mpfield() function for fast field arithmetic
instead of testing for special field primes each time in mpmod(), make it explicit with a mpfiled() function that tests a modulus N to be of some special form that can be reduced more efficiently with some precalculation, and replaces N with a Mfield* when it can. the Mfield*'s are recognized by mpmod() as they have the MPfield flag set and provide a function pointer that executes the fast reduction.
Diffstat (limited to 'sys/src/libmp/port/mpfield.c')
-rw-r--r--sys/src/libmp/port/mpfield.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/sys/src/libmp/port/mpfield.c b/sys/src/libmp/port/mpfield.c
new file mode 100644
index 000000000..b5f8a9b00
--- /dev/null
+++ b/sys/src/libmp/port/mpfield.c
@@ -0,0 +1,21 @@
+#include "os.h"
+#include <mp.h>
+#include "dat.h"
+
+mpint*
+mpfield(mpint *N)
+{
+ Mfield *f;
+
+ if(N == nil || N->flags & (MPfield|MPstatic))
+ return N;
+ if((f = cnfield(N)) != nil)
+ goto Exchange;
+ if((f = gmfield(N)) != nil)
+ goto Exchange;
+ return N;
+Exchange:
+ setmalloctag(f, getcallerpc(&N));
+ mpfree(N);
+ return f;
+}