=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/engine/Z.c,v retrieving revision 1.3 retrieving revision 1.12 diff -u -p -r1.3 -r1.12 --- OpenXM_contrib2/asir2000/engine/Z.c 2004/09/27 12:43:07 1.3 +++ OpenXM_contrib2/asir2000/engine/Z.c 2013/11/05 11:36:58 1.12 @@ -1,53 +1,78 @@ -#if 0 #include "ca.h" +#include "base.h" #include "inline.h" + +#if defined(__GNUC__) +#define INLINE static inline +#elif defined(VISUAL) +#define INLINE __inline +#else +#define INLINE #endif -typedef struct oZ { - int p; - unsigned int b[1]; -} *Z; +INLINE void _addz(Z n1,Z n2,Z nr); +INLINE void _subz(Z n1,Z n2,Z nr); +INLINE void _mulz(Z n1,Z n2,Z nr); +int _addz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr); +int _subz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr); -#define IMM_MAX 1073741823 -#define IMM_MIN -1073741823 - /* immediate int -> Z */ -#define IMMTOZ(c,n) ((c)>=IMM_MIN&&(c)<=IMM_MAX?(n)=(Z)(((c)<<1)|1):(n)=immtoz(c)) +#define UTOZ(c,n) (n)=(!((unsigned int)(c))?0:(((unsigned int)(c))<=IMM_MAX?((Z)((((unsigned int)(c))<<1)|1)):utoz((unsigned int)(c)))) +#define STOZ(c,n) (n)=(!((int)(c))?0:(((int)(c))>=IMM_MIN&&((int)(c))<=IMM_MAX?((Z)((((int)(c))<<1)|1)):stoz((int)(c)))) /* immediate Z ? */ #define IS_IMM(c) (((unsigned int)c)&1) /* Z can be conver to immediate ? */ -#define IS_IMMZ(n) (SL(n) == 1&&BD(n)[0]<=IMM_MAX) +#define IS_SZ(n) (((SL(n) == 1)||(SL(n)==-1))&&BD(n)[0]<=IMM_MAX) /* Z -> immediate Z */ -#define IMMZTOZ(n,z) (SL(n)<0?(z)=(Z)(((-BD(n)[0])<<1)|1):(Z)(((BD(n)[0])<<1)|1)) +#define SZTOZ(n,z) (z)=(Z)(SL(n)<0?(((-BD(n)[0])<<1)|1):(((BD(n)[0])<<1)|1)) /* Z -> immediate int */ -#define ZTOIMM(c) (((int)(c))>>1) -#define ZALLOC(d) ((Z)MALLOC_ATOMIC(TRUESIZE(oZ,(d)-1,int))) -#define SL(n) ((n)->p) +#define ZTOS(c) (((int)(c))>>1) -Z immtoz(int c); -Z qtoz(Q n); -Q ztoq(Z n); -Z chsgnz(Z n); -Z dupz(Z n); -Z addz(Z n1,Z n2); -Z subz(Z n1,Z n2); -Z mulz(Z n1,Z n2); -Z divsz(Z n1,Z n2); -Z divz(Z n1,Z n2,Z *rem); -Z gcdz(Z n1,Z n2); -Z gcdz_cofactor(Z n1,Z n2,Z *c1,Z *c2); -Z estimate_array_gcdz(Z *a,int n); -Z array_gcdz(Z *a,int n); -void mkwcz(int k,int l,Z *t); -int remzi(Z n,int m); -inline void _addz(Z n1,Z n2,Z nr); -inline void _subz(Z n1,Z n2,Z nr); -inline void _mulz(Z n1,Z n2,Z nr); -inline int _addz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr); -inline int _subz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr); +int uniz(Z a) +{ + if ( IS_IMM(a) && ZTOS(a) == 1 ) return 1; + else return 0; +} -Z immtoz(int c) +int cmpz(Z a,Z b) { + int *ma,*mb; + int sa,sb,da,db,ca,cb,i; + + if ( !a ) + return -sgnz(b); + else if ( !b ) + return sgnz(a); + else { + sa = sgnz(a); sb = sgnz(b); + if ( sa > sb ) return 1; + else if ( sa < sb ) return -1; + else if ( IS_IMM(a) ) + if ( IS_IMM(b) ) { + ca = ZTOS(a); cb = ZTOS(b); + if ( ca > cb ) return sa; + else if ( ca < cb ) return -sa; + else return 0; + } else + return -sa; + else if ( IS_IMM(b) ) + return sa; + else { + da = SL(a)*sa; db = SL(b)*sa; + if ( da > db ) return sa; + else if ( da < db ) return -sa; + else { + for ( i = da-1, ma = BD(a)+i, mb = BD(b)+i; i >= 0; i-- ) + if ( *ma > *mb ) return sa; + else if ( *ma < *mb ) return -sa; + return 0; + } + } + } +} + +Z stoz(int c) +{ Z z; z = ZALLOC(1); @@ -59,21 +84,42 @@ Z immtoz(int c) return z; } +Z utoz(unsigned int c) +{ + Z z; + + z = ZALLOC(1); + SL(z) = 1; BD(z)[0] = c; + return z; +} + +Z simpz(Z n) +{ + Z n1; + + if ( !n ) return 0; + else if ( IS_IMM(n) ) return n; + else if ( IS_SZ(n) ) { + SZTOZ(n,n1); return n1; + } else + return n; +} + int sgnz(Z n) { if ( !n ) return 0; - else if ( IS_IMM(n) ) return ZTOIMM(n)>0?1:1; + else if ( IS_IMM(n) ) return ZTOS(n)>0?1:-1; else if ( SL(n) < 0 ) return -1; else return 1; } z_mag(Z n) { - int n; + int c,i; if ( !n ) return 0; else if ( IS_IMM(n) ) { - c = ZTOIMM(n); + c = ZTOS(n); if ( c < 0 ) c = -c; for ( i = 0; c; c >>= 1, i++ ); return i; @@ -84,18 +130,20 @@ z_mag(Z n) Z qtoz(Q n) { Z r,t; + int c; if ( !n ) return 0; else if ( !INT(n) ) error("qtoz : invalid input"); else { t = (Z)NM(n); - if ( IS_IMMZ(t) ) { - IMMZTOZ(t,r); + if ( IS_SZ(t) ) { + c = SGN(n) < 0 ? -BD(t)[0] : BD(t)[0]; + STOZ(c,r); } else { r = dupz((Z)t); + if ( SGN(n) < 0 ) SL(r) = -SL(r); } - if ( SGN(n) < 0 ) SL(r) = -SL(r); return r; } } @@ -108,7 +156,7 @@ Q ztoq(Z n) if ( !n ) return 0; else if ( IS_IMM(n) ) { - c = ZTOIMM(n); + c = ZTOS(n); STOQ(c,r); return r; } else { @@ -125,17 +173,17 @@ Q ztoq(Z n) Z dupz(Z n) { - Z nr; + Z r; int sd,i; if ( !n ) return 0; else if ( IS_IMM(n) ) return n; else { if ( (sd = SL(n)) < 0 ) sd = -sd; - nr = ZALLOC(sd); - SL(nr) = SL(n); - for ( i = 0; i < sd; i++ ) BD(nr)[i] = BD(n)[i]; - return nr; + r = ZALLOC(sd); + SL(r) = SL(n); + for ( i = 0; i < sd; i++ ) BD(r)[i] = BD(n)[i]; + return r; } } @@ -146,8 +194,8 @@ Z chsgnz(Z n) if ( !n ) return 0; else if ( IS_IMM(n) ) { - c = -ZTOIMM(n); - IMMTOZ(c,r); + c = -ZTOS(n); + STOZ(c,r); return r; } else { r = dupz(n); @@ -156,7 +204,18 @@ Z chsgnz(Z n) } } +Z absz(Z n) +{ + Z r; + int c; + if ( !n ) return 0; + else if ( sgnz(n) > 0 ) + return n; + else + return chsgnz(n); +} + Z addz(Z n1,Z n2) { int d1,d2,d,c; @@ -167,11 +226,10 @@ Z addz(Z n1,Z n2) else if ( !n2 ) return dupz(n1); else if ( IS_IMM(n1) ) { if ( IS_IMM(n2) ) { - c = ZTOIMM(n1)+ZTOIMM(n2); - IMMTOZ(c,r); - return r; + c = ZTOS(n1)+ZTOS(n2); + STOZ(c,r); } else { - c = ZTOIMM(n1); + c = ZTOS(n1); if ( c < 0 ) { t.p = -1; t.b[0] = -c; } else { @@ -180,10 +238,10 @@ Z addz(Z n1,Z n2) if ( (d2 = SL(n2)) < 0 ) d2 = -d2; r = ZALLOC(d2+1); _addz(&t,n2,r); - return r; + if ( !SL(r) ) r = 0; } } else if ( IS_IMM(n2) ) { - c = ZTOIMM(n2); + c = ZTOS(n2); if ( c < 0 ) { t.p = -1; t.b[0] = -c; } else { @@ -192,7 +250,7 @@ Z addz(Z n1,Z n2) if ( (d1 = SL(n1)) < 0 ) d1 = -d1; r = ZALLOC(d1+1); _addz(n1,&t,r); - return r; + if ( !SL(r) ) r = 0; } else { if ( (d1 = SL(n1)) < 0 ) d1 = -d1; if ( (d2 = SL(n2)) < 0 ) d2 = -d2; @@ -200,11 +258,11 @@ Z addz(Z n1,Z n2) r = ZALLOC(d); _addz(n1,n2,r); if ( !SL(r) ) r = 0; - else if ( IS_IMMZ(r) ) { - IMMZTOZ(r,r1); r = r1; - } - return r; } + if ( r && !((int)r&1) && IS_SZ(r) ) { + SZTOZ(r,r1); r = r1; + } + return r; } Z subz(Z n1,Z n2) @@ -213,18 +271,15 @@ Z subz(Z n1,Z n2) Z r,r1; struct oZ t; - if ( !n1 ) { - r = dupz(n2); - SL(r) = -SL(r); - return r; - } else if ( !n2 ) return dupz(n1); + if ( !n1 ) + return chsgnz(n2); + else if ( !n2 ) return n1; else if ( IS_IMM(n1) ) { if ( IS_IMM(n2) ) { - c = ZTOIMM(n1)-ZTOIMM(n2); - IMMTOZ(c,r); - return r; + c = ZTOS(n1)-ZTOS(n2); + STOZ(c,r); } else { - c = ZTOIMM(n1); + c = ZTOS(n1); if ( c < 0 ) { t.p = -1; t.b[0] = -c; } else { @@ -233,10 +288,10 @@ Z subz(Z n1,Z n2) if ( (d2 = SL(n2)) < 0 ) d2 = -d2; r = ZALLOC(d2+1); _subz(&t,n2,r); - return r; + if ( !SL(r) ) r = 0; } } else if ( IS_IMM(n2) ) { - c = ZTOIMM(n2); + c = ZTOS(n2); if ( c < 0 ) { t.p = -1; t.b[0] = -c; } else { @@ -245,7 +300,7 @@ Z subz(Z n1,Z n2) if ( (d1 = SL(n1)) < 0 ) d1 = -d1; r = ZALLOC(d1+1); _subz(n1,&t,r); - return r; + if ( !SL(r) ) r = 0; } else { if ( (d1 = SL(n1)) < 0 ) d1 = -d1; if ( (d2 = SL(n2)) < 0 ) d2 = -d2; @@ -253,33 +308,50 @@ Z subz(Z n1,Z n2) r = ZALLOC(d); _subz(n1,n2,r); if ( !SL(r) ) r = 0; - else if ( IS_IMMZ(r) ) { - IMMZTOZ(r,r1); r = r1; - } - return r; } + if ( r && !((int)r&1) && IS_SZ(r) ) { + SZTOZ(r,r1); r = r1; + } + return r; } Z mulz(Z n1,Z n2) { int d1,d2,sgn,i; + int c1,c2; unsigned int u1,u2,u,l; Z r; if ( !n1 || !n2 ) return 0; if ( IS_IMM(n1) ) { - sgn = 1; - u1 = ZTOIMM(n1); if ( u1 < 0 ) { sgn = -sgn; u1 = -u1; } + c1 = ZTOS(n1); if ( IS_IMM(n2) ) { - u2 = ZTOIMM(n2); if ( u2 < 0 ) { sgn = -sgn; u2 = -u2; } - DM(u1,u2,u,l); - if ( !u ) { - IMMTOZ(l,r); - } else { - r = ZALLOC(2); SL(r) = 2; BD(r)[1] = u; BD(r)[0] = l; + c2 = ZTOS(n2); + if ( c1 == 1 ) + return n2; + else if ( c1 == -1 ) + return chsgnz(n2); + else if ( c2 == 1 ) + return n1; + else if ( c2 == -1 ) + return chsgnz(n1); + else { + sgn = 1; + if ( c1 < 0 ) { c1 = -c1; sgn = -sgn; } + if ( c2 < 0 ) { c2 = -c2; sgn = -sgn; } + u1 = (unsigned int)c1; u2 = (unsigned int)c2; + DM(u1,u2,u,l); + if ( !u ) { + UTOZ(l,r); + } else { + r = ZALLOC(2); SL(r) = 2; BD(r)[1] = u; BD(r)[0] = l; + } } } else { + sgn = 1; + if ( c1 < 0 ) { c1 = -c1; sgn = -sgn; } + u1 = (unsigned int)c1; if ( (d2 = SL(n2)) < 0 ) { sgn = -sgn; d2 = -d2; } r = ZALLOC(d2+1); for ( i = d2; i >= 0; i-- ) BD(r)[i] = 0; @@ -287,8 +359,15 @@ Z mulz(Z n1,Z n2) SL(r) = BD(r)[d2]?d2+1:d2; } } else if ( IS_IMM(n2) ) { + c2 = ZTOS(n2); + if ( c2 == 1 ) + return n1; + else if ( c2 == -1 ) + return chsgnz(n1); + sgn = 1; - u2 = ZTOIMM(n2); if ( u2 < 0 ) { sgn = -sgn; u2 = -u2; } + if ( c2 < 0 ) { sgn = -sgn; c2 = -c2; } + u2 = (unsigned int)c2; if ( (d1 = SL(n1)) < 0 ) { sgn = -sgn; d1 = -d1; } r = ZALLOC(d1+1); for ( i = d1; i >= 0; i-- ) BD(r)[i] = 0; @@ -296,17 +375,17 @@ Z mulz(Z n1,Z n2) SL(r) = BD(r)[d1]?d1+1:d1; } else { sgn = 1; - if ( (d1 = SL(n1)) < 0 ) { sgn = -sgn; d1 = -d1; } - if ( (d2 = SL(n2)) < 0 ) { sgn = -sgn; d2 = -d2; } + if ( (d1 = SL(n1)) < 0 ) d1 = -d1; + if ( (d2 = SL(n2)) < 0 ) d2 = -d2; r = ZALLOC(d1+d2); _mulz(n1,n2,r); } - if ( sgn < 0 ) SL(r) = -SL(r); + if ( sgn < 0 ) r = chsgnz(r); return r; } /* kokokara */ - +#if 0 Z divsz(Z n1,Z n2) { int sgn,d1,d2; @@ -318,13 +397,13 @@ Z divsz(Z n1,Z n2) if ( IS_IMM(n1) ) { if ( !IS_IMM(n2) ) error("divsz : cannot happen"); - c = ZTOIMM(n1)/ZTOIMM(n2); - IMMTOZ(c,q); + c = ZTOS(n1)/ZTOS(n2); + STOZ(c,q); return q; } if ( IS_IMM(n2) ) { sgn = 1; - u2 = ZTOIMM(n2); if ( u2 < 0 ) { sgn = -sgn; u2 = -u2; } + u2 = ZTOS(n2); if ( u2 < 0 ) { sgn = -sgn; u2 = -u2; } diviz(n1,u2,&q); if ( sgn < 0 ) SL(q) = -SL(q); return q; @@ -341,30 +420,116 @@ Z divsz(Z n1,Z n2) if ( d1 < d2 ) error("divsz : cannot happen"); return q; } +#endif +/* XXX */ +Z divz(Z n1,Z n2,Z *r) +{ + int s1,s2; + Q t1,t2,qq,rq; + N qn,rn; + + if ( !n1 ) { + *r = 0; return 0; + } + if ( !n2 ) + error("divz : division by 0"); + t1 = ztoq(n1); t2 = ztoq(n2); + s1 = sgnz(n1); s2 = sgnz(n2); + /* n1 = qn*SGN(n1)*SGN(n2)*n2+SGN(n1)*rn */ + divn(NM(t1),NM(t2),&qn,&rn); + NTOQ(qn,s1*s2,qq); + NTOQ(rn,s1,rq); + *r = qtoz(rq); + return qtoz(qq); +} + +Z divsz(Z n1,Z n2) +{ + int s1,s2; + Q t1,t2,qq; + N qn; + + if ( !n1 ) + return 0; + if ( !n2 ) + error("divsz : division by 0"); + t1 = ztoq(n1); t2 = ztoq(n2); + s1 = sgnz(n1); s2 = sgnz(n2); + /* n1 = qn*SGN(n1)*SGN(n2)*n2 */ + divsn(NM(t1),NM(t2),&qn); + NTOQ(qn,s1*s2,qq); + return qtoz(qq); +} + +int gcdimm(int c1,int c2) +{ + int r; + + if ( !c1 ) return c2; + else if ( !c2 ) return c1; + while ( 1 ) { + r = c1%c2; + if ( !r ) return c2; + c1 = c2; c2 = r; + } +} + Z gcdz(Z n1,Z n2) { - int d1,d2; - N gcd; + int c1,c2,g; + Z gcd,r; + N gn; if ( !n1 ) return n2; else if ( !n2 ) return n1; - n1 = dupz(n1); - if ( SL(n1) < 0 ) SL(n1) = -SL(n1); - n2 = dupz(n2); - if ( SL(n2) < 0 ) SL(n2) = -SL(n2); - gcdn((N)n1,(N)n2,&gcd); - return (Z)gcd; + if ( IS_IMM(n1) ) { + c1 = ZTOS(n1); + if ( c1 < 0 ) c1 = -c1; + if ( IS_IMM(n2) ) + c2 = ZTOS(n2); + else + c2 = remzi(n2,c1>0?c1:-c1); + if ( c2 < 0 ) c2 = -c2; + g = gcdimm(c1,c2); + STOZ(g,gcd); + return gcd; + } else if ( IS_IMM(n2) ) { + c2 = ZTOS(n2); + if ( c2 < 0 ) c2 = -c2; + c1 = remzi(n1,c2>0?c2:-c2); + if ( c1 < 0 ) c1 = -c1; + g = gcdimm(c1,c2); + STOZ(g,gcd); + return gcd; + } else { + n1 = dupz(n1); + if ( SL(n1) < 0 ) SL(n1) = -SL(n1); + n2 = dupz(n2); + if ( SL(n2) < 0 ) SL(n2) = -SL(n2); + gcdn((N)n1,(N)n2,&gn); + gcd = (Z)gn; + if ( IS_SZ(gcd) ) { + SZTOZ(gcd,r); gcd = r; + } + return gcd; + } } int remzi(Z n,int m) { unsigned int *x; unsigned int t,r; - int i; + int i,c; if ( !n ) return 0; + if ( IS_IMM(n) ) { + c = ZTOS(n)%m; + if ( c < 0 ) c += m; + return c; + } + i = SL(n); if ( i < 0 ) i = -i; for ( i--, x = BD(n)+i, r = 0; i >= 0; i--, x-- ) { @@ -374,6 +539,8 @@ int remzi(Z n,int m) DSAB(m,r,*x,t,r); #endif } + if ( r && SL(n) < 0 ) + r = m-r; return r; } @@ -387,6 +554,7 @@ Z gcdz_cofactor(Z n1,Z n2,Z *c1,Z *c2) return gcd; } +#if 0 Z estimate_array_gcdz(Z *b,int n) { int m,i,j,sd; @@ -427,6 +595,7 @@ Z array_gcdz(Z *b,int n) gcd = gcdz(gcd,a[i]); return gcd; } +#endif void _copyz(Z n1,Z n2) { @@ -508,7 +677,7 @@ int _addz_main(unsigned int *m1,int d1,unsigned int *m t = m1; m1 = m2; m2 = t; d = d1; d1 = d2; d2 = d; } -#if defined(VISUAL) +#if defined(_M_IX86) __asm { push esi push edi @@ -535,6 +704,7 @@ int _addz_main(unsigned int *m1,int d1,unsigned int *m } #elif defined(i386) asm volatile("\ + pushl %%ebx;\ movl %1,%%esi;\ movl %2,%%edi;\ movl %3,%%ebx;\ @@ -552,12 +722,13 @@ int _addz_main(unsigned int *m1,int d1,unsigned int *m jnz Lstart__addz;\ movl $0,%%eax;\ adcl %%eax,%%eax;\ - movl %%eax,%0"\ + movl %%eax,%0;\ + popl %%ebx"\ :"=m"(c)\ :"m"(m1),"m"(m2),"m"(mr),"m"(d2)\ - :"eax","ebx","ecx","edx","esi","edi"); + :"eax","ecx","edx","esi","edi"); #else - for ( i = 0, c = 0, mr = BD(nr); i < d2; i++, m1++, m2++, mr++ ) { + for ( i = 0, c = 0; i < d2; i++, m1++, m2++, mr++ ) { tmp = *m1 + *m2; if ( tmp < *m1 ) { tmp += c; @@ -598,7 +769,7 @@ int _subz_main(unsigned int *m1,int d1,unsigned int *m m = m1; m1 = m2; m2 = m; d = d1; d1 = d2; d2 = d; } -#if defined(VISUAL) +#if defined(_M_IX86) __asm { push esi push edi @@ -625,6 +796,7 @@ int _subz_main(unsigned int *m1,int d1,unsigned int *m } #elif defined(i386) asm volatile("\ + pushl %%ebx;\ movl %1,%%esi;\ movl %2,%%edi;\ movl %3,%%ebx;\ @@ -642,12 +814,13 @@ int _subz_main(unsigned int *m1,int d1,unsigned int *m jnz Lstart__subz;\ movl $0,%%eax;\ adcl %%eax,%%eax;\ - movl %%eax,%0"\ + movl %%eax,%0;\ + popl %%ebx"\ :"=m"(br)\ :"m"(m1),"m"(m2),"m"(mr),"m"(d2)\ - :"eax","ebx","ecx","edx","esi","edi"); + :"eax","ecx","edx","esi","edi"); #else - for ( i = 0, br = 0, mr = BD(nr); i < d2; i++, mr++ ) { + for ( i = 0, br = 0; i < d2; i++, mr++ ) { t = *m1++; tmp = *m2++ + br; if ( br > 0 && !tmp ) { @@ -675,11 +848,14 @@ int _subz_main(unsigned int *m1,int d1,unsigned int *m void printz(Z n) { - int sd; + int sd,u; if ( !n ) fprintf(asir_out,"0"); - else { + else if ( IS_IMM(n) ) { + u = ZTOS(n); + fprintf(asir_out,"%d",u); + } else { if ( (sd = SL(n)) < 0 ) { SL(n) = -SL(n); fprintf(asir_out,"-"); } printn((N)n); if ( sd < 0 ) SL(n) = -SL(n);