Annotation of OpenXM_contrib2/asir2000/engine/Z.c, Revision 1.7
1.1 noro 1: #include "ca.h"
1.5 noro 2: #include "base.h"
1.1 noro 3: #include "inline.h"
4:
1.7 ! fujiwara 5: #if defined(__GNUC__)
! 6: #define INLINE inline
! 7: #elif defined(VISUAL)
! 8: #define INLINE __inline
! 9: #else
! 10: #define INLINE
! 11: #endif
! 12:
! 13: INLINE void _addz(Z n1,Z n2,Z nr);
! 14: INLINE void _subz(Z n1,Z n2,Z nr);
! 15: INLINE void _mulz(Z n1,Z n2,Z nr);
! 16: INLINE int _addz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr);
! 17: INLINE int _subz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr);
1.3 noro 18:
19: /* immediate int -> Z */
1.5 noro 20: #define UTOZ(c,n) (n)=(!((unsigned int)(c))?0:(((unsigned int)(c))<=IMM_MAX?((Z)((((unsigned int)(c))<<1)|1)):utoz((unsigned int)(c))))
21: #define STOZ(c,n) (n)=(!((int)(c))?0:(((int)(c))>=IMM_MIN&&((int)(c))<=IMM_MAX?((Z)((((int)(c))<<1)|1)):stoz((int)(c))))
1.3 noro 22: /* immediate Z ? */
23: #define IS_IMM(c) (((unsigned int)c)&1)
24: /* Z can be conver to immediate ? */
1.5 noro 25: #define IS_SZ(n) (((SL(n) == 1)||(SL(n)==-1))&&BD(n)[0]<=IMM_MAX)
1.3 noro 26: /* Z -> immediate Z */
1.5 noro 27: #define SZTOZ(n,z) (z)=(Z)(SL(n)<0?(((-BD(n)[0])<<1)|1):(((BD(n)[0])<<1)|1))
1.3 noro 28: /* Z -> immediate int */
1.5 noro 29: #define ZTOS(c) (((int)(c))>>1)
30:
31: int uniz(Z a)
32: {
33: if ( IS_IMM(a) && ZTOS(a) == 1 ) return 1;
34: else return 0;
35: }
36:
37: int cmpz(Z a,Z b)
38: {
39: int *ma,*mb;
40: int sa,sb,da,db,ca,cb,i;
41:
42: if ( !a )
43: return -sgnz(b);
44: else if ( !b )
45: return sgnz(a);
46: else {
47: sa = sgnz(a); sb = sgnz(b);
48: if ( sa > sb ) return 1;
49: else if ( sa < sb ) return -1;
50: else if ( IS_IMM(a) )
51: if ( IS_IMM(b) ) {
52: ca = ZTOS(a); cb = ZTOS(b);
53: if ( ca > cb ) return sa;
54: else if ( ca < cb ) return -sa;
55: else return 0;
56: } else
57: return -sa;
58: else if ( IS_IMM(b) )
59: return sa;
60: else {
61: da = SL(a)*sa; db = SL(b)*sa;
62: if ( da > db ) return sa;
63: else if ( da < db ) return -sa;
64: else {
65: for ( i = da-1, ma = BD(a)+i, mb = BD(b)+i; i >= 0; i-- )
66: if ( *ma > *mb ) return sa;
67: else if ( *ma < *mb ) return -sa;
68: return 0;
69: }
70: }
71: }
72: }
1.1 noro 73:
1.5 noro 74: Z stoz(int c)
1.3 noro 75: {
76: Z z;
77:
78: z = ZALLOC(1);
79: if ( c < 0 ) {
80: SL(z) = -1; BD(z)[0] = -c;
81: } else {
82: SL(z) = 1; BD(z)[0] = c;
83: }
84: return z;
85: }
86:
1.5 noro 87: Z utoz(unsigned int c)
88: {
89: Z z;
90:
91: z = ZALLOC(1);
92: SL(z) = 1; BD(z)[0] = c;
93: return z;
94: }
95:
96: Z simpz(Z n)
97: {
98: Z n1;
99:
100: if ( !n ) return 0;
101: else if ( IS_IMM(n) ) return n;
102: else if ( IS_SZ(n) ) {
103: SZTOZ(n,n1); return n1;
104: } else
105: return n;
106: }
107:
1.3 noro 108: int sgnz(Z n)
1.2 noro 109: {
110: if ( !n ) return 0;
1.5 noro 111: else if ( IS_IMM(n) ) return ZTOS(n)>0?1:-1;
1.2 noro 112: else if ( SL(n) < 0 ) return -1;
113: else return 1;
114: }
115:
1.1 noro 116: z_mag(Z n)
117: {
1.4 noro 118: int c,i;
1.3 noro 119:
120: if ( !n ) return 0;
121: else if ( IS_IMM(n) ) {
1.5 noro 122: c = ZTOS(n);
1.3 noro 123: if ( c < 0 ) c = -c;
124: for ( i = 0; c; c >>= 1, i++ );
125: return i;
126: }
127: else return n_bits((N)n);
1.1 noro 128: }
129:
130: Z qtoz(Q n)
131: {
1.3 noro 132: Z r,t;
1.4 noro 133: int c;
1.1 noro 134:
135: if ( !n ) return 0;
136: else if ( !INT(n) )
137: error("qtoz : invalid input");
138: else {
1.3 noro 139: t = (Z)NM(n);
1.5 noro 140: if ( IS_SZ(t) ) {
1.4 noro 141: c = SGN(n) < 0 ? -BD(t)[0] : BD(t)[0];
1.5 noro 142: STOZ(c,r);
1.3 noro 143: } else {
144: r = dupz((Z)t);
1.4 noro 145: if ( SGN(n) < 0 ) SL(r) = -SL(r);
1.3 noro 146: }
1.1 noro 147: return r;
148: }
149: }
150:
151: Q ztoq(Z n)
152: {
153: Q r;
154: Z nm;
1.3 noro 155: int sgn,c;
1.1 noro 156:
157: if ( !n ) return 0;
1.3 noro 158: else if ( IS_IMM(n) ) {
1.5 noro 159: c = ZTOS(n);
1.3 noro 160: STOQ(c,r);
161: return r;
162: } else {
1.1 noro 163: nm = dupz(n);
164: if ( SL(nm) < 0 ) {
165: sgn = -1;
166: SL(nm) = -SL(nm);
167: } else
168: sgn = 1;
169: NTOQ((N)nm,sgn,r);
170: return r;
171: }
172: }
173:
174: Z dupz(Z n)
175: {
1.5 noro 176: Z r;
1.1 noro 177: int sd,i;
178:
179: if ( !n ) return 0;
1.3 noro 180: else if ( IS_IMM(n) ) return n;
181: else {
182: if ( (sd = SL(n)) < 0 ) sd = -sd;
1.5 noro 183: r = ZALLOC(sd);
184: SL(r) = SL(n);
185: for ( i = 0; i < sd; i++ ) BD(r)[i] = BD(n)[i];
186: return r;
1.3 noro 187: }
1.1 noro 188: }
189:
190: Z chsgnz(Z n)
191: {
192: Z r;
1.3 noro 193: int c;
1.1 noro 194:
195: if ( !n ) return 0;
1.3 noro 196: else if ( IS_IMM(n) ) {
1.5 noro 197: c = -ZTOS(n);
198: STOZ(c,r);
1.3 noro 199: return r;
200: } else {
1.1 noro 201: r = dupz(n);
202: SL(r) = -SL(r);
203: return r;
204: }
205: }
206:
1.5 noro 207: Z absz(Z n)
208: {
209: Z r;
210: int c;
211:
212: if ( !n ) return 0;
213: else if ( sgnz(n) > 0 )
214: return n;
215: else
216: return chsgnz(n);
217: }
1.3 noro 218:
1.1 noro 219: Z addz(Z n1,Z n2)
220: {
1.3 noro 221: int d1,d2,d,c;
222: Z r,r1;
223: struct oZ t;
1.1 noro 224:
225: if ( !n1 ) return dupz(n2);
226: else if ( !n2 ) return dupz(n1);
1.3 noro 227: else if ( IS_IMM(n1) ) {
228: if ( IS_IMM(n2) ) {
1.5 noro 229: c = ZTOS(n1)+ZTOS(n2);
230: STOZ(c,r);
1.3 noro 231: } else {
1.5 noro 232: c = ZTOS(n1);
1.3 noro 233: if ( c < 0 ) {
234: t.p = -1; t.b[0] = -c;
1.1 noro 235: } else {
1.3 noro 236: t.p = 1; t.b[0] = c;
1.1 noro 237: }
1.3 noro 238: if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
239: r = ZALLOC(d2+1);
240: _addz(&t,n2,r);
1.5 noro 241: if ( !SL(r) ) r = 0;
1.3 noro 242: }
243: } else if ( IS_IMM(n2) ) {
1.5 noro 244: c = ZTOS(n2);
1.3 noro 245: if ( c < 0 ) {
246: t.p = -1; t.b[0] = -c;
1.1 noro 247: } else {
1.3 noro 248: t.p = 1; t.b[0] = c;
249: }
250: if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
251: r = ZALLOC(d1+1);
252: _addz(n1,&t,r);
1.5 noro 253: if ( !SL(r) ) r = 0;
1.3 noro 254: } else {
255: if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
256: if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
257: d = MAX(d1,d2)+1;
258: r = ZALLOC(d);
259: _addz(n1,n2,r);
260: if ( !SL(r) ) r = 0;
1.1 noro 261: }
1.5 noro 262: if ( r && !((int)r&1) && IS_SZ(r) ) {
263: SZTOZ(r,r1); r = r1;
264: }
265: return r;
1.1 noro 266: }
267:
268: Z subz(Z n1,Z n2)
269: {
1.3 noro 270: int d1,d2,d,c;
271: Z r,r1;
272: struct oZ t;
1.1 noro 273:
1.5 noro 274: if ( !n1 )
275: return chsgnz(n2);
276: else if ( !n2 ) return n1;
1.3 noro 277: else if ( IS_IMM(n1) ) {
278: if ( IS_IMM(n2) ) {
1.5 noro 279: c = ZTOS(n1)-ZTOS(n2);
280: STOZ(c,r);
1.3 noro 281: } else {
1.5 noro 282: c = ZTOS(n1);
1.3 noro 283: if ( c < 0 ) {
284: t.p = -1; t.b[0] = -c;
285: } else {
286: t.p = 1; t.b[0] = c;
287: }
288: if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
289: r = ZALLOC(d2+1);
290: _subz(&t,n2,r);
1.5 noro 291: if ( !SL(r) ) r = 0;
1.3 noro 292: }
293: } else if ( IS_IMM(n2) ) {
1.5 noro 294: c = ZTOS(n2);
1.3 noro 295: if ( c < 0 ) {
296: t.p = -1; t.b[0] = -c;
297: } else {
298: t.p = 1; t.b[0] = c;
299: }
300: if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
301: r = ZALLOC(d1+1);
302: _subz(n1,&t,r);
1.5 noro 303: if ( !SL(r) ) r = 0;
1.3 noro 304: } else {
305: if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
306: if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
307: d = MAX(d1,d2)+1;
308: r = ZALLOC(d);
309: _subz(n1,n2,r);
310: if ( !SL(r) ) r = 0;
1.1 noro 311: }
1.5 noro 312: if ( r && !((int)r&1) && IS_SZ(r) ) {
313: SZTOZ(r,r1); r = r1;
314: }
315: return r;
1.1 noro 316: }
317:
318: Z mulz(Z n1,Z n2)
319: {
1.3 noro 320: int d1,d2,sgn,i;
1.5 noro 321: int c1,c2;
1.1 noro 322: unsigned int u1,u2,u,l;
1.3 noro 323: Z r;
1.1 noro 324:
325: if ( !n1 || !n2 ) return 0;
1.3 noro 326:
327: if ( IS_IMM(n1) ) {
1.5 noro 328: c1 = ZTOS(n1);
1.3 noro 329: if ( IS_IMM(n2) ) {
1.5 noro 330: c2 = ZTOS(n2);
331: if ( c1 == 1 )
332: return n2;
333: else if ( c1 == -1 )
334: return chsgnz(n2);
335: else if ( c2 == 1 )
336: return n1;
337: else if ( c2 == -1 )
338: return chsgnz(n1);
339: else {
340: sgn = 1;
341: if ( c1 < 0 ) { c1 = -c1; sgn = -sgn; }
342: if ( c2 < 0 ) { c2 = -c2; sgn = -sgn; }
343: u1 = (unsigned int)c1; u2 = (unsigned int)c2;
344: DM(u1,u2,u,l);
345: if ( !u ) {
346: UTOZ(l,r);
347: } else {
348: r = ZALLOC(2); SL(r) = 2; BD(r)[1] = u; BD(r)[0] = l;
349: }
1.1 noro 350: }
351: } else {
1.5 noro 352: sgn = 1;
353: if ( c1 < 0 ) { c1 = -c1; sgn = -sgn; }
354: u1 = (unsigned int)c1;
1.3 noro 355: if ( (d2 = SL(n2)) < 0 ) { sgn = -sgn; d2 = -d2; }
356: r = ZALLOC(d2+1);
357: for ( i = d2; i >= 0; i-- ) BD(r)[i] = 0;
358: muln_1(BD(n2),d2,u1,BD(r));
359: SL(r) = BD(r)[d2]?d2+1:d2;
1.1 noro 360: }
1.3 noro 361: } else if ( IS_IMM(n2) ) {
1.5 noro 362: c2 = ZTOS(n2);
363: if ( c2 == 1 )
364: return n1;
365: else if ( c2 == -1 )
366: return chsgnz(n1);
367:
1.3 noro 368: sgn = 1;
1.5 noro 369: if ( c2 < 0 ) { sgn = -sgn; c2 = -c2; }
370: u2 = (unsigned int)c2;
1.3 noro 371: if ( (d1 = SL(n1)) < 0 ) { sgn = -sgn; d1 = -d1; }
372: r = ZALLOC(d1+1);
373: for ( i = d1; i >= 0; i-- ) BD(r)[i] = 0;
374: muln_1(BD(n1),d1,u2,BD(r));
375: SL(r) = BD(r)[d1]?d1+1:d1;
376: } else {
377: sgn = 1;
1.5 noro 378: if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
379: if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
1.3 noro 380: r = ZALLOC(d1+d2);
381: _mulz(n1,n2,r);
1.1 noro 382: }
1.5 noro 383: if ( sgn < 0 ) r = chsgnz(r);
1.3 noro 384: return r;
1.1 noro 385: }
386:
1.3 noro 387: /* kokokara */
1.4 noro 388: #if 0
1.1 noro 389: Z divsz(Z n1,Z n2)
390: {
1.3 noro 391: int sgn,d1,d2;
392: Z q;
1.1 noro 393:
394: if ( !n2 ) error("divsz : division by 0");
1.3 noro 395: if ( !n1 ) return 0;
396:
397: if ( IS_IMM(n1) ) {
398: if ( !IS_IMM(n2) )
399: error("divsz : cannot happen");
1.5 noro 400: c = ZTOS(n1)/ZTOS(n2);
401: STOZ(c,q);
1.3 noro 402: return q;
1.1 noro 403: }
1.3 noro 404: if ( IS_IMM(n2) ) {
405: sgn = 1;
1.5 noro 406: u2 = ZTOS(n2); if ( u2 < 0 ) { sgn = -sgn; u2 = -u2; }
1.3 noro 407: diviz(n1,u2,&q);
408: if ( sgn < 0 ) SL(q) = -SL(q);
409: return q;
410: }
411:
412: sgn = 1;
413: if ( (d2 = SL(n2)) < 0 ) { sgn = -sgn; d2 = -d2; }
414: if ( d2 == 1 ) {
415: diviz(n1,BD(u2)[0],&q);
416: if ( sgn < 0 ) SL(q) = -SL(q);
417: return q;
418: }
419: if ( (d1 = SL(n1)) < 0 ) { sgn = -sgn; d1 = -d1; }
420: if ( d1 < d2 ) error("divsz : cannot happen");
421: return q;
1.1 noro 422: }
1.5 noro 423: #endif
424:
425: /* XXX */
426: Z divz(Z n1,Z n2,Z *r)
427: {
428: int s1,s2;
429: Q t1,t2,qq,rq;
430: N qn,rn;
431:
432: if ( !n1 ) {
433: *r = 0; return 0;
434: }
435: if ( !n2 )
436: error("divz : division by 0");
437: t1 = ztoq(n1); t2 = ztoq(n2);
438: s1 = sgnz(n1); s2 = sgnz(n2);
439: /* n1 = qn*SGN(n1)*SGN(n2)*n2+SGN(n1)*rn */
440: divn(NM(t1),NM(t2),&qn,&rn);
441: NTOQ(qn,s1*s2,qq);
442: NTOQ(rn,s1,rq);
443: *r = qtoz(rq);
444: return qtoz(qq);
445: }
446:
447: Z divsz(Z n1,Z n2)
448: {
449: int s1,s2;
450: Q t1,t2,qq;
451: N qn;
452:
453: if ( !n1 )
454: return 0;
455: if ( !n2 )
456: error("divsz : division by 0");
457: t1 = ztoq(n1); t2 = ztoq(n2);
458: s1 = sgnz(n1); s2 = sgnz(n2);
459: /* n1 = qn*SGN(n1)*SGN(n2)*n2 */
460: divsn(NM(t1),NM(t2),&qn);
461: NTOQ(qn,s1*s2,qq);
462: return qtoz(qq);
463: }
464:
465: int gcdimm(int c1,int c2)
466: {
467: int r;
468:
469: if ( !c1 ) return c2;
470: else if ( !c2 ) return c1;
471: while ( 1 ) {
472: r = c1%c2;
473: if ( !r ) return c2;
474: c1 = c2; c2 = r;
475: }
476: }
1.1 noro 477:
478: Z gcdz(Z n1,Z n2)
479: {
1.5 noro 480: int c1,c2,g;
481: Z gcd,r;
482: N gn;
1.1 noro 483:
484: if ( !n1 ) return n2;
485: else if ( !n2 ) return n1;
486:
1.5 noro 487: if ( IS_IMM(n1) ) {
488: c1 = ZTOS(n1);
489: if ( c1 < 0 ) c1 = -c1;
490: if ( IS_IMM(n2) )
491: c2 = ZTOS(n2);
492: else
493: c2 = remzi(n2,c1>0?c1:-c1);
494: if ( c2 < 0 ) c2 = -c2;
495: g = gcdimm(c1,c2);
496: STOZ(g,gcd);
497: return gcd;
498: } else if ( IS_IMM(n2) ) {
499: c2 = ZTOS(n2);
500: if ( c2 < 0 ) c2 = -c2;
501: c1 = remzi(n1,c2>0?c2:-c2);
502: if ( c1 < 0 ) c1 = -c1;
503: g = gcdimm(c1,c2);
504: STOZ(g,gcd);
505: return gcd;
506: } else {
507: n1 = dupz(n1);
508: if ( SL(n1) < 0 ) SL(n1) = -SL(n1);
509: n2 = dupz(n2);
510: if ( SL(n2) < 0 ) SL(n2) = -SL(n2);
511: gcdn((N)n1,(N)n2,&gn);
512: gcd = (Z)gn;
513: if ( IS_SZ(gcd) ) {
514: SZTOZ(gcd,r); gcd = r;
515: }
516: return gcd;
517: }
1.1 noro 518: }
519:
520: int remzi(Z n,int m)
521: {
522: unsigned int *x;
523: unsigned int t,r;
1.5 noro 524: int i,c;
1.1 noro 525:
526: if ( !n ) return 0;
1.5 noro 527: if ( IS_IMM(n) ) {
528: c = ZTOS(n)%m;
529: if ( c < 0 ) c += m;
530: return c;
531: }
532:
1.1 noro 533: i = SL(n);
534: if ( i < 0 ) i = -i;
535: for ( i--, x = BD(n)+i, r = 0; i >= 0; i--, x-- ) {
536: #if defined(sparc)
537: r = dsa(m,r,*x);
538: #else
539: DSAB(m,r,*x,t,r);
540: #endif
541: }
1.5 noro 542: if ( r && SL(n) < 0 )
543: r = m-r;
1.1 noro 544: return r;
545: }
546:
547: Z gcdz_cofactor(Z n1,Z n2,Z *c1,Z *c2)
548: {
549: Z gcd;
550:
551: gcd = gcdz(n1,n2);
552: *c1 = divsz(n1,gcd);
553: *c2 = divsz(n2,gcd);
554: return gcd;
555: }
556:
1.5 noro 557: #if 0
1.1 noro 558: Z estimate_array_gcdz(Z *b,int n)
559: {
560: int m,i,j,sd;
561: Z *a;
562: Z s,t;
563:
564: a = (Z *)ALLOCA(n*sizeof(Z));
565: for ( i = j = 0; i < n; i++ ) if ( b[i] ) a[j++] = b[i];
566: n = j;
567: if ( !n ) return 0;
568: if ( n == 1 ) return a[0];
569:
570: m = n/2;
571: for ( i = 0, s = 0; i < m; i++ ) {
572: if ( !a[i] ) continue;
573: else s = (SL(a[i])<0)?subz(s,a[i]):addz(s,a[i]);
574: }
575: for ( t = 0; i < n; i++ ) {
576: if ( !a[i] ) continue;
577: else t = (SL(a[i])<0)?subz(t,a[i]):addz(t,a[i]);
578: }
579: return gcdz(s,t);
580: }
581:
582: Z array_gcdz(Z *b,int n)
583: {
584: int m,i,j,sd;
585: Z *a;
586: Z gcd;
587:
588: a = (Z *)ALLOCA(n*sizeof(Z));
589: for ( i = j = 0; i < n; i++ ) if ( b[i] ) a[j++] = b[i];
590: n = j;
591: if ( !n ) return 0;
592: if ( n == 1 ) return a[0];
593: gcd = a[0];
594: for ( i = 1; i < n; i++ )
595: gcd = gcdz(gcd,a[i]);
596: return gcd;
597: }
1.4 noro 598: #endif
1.1 noro 599:
600: void _copyz(Z n1,Z n2)
601: {
602: int n,i;
603:
604: if ( !n1 || !SL(n1) ) SL(n2) = 0;
605: else {
606: n = SL(n2) = SL(n1);
607: if ( n < 0 ) n = -n;
608: for ( i = 0; i < n; i++ ) BD(n2)[i] = BD(n1)[i];
609: }
610: }
611:
612: void _addz(Z n1,Z n2,Z nr)
613: {
1.3 noro 614: int d1,d2;
1.1 noro 615:
616: if ( !n1 || !SL(n1) ) _copyz(n2,nr);
617: else if ( !n2 || !SL(n2) ) _copyz(n1,nr);
1.3 noro 618: else if ( (d1=SL(n1)) > 0 )
619: if ( (d2=SL(n2)) > 0 )
620: SL(nr) = _addz_main(BD(n1),d1,BD(n2),d2,BD(nr));
1.1 noro 621: else
1.3 noro 622: SL(nr) = _subz_main(BD(n1),d1,BD(n2),-d2,BD(nr));
623: else if ( (d2=SL(n2)) > 0 )
624: SL(nr) = _subz_main(BD(n2),d2,BD(n1),-d1,BD(nr));
1.1 noro 625: else
1.3 noro 626: SL(nr) = -_addz_main(BD(n1),-d1,BD(n2),-d2,BD(nr));
1.1 noro 627: }
628:
629: void _subz(Z n1,Z n2,Z nr)
630: {
1.3 noro 631: int d1,d2;
1.1 noro 632:
633: if ( !n1 || !SL(n1) ) _copyz(n2,nr);
634: else if ( !n2 || !SL(n2) ) {
635: _copyz(n1,nr);
636: SL(nr) = -SL(nr);
1.3 noro 637: } else if ( (d1=SL(n1)) > 0 )
638: if ( (d2=SL(n2)) > 0 )
639: SL(nr) = _subz_main(BD(n1),d1,BD(n2),d2,BD(nr));
1.1 noro 640: else
1.3 noro 641: SL(nr) = _addz_main(BD(n1),d1,BD(n2),-d2,BD(nr));
642: else if ( (d2=SL(n2)) > 0 )
643: SL(nr) = -_addz_main(BD(n1),-d1,BD(n2),d2,BD(nr));
1.1 noro 644: else
1.3 noro 645: SL(nr) = -_subz_main(BD(n1),-d1,BD(n2),-d2,BD(nr));
1.1 noro 646: }
647:
648: void _mulz(Z n1,Z n2,Z nr)
649: {
1.3 noro 650: int d1,d2;
1.1 noro 651: int i,d,sgn;
652: unsigned int mul;
653: unsigned int *m1,*m2;
654:
655: if ( !n1 || !SL(n1) || !n2 || !SL(n2) )
656: SL(nr) = 0;
657: else {
1.3 noro 658: d1 = SL(n1); d2 = SL(n2);
1.1 noro 659: sgn = 1;
1.3 noro 660: if ( d1 < 0 ) { sgn = -sgn; d1 = -d1; }
661: if ( d2 < 0 ) { sgn = -sgn; d2 = -d2; }
662: d = d1+d2;
1.1 noro 663: for ( i = d-1, m1 = BD(nr); i >= 0; i-- ) *m1++ = 0;
1.3 noro 664: for ( i = 0, m1 = BD(n1), m2 = BD(n2); i < d2; i++, m2++ )
665: if ( mul = *m2 ) muln_1(m1,d1,mul,BD(nr)+i);
1.1 noro 666: SL(nr) = sgn*(BD(nr)[d-1]?d:d-1);
667: }
668: }
669:
670: int _addz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr)
671: {
672: int d,i;
673: unsigned int tmp,c;
674: unsigned int *t;
675:
676: if ( d2 > d1 ) {
677: t = m1; m1 = m2; m2 = t;
678: d = d1; d1 = d2; d2 = d;
679: }
680: #if defined(VISUAL)
681: __asm {
682: push esi
683: push edi
684: mov esi,m1
685: mov edi,m2
686: mov ebx,mr
687: mov ecx,d2
688: xor eax,eax
689: Lstart__addz:
690: mov eax,DWORD PTR [esi]
691: mov edx,DWORD PTR [edi]
692: adc eax,edx
693: mov DWORD PTR [ebx],eax
694: lea esi,DWORD PTR [esi+4]
695: lea edi,DWORD PTR [edi+4]
696: lea ebx,DWORD PTR [ebx+4]
697: dec ecx
698: jnz Lstart__addz
699: pop edi
700: pop esi
701: mov eax,0
702: adc eax,eax
703: mov c,eax
704: }
705: #elif defined(i386)
706: asm volatile("\
707: movl %1,%%esi;\
708: movl %2,%%edi;\
709: movl %3,%%ebx;\
710: movl %4,%%ecx;\
711: testl %%eax,%%eax;\
712: Lstart__addz:;\
713: movl (%%esi),%%eax;\
714: movl (%%edi),%%edx;\
715: adcl %%edx,%%eax;\
716: movl %%eax,(%%ebx);\
717: leal 4(%%esi),%%esi;\
718: leal 4(%%edi),%%edi;\
719: leal 4(%%ebx),%%ebx;\
720: decl %%ecx;\
721: jnz Lstart__addz;\
722: movl $0,%%eax;\
723: adcl %%eax,%%eax;\
724: movl %%eax,%0"\
725: :"=m"(c)\
726: :"m"(m1),"m"(m2),"m"(mr),"m"(d2)\
727: :"eax","ebx","ecx","edx","esi","edi");
728: #else
1.6 noro 729: for ( i = 0, c = 0; i < d2; i++, m1++, m2++, mr++ ) {
1.1 noro 730: tmp = *m1 + *m2;
731: if ( tmp < *m1 ) {
732: tmp += c;
733: c = 1;
734: } else {
735: tmp += c;
736: c = tmp < c ? 1 : 0;
737: }
738: *mr = tmp;
739: }
740: #endif
741: for ( i = d2, m1 += d2, mr += d2; (i < d1) && c ; i++ ) {
742: tmp = *m1++ + c;
743: c = tmp < c ? 1 : 0;
744: *mr++ = tmp;
745: }
746: for ( ; i < d1; i++ )
747: *mr++ = *m1++;
748: *mr = c;
749: return (c?d1+1:d1);
750: }
751:
752: int _subz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr)
753: {
754: int d,i,sgn;
755: unsigned int t,tmp,br;
756: unsigned int *m;
757:
758: if ( d1 > d2 ) sgn = 1;
759: else if ( d1 < d2 ) sgn = -1;
760: else {
761: for ( i = d1-1; i >= 0 && m1[i] == m2[i]; i-- );
762: if ( i < 0 ) return 0;
763: if ( m1[i] > m2[i] ) sgn = 1;
764: else if ( m1[i] < m2[i] ) sgn = -1;
765: }
766: if ( sgn < 0 ) {
767: m = m1; m1 = m2; m2 = m;
768: d = d1; d1 = d2; d2 = d;
769: }
770: #if defined(VISUAL)
771: __asm {
772: push esi
773: push edi
774: mov esi,m1
775: mov edi,m2
776: mov ebx,mr
777: mov ecx,d2
778: xor eax,eax
779: Lstart__subz:
780: mov eax,DWORD PTR [esi]
781: mov edx,DWORD PTR [edi]
782: sbb eax,edx
783: mov DWORD PTR [ebx],eax
784: lea esi,DWORD PTR [esi+4]
785: lea edi,DWORD PTR [edi+4]
786: lea ebx,DWORD PTR [ebx+4]
787: dec ecx
788: jnz Lstart__subz
789: pop edi
790: pop esi
791: mov eax,0
792: adc eax,eax
793: mov br,eax
794: }
795: #elif defined(i386)
796: asm volatile("\
797: movl %1,%%esi;\
798: movl %2,%%edi;\
799: movl %3,%%ebx;\
800: movl %4,%%ecx;\
801: testl %%eax,%%eax;\
802: Lstart__subz:;\
803: movl (%%esi),%%eax;\
804: movl (%%edi),%%edx;\
805: sbbl %%edx,%%eax;\
806: movl %%eax,(%%ebx);\
807: leal 4(%%esi),%%esi;\
808: leal 4(%%edi),%%edi;\
809: leal 4(%%ebx),%%ebx;\
810: decl %%ecx;\
811: jnz Lstart__subz;\
812: movl $0,%%eax;\
813: adcl %%eax,%%eax;\
814: movl %%eax,%0"\
815: :"=m"(br)\
816: :"m"(m1),"m"(m2),"m"(mr),"m"(d2)\
817: :"eax","ebx","ecx","edx","esi","edi");
818: #else
1.6 noro 819: for ( i = 0, br = 0; i < d2; i++, mr++ ) {
1.1 noro 820: t = *m1++;
821: tmp = *m2++ + br;
822: if ( br > 0 && !tmp ) {
823: /* tmp = 2^32 => br = 1 */
824: }else {
825: tmp = t-tmp;
826: br = tmp > t ? 1 : 0;
827: *mr = tmp;
828: }
829: }
830: #endif
831: for ( i = d2, m1 += d2, mr += d2; (i < d1) && br; i++ ) {
832: t = *m1++;
833: tmp = t - br;
834: br = tmp > t ? 1 : 0;
835: *mr++ = tmp;
836: }
837: for ( ; i < d1; i++ )
838: *mr++ = *m1++;
839: for ( i = d1-1, mr--; i >= 0 && !*mr--; i-- );
840: return sgn*(i+1);
841: }
842:
843: /* XXX */
844:
845: void printz(Z n)
846: {
1.4 noro 847: int sd,u;
1.1 noro 848:
849: if ( !n )
850: fprintf(asir_out,"0");
1.4 noro 851: else if ( IS_IMM(n) ) {
1.5 noro 852: u = ZTOS(n);
1.4 noro 853: fprintf(asir_out,"%d",u);
854: } else {
1.1 noro 855: if ( (sd = SL(n)) < 0 ) { SL(n) = -SL(n); fprintf(asir_out,"-"); }
856: printn((N)n);
857: if ( sd < 0 ) SL(n) = -SL(n);
1.2 noro 858: }
859: }
860:
861: /*
862: * Dx^k*x^l = W(k,l,0)*x^l*Dx^k+W(k,l,1)*x^(l-1)*x^(k-1)*+...
863: *
864: * t = [W(k,l,0) W(k,l,1) ... W(k,l,min(k,l)]
865: * where W(k,l,i) = i! * kCi * lCi
866: */
867:
868: void mkwcz(int k,int l,Z *t)
869: {
870: int i,n,up,low;
871: N nm,d,c;
872:
873: n = MIN(k,l);
874: for ( t[0] = (Z)ONEN, i = 1; i <= n; i++ ) {
875: DM(k-i+1,l-i+1,up,low);
876: if ( up ) {
877: nm = NALLOC(2); PL(nm) = 2; BD(nm)[0] = low; BD(nm)[1] = up;
878: } else {
879: nm = NALLOC(1); PL(nm) = 1; BD(nm)[0] = low;
880: }
881: kmuln((N)t[i-1],nm,&d); divin(d,i,&c); t[i] = (Z)c;
1.1 noro 882: }
883: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>