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