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