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