From 091047f36cfd64ff576080fe5b0e0279b2780ed8 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Sat, 9 Aug 2008 17:33:35 -0700 Subject: [PATCH] adding and deleting files R=r DELTA=1685 (920 added, 765 deleted, 0 changed) OCL=14030 CL=14030 --- src/cmd/gc/{mparith.c => mparith1.c} | 197 +++------- src/cmd/gc/mparith2.c | 529 +++++++++++++++++++++++++++ src/cmd/gc/mparith3.c | 53 +++ src/cmd/gc/mpatof.c | 342 ----------------- 4 files changed, 640 insertions(+), 481 deletions(-) rename src/cmd/gc/{mparith.c => mparith1.c} (73%) create mode 100644 src/cmd/gc/mparith2.c create mode 100644 src/cmd/gc/mparith3.c delete mode 100644 src/cmd/gc/mpatof.c diff --git a/src/cmd/gc/mparith.c b/src/cmd/gc/mparith1.c similarity index 73% rename from src/cmd/gc/mparith.c rename to src/cmd/gc/mparith1.c index 7295493d7e..6c625f3fd9 100644 --- a/src/cmd/gc/mparith.c +++ b/src/cmd/gc/mparith1.c @@ -1,17 +1,19 @@ -// Copyright 2009 The Go Authors. All rights reserved. +// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. #include "go.h" +/// uses arihmetic + int mpcmpfixfix(Mpint *a, Mpint *b) { - if(a->val > b->val) - return +1; - if(a->val < b->val) - return -1; - return 0; + Mpint c; + + mpmovefixfix(&c, a); + mpsubfixfix(&c, b); + return mptestfix(&c); } int @@ -26,206 +28,124 @@ mpcmpfixc(Mpint *b, vlong c) int mpcmpfltflt(Mpflt *a, Mpflt *b) { - if(a->val > b->val) - return +1; - if(a->val < b->val) - return -1; - return 0; + Mpflt c; + + mpmovefltflt(&c, a); + mpsubfltflt(&c, b); + return mptestflt(&c); } int -mpcmpfltc(Mpint *b, double c) +mpcmpfltc(Mpflt *b, double c) { - Mpint a; + Mpflt a; mpmovecflt(&a, c); return mpcmpfltflt(&a, b); } -void -mpaddfixfix(Mpint *a, Mpint *b) -{ - a->val += b->val; -} - void mpsubfixfix(Mpint *a, Mpint *b) { - a->val -= b->val; + mpnegfix(b); + mpaddfixfix(a, b); + mpnegfix(b); } void -mpmulfixfix(Mpint *a, Mpint *b) -{ - a->val *= b->val; -} - -void -mpdivfixfix(Mpint *a, Mpint *b) -{ - a->val /= b->val; -} - -void -mpmodfixfix(Mpint *a, Mpint *b) +mpsubfltflt(Mpflt *a, Mpflt *b) { - a->val %= b->val; + mpnegflt(b); + mpaddfltflt(a, b); + mpnegflt(b); } void -mporfixfix(Mpint *a, Mpint *b) +mpaddcfix(Mpint *a, vlong c) { - a->val |= b->val; -} + Mpint b; -void -mpandfixfix(Mpint *a, Mpint *b) -{ - a->val &= b->val; + mpmovecfix(&b, c); + mpaddfixfix(a, &b); } void -mpxorfixfix(Mpint *a, Mpint *b) +mpaddcflt(Mpflt *a, double c) { - a->val ^= b->val; -} + Mpflt b; -void -mplshfixfix(Mpint *a, Mpint *b) -{ - a->val <<= b->val; + mpmovecflt(&b, c); + mpaddfltflt(a, &b); } void -mprshfixfix(Mpint *a, Mpint *b) +mpmulcfix(Mpint *a, vlong c) { - a->val >>= b->val; -} + Mpint b; -void -mpnegfix(Mpint *a) -{ - a->val = -a->val; + mpmovecfix(&b, c); + mpmulfixfix(a, &b); } void -mpcomfix(Mpint *a) +mpmulcflt(Mpflt *a, double c) { - a->val = ~a->val; -} + Mpflt b; -void -mpaddfltflt(Mpflt *a, Mpflt *b) -{ - a->val += b->val; + mpmovecflt(&b, c); + mpmulfltflt(a, &b); } void -mpsubfltflt(Mpflt *a, Mpflt *b) +mpdivfixfix(Mpint *a, Mpint *b) { - a->val -= b->val; -} + Mpint q, r; -void -mpmulfltflt(Mpflt *a, Mpflt *b) -{ - a->val *= b->val; + mpdivmodfixfix(&q, &r, a, b); + mpmovefixfix(a, &q); } void -mpdivfltflt(Mpflt *a, Mpflt *b) -{ - a->val /= b->val; -} - -vlong -mpgetfix(Mpint *a) +mpmodfixfix(Mpint *a, Mpint *b) { - return a->val; -} + Mpint q, r; -double -mpgetflt(Mpflt *a) -{ - return a->val; + mpdivmodfixfix(&q, &r, a, b); + mpmovefixfix(a, &r); } void -mpmovefixfix(Mpint *a, Mpint *b) +mpcomfix(Mpint *a) { - *a = *b; -} + Mpint b; -void -mpmovefltflt(Mpflt *a, Mpflt *b) -{ - *a = *b; + mpmovecfix(&b, 1); + mpnegfix(a); + mpsubfixfix(a, &b); } void mpmovefixflt(Mpflt *a, Mpint *b) { - a->val = b->val; -} - -void -mpmovecfix(Mpint *a, vlong c) -{ - a->val = c; -} - -void -mpmovecflt(Mpflt *a, double c) -{ - a->val = c; + mpmovecflt(a, mpgetfix(b)); } void mpmovefltfix(Mpint *a, Mpflt *b) { - a->val = b->val; -} - -void -mpnegflt(Mpflt *a) -{ - a->val = -a->val; + mpmovecfix(a, mpgetflt(b)); } void -mpaddcflt(Mpflt *a, double c) -{ - Mpflt b; - - mpmovecflt(&b, c); - mpaddfltflt(a, &b); -} - -void -mpmulcflt(Mpflt *a, double c) -{ - Mpflt b; - - mpmovecflt(&b, c); - mpmulfltflt(a, &b); -} - -void -mpaddcfix(Mpint *a, vlong c) +mpmovefixfix(Mpint *a, Mpint *b) { - Mpint b; - - mpmovecfix(&b, c); - mpaddfixfix(a, &b); + *a = *b; } void -mpmulcfix(Mpint *a, vlong c) +mpmovefltflt(Mpflt *a, Mpflt *b) { - Mpint b; - - mpmovecfix(&b, c); - mpmulfixfix(a, &b); + *a = *b; } // @@ -265,7 +185,7 @@ mpatoflt(Mpflt *a, char *as) ex = 0; /* exponent */ zer = 1; /* zero */ - mpmovecflt(a, 0); + mpmovecflt(a, 0.0); for(;;) { switch(c = *s++) { default: @@ -348,7 +268,6 @@ bad: void mpatofix(Mpint *a, char *as) { - int c, f; char *s; diff --git a/src/cmd/gc/mparith2.c b/src/cmd/gc/mparith2.c new file mode 100644 index 0000000000..ecc4c1d870 --- /dev/null +++ b/src/cmd/gc/mparith2.c @@ -0,0 +1,529 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "go.h" + +// +// return the significant +// words of the argument +// +static int +mplen(Mpint *a) +{ + int i, n; + long *a1; + + n = -1; + a1 = &a->a[0]; + for(i=0; ia[0]; + for(i=0; i= Mpbase) { + x -= Mpbase; + c = 1; + } + *a1++ = x; + } +} + +// +// left shift mpint by Mpscale +// ignores sign and overflow +// +static void +mplshw(Mpint *a) +{ + long *a1; + int i; + + a1 = &a->a[Mpprec-1]; + for(i=1; ia[Mpprec]; + for(i=0; i> 1; + c = 0; + if(x & 1) + c = Mpbase; + } +} + +// +// right shift mpint by Mpscale +// ignores sign and overflow +// +static void +mprshw(Mpint *a) +{ + long *a1; + int i; + + a1 = &a->a[0]; + for(i=1; iovf || b->ovf) { + warn("ovf in cmp"); + return 0; + } + + a1 = &a->a[0] + Mpprec; + b1 = &b->a[0] + Mpprec; + + for(i=0; i 0) + return +1; + if(x < 0) + return -1; + } + return 0; +} + +// +// negate a +// ignore sign and ovf +// +static void +mpneg(Mpint *a) +{ + long x, *a1; + int i, c; + + a1 = &a->a[0]; + c = 0; + for(i=0; iovf || b->ovf) { + warn("ovf in mpaddxx"); + a->ovf = 1; + return; + } + + c = 0; + a1 = &a->a[0]; + b1 = &b->a[0]; + if(a->neg != b->neg) + goto sub; + + // perform a+b + for(i=0; i= Mpbase) { + x -= Mpbase; + c = 1; + } + *a1++ = x; + } + a->ovf = c; + if(a->ovf) + warn("set ovf in mpaddxx"); + + return; + +sub: + // perform a-b + switch(mpcmp(a, b)) { + case 0: + mpmovecfix(a, 0); + break; + + case 1: + for(i=0; ineg ^= 1; + for(i=0; iovf || b->ovf) { + warn("ovf in mpmulfixfix"); + a->ovf = 1; + return; + } + + // pick the smaller + // to test for bits + na = mplen(a); + nb = mplen(b); + if(na > nb) { + mpmovefixfix(&s, a); + a1 = &b->a[0]; + na = nb; + } else { + mpmovefixfix(&s, b); + a1 = &a->a[0]; + } + s.neg = 0; + + mpmovecfix(&q, 0); + for(i=0; i>= 1; + } + } + + q.neg = a->neg ^ b->neg; + mpmovefixfix(a, &q); + if(a->ovf) + warn("set ovf in mpmulfixfix"); +} + +void +mporfixfix(Mpint *a, Mpint *b) +{ + int i; + long x, *a1, *b1; + + if(a->ovf || b->ovf) { + warn("ovf in mporfixfix"); + mpmovecfix(a, 0); + a->ovf = 1; + return; + } + if(a->neg) { + a->neg = 0; + mpneg(a); + } + if(b->neg) + mpneg(b); + + a1 = &a->a[0]; + b1 = &b->a[0]; + for(i=0; ineg) + mpneg(b); + if(x & Mpsign) { + a->neg = 1; + mpneg(a); + } +} + +void +mpandfixfix(Mpint *a, Mpint *b) +{ + int i; + long x, *a1, *b1; + + if(a->ovf || b->ovf) { + warn("ovf in mpandfixfix"); + mpmovecfix(a, 0); + a->ovf = 1; + return; + } + if(a->neg) { + a->neg = 0; + mpneg(a); + } + if(b->neg) + mpneg(b); + + a1 = &a->a[0]; + b1 = &b->a[0]; + for(i=0; ineg) + mpneg(b); + if(x & Mpsign) { + a->neg = 1; + mpneg(a); + } +} + +void +mpxorfixfix(Mpint *a, Mpint *b) +{ + int i; + long x, *a1, *b1; + + if(a->ovf || b->ovf) { + warn("ovf in mporfixfix"); + mpmovecfix(a, 0); + a->ovf = 1; + return; + } + if(a->neg) { + a->neg = 0; + mpneg(a); + } + if(b->neg) + mpneg(b); + + a1 = &a->a[0]; + b1 = &b->a[0]; + for(i=0; ineg) + mpneg(b); + if(x & Mpsign) { + a->neg = 1; + mpneg(a); + } +} + +void +mplshfixfix(Mpint *a, Mpint *b) +{ + vlong s; + + if(a->ovf || b->ovf) { + warn("ovf in mporfixfix"); + mpmovecfix(a, 0); + a->ovf = 1; + return; + } + s = mpgetfix(b); + if(s < 0 || s >= Mpprec*Mpscale) { + warn("stupid shift: %lld", s); + mpmovecfix(a, 0); + return; + } + + while(s >= Mpscale) { + mplshw(a); + s -= Mpscale; + } + while(s > 0) { + mplsh(a); + s--; + } +} + +void +mprshfixfix(Mpint *a, Mpint *b) +{ + vlong s; + + if(a->ovf || b->ovf) { + warn("ovf in mprshfixfix"); + mpmovecfix(a, 0); + a->ovf = 1; + return; + } + s = mpgetfix(b); + if(s < 0 || s >= Mpprec*Mpscale) { + warn("stupid shift: %lld", s); + mpmovecfix(a, 0); + return; + } + + while(s >= Mpscale) { + mprshw(a); + s -= Mpscale; + } + while(s > 0) { + mprsh(a); + s--; + } +} + +void +mpnegfix(Mpint *a) +{ + a->neg ^= 1; +} + +vlong +mpgetfix(Mpint *a) +{ + vlong v; + + if(a->ovf) { + warn("ovf in mpgetfix"); + return 0; + } + + v = (vlong)a->a[0]; + v |= (vlong)a->a[1] << Mpscale; + v |= (vlong)a->a[2] << (Mpscale+Mpscale); + if(a->neg) + v = -v; + return v; +} + +void +mpmovecfix(Mpint *a, vlong c) +{ + int i; + long *a1; + vlong x; + + a->neg = 0; + a->ovf = 0; + + x = c; + if(x < 0) { + a->neg = 1; + x = -x; + } + + a1 = &a->a[0]; + for(i=0; i>= Mpscale; + } +} + +void +mpdivmodfixfix(Mpint *q, Mpint *r, Mpint *n, Mpint *d) +{ + int i, nn, dn; + + mpmovefixfix(r, n); + mpmovecfix(q, 0); + + // shift denominator until it + // is larger than numerator + for(i=0; i 0) + break; + mplsh(d); + } + + // if it never happens + // denominator is probably zero + if(i >= Mpprec*Mpscale) { + q->ovf = 1; + r->ovf = 1; + warn("set ovf in mpdivmodfixfix"); + return; + } + + // shift denominator back creating + // quotient a bit at a time + // when done the remaining numerator + // will be the remainder + for(; i>0; i--) { + mplsh(q); + mprsh(d); + if(mpcmp(d, r) <= 0) { + mpaddcfix(q, 1); + mpsubfixfix(r, d); + } + } +} + +int +mptestfix(Mpint *a) +{ + Mpint b; + int r; + + mpmovecfix(&b, 0); + r = mpcmp(a, &b); + if(a->neg) { + if(r > 0) + return -1; + if(r < 0) + return +1; + } + return r; +} diff --git a/src/cmd/gc/mparith3.c b/src/cmd/gc/mparith3.c new file mode 100644 index 0000000000..2a0a1c6c2e --- /dev/null +++ b/src/cmd/gc/mparith3.c @@ -0,0 +1,53 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "go.h" + +/// implements float arihmetic + +void +mpaddfltflt(Mpflt *a, Mpflt *b) +{ + a->val += b->val; +} + +void +mpmulfltflt(Mpflt *a, Mpflt *b) +{ + a->val *= b->val; +} + +void +mpdivfltflt(Mpflt *a, Mpflt *b) +{ + a->val /= b->val; +} + +double +mpgetflt(Mpflt *a) +{ + return a->val; +} + +void +mpmovecflt(Mpflt *a, double c) +{ + a->val = c; +} + +void +mpnegflt(Mpflt *a) +{ + a->val = -a->val; +} + +int +mptestflt(Mpflt *a) +{ + if(a->val < 0) + return -1; + if(a->val > 0) + return +1; + return 0; +} diff --git a/src/cmd/gc/mpatof.c b/src/cmd/gc/mpatof.c deleted file mode 100644 index 3ddc6130f5..0000000000 --- a/src/cmd/gc/mpatof.c +++ /dev/null @@ -1,342 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include -#include - -int mpatof(char*, double*); -int mpatov(char *s, vlong *v); - -enum -{ - Mpscale = 29, /* safely smaller than bits in a int32 */ - Mpprec = 36, /* Mpscale*Mpprec sb > largest fp exp */ - Mpbase = 1L<= '0' && c <= '9') { - ex = ex*10 + (c-'0'); - continue; - } - break; - } - if(ef) - ex = -ex; - case 0: - break; - } - break; - } - if(a.ovf) - goto bad; - if(zer) { - *d = 0; - return 0; - } - if(dp) - dp--; - dp -= ex; - if(dp > 0) { - /* - * must divide by 10**dp - */ - if(mptof(&a, &d1)) - goto bad; - - /* - * trial exponent of 8**dp - * 8 (being between 5 and 10) - * should pick up all underflows - * in the division of 5**dp. - */ - d2 = frexp(d1, &ex); - d2 = ldexp(d2, ex-3*dp); - if(d2 == 0) - goto bad; - - /* - * decompose each 10 into 5*2. - * create 5**dp in fixed point - * and then play with the exponent - * for the remaining 2**dp. - * note that 5**dp will overflow - * with as few as 134 input digits. - */ - mpint(&a, 1); - mppow(&a, 5, dp); - if(mptof(&a, &d2)) - goto bad; - d1 = frexp(d1/d2, &ex); - d1 = ldexp(d1, ex-dp); - if(d1 == 0) - goto bad; - } else { - /* - * must multiply by 10**|dp| -- - * just do it in fixed point. - */ - mppow(&a, 10, -dp); - if(mptof(&a, &d1)) - goto bad; - } - if(f) - d1 = -d1; - *d = d1; - return 0; - -bad: - return 1; -} - -/* - * convert a to floating in *d - * return conversion overflow - */ -static int -mptof(Mp *a, double *d) -{ - double f, g; - int32 x, *a1; - int i; - - if(a->ovf) - return 1; - a1 = a->a; - f = ldexp(*a1++, 0); - for(i=Mpscale; iovf) - a->ovf = 1; - if(a->ovf) - return; - c = 0; - a1 = a->a; - b1 = b->a; - for(i=0; i= Mpbase) { - x -= Mpbase; - c = 1; - } - *a1++ = x; - } - a->ovf = c; -} - -/* - * return a = c - */ -static void -mpint(Mp *a, int c) -{ - - memset(a, 0, sizeof(*a)); - a->a[0] = c; -} - -/* - * return a *= c - */ -static void -mpmul(Mp *a, int c) -{ - Mp p; - int b; - memmove(&p, a, sizeof(p)); - if(!(c & 1)) - memset(a, 0, sizeof(*a)); - c &= ~1; - for(b=2; c; b<<=1) { - mpadd(&p, &p); - if(c & b) { - mpadd(a, &p); - c &= ~b; - } - } -} - -/* - * return a *= b**e - */ -static void -mppow(Mp *a, int b, int e) -{ - int b1; - - b1 = b*b; - b1 = b1*b1; - while(e >= 4) { - mpmul(a, b1); - e -= 4; - if(a->ovf) - return; - } - while(e > 0) { - mpmul(a, b); - e--; - } -} - -/* - * convert a string, s, to vlong in *v - * return conversion overflow. - * required syntax is [0[x]]d* - */ -int -mpatov(char *s, vlong *v) -{ - vlong n, nn; - int c; - n = 0; - c = *s; - if(c == '0') - goto oct; - while(c = *s++) { - if(c >= '0' && c <= '9') - nn = n*10 + c-'0'; - else - goto bad; - if(n < 0 && nn >= 0) - goto bad; - n = nn; - } - goto out; -oct: - s++; - c = *s; - if(c == 'x' || c == 'X') - goto hex; - while(c = *s++) { - if(c >= '0' || c <= '7') - nn = n*8 + c-'0'; - else - goto bad; - if(n < 0 && nn >= 0) - goto bad; - n = nn; - } - goto out; -hex: - s++; - while(c = *s++) { - if(c >= '0' && c <= '9') - c += 0-'0'; - else - if(c >= 'a' && c <= 'f') - c += 10-'a'; - else - if(c >= 'A' && c <= 'F') - c += 10-'A'; - else - goto bad; - nn = n*16 + c; - if(n < 0 && nn >= 0) - goto bad; - n = nn; - } -out: - *v = n; - return 0; - -bad: - *v = ~0; - return 1; -} -- 2.48.1