Annotation of OpenXM_contrib2/asir2000/engine-27/igcdhack.c, Revision 1.1.1.1
1.1 noro 1: /* $OpenXM: OpenXM/src/asir99/engine-27/igcdhack.c,v 1.1.1.1 1999/11/10 08:12:27 noro Exp $ */
2: #if 0
3: #include "base.h"
4:
5: #define SWAP(a,b,Type) { Type temp=a; a = b; b = temp; }
6: #define SIGNED_VAL(a,s) ((s)>0?(a): -(a))
7: #endif
8:
9: #undef FULLSET
10:
11:
12: static int negate_nbd( b, l )
13: int *b, l;
14: /* It is assumed that l > 0 and b[0] != 0 */
15: {
16: int i, nz;
17:
18: *b = BASE27 - *b;
19: for ( nz = i = 1 ; i < l; ) {
20: b++, i++;
21: if ( (*b ^= BMASK27) != 0 ) nz = i;
22: }
23: return nz;
24: }
25:
26: /****************/
27: /****************/
28:
29: static int abs_U_V_maxrshift( u, lu, v, lv, a )
30: int *u, lu, *v, lv, *a;
31: /*
32: * Compute | U - V | >> (as much as possible) in a[], where U = u[0:lu-1]
33: * and V = v[0:lv-1]. Value returned is the length of the result
34: * multiplied by the sign of (U-V).
35: */
36: {
37: int sign, rsh, t, b, i, l, *p = a;
38:
39: /* first, determine U <, ==, > V */
40: sign = 1;
41: if ( lu == lv ) {
42: int i;
43:
44: for ( i = lu -1; i >= 0; i-- ) {
45: if ( u[i] == v[i] ) continue;
46: lu = lv = i + 1;
47: if ( u[i] > v[i] ) goto U_V;
48: else goto swap;
49: }
50: return 0;
51: } else if ( lu > lv ) goto U_V;
52: swap:
53: SWAP( lu, lv, int ); SWAP( u, v, int * );
54: sign = -1;
55: U_V: /* U > V, i.e., (lu > lv) || (lu == lv && u[lu-1] > v[lv-1]) */
56: for ( i = 0; i < lv; i++ ) if ( u[i] != v[i] ) break;
57: if ( i != 0 ) u += i, lu -= i, v += i, lv -= i;
58: if ( lv == 0 ) { /* no more pv[], and lu > 0 */
59: i = trailingzeros_nbd( u, &rsh );
60: i = rshift_nbd( u, lu, rsh, i, a );
61: return SIGNED_VAL( i, sign );
62: }
63: /**/
64: if ( (t = u[0] - v[0]) >= 0 ) b = 0;
65: else b = 1, t += BASE27;
66: TRAILINGZEROS( t, rsh );
67: /**/
68: if ( rsh != 0 ) {
69: int w, lsh = BSH27 - rsh;
70:
71: /* subtract v[*] from u[*] */
72: for ( i = 1, l = 0; i < lv; i++, t = w >> rsh ) {
73: if ( (w = u[i] - v[i] - b) >= 0 ) b = 0;
74: else b = 1, w += BASE27;
75: if ( (*p++ = t | ((w << lsh) & BMASK27)) != 0 ) l = i;
76: }
77: /* subtraction of V completed. Note there may exist non-0 borrow b */
78: if ( i >= lu ) /* lu == lv, and b==0 is implied */ goto chk_nz;
79: /* we still have (lu-i) elms in U */
80: if ( b != 0 ) { /* non-zero borrow */
81: if ( (w = u[i++] -1) != 0 ) t |= ((w << lsh) & BMASK27);
82: if ( i >= lu ) { /* lu == lv+1. The M.S. word w may beome 0 */
83: if ( w != 0 ) {
84: *p++ = t;
85: l = lv;
86: t = w >> rsh;
87: } else lu--;
88: goto chk_nz;
89: }
90: *p++ = t;
91: if ( w < 0 ) {
92: while ( (w = u[i++]) == 0 ) *p++ = BMASK27;
93: w -= 1;
94: *p++ = (BMASK27 >> rsh) | ((w << lsh) & BMASK27);
95: }
96: t = w >> rsh;
97: }
98: for ( ; i < lu; i++, t = w >> rsh ) *p++ = t | (((w = u[i]) << lsh) & BMASK27);
99: l = i -1;
100: chk_nz:
101: if ( t != 0 ) *p = t, l = /*1 + (p - a)*/ lu;
102: goto ret_nz;
103: }
104: /* rsh == 0 : need not be right-shifted */
105: *p++ = t, l = 1;
106: for ( i = 1; i < lv; ) {
107: if ( (t = u[i] - v[i] - b) >= 0 ) b = 0;
108: else b = 1, t += BASE27;
109: i++;
110: if ( (*p++ = t) != 0 ) l = i;
111: }
112: if ( i >= lu ) /* lu == lv, and b==0 is implied */ goto ret_nz;
113: if ( b != 0 ) { /* non-zero borrow */
114: t = u[i++] -1;
115: if ( i >= lu ) /* lu == lv+1. The M.S. word w may beome 0 */ goto chk_nz;
116: if ( t < 0 ) {
117: do *p++ = BMASK27; while ( (t = u[i++]) == 0 );
118: t -= 1;
119: if ( i >= lu ) {
120: l = lu;
121: if ( t == 0 ) l--;
122: else *p = t;
123: goto ret_nz;
124: }
125: }
126: *p++ = t;
127: }
128: for ( ; i < lu; i++ ) *p++ = u[i];
129: l = lu;
130: /**/
131: ret_nz:
132: return SIGNED_VAL( l, sign );
133: }
134:
135: /****************/
136: /****************/
137:
138: #ifdef CALL
139: static int aV_plus_c(), aV_plus_c_sh();
140: #endif
141: static int abs_U_aV_c(), abs_U_aV_c_sh();
142: static int abs_aVplusc_U(), abs_aVplusc_U_sh();
143:
144: static int abs_U_aV_maxrshift( u, lu, a, v, lv, ans )
145: int *u, lu, a, *v, lv, *ans;
146: {
147: int i, t, c, rsh, l, *p = ans, w, lsh;
148: int hi;
149:
150: if ( a == 1 ) return( (l = abs_U_V_maxrshift( u, lu, v, lv, ans )) >= 0 ? l : -l );
151: /**/
152: for ( l = lu <= lv ? lu : lv, i = c = 0; i < l; ) {
153: DMA27( a, v[i], c, hi, t)
154: c = hi;
155: if ( (t -= u[i++]) != 0 ) goto non0w;
156: }
157: /**/
158: if ( i < lv ) { /* no more u[] elm.'s, and we still have non-zero v[] elm's */
159: do {
160: DMA27( a, v[i], c, hi, t)
161: i++, c = hi;
162: } while ( t == 0 );
163: TRAILINGZEROS( t, rsh );
164: v += i, lv -= i;
165: #ifdef CALL
166: if ( rsh == 0 ) {
167: *p++ = t;
168: return( aV_plus_c( a, v, lv, c, p ) + 1 );
169: } else return aV_plus_c_sh( a, v, lv, c, rsh, t, ans );
170: #else
171: i = 0;
172: if ( rsh == 0 ) {
173: *p++ = t;
174: for ( ; i < lv; i++, c = hi, *p++ = t ) { DMA27( a, v[i], c, hi, t); }
175: if ( c == 0 ) return( i + 1 );
176: *p = c;
177: return( i + 2 );
178: } else {
179: for ( lsh = BSH27 - rsh; i < lv; i++, c = hi, t = w >> rsh ) {
180: DMA27( a, v[i], c, hi, w);
181: *p++ = t | ((w << lsh) & BMASK27);
182: }
183: if ( c != 0 ) {
184: *p++ = t | ((c << lsh) & BMASK27);
185: i++;
186: t = c >> rsh;
187: }
188: if ( t == 0 ) return i;
189: *p = t;
190: return( i + 1 );
191: }
192: #endif
193: }
194: /* no more v[] elm.'s */
195: if ( i >= lu ) {
196: if ( c == 0 ) return 0;
197: c_sh:
198: while ( (c&1) == 0 ) c >>= 1;
199: *p = c;
200: return 1;
201: }
202: t = u[i++] - c;
203: if ( i >= lu ) {
204: if ( t == 0 ) return 0;
205: c = t < 0 ? -t : t;
206: goto c_sh;
207: } else if ( t == 0 ) {
208: while ( (t = u[i++]) == 0 ) ;
209: c = 0;
210: } else if ( t < 0 ) t += BASE27, c = 1;
211: else c = 0;
212: /* diff turned out to be > 0 */
213: u += i, lu -= i;
214: TRAILINGZEROS( t, rsh );
215: i = 0;
216: if ( rsh == 0 ) {
217: *p++ = t;
218: if ( c != 0 ) {
219: for ( ; i < lu; *p++ = BMASK27 ) if ( (t = u[i++]) != 0 ) break;
220: t--;
221: if ( i >= lu && t == 0 ) return i;
222: *p++ = t;
223: }
224: for ( ; i < lu; i++ ) *p++ = u[i];
225: } else { /* rsh != 0 */
226: lsh = BSH27 - rsh;
227: if ( c != 0 ) { /* there still exists u[] elms.'s because diff is known to be > 0 */
228: if ( (w = u[i++]) == 0 ) {
229: *p++ = t | ((BMASK27 << lsh) & BMASK27);
230: for ( ; (w = u[i++]) == 0; *p++ = BMASK27 ) ;
231: t = BMASK27 >> rsh;
232: }
233: w--;
234: *p++ = t | ((w << lsh) & BMASK27);
235: t = w >> rsh;
236: }
237: for ( ; i < lu; i++, t = w >> rsh ) *p++ = t | (((w = u[i]) << lsh) & BMASK27);
238: if ( t == 0 ) return( i );
239: *p = t;
240: }
241: return( i + 1 );
242: /**/
243: non0w:
244: u += i, lu -= i, v += i, lv -= i;
245: /* | t + BASE27*(c + a*v[0:lv-1] - u[0:lu-1] | */
246: if ( lv < lu ) { /* a*V < U if lv<lu-1, and very likely if lv==lu-1 */
247: t = -t; /* We shall compute U - a*V */
248: if ( t < 0 ) t += BASE27, c++;
249: } else /* a*V > U if lv>lu, and very likely even if lv==lu */
250: if ( t < 0 ) t += BASE27, c--;
251: TRAILINGZEROS( t, rsh );
252: return( rsh == 0 ? (lv < lu ? abs_U_aV_c( t, u, lu, a, v, lv, c, ans ) :
253: abs_aVplusc_U( t, a, v, lv, c, u, lu, ans )) :
254: lv < lu ? abs_U_aV_c_sh( t, u, lu, a, v, lv, c, rsh, ans ) :
255: abs_aVplusc_U_sh( t, a, v, lv, c, u, lu, rsh, ans ) );
256: }
257:
258: /*********/
259:
260: static int aV_plus_c( a, v, lv, c, p )
261: int a, *v, lv, c, *p;
262: /*
263: * Compute (a*V + c) in p[], where V = v[0:lv-1].
264: */
265: {
266: int i, t;
267: int hi;
268:
269: for ( i = 0; i < lv; i++, *p++ = t, c = hi ) { DMA27( a, v[i], c, hi, t); }
270: if ( c == 0 ) return i;
271: *p = c;
272: return( i + 1 );
273: }
274:
275: static int aV_plus_c_sh( a, v, lv, c, rsh, t, p )
276: int a, *v, lv, c, rsh, *p;
277: /*
278: * Compute (t + BASE27*((a*V + c) >> rsh)) in p[], where V = v[0:lv-1].
279: */
280: {
281: int i, w, lsh = BSH27 - rsh;
282: int hi;
283:
284: for ( i = 0; i < lv; i++, c = hi, t = w >> rsh ) {
285: DMA27( a, v[i], c, hi, w);
286: *p++ = t | ((w << lsh) & BMASK27);
287: }
288: if ( c != 0 ) {
289: *p++ = t | ((c << lsh) & BMASK27);
290: i++;
291: t = c >> rsh;
292: }
293: if ( t == 0 ) return i;
294: *p = t;
295: return( i + 1 );
296: }
297:
298: /*********/
299:
300: static int abs_aVplusc_U( t, a, v, lv, c, u, lu, ans )
301: int t, a, *v, lv, c, *u, lu, *ans;
302: /* compute | t + BASE27*(a*V+c - U) | in ans[], where V=v[0:lv-1], U=u[0:lu-1],
303: * and a > 1, -1 <= c < BASE27, lv >= lu >=0 && t != 0 are assumed.
304: */
305: {
306: int i, l, b, *p = ans;
307: int hi;
308:
309: *p++ = t, l = 1;
310: if ( c < 0 ) c = 0, b = 1;
311: else b = 0;
312: for ( i = 0; i < lu; *p++ = t ) {
313: DMA27( a, v[i], c, hi, t);
314: t -= u[i++], c = hi;
315: if ( b != 0 ) t--;
316: b = 0;
317: if ( t > 0 ) l = i + 1;
318: else if ( t < 0 ) {
319: t += BASE27, l = i + 1;
320: if ( c != 0 ) c--;
321: else b = 1;
322: }
323: }
324: /* at this point, i == lu and we have written (i+1) entries in ans[] */
325: if ( i >= lv ) { /* no more elms in v[] */
326: if ( b != 0 ) {
327: if ( i == 0 ) { ans[i] = BASE27 - t; return 1; }
328: l = negate_nbd( ans, i ); /* <================ */
329: /* if ( (t = BMASK27 ^ ans[i]) == 0 ) return l;*/
330: if ( (t ^= BMASK27) == 0 ) return l;
331: ans[i] = t;
332: return( i + 1 );
333: }
334: if ( c == 0 ) return l;
335: *p = c;
336: return( i + 2 );
337: }
338: /* diff turned out to be > 0 */
339: if ( b != 0 ) { /* c == 0 */
340: while ( (b = v[i++]) == 0 ) *p++ = BMASK27;
341: DM27( a, b, hi, t );
342: if ( t != 0 ) t--, c = hi;
343: else t = BMASK27, c = hi - 1;
344: *p++ - t;
345: }
346: #ifdef CALL
347: return( aV_plus_c( a, &v[i], lv - i, c, p ) + i +1 );
348: #else
349: for ( ; i < lv; i++, *p++ = t, c = hi ) { DMA27( a, v[i], c, hi, t);}
350: if ( c == 0 ) return( i + 1 );
351: *p = c;
352: return( i + 2 );
353: #endif
354: }
355:
356: static int abs_aVplusc_U_sh( t, a, v, lv, c, u, lu, rsh, ans )
357: int t, a, *v, lv, c, *u, lu, rsh, *ans;
358: {
359: int i, l, w, b, lsh = BSH27 - rsh, *p = ans;
360: int hi;
361:
362: if ( c < 0 ) c = 0, b = 1;
363: else b = 0;
364: for ( i = 0; i < lu; t = w >> rsh ) {
365: DMA27( a, v[i], c, hi, w);
366: w -= u[i++], c = hi;
367: if ( b != 0 ) w--;
368: b = 0;
369: if ( w < 0 ) {
370: w += BASE27;
371: if ( c != 0 ) c--;
372: else b = 1;
373: }
374: if ( (*p++ = t | ((w << lsh) & BMASK27)) != 0 ) l = i;
375: }
376: /* at this point, i == lu and we have written i entries in ans[] */
377: if ( i >= lv ) {
378: if ( b != 0 ) { /* diff turned out to be < 0 */
379: if ( i == 0 ) {
380: *p = (BASE27 >> rsh) - t;
381: return 1;
382: }
383: l = negate_nbd( ans, i ); /* <================ */
384: if ( (t ^= (BMASK27 >> rsh)) == 0 ) return l;
385: *p = t;
386: return( i + 1 );
387: }
388: if ( c == 0 ) {
389: if ( t == 0 ) return l;
390: *p = t;
391: return( i + 1 );
392: }
393: *p++ = t | ((c << lsh) & BMASK27);
394: if ( (t = c >> rsh) == 0 ) return( i + 1 );
395: *p = t;
396: return( i + 2 );
397: }
398: /* lv >= lu+1 = i+1, and diff is > 0 */
399: if ( b != 0 ) { /* c == 0 */
400: if ( (w = v[i++]) == 0 ) {
401: *p++ = t | ((BMASK27 << lsh) & BMASK27);
402: while ( (w = v[i++]) == 0 ) *p++ = BMASK27;
403: t = BMASK27 >> rsh;
404: } else {
405: DM27( a, w, c, b );
406: if ( b != 0 ) b--;
407: else b = BMASK27, c--;
408: *p++ = t | ((b << lsh) & BMASK27);
409: t = b >> rsh;
410: }
411: }
412: /**/
413: #ifdef CALL
414: return( aV_plus_c_sh( a, &v[i], lv - i, c, rsh, t, p ) + i );
415: #else
416: for ( ; i < lv; i++, t = w >> rsh, c = hi ) {
417: DMA27( a, v[i], c, hi, w);
418: *p++ = t | ((w << lsh) & BMASK27);
419: }
420: if ( c != 0 ) {
421: *p++ = t | ((c << lsh) & BMASK27);
422: i++, t = c >> rsh;
423: }
424: if ( t == 0 ) return i;
425: *p = t;
426: return( i + 1 );
427: #endif
428: }
429:
430: /*********/
431:
432: static int abs_U_aV_c( t, u, lu, a, v, lv, c, ans )
433: int t, *u, lu, a, *v, lv, c, *ans;
434: /* compute | t + BASE27*(U - a*V - c) | in ans[], where U = u[0:lu-1], V = v[0:lv-1],
435: * c is <= BASE27-1, and lu >= lv+1 && t != 0 assumed.
436: */
437: {
438: int i, w, l, *p = ans;
439: int hi;
440:
441: *p++ = t, l = 1;
442: for ( i = 0; i < lv; *p++ = t ) {
443: DMA27( a, v[i], c, hi, w);
444: t = u[i] - w;
445: i++, c = hi;
446: if ( t != 0 ) l = i + 1;
447: if ( t < 0 ) t += BASE27, c++;
448: }
449: /* at this point, i == lv */
450: if ( lu == lv+1 ) {
451: if ( (t = u[i]) == c ) return l;
452: else if ( t > c ) { *p = t - c; return( lu + 1 ); }
453: l = negate_nbd( ans, lu ); /* <================ */
454: if ( (c -= (t + 1)) == 0 ) return l;
455: *p = c;
456: return( lu + 1 );
457: }
458: /* lu >= lv+2 and the diff turned out to be >= 0 */
459: if ( c != 0 ) {
460: /* note c <= BASE27. If c == BASE27, we must care about the length of the result
461: of the case when lu == lv+2 && u[lu-2:lu-1]=u[i:i+1] == BASE27 */
462: if ( c >= BASE27 && i+2 == lu && u[i+1] == 1 ) {
463: /* m.s. word of the diff becomes 0 */
464: if ( (t = u[i] - (c & BMASK27)) == 0 ) return l;
465: *p = t;
466: return lu;
467: }
468: for ( ; 1; c = 1, *p++ = t + BASE27 ) if ( (t = u[i++] - c) >= 0 ) break;
469: if ( t == 0 && i >= lu ) return lu;
470: *p++ = t;
471: }
472: for ( ; i < lu; i++ ) *p++ = u[i];
473: return( lu + 1 );
474: }
475:
476: static int abs_U_aV_c_sh( t, u, lu, a, v, lv, c, rsh, ans )
477: int t, *u, lu, a, *v, lv, c, rsh, *ans;
478: /* r-shift version of the above */
479: {
480: int i, w, l, lsh = BSH27 - rsh, *p = ans;
481: int hi;
482:
483: for ( l = i = 0; i < lv; t = w >> rsh ) {
484: DMA27( a, v[i], c, hi, w);
485: w = u[i] - w, c = hi;
486: i++;
487: if ( w < 0 ) w += BASE27, c++;
488: if ( (*p++ = t | ((w << lsh) & BMASK27)) != 0 ) l = i;
489: }
490: /* at this point, i == lv, and we have written lv elm.s in ans[] */
491: if ( lu == lv+1 ) {
492: if ( (w = u[i] - c) == 0 ) {
493: if ( t == 0 ) return l;
494: *p = t;
495: return lu; /* == lv+1 */
496: } else if ( w > 0 ) {
497: l0: *p++ = t | ((w << lsh) & BMASK27);
498: if ( (w >>= rsh) == 0 ) return lu; /* == lv+1 */
499: *p = w;
500: return( lu + 1 );
501: }
502: /* diff turned out to be < 0 */
503: w = - w - 1;
504: if ( lv == 0 ) { /* lu == 1 */
505: t = (BASE27 >> rsh) - t;
506: if ( w != 0 ) goto l0;
507: *p = t;
508: return 1;
509: }
510: l = negate_nbd( ans, lv ); /* <================ */
511: t ^= (BMASK27 >> rsh);
512: if ( w != 0 ) goto l0;
513: if ( t == 0 ) return l;
514: *p = t;
515: return lu; /* == lv + 1 */
516: }
517: /* now, lu >= lv+2 == i+2 */
518: if ( c != 0 ) {
519: /* note c <= BASE27. If c == BASE27, we must care about the length of the result
520: of the case when lu == lv+2 && u[lu-2:lu-1]=u[i:i+1] == BASE27 */
521: if ( c >= BASE27 && i+2 == lu && t == 0 && u[i] == 0 && u[i+1] == 1 )
522: return l; /* m.s. word of the diff has become 0 */
523: for ( ; 1; t = w >> rsh, c = 1 ) {
524: if ( (w = u[i++] - c) >= 0 ) break;
525: w += BASE27;
526: *p++ = t | ((w << lsh) & BMASK27);
527: }
528: t |= ((w << lsh) & BMASK27);
529: w >>= rsh;
530: if ( i >= lu ) {
531: if ( w != 0 ) {
532: *p++ = t;
533: *p = w;
534: return( lu + 1 );
535: } else if ( t == 0 ) return( i - 1 );
536: else { *p = t; return i; }
537: }
538: *p++ = t;
539: t = w;
540: }
541: for ( ; i < lu; i++, t = w >> rsh ) *p++ = t | (((w = u[i]) << lsh) & BMASK27);
542: if ( t == 0 ) return i;
543: *p = t;
544: return( i + 1 );
545: }
546:
547: /****************/
548: /****************/
549: #ifdef FULLSET
550: static int abs_axU_V_maxrshift(), abs_axU_bxV_maxrshift();
551:
552: static int abs_aU_bV_maxrshift( a, u, lu, b, v, lv, ans )
553: int a, *u, lu, b, *v, lv, *ans;
554: /*
555: * Compute | a*U - b*V | >> (as much as possible) in ans[], where U=u[0:lu-1]
556: * and V=v[0:lv-1].
557: */
558: {
559: if ( a == 1 ) return abs_U_aV_maxrshift( u, lu, b, v, lv, ans );
560: else if ( b == 1 ) return abs_U_aV_maxrshift( v, lv, a, u, lu, ans );
561: else if ( a == b ) return abs_axU_V_maxrshift( a, u, lu, v, lv, ans );
562: return abs_axU_bxV_maxrshift( a, u, lu, b, v, lv, ans );
563: }
564:
565: static int abs_axU_V_maxrshift( a, u, lu, v, lv, ans )
566: int a, *u, lu, *v, lv, *ans;
567: /*
568: * Compute a*| U - V | >> (as much as possible) in ans[], where U=u[0:lu-1]
569: * and V=v[0:lv-1], 0 < a < 2^BASE27.
570: */
571: {
572: int i, l, b, c, t, rsh, *p = ans, lsh, w, x;
573: int hi;
574:
575: if ( lu > lv ) goto U_V;
576: else if ( lu < lv ) goto swap;
577: else {
578: for ( i = lu; i-- > 0; ) {
579: if ( u[i] == v[i] ) continue;
580: lu = lv = i + 1;
581: if ( u[i] > v[i] ) goto U_V;
582: else goto swap;
583: }
584: return 0;
585: }
586: swap:
587: SWAP( lu, lv, int ); SWAP( u, v, int * );
588: U_V:
589: for ( b = c = i = 0; i < lv; ) {
590: if ( (w = u[i] - v[i] - b) < 0 ) w += BASE27, b = 1;
591: else b = 0;
592: DMA27( a, w, c, hi, t);
593: i++, c = hi;
594: if ( t != 0 ) goto non0w;
595: }
596: while ( i < lu ) {
597: if ( (w = u[i] - b) < 0 ) w += BASE27, b = 1;
598: else b = 0;
599: DMA27( a, w, c, hi, t);
600: i++, c = hi;
601: if ( t != 0 ) goto non0w;
602: }
603: if ( b != 0 ) c -= a;
604: else if ( c == 0 ) return 0;
605: while ( (c&1) == 0 ) c >>= 1;
606: *p = c;
607: return 1;
608: /**/
609: non0w:
610: u += i, lu -= i, v += i, lv -= i;
611: TRAILINGZEROS( t, rsh );
612: i = 0;
613: if ( rsh == 0 ) {
614: *p++ = t, l = 0;
615: for ( ; i < lv; c = hi ) {
616: if ( (w = u[i] - v[i] - b) < 0 ) w += BASE27, b = 1;
617: else b = 0;
618: DMA27( a, w, c, hi, t);
619: i++;
620: if ( (*p++ = t) != 0 ) l = i;
621: }
622: for ( ; i < lu; c = hi ) {
623: if ( (w = u[i] - b) < 0 ) w += BASE27, b = 1;
624: else b = 1;
625: DMA27( a, w, c, hi, t);
626: i++;
627: if ( (*p++ = t) != 0 ) l = i;
628: }
629: if ( b != 0 ) c -= a;
630: if ( c == 0 ) return( l + 1 );
631: *p = c;
632: return( i + 2 );
633: } else {
634: for ( lsh = BSH27 - rsh, l = 0; i < lv; c = hi, t = x >> rsh ) {
635: if ( (w = u[i] - v[i] - b) < 0 ) w += BASE27, b = 1;
636: else b = 0;
637: DMA27( a, w, c, hi, x);
638: i++;
639: if ( (*p++ = t | ((x << lsh) & BMASK27)) != 0 ) l = i;
640: }
641: for ( ; i < lu; i++, c = hi, t = x >> rsh ) {
642: if ( (w = u[i] - b) < 0 ) w += BASE27, b = 1;
643: else b = 0;
644: DMA27( a, w, c, hi, x);
645: i++;
646: if ( (*p++ = t | ((x << lsh) & BMASK27)) != 0 ) l = i;
647: }
648: if ( b != 0 ) c -= a;
649: if ( c != 0 ) {
650: *p++ = t | ((c << lsh) & BMASK27);
651: i++, t = c >> rsh;
652: } else if ( t == 0 ) return l;
653: if ( t == 0 ) return( i );
654: *p = t;
655: return( i + 1 );
656: }
657: }
658: #endif /* FULLSET */
659:
660: static int abs_axU_bxV_maxrshift( a, u, lu, b, v, lv, ans )
661: int a, *u, lu, b, *v, lv, *ans;
662: /*
663: * Compute | a*U - b*V | >> (as much as possible) in ans[], where U=u[0:lu-1]
664: * and V=v[0:lv-1], 0 < a, b < 2^BASE27.
665: */
666: {
667: int i, l, c, d, s, t, w, rsh, *p = ans, lsh;
668: int hi;
669: #if 0
670: static int bw_int32();
671: #endif
672:
673: BitWidth( a, c ); BitWidth( u[lu -1], s );
674: BitWidth( b, d ); BitWidth( v[lv -1], t );
675: if ( lu < lv || lu == lv && (c + s) < (d + t) ) {
676: SWAP( a, b, int ); SWAP( lu, lv, int ); SWAP( u, v, int * );
677: }
678: for ( i = c = d = 0; i < lv; ) {
679: DMA27( a, u[i], c, hi, t); /* 0 <= c <= 2^BSH27 -2 */
680: c = hi;
681: DMA27( b, v[i], d, hi, s); /* 0 <= d <= 2^BSH27 -1 */
682: i++, d = hi;
683: if ( (t -= s) == 0 ) continue;
684: else if ( t < 0 ) {
685: t += BASE27;
686: if ( c != 0 ) c--;
687: else d++;
688: }
689: goto non0w;
690: }
691: if ( i >= lu ) { /* no more elm.'s in u[] and v[] */
692: only_c:
693: if ( (c -= d) == 0 ) return 0;
694: else if ( c < 0 ) c = -c;
695: sh_onlyc:
696: /* TRAILINGZEROS( c, rsh ); */
697: while ( (c&1) == 0 ) c >>= 1;
698: *p = c;
699: return 1;
700: }
701: /* there is at least one more elm. in u[] */
702: DMA27( a, u[i], c, hi, t);
703: i++, c = hi;
704: if ( i >= lu ) { /* in this case, diff still can be <= 0 */
705: if ( hi == 0 ) { c = t; goto only_c; }
706: if ( (t -= d) == 0 ) { c = hi; goto sh_onlyc; }
707: else if ( t < 0 ) t += BASE27, hi--;
708: TRAILINGZEROS( t, rsh );
709: if ( rsh == 0 ) *p++ = t;
710: else {
711: *p++ = t | ((hi << (BSH27 - rsh)) & BMASK27);
712: hi >>= rsh;
713: }
714: if ( hi == 0 ) return 1;
715: *p = hi;
716: return 2;
717: } /* diff turned out to be > 0 */ else if ( (t -= d) > 0 ) d = 0;
718: else if ( t < 0 ) t += BASE27, d = 1;
719: else {
720: while ( i < lu ) {
721: DMA27( a, u[i], c, hi, t);
722: i++, c = hi;
723: if ( t != 0 ) break;
724: }
725: }
726: u += i, lu -= i;
727: TRAILINGZEROS( t, rsh );
728: l = i = 0;
729: if ( rsh == 0 ) {
730: *p++ = t;
731: goto no_more_v;
732: } else goto no_more_v_sh;
733: /**/
734: non0w:
735: u += i, lu -= i, v += i, lv -= i;
736: TRAILINGZEROS( t, rsh );
737: i = 0;
738: if ( rsh == 0 ) {
739: *p++ = t, l = 0;
740: for ( ; i < lv; *p++ = t ) {
741: DMA27( a, u[i], c, hi, t);
742: c = hi;
743: DMA27( b, v[i], d, hi, s);
744: i++, d = hi;
745: if ( (t -= s) == 0 ) continue;
746: else if ( t < 0 ) {
747: t += BASE27;
748: if ( c != 0 ) c--;
749: else d++;
750: }
751: l = i;
752: }
753: no_more_v:
754: if ( i >= lu ) {
755: final_c_d:
756: if ( (c -= d) == 0 ) return( l + 1 );
757: else if ( c < 0 ) {
758: l = negate_nbd( ans, i + 1 ); /* <================ */
759: if ( (c = -c - 1) == 0 ) return l;
760: }
761: *p = c;
762: return( i + 2 );
763: }
764: /* a*u[i:lu-1] + c - d */
765: if ( c >= d ) c -= d;
766: else {
767: DMA27( a, u[i], c, hi, t);
768: if ( i+1 >= lu ) {
769: if ( hi == 0 ) { c = t; goto final_c_d; }
770: if ( (t -= d) < 0 ) t += BASE27, c = hi - 1;
771: else c = hi;
772: i++, *p++ = t;
773: goto final_c;
774: }
775: i++, c = hi;
776: if ( (t -= d) >= 0 ) *p++ = t;
777: else {
778: *p++ = t + BASE27;
779: if ( c != 0 ) c--;
780: else {
781: for ( ; i < lu; *p++ = BMASK27 ) {
782: DMA27( a, u[i], c, hi, t);
783: i++, c = hi;
784: if ( t == 0 ) continue;
785: *p++ = t - 1;
786: goto aU;
787: }
788: c--;
789: goto final_c;
790: }
791: }
792: }
793: /*** return( aV_plus_c( a, &u[i], lu - i, c, p ) + i + 1 ); ***/
794: aU:
795: for ( ; i < lu; i++, c = hi, *p++ = t ) { DMA27( a, u[i], c, hi, t); }
796: final_c:
797: if ( c == 0 ) return( i + 1 );
798: *p = c;
799: return( i + 2 );
800: } else { /* rsh != 0 */
801: for ( lsh = BSH27 - rsh; i < lv; t = w >> rsh ) {
802: DMA27( a, u[i], c, hi, w);
803: c = hi;
804: DMA27( b, v[i], d, hi, s);
805: i++, d = hi;
806: if ( (w -= s) < 0 ) {
807: w += BASE27;
808: if ( c != 0 ) c--;
809: else d++;
810: }
811: if ( (*p++ = t | ((w << lsh) & BMASK27)) != 0 ) l = i;
812: }
813: no_more_v_sh:
814: if ( i >= lu ) {
815: final_c_d_sh:
816: if ( (c -= d) == 0 )
817: if ( t == 0 ) return l;
818: else { *p = t; return( i + 1 ); }
819: else if ( c < 0 ) {
820: if ( i == 0 ) t = (BASE27 >> rsh) - t;
821: else {
822: l = negate_nbd( ans, i ); /* <================ */
823: /* t = (BASE27 >> rsh) - t;*/
824: t ^= ((BMASK27 >> rsh));
825: }
826: c = -c -1;
827: }
828: *p++ = t | ((c << lsh) & BMASK27);
829: if ( (c >>= rsh) == 0 ) return( i + 1 );
830: *p = c;
831: return( i + 2 );
832: } else if ( c >= d ) c -= d;
833: else {
834: DMA27( a, u[i], c, hi, w);
835: if ( i+1 >= lu ) {
836: if ( hi == 0 ) { c = w; goto final_c_d_sh; }
837: if ( (w -= d) < 0 ) w += BASE27, c = hi - 1;
838: else c = hi;
839: i++, *p++ = t | ((w << lsh) & BMASK27);
840: t = w >> rsh;
841: goto final_c_sh;
842: }
843: i++, c = hi;
844: if ( (w -= d) >= 0 ) { *p++ = t | ((w << lsh) & BMASK27); t = w >> rsh; }
845: else {
846: w += BASE27;
847: *p++ = t | ((w << lsh) & BMASK27);
848: t = w >> rsh;
849: if ( c != 0 ) c--;
850: else {
851: while ( i < lu ) {
852: DMA27( a, u[i], c, hi, w);
853: i++, c = hi;
854: if ( w == 0 ) {
855: *p++ = t | ((BMASK27 << lsh) & BMASK27);
856: t = BMASK27 >> rsh;
857: continue;
858: } else {
859: w--;
860: *p++ = t | ((w << lsh) & BMASK27);
861: t = w >> rsh;
862: goto aU_sh;
863: }
864: }
865: c--;
866: goto final_c_sh;
867: }
868: }
869: }
870: /*** return( aV_plus_c_sh( a, &u[i], lu - i, c, rsh, t ) + i ); ***/
871: aU_sh:
872: for ( ; i < lu; i++, c = hi, t = w >> rsh ) {
873: DMA27( a, u[i], c, hi, w);
874: *p++ = t | ((w << lsh) & BMASK27);
875: }
876: final_c_sh:
877: if ( c != 0 ) {
878: *p++ = t | ((c << lsh) & BMASK27);
879: i++, t = c >> rsh;
880: }
881: if ( t == 0 ) return i;
882: *p = t;
883: return( i + 1 );
884: }
885: }
886: /****************/
887: /****************/
888: #ifdef FULLSET
889: static int UplusV_maxrshift(), aUplusV_maxrshift(), axUplusV_maxrshift(), aUplusbV_maxrshift();
890:
891: static int aU_plus_bV_maxrshift( a, u, lu, b, v, lv, ans )
892: int a, *u, lu, b, *v, lv, *ans;
893: {
894: if ( a == 1 )
895: return( b == 1 ? UplusV_maxrshift( u, lu, v, lv, ans ) :
896: aUplusV_maxrshift( b, v, lv, u, lu, ans ) );
897: else if ( b == 1 ) return aUplusV_maxrshift( a, u, lu, v, lv, ans );
898: else if ( a == b ) return axUplusV_maxrshift( a, u, lu, v, lv, ans );
899: return aUplusbV_maxrshift( a, u, lu, b, v, lv, ans );
900: }
901:
902: static int UplusV_maxrshift( u, lu, v, lv, ans )
903: int *u, lu, *v, lv, *ans;
904: /*
905: * Compute ( (U + V) >> (as much as possible) ) in ans[], where U=u[0:lu-1],
906: * V=v[0:lv-1], and 0 < a < BASE27.
907: */
908: {
909: int i, t, c, rsh, *p = ans;
910: int hi;
911:
912: if ( lu < lv ) { SWAP( lu, lv, int ); SWAP( u, v, int * ); }
913: for ( c = i = 0; i < lv; ) {
914: t = (c += (u[i] + v[i])) & BMASK27;
915: /* 0 <= c <= 2*(2^BSH27 -1) + 1 = 2^BSH27 + (2^BSH27 -1) */
916: i++, c >>= BSH27;
917: if ( t != 0 ) goto non0w;
918: }
919: while ( i < lu ) {
920: t = (c += u[i]) & BMASK27;
921: i++, c >>= BSH27;
922: if ( t != 0 ) goto non0w;
923: }
924: *p = c;
925: return 1;
926: /**/
927: non0w:
928: u += i, lu -= i, v += i, lv -= i;
929: TRAILINGZEROS( t, rsh );
930: i = 0;
931: if ( rsh == 0 ) {
932: *p++ = t;
933: for ( ; i < lv; i++, c >>= BSH27 ) *p++ = (c += (u[i] + v[i])) & BMASK27;
934: if ( c != 0 ) {
935: while ( i < lu )
936: if ( (c = u[i++] + 1) >= BASE27 ) *p++ = c & BMASK27;
937: else {
938: *p++ = c;
939: goto cpu;
940: }
941: *p = 1; /* == c */
942: return( lu + 2 );
943: }
944: cpu:
945: for ( ; i < lu; i++ ) *p++ = u[i];
946: return( lu + 1 );
947: } else {
948: int lsh = BSH27 - rsh;
949:
950: for ( ; i < lv; i++, c >>= BSH27 ) {
951: c += (u[i] + v[i]);
952: *p++ = t | ((c << lsh) & BMASK27);
953: t = (c & BMASK27) >> rsh;
954: }
955: if ( c != 0 ) {
956: while ( i < lu ) {
957: c = u[i++] + 1;
958: *p++ = t | ((c << lsh) & BMASK27);
959: t = (c & BMASK27) >> rsh;
960: if ( (c >>= BSH27) == 0 ) goto cpu_sh;
961: }
962: *p = t | (1 << lsh);
963: return( lu + 1 );
964: }
965: cpu_sh:
966: for ( ; i < lu; t = c >> rsh ) *p++ = t | (((c = u[i++]) << lsh) & BMASK27);
967: if ( t == 0 ) return( lu );
968: *p = t;
969: return( lu + 1 );
970: }
971: }
972:
973: static int aUplusV_maxrshift( a, u, lu, v, lv, ans )
974: int a, *u, lu, *v, lv, *ans;
975: /*
976: * Compute ( (a*U + V) >> (as much as possible) ) in ans[], where U=u[0:lu-1],
977: * V=v[0:lv-1], and 1 < a < BASE27.
978: */
979: {
980: int i, l, t, c, rsh, *p = ans, w, lsh;
981: int hi;
982:
983: for ( l = lu < lv ? lu : lv, c = i = 0; i < l; ) {
984: /* Note that (carry in a*U[*]) <= 2^BSH27-2 because {(2^j-1)}^2 + (2^j-2)
985: * = 2^j*(2^j -2)+(2^j -1), and the following c is <= 2^j -1 because
986: * {(2^j -1)}^2 + (2^j -1) + (2^j -1) = 2^j*(2^j -1) + (2^j -1).
987: * ^^^^^^carry^^^^^^ pv[?].
988: */
989: c += v[i];
990: DMA27( a, u[i], c, hi, t);
991: i++, c = hi;
992: if ( t != 0 ) goto non0sum;
993: }
994: if ( i >= lu ) { /* compute (c + v[i:lv-1]) */
995: while ( i < lv ) {
996: t = (c += v[i++]) & BMASK27;
997: c >>= BSH27;
998: if ( t != 0 ) goto non0w_v;
999: }
1000: *p = 1;
1001: return 1;
1002: non0w_v:
1003: v += i, lv -= i;
1004: i = 0;
1005: TRAILINGZEROS( t, rsh );
1006: if ( rsh == 0 ) {
1007: *p++ = t;
1008: L_addv:
1009: if ( c != 0 ) {
1010: while ( i < lv )
1011: if ( (c = u[i++] + 1) >= BASE27 ) *p++ = c & BMASK27;
1012: else {
1013: *p++ = c;
1014: goto cpv;
1015: }
1016: *p = 1; /* == c */
1017: return( lv + 2 );
1018: }
1019: cpv:
1020: for ( ; i < lv; i++ ) *p++ = v[i];
1021: return( lv + 1 );
1022: } else {
1023: lsh = BSH27 - rsh;
1024: L_addv_sh:
1025: if ( c != 0 ) {
1026: while ( i < lv ) {
1027: c += v[i++];
1028: *p++ = t | ((c << lsh) & BMASK27);
1029: t = (c & BMASK27) >> rsh;
1030: if ( (c >>= BSH27) == 0 ) goto cpv_sh;
1031: }
1032: *p = t | (1 << lsh);
1033: return( lv + 1 );
1034: }
1035: cpv_sh:
1036: for ( ; i < lv; t = c >> rsh ) *p++ = t | (((c = v[i++]) << lsh) & BMASK27);
1037: if ( t == 0 ) return( lv );
1038: *p = t;
1039: return( lv + 1 );
1040: }
1041: } else { /* i >= lv, and compute (c + a*u[i:lu-1]) */
1042: while ( i < lu ) {
1043: DMA27( a, u[i], c, hi, t);
1044: i++, c = hi;
1045: if ( t != 0 ) goto non0w_u;
1046: }
1047: TRAILINGZEROS( c, rsh );
1048: *p = c;
1049: return 1;
1050: /**/
1051: non0w_u:
1052: u += i, lu -= i;
1053: TRAILINGZEROS( t, rsh );
1054: i = 0;
1055: if ( rsh == 0 ) {
1056: *p++ = t;
1057: L_addu:
1058: #ifdef CALL
1059: return( aV_plus_c( a, u, lv, c, p ) + 1 );
1060: #else
1061: for ( ; i < lu; i++, *p++ = t, c = hi ) { DMA27( a, u[i], c, hi, t); }
1062: if ( c == 0 ) return( lu + 1 );
1063: *p = c;
1064: return( lu + 2 );
1065: #endif
1066: } else {
1067: lsh = BSH27 - rsh;
1068: L_addu_sh:
1069: #ifdef CALL
1070: return aV_plus_c_sh( a, u, lu, c, rsh, t, p );
1071: #else
1072: for ( ; i < lu; i++, c = hi, t = w >> rsh ) {
1073: DMA27( a, u[i], c, hi, w);
1074: *p++ = t | ((w << lsh) & BMASK27);
1075: }
1076: if ( c != 0 ) {
1077: *p++ = t | ((c << lsh) & BMASK27);
1078: i++, t = c >> rsh;
1079: }
1080: if ( t == 0 ) return i;
1081: *p = t;
1082: return( i + 1 );
1083: #endif
1084: }
1085: }
1086: /**/
1087: non0sum:
1088: u += i, lu -= i, v += i, lv -= i, l -= i;
1089: TRAILINGZEROS( t, rsh );
1090: i = 0;
1091: if ( rsh == 0 ) {
1092: *p++ = t;
1093: for ( ; i < l; i++, *p++ = t, c = hi ) {
1094: c += v[i];
1095: DMA27( a, u[i], c, hi, t);
1096: }
1097: if ( i >= lu ) /* compute (c + v[i:lv-1]). note i may be >= lv */ goto L_addv;
1098: else /* i >= lv, and compute (c + u[i:lu-1]) */ goto L_addu;
1099: } else {
1100: lsh = BSH27 - rsh;
1101: for ( ; i < l; i++, c = hi, t = w >> rsh ) {
1102: c += v[i];
1103: DMA27( a, u[i], c, hi, w);
1104: *p++ = t | ((w << lsh) & BMASK27);
1105: }
1106: if ( i >= lu ) /* compute (c + v[i:lv-1]) >> rsh. note i may be >= lv */ goto L_addv_sh;
1107: else /* i >= lv, and compute (c + u[i:lu-1]) >> rsh */ goto L_addu_sh;
1108: }
1109: }
1110:
1111:
1112: static int axUplusV_maxrshift( a, u, lu, v, lv, ans )
1113: int a, *u, lu, *v, lv, *ans;
1114: /*
1115: * Compute ( a*(U + V) >> (as much as possible) ) in ans[], where U=u[0:lu-1],
1116: * V=v[0:lv-1], and 1 < a < BASE27.
1117: */
1118: {
1119: int i, t, c, d, rsh, w, *p = ans, lsh, x;
1120: int hi;
1121:
1122: if ( lu < lv ) { SWAP( lu, lv, int ); SWAP( u, v, int * ); }
1123: for ( i = c = d = 0; i < lv; ) {
1124: w = (d += (u[i] + v[i])) & BMASK27;
1125: DMA27( a, w, c, hi, t);
1126: i++, d >>= BSH27, c = hi;
1127: if ( t != 0 ) goto non0w;
1128: }
1129: while ( i < lu ) {
1130: w = (d += u[i++]) & BMASK27;
1131: DMA27( a, w, c, hi, t);
1132: d >>= BSH27, c = hi;
1133: if ( t != 0 ) goto non0w;
1134: }
1135: if ( d != 0 ) c += a;
1136: TRAILINGZEROS( c, rsh );
1137: if ( rsh != 0 || c <= BMASK27 ) { *p = c; return 1; }
1138: *p++ = c & BMASK27;
1139: *p = c >> BSH27;
1140: return 2;
1141: /**/
1142: non0w:
1143: u += i, lu -= i, v += i, lv -= i;
1144: TRAILINGZEROS( t, rsh );
1145: i = 0;
1146: if ( rsh == 0 ) {
1147: *p++ = t;
1148: for ( ; i < lv; i++, d >>= BSH27, *p++ = t, c = hi ) {
1149: w = (d += (u[i] + v[i])) & BMASK27;
1150: DMA27( a, w, c, hi, t);
1151: }
1152: for ( ; i < lu; d >>= BSH27, *p++ = t, c = hi ) {
1153: w = (d += u[i++]) & BMASK27;
1154: DMA27( a, w, c, hi, t);
1155: }
1156: if ( d != 0 ) c += a;
1157: if ( c == 0 ) return( lu + 1 );
1158: *p++ = c & BMASK27;
1159: if ( (c >>= BSH27) == 0 ) return( lu + 2 );
1160: *p = c;
1161: return( lu + 3 );
1162: } else {
1163: for ( lsh = BSH27 - rsh; i < lv; i++, d >>= BSH27, t = x >> rsh, c = hi ) {
1164: w = (d += (u[i] + v[i])) & BMASK27;
1165: DMA27( a, w, c, hi, x);
1166: *p++ = t | ((x << lsh) & BMASK27);
1167: }
1168: for ( ; i < lu; d >>= BSH27, t = x >> rsh, c = hi ) {
1169: w = (d += u[i++]) & BMASK27;
1170: DMA27( a, w, c, hi, x);
1171: *p++ = t | ((x << lsh) & BMASK27);
1172: }
1173: if ( d != 0 ) c += a;
1174: t |= ((c << lsh) & BMASK27);
1175: c >>= rsh;
1176: if ( c != 0 ) {
1177: *p++ = t;
1178: *p = c;
1179: return( lu + 2 );
1180: } else if ( t == 0 ) return lu;
1181: *p = t;
1182: return( lu + 1 );
1183: }
1184: }
1185: #endif /* FULLSET */
1186:
1187: static int aUplusbV_maxrshift( a, u, lu, b, v, lv, ans )
1188: int a, *u, lu, b, *v, lv, *ans;
1189: /*
1190: * Compute ( (a*U + b*V) >> (as much as possible) ) in ans[], where U=u[0:lu-1],
1191: * V=v[0:lv-1], and 0 < a,b < BASE27.
1192: */
1193: {
1194: int i, c, d, s, t, w, rsh, *p = ans, lsh;
1195: int hi;
1196:
1197: if ( lu < lv ) { SWAP( a, b, int ); SWAP( lu, lv, int ); SWAP( u, v, int * ); }
1198: for ( c = d = i = 0; i < lv; ) {
1199: DMA27( a, u[i], c, hi, t); /* 0 <= c <= 2^BSH27 -1 */
1200: c = hi;
1201: DMA27( b, v[i], d, hi, s); /* 0 <= d <= 2^BSH27 -2 */
1202: i++, d = hi, t += s;
1203: if ( t > BMASK27 ) c++, t &= BMASK27;
1204: if ( t != 0 ) goto non0w;
1205: }
1206: c += d;
1207: for ( d = 0; i < lu; ) {
1208: DMA27( a, u[i], c, hi, t);
1209: i++, c = hi;
1210: if ( t != 0 ) goto non0w;
1211: }
1212: TRAILINGZEROS( c, rsh );
1213: if ( rsh != 0 || c <= BMASK27 ) { *p = c; return 1; }
1214: *p++ = c & BMASK27;
1215: *p = 1;
1216: return 2;
1217: /**/
1218: non0w:
1219: u += i, lu -= i, v += i, lv -= i;
1220: TRAILINGZEROS( t, rsh );
1221: i = 0;
1222: if ( rsh == 0 ) {
1223: *p++ = t;
1224: for ( ; i < lv; i++, *p++ = t ) {
1225: DMA27( a, u[i], c, hi, t);
1226: c = hi;
1227: DMA27( b, v[i], d, hi, s);
1228: d = hi, t += s;
1229: if ( t > BMASK27 ) c++, t &= BMASK27;
1230: }
1231: c += d;
1232: for ( ; i < lu; i++, *p++ = t, c = hi ) {
1233: DMA27( a, u[i], c, hi, t);
1234: }
1235: if ( c == 0 ) return( lu + 1 );
1236: else if ( c <= BMASK27 ) { *p = c; return( lu + 2 ); }
1237: *p++ = c & BMASK27;
1238: *p = 1;
1239: return( lu + 3 );
1240: } else {
1241: for ( lsh = BSH27 - rsh; i < lv; i++, t = w >> rsh ) {
1242: DMA27( a, u[i], c, hi, w);
1243: c = hi;
1244: DMA27( b, v[i], d, hi, s);
1245: d = hi, w += s;
1246: if ( w > BMASK27 ) c++, w &= BMASK27;
1247: *p++ = t | ((w << lsh) & BMASK27);
1248: }
1249: c += d; /* <= 2^BSH27 + (2^BSH27 - 3) */
1250: for ( ; i < lu; i++, c = hi, t = w >> rsh ) {
1251: DMA27( a, u[i], c, hi, w);
1252: *p++ = t | ((w << lsh) & BMASK27);
1253: }
1254: if ( c == 0 ) {
1255: if ( t == 0 ) return lu;
1256: *p = t;
1257: return( lu + 1 );
1258: }
1259: *p++ = t | ((c << lsh) & BMASK27);
1260: if ( (c >>= rsh) == 0 ) return( lu + 1 );
1261: *p = c;
1262: return( lu + 2 );
1263: }
1264: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>