[BACK]Return to igcdhack.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / engine-27

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>