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 <d...@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 _______________________________________________ Pkg-perl-cvs-commits mailing list Pkg-perl-cvs-commits@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-perl-cvs-commits