[libmath-prime-util-perl] 04/16: Make asm x64 only
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:44:24 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.06
in repository libmath-prime-util-perl.
commit eafd373d048098ca699a07972d99414d09611566
Author: Dana Jacobsen <dana at acm.org>
Date: Fri Jun 8 16:13:44 2012 -0600
Make asm x64 only
---
MANIFEST | 1 +
TODO | 2 ++
factor.c | 102 +++++++++++++++++++++++++++++++++------------------------------
3 files changed, 56 insertions(+), 49 deletions(-)
diff --git a/MANIFEST b/MANIFEST
index 80c5c05..40dfd94 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -32,6 +32,7 @@ t/13-primecount.t
t/14-nthprime.t
t/15-probprime.t
t/16-randomprime.t
+t/17-pseudoprime.t
t/30-relations.t
t/50-factoring.t
t/90-release-perlcritic.t
diff --git a/TODO b/TODO
index a559ec0..8644218 100644
--- a/TODO
+++ b/TODO
@@ -22,3 +22,5 @@
- speed up random_prime for large numbers
- Add other bases to pseudoprime test
+
+- test x64 asm if Perl is built for 32-bit
diff --git a/factor.c b/factor.c
index 1b06519..d5be28a 100644
--- a/factor.c
+++ b/factor.c
@@ -85,66 +85,71 @@ int trial_factor(UV n, UV *factors, UV maxtrial)
#define mulmod(a,b,m) (UV)(((uint64_t)(a)*(uint64_t)(b)) % ((uint64_t)(m)))
#define sqrmod(n,m) (UV)(((uint64_t)(n)*(uint64_t)(n)) % ((uint64_t)(m)))
- static UV powmod(UV n, UV power, UV m) {
- UV t = 1;
- while (power) {
- if (power & 1)
- t = mulmod(t, n, m);
- n = sqrmod(n, m);
- power >>= 1;
- }
- return t;
+#elif defined(__GNUC__) && defined(__x86_64__)
+
+ /* GCC on a 64-bit Intel x86 */
+ static UV _mulmod(UV a, UV b, UV c) {
+ UV d; /* to hold the result of a*b mod c */
+ /* calculates a*b mod c, stores result in d */
+ asm ("mov %1, %%rax;" /* put a into rax */
+ "mul %2;" /* mul a*b -> rdx:rax */
+ "div %3;" /* (a*b)/c -> quot in rax remainder in rdx */
+ "mov %%rdx, %0;" /* store result in d */
+ :"=r"(d) /* output */
+ :"r"(a), "r"(b), "r"(c) /* input */
+ :"%rax", "%rdx" /* clobbered registers */
+ );
+ return d;
}
+ #define mulmod(a,b,m) _mulmod(a,b,m)
+ #define sqrmod(n,m) _mulmod(n,n,m)
#else
/* UV is the largest integral type available (that we know of). */
- /* if n is smaller than this, you can multiply without overflow */
- #define HALF_WORD (UVCONST(1) << (BITS_PER_WORD/2))
-
- #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
- /* Inline assembly -- basically as fast as a regular (a*b)%m */
- static UV _mulmod(UV a, UV b, UV c) {
- UV d; /* to hold the result of a*b mod c */
- /* calculates a*b mod c, stores result in d */
- asm ("mov %1, %%rax;" /* put a into rax */
- "mul %2;" /* mul a*b -> rdx:rax */
- "div %3;" /* (a*b)/c -> quot in rax remainder in rdx */
- "mov %%rdx, %0;" /* store result in d */
- :"=r"(d) /* output */
- :"r"(a), "r"(b), "r"(c) /* input */
- :"%rax", "%rdx" /* clobbered registers */
- );
- return d;
- }
- #define mulmod(a,b,m) _mulmod(a,b,m)
- #define sqrmod(n,m) _mulmod(n,n,m)
- #else
- /* Do it by hand */
- static UV _mulmod(UV a, UV b, UV m) {
- UV r = 0;
- while (b > 0) {
- if (b & 1) {
- if (r == 0) {
- r = a;
- } else {
- r = m - r;
- r = (a >= r) ? a-r : m-r+a;
- }
+ /* Do it by hand */
+ static UV _mulmod(UV a, UV b, UV m) {
+ UV r = 0;
+ while (b > 0) {
+ if (b & 1) {
+ if (r == 0) {
+ r = a;
+ } else {
+ r = m - r;
+ r = (a >= r) ? a-r : m-r+a;
}
- a = (a > (m-a)) ? (a-m)+a : a+a;
- b >>= 1;
}
- return r;
+ a = (a > (m-a)) ? (a-m)+a : a+a;
+ b >>= 1;
}
- #define mulmod(a,b,m) (((a)|(b)) < HALF_WORD) ? ((a)*(b))%(m):_mulmod(a,b,m)
- #define sqrmod(n,m) ((n) < HALF_WORD) ? ((n)*(n))%(m):_mulmod(n,n,m)
- #endif
+ return r;
+ }
+
+ /* if n is smaller than this, you can multiply without overflow */
+ #define HALF_WORD (UVCONST(1) << (BITS_PER_WORD/2))
+ #define mulmod(a,b,m) (((a)|(b)) < HALF_WORD) ? ((a)*(b))%(m):_mulmod(a,b,m)
+ #define sqrmod(n,m) ((n) < HALF_WORD) ? ((n)*(n))%(m):_mulmod(n,n,m)
+
+#endif
+#ifndef addmod
#define addmod(n,a,m) ((((m)-(n)) > (a)) ? ((n)+(a)) : ((n)+(a)-(m)))
+#endif
- /* n^power mod m */
+/* n^power mod m */
+#ifndef HALF_WORD
+ static UV powmod(UV n, UV power, UV m) {
+ UV t = 1;
+ while (power) {
+ if (power & 1)
+ t = mulmod(t, n, m);
+ n = sqrmod(n, m);
+ power >>= 1;
+ }
+ return t;
+ }
+#else
static UV powmod(UV n, UV power, UV m) {
UV t = 1;
if (m < HALF_WORD) {
@@ -165,7 +170,6 @@ int trial_factor(UV n, UV *factors, UV maxtrial)
}
return t;
}
-
#endif
/* n^power + a mod m */
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git
More information about the Pkg-perl-cvs-commits
mailing list