Annotation of OpenXM_contrib2/asir2000/engine/igcdhack.c, Revision 1.4
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.4 ! murao 48: * $OpenXM: OpenXM_contrib2/asir2000/engine/igcdhack.c,v 1.3 2000/08/22 05:04:05 noro 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.1 noro 872: static int bw_int32();
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>