12aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/* $NetBSD: misc.c,v 1.3.12.1 2008/04/08 21:10:55 jdc Exp $ */
22aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
32aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/****************************************************************
42aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
52aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmThe author of this software is David M. Gay.
62aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
72aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmCopyright (C) 1998, 1999 by Lucent Technologies
82aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmAll Rights Reserved
92aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmPermission to use, copy, modify, and distribute this software and
112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmits documentation for any purpose and without fee is hereby
122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmgranted, provided that the above copyright notice appear in all
132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmcopies and that both that the copyright notice and this
142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmpermission notice and warranty disclaimer appear in supporting
152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmdocumentation, and that the name of Lucent or any of its entities
162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmnot be used in advertising or publicity pertaining to
172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmdistribution of the software without specific, written prior
182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmpermission.
192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmTHIS SOFTWARE.
282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm****************************************************************/
302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm/* Please send bug reports to David M. Gay (dmg at acm dot org,
322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm * with " at " changed at "@" and " dot " changed to ".").  */
332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include  <LibConfig.h>
342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#include "gdtoaimp.h"
362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#if defined(_MSC_VER)
382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  // Disable warnings about assignment within conditional expressions.
392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  #pragma warning ( disable : 4706 )
402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic Bigint *freelist[Kmax+1];
432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef Omit_Private_Memory
442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef PRIVATE_MEM
452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define PRIVATE_MEM 2304
462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstatic double private_mem[PRIVATE_mem], *pmem_next = private_mem;
492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Bigint *
522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmBalloc
532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (k) int k;
552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (int k)
572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int x;
602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  Bigint *rv;
612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef Omit_Private_Memory
622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  unsigned int len;
632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ACQUIRE_DTOA_LOCK(0);
662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ( (rv = freelist[k]) !=0) {
672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    freelist[k] = rv->next;
682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  else {
702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    x = 1 << k;
712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef Omit_Private_Memory
722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /sizeof(double);
762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (pmem_next - private_mem + len <= PRIVATE_mem) {
772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      rv = (Bigint*)(void *)pmem_next;
782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      pmem_next += len;
792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else
812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      rv = (Bigint*)MALLOC(len*sizeof(double));
822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (rv == NULL)
842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return NULL;
852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    rv->k = k;
862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    rv->maxwds = x;
872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  FREE_DTOA_LOCK(0);
892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  rv->sign = rv->wds = 0;
902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return rv;
912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm void
942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmBfree
952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (v) Bigint *v;
972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (Bigint *v)
992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
1002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
1012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (v) {
1022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ACQUIRE_DTOA_LOCK(0);
1032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    v->next = freelist[v->k];
1042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    freelist[v->k] = v;
1052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    FREE_DTOA_LOCK(0);
1062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
1072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
1082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
1092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm int
1102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmlo0bits
1112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
1122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (y) ULong *y;
1132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
1142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (ULong *y)
1152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
1162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
1172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int k;
1182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong x = *y;
1192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
1202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (x & 7) {
1212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (x & 1)
1222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return 0;
1232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (x & 2) {
1242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *y = x >> 1;
1252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return 1;
1262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
1272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *y = x >> 2;
1282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return 2;
1292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
1302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  k = 0;
1312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (!(x & 0xffff)) {
1322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k = 16;
1332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    x >>= 16;
1342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
1352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (!(x & 0xff)) {
1362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k += 8;
1372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    x >>= 8;
1382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
1392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (!(x & 0xf)) {
1402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k += 4;
1412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    x >>= 4;
1422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
1432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (!(x & 0x3)) {
1442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k += 2;
1452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    x >>= 2;
1462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
1472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (!(x & 1)) {
1482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k++;
1492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    x >>= 1;
1502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (!x)
1512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return 32;
1522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
1532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  *y = x;
1542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return k;
1552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
1562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
1572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Bigint *
1582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmmultadd
1592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
1602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (b, m, a) Bigint *b; int m, a;
1612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
1622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (Bigint *b, int m, int a) /* multiply by m and add a */
1632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
1642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
1652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int i, wds;
1662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef ULLong
1672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong *x;
1682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULLong carry, y;
1692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
1702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong carry, *x, y;
1712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef Pack_32
1722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong xi, z;
1732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
1742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
1752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  Bigint *b1;
1762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
1772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  wds = b->wds;
1782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  x = b->x;
1792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  i = 0;
1802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  carry = a;
1812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  do {
1822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef ULLong
1832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    y = *x * (ULLong)m + carry;
1842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    carry = y >> 32;
1852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /* LINTED conversion */
1862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *x++ = (uint32_t)(y & 0xffffffffUL);
1872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
1882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef Pack_32
1892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    xi = *x;
1902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    y = (xi & 0xffff) * m + carry;
1912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    z = (xi >> 16) * m + (y >> 16);
1922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    carry = z >> 16;
1932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *x++ = (z << 16) + (y & 0xffff);
1942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
1952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    y = *x * m + carry;
1962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    carry = y >> 16;
1972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *x++ = y & 0xffff;
1982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
1992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
2002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
2012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    while(++i < wds);
2022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (carry) {
2032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (wds >= b->maxwds) {
2042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      b1 = Balloc(b->k+1);
2052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (b1 == NULL) {
2062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        Bfree(b);
2072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        return NULL;
2082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
2092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      Bcopy(b1, b);
2102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      Bfree(b);
2112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      b = b1;
2122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
2132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /* LINTED conversion */
2142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      b->x[wds++] = (uint32_t)carry;
2152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    b->wds = wds;
2162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
2172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return b;
2182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
2192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
2202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm int
2212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmhi0bits_D2A
2222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
2232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (x) ULong x;
2242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
2252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (ULong x)
2262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
2272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
2282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int k = 0;
2292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
2302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (!(x & 0xffff0000)) {
2312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k = 16;
2322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    x <<= 16;
2332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
2342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (!(x & 0xff000000)) {
2352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k += 8;
2362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    x <<= 8;
2372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
2382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (!(x & 0xf0000000)) {
2392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k += 4;
2402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    x <<= 4;
2412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
2422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (!(x & 0xc0000000)) {
2432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k += 2;
2442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    x <<= 2;
2452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
2462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (!(x & 0x80000000)) {
2472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k++;
2482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (!(x & 0x40000000))
2492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return 32;
2502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
2512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return k;
2522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
2532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
2542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Bigint *
2552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmi2b
2562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
2572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (i) int i;
2582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
2592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (int i)
2602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
2612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
2622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  Bigint *b;
2632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
2642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  b = Balloc(1);
2652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (b == NULL)
2662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return NULL;
2672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  b->x[0] = i;
2682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  b->wds = 1;
2692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return b;
2702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
2712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
2722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Bigint *
2732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmmult
2742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
2752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (a, b) Bigint *a, *b;
2762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
2772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (Bigint *a, Bigint *b)
2782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
2792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
2802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  Bigint *c;
2812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int k, wa, wb, wc;
2822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
2832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong y;
2842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef ULLong
2852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULLong carry, z;
2862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
2872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong carry, z;
2882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef Pack_32
2892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong z2;
2902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
2912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
2922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
2932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (a->wds < b->wds) {
2942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    c = a;
2952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    a = b;
2962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    b = c;
2972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
2982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  k = a->k;
2992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  wa = a->wds;
3002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  wb = b->wds;
3012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  wc = wa + wb;
3022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (wc > a->maxwds)
3032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k++;
3042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  c = Balloc(k);
3052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (c == NULL)
3062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return NULL;
3072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for(x = c->x, xa = x + wc; x < xa; x++)
3082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *x = 0;
3092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xa = a->x;
3102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xae = xa + wa;
3112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xb = b->x;
3122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xbe = xb + wb;
3132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xc0 = c->x;
3142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef ULLong
3152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for(; xb < xbe; xc0++) {
3162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ( (y = *xb++) !=0) {
3172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      x = xa;
3182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      xc = xc0;
3192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      carry = 0;
3202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      do {
3212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        z = *x++ * (ULLong)y + *xc + carry;
3222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        carry = z >> 32;
3232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        /* LINTED conversion */
3242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *xc++ = (uint32_t)(z & 0xffffffffUL);
3252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
3262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        while(x < xae);
3272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      /* LINTED conversion */
3282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *xc = (uint32_t)carry;
3292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
3302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
3312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
3322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef Pack_32
3332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for(; xb < xbe; xb++, xc0++) {
3342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ( (y = *xb & 0xffff) !=0) {
3352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      x = xa;
3362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      xc = xc0;
3372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      carry = 0;
3382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      do {
3392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
3402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        carry = z >> 16;
3412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
3422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        carry = z2 >> 16;
3432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        Storeinc(xc, z2, z);
3442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
3452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        while(x < xae);
3462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *xc = carry;
3472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
3482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ( (y = *xb >> 16) !=0) {
3492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      x = xa;
3502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      xc = xc0;
3512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      carry = 0;
3522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      z2 = *xc;
3532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      do {
3542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        z = (*x & 0xffff) * y + (*xc >> 16) + carry;
3552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        carry = z >> 16;
3562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        Storeinc(xc, z, z2);
3572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
3582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        carry = z2 >> 16;
3592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
3602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        while(x < xae);
3612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *xc = z2;
3622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
3632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
3642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
3652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for(; xb < xbe; xc0++) {
3662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ( (y = *xb++) !=0) {
3672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      x = xa;
3682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      xc = xc0;
3692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      carry = 0;
3702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      do {
3712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        z = *x++ * y + *xc + carry;
3722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        carry = z >> 16;
3732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        *xc++ = z & 0xffff;
3742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
3752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        while(x < xae);
3762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *xc = carry;
3772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
3782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
3792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
3802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
3812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
3822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  c->wds = wc;
3832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return c;
3842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
3852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
3862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm static Bigint *p5s;
3872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
3882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Bigint *
3892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmpow5mult
3902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
3912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (b, k) Bigint *b; int k;
3922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
3932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (Bigint *b, int k)
3942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
3952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
3962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  Bigint *b1, *p5, *p51;
3972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int i;
3982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  static CONST int p05[3] = { 5, 25, 125 };
3992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
4002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ( (i = k & 3) !=0) {
4012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    b = multadd(b, p05[i-1], 0);
4022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (b == NULL)
4032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return NULL;
4042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
4052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
4062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ((k = (unsigned int)k >> 2) == 0)
4072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return b;
4082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ((p5 = p5s) == 0) {
4092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /* first time */
4102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef MULTIPLE_THREADS
4112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    ACQUIRE_DTOA_LOCK(1);
4122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (!(p5 = p5s)) {
4132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      p5 = p5s = i2b(625);
4142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (p5 == NULL)
4152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        return NULL;
4162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      p5->next = 0;
4172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
4182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    FREE_DTOA_LOCK(1);
4192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
4202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    p5 = p5s = i2b(625);
4212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (p5 == NULL)
4222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return NULL;
4232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    p5->next = 0;
4242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
4252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
4262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for(;;) {
4272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (k & 1) {
4282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      b1 = mult(b, p5);
4292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (b1 == NULL)
4302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        return NULL;
4312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      b = b1;
4322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
4332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ((k = (unsigned int)k >> 1) == 0)
4342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
4352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ((p51 = p5->next) == 0) {
4362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef MULTIPLE_THREADS
4372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ACQUIRE_DTOA_LOCK(1);
4382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (!(p51 = p5->next)) {
4392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        p51 = p5->next = mult(p5,p5);
4402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        if (p51 == NULL)
4412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm          return NULL;
4422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        p51->next = 0;
4432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
4442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      FREE_DTOA_LOCK(1);
4452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
4462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      p51 = p5->next = mult(p5,p5);
4472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (p51 == NULL)
4482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        return NULL;
4492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      p51->next = 0;
4502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
4512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
4522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    p5 = p51;
4532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
4542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return b;
4552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
4562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
4572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Bigint *
4582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmlshift
4592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
4602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (b, k) Bigint *b; int k;
4612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
4622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (Bigint *b, int k)
4632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
4642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
4652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int i, k1, n, n1;
4662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  Bigint *b1;
4672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong *x, *x1, *xe, z;
4682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
4692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  n = (unsigned int)k >> kshift;
4702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  k1 = b->k;
4712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  n1 = n + b->wds + 1;
4722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for(i = b->maxwds; n1 > i; i <<= 1)
4732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k1++;
4742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  b1 = Balloc(k1);
4752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (b1 == NULL)
4762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return NULL;
4772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  x1 = b1->x;
4782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for(i = 0; i < n; i++)
4792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *x1++ = 0;
4802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  x = b->x;
4812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xe = x + b->wds;
4822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (k &= kmask) {
4832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef Pack_32
4842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k1 = 32 - k;
4852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    z = 0;
4862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    do {
4872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *x1++ = *x << k | z;
4882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      z = *x++ >> k1;
4892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
4902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      while(x < xe);
4912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ((*x1 = z) !=0)
4922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ++n1;
4932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
4942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k1 = 16 - k;
4952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    z = 0;
4962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    do {
4972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      *x1++ = *x << k  & 0xffff | z;
4982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      z = *x++ >> k1;
4992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
5002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      while(x < xe);
5012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (*x1 = z)
5022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      ++n1;
5032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
5042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
5052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  else do
5062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *x1++ = *x++;
5072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    while(x < xe);
5082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  b1->wds = n1 - 1;
5092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  Bfree(b);
5102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return b1;
5112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
5122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm int
5142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmcmp
5152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
5162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (a, b) Bigint *a, *b;
5172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
5182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (Bigint *a, Bigint *b)
5192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
5202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
5212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong *xa, *xa0, *xb, *xb0;
5222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int i, j;
5232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  i = a->wds;
5252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  j = b->wds;
5262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef DEBUG
5272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (i > 1 && !a->x[i-1])
5282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    Bug("cmp called with a->x[a->wds-1] == 0");
5292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (j > 1 && !b->x[j-1])
5302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    Bug("cmp called with b->x[b->wds-1] == 0");
5312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
5322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (i -= j)
5332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return i;
5342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xa0 = a->x;
5352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xa = xa0 + j;
5362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xb0 = b->x;
5372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xb = xb0 + j;
5382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  for(;;) {
5392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (*--xa != *--xb)
5402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return *xa < *xb ? -1 : 1;
5412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (xa <= xa0)
5422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      break;
5432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
5442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return 0;
5452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
5462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Bigint *
5482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmdiff
5492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
5502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (a, b) Bigint *a, *b;
5512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
5522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (Bigint *a, Bigint *b)
5532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
5542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
5552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  Bigint *c;
5562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int i, wa, wb;
5572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong *xa, *xae, *xb, *xbe, *xc;
5582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef ULLong
5592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULLong borrow, y;
5602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
5612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong borrow, y;
5622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef Pack_32
5632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong z;
5642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
5652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
5662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
5672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  i = cmp(a,b);
5682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (!i) {
5692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    c = Balloc(0);
5702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (c == NULL)
5712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      return NULL;
5722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    c->wds = 1;
5732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    c->x[0] = 0;
5742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return c;
5752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
5762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (i < 0) {
5772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    c = a;
5782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    a = b;
5792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    b = c;
5802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    i = 1;
5812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
5822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  else
5832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    i = 0;
5842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  c = Balloc(a->k);
5852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (c == NULL)
5862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return NULL;
5872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  c->sign = i;
5882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  wa = a->wds;
5892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xa = a->x;
5902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xae = xa + wa;
5912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  wb = b->wds;
5922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xb = b->x;
5932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xbe = xb + wb;
5942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xc = c->x;
5952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  borrow = 0;
5962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef ULLong
5972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  do {
5982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    y = (ULLong)*xa++ - *xb++ - borrow;
5992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    borrow = y >> 32 & 1UL;
6002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /* LINTED conversion */
6012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *xc++ = (uint32_t)(y & 0xffffffffUL);
6022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
6032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    while(xb < xbe);
6042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  while(xa < xae) {
6052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    y = *xa++ - borrow;
6062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    borrow = y >> 32 & 1UL;
6072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    /* LINTED conversion */
6082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *xc++ = (uint32_t)(y & 0xffffffffUL);
6092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
6102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
6112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef Pack_32
6122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  do {
6132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
6142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    borrow = (y & 0x10000) >> 16;
6152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
6162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    borrow = (z & 0x10000) >> 16;
6172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    Storeinc(xc, z, y);
6182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
6192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    while(xb < xbe);
6202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  while(xa < xae) {
6212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    y = (*xa & 0xffff) - borrow;
6222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    borrow = (y & 0x10000) >> 16;
6232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    z = (*xa++ >> 16) - borrow;
6242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    borrow = (z & 0x10000) >> 16;
6252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    Storeinc(xc, z, y);
6262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
6272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
6282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  do {
6292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    y = *xa++ - *xb++ - borrow;
6302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    borrow = (y & 0x10000) >> 16;
6312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *xc++ = y & 0xffff;
6322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
6332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    while(xb < xbe);
6342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  while(xa < xae) {
6352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    y = *xa++ - borrow;
6362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    borrow = (y & 0x10000) >> 16;
6372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *xc++ = y & 0xffff;
6382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
6392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
6402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
6412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  while(!*--xc)
6422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    wa--;
6432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  c->wds = wa;
6442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return c;
6452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
6462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
6472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm double
6482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmb2d
6492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
6502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (a, e) Bigint *a; int *e;
6512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
6522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (Bigint *a, int *e)
6532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
6542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
6552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong *xa, *xa0, w, y, z;
6562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int k;
6572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  double d;
6582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef VAX
6592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong d0, d1;
6602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
6612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define d0 word0(d)
6622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define d1 word1(d)
6632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
6642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
6652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xa0 = a->x;
6662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  xa = xa0 + a->wds;
6672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  y = *--xa;
6682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef DEBUG
6692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (!y) Bug("zero y in b2d");
6702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
6712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  k = hi0bits(y);
6722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  *e = 32 - k;
6732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef Pack_32
6742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (k < Ebits) {
6752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    d0 = (UINT32)(Exp_1 | y >> (Ebits - k));
6762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    w = xa > xa0 ? *--xa : 0;
6772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    d1 = (UINT32)(y << ((32-Ebits) + k) | w >> (Ebits - k));
6782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    goto ret_d;
6792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
6802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  z = xa > xa0 ? *--xa : 0;
6812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (k -= Ebits) {
6822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    d0 = (UINT32)(Exp_1 | y << k | z >> (32 - k));
6832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    y = xa > xa0 ? *--xa : 0;
6842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    d1 = (UINT32)(z << k | y >> (32 - k));
6852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
6862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  else {
6872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    d0 = (UINT32)(Exp_1 | y);
6882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    d1 = (UINT32)z;
6892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
6902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
6912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (k < Ebits + 16) {
6922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    z = xa > xa0 ? *--xa : 0;
6932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
6942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    w = xa > xa0 ? *--xa : 0;
6952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    y = xa > xa0 ? *--xa : 0;
6962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
6972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    goto ret_d;
6982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
6992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  z = xa > xa0 ? *--xa : 0;
7002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  w = xa > xa0 ? *--xa : 0;
7012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  k -= Ebits + 16;
7022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
7032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  y = xa > xa0 ? *--xa : 0;
7042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  d1 = w << k + 16 | y << k;
7052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
7062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm ret_d:
7072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef VAX
7082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  word0(d) = d0 >> 16 | d0 << 16;
7092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  word1(d) = d1 >> 16 | d1 << 16;
7102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
7112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return dval(d);
7122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
7132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#undef d0
7142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#undef d1
7152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
7162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Bigint *
7172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmd2b
7182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
7192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (d, e, bits) double d; int *e, *bits;
7202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
7212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  (double d, int *e, int *bits)
7222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
7232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
7242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  Bigint *b;
7252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef Sudden_Underflow
7262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int i;
7272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
7282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  int de, k;
7292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong *x, y, z;
7302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef VAX
7312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  ULong d0, d1;
7322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  d0 = word0(d) >> 16 | word0(d) << 16;
7332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  d1 = word1(d) >> 16 | word1(d) << 16;
7342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
7352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define d0 word0(d)
7362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#define d1 word1(d)
7372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
7382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
7392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef Pack_32
7402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  b = Balloc(1);
7412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
7422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  b = Balloc(2);
7432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
7442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (b == NULL)
7452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    return NULL;
7462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  x = b->x;
7472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
7482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  z = d0 & Frac_mask;
7492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
7502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef Sudden_Underflow
7512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  de = (int)(d0 >> Exp_shift);
7522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef IBM
7532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  z |= Exp_msk11;
7542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
7552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
7562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ( (de = (int)(d0 >> Exp_shift)) !=0)
7572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    z |= Exp_msk1;
7582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
7592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef Pack_32
7602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ( (y = d1) !=0) {
7612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ( (k = lo0bits(&y)) !=0) {
7622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      x[0] = y | z << (32 - k);
7632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      z >>= k;
7642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
7652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else
7662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      x[0] = y;
7672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef Sudden_Underflow
7682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    i =
7692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
7702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm         b->wds = (x[1] = z) !=0 ? 2 : 1;
7712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
7722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  else {
7732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef DEBUG
7742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (!z)
7752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      Bug("Zero passed to d2b");
7762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
7772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k = lo0bits(&z);
7782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    x[0] = z;
7792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef Sudden_Underflow
7802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    i =
7812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
7822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        b->wds = 1;
7832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k += 32;
7842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
7852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
7862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if ( (y = d1) !=0) {
7872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if ( (k = lo0bits(&y)) !=0)
7882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      if (k >= 16) {
7892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        x[0] = y | z << 32 - k & 0xffff;
7902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        x[1] = z >> k - 16 & 0xffff;
7912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        x[2] = z >> k;
7922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        i = 2;
7932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
7942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      else {
7952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        x[0] = y & 0xffff;
7962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        x[1] = y >> 16 | z << 16 - k & 0xffff;
7972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        x[2] = z >> k & 0xffff;
7982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        x[3] = z >> k+16;
7992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        i = 3;
8002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm        }
8012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else {
8022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      x[0] = y & 0xffff;
8032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      x[1] = y >> 16;
8042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      x[2] = z & 0xffff;
8052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      x[3] = z >> 16;
8062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      i = 3;
8072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
8082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
8092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  else {
8102aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef DEBUG
8112aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (!z)
8122aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      Bug("Zero passed to d2b");
8132aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
8142aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k = lo0bits(&z);
8152aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    if (k >= 16) {
8162aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      x[0] = z;
8172aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      i = 0;
8182aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
8192aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    else {
8202aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      x[0] = z & 0xffff;
8212aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      x[1] = z >> 16;
8222aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      i = 1;
8232aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm      }
8242aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    k += 32;
8252aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
8262aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  while(!x[i])
8272aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    --i;
8282aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  b->wds = i + 1;
8292aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
8302aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef Sudden_Underflow
8312aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  if (de) {
8322aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
8332aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef IBM
8342aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *e = (de - Bias - (P-1) << 2) + k;
8352aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
8362aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
8372aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *e = de - Bias - (P-1) + k;
8382aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *bits = P - k;
8392aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
8402aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifndef Sudden_Underflow
8412aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
8422aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  else {
8432aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *e = de - Bias - (P-1) + 1 + k;
8442aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef Pack_32
8452aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *bits = 32*i - hi0bits(x[i-1]);
8462aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
8472aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *bits = (i+2)*16 - hi0bits(x[i]);
8482aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
8492aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    }
8502aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
8512aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return b;
8522aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
8532aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#undef d0
8542aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#undef d1
8552aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8562aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm CONST double
8572aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef IEEE_Arith
8582aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmbigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
8592aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmCONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
8602aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    };
8612aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
8622aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef IBM
8632aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmbigtens[] = { 1e16, 1e32, 1e64 };
8642aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmCONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
8652aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
8662aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmbigtens[] = { 1e16, 1e32 };
8672aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmCONST double tinytens[] = { 1e-16, 1e-32 };
8682aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
8692aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
8702aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8712aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm CONST double
8722aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmtens[] = {
8732aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
8742aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
8752aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    1e20, 1e21, 1e22
8762aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef VAX
8772aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    , 1e23, 1e24
8782aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
8792aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    };
8802aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8812aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm char *
8822aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
8832aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstrcp_D2A(a, b) char *a; char *b;
8842aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
8852aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmstrcp_D2A(char *a, CONST char *b)
8862aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
8872aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
8882aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  while((*a = *b++))
8892aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    a++;
8902aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return a;
8912aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
8922aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8932aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef NO_STRING_H
8942aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
8952aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm Char *
8962aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#ifdef KR_headers
8972aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmmemcpy_D2A(a, b, len) Char *a; Char *b; size_t len;
8982aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#else
8992aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylmmemcpy_D2A(void *a1, void *b1, size_t len)
9002aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif
9012aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm{
9022aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  char *a = (char*)a1, *ae = a + len;
9032aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  char *b = (char*)b1, *a0 = a;
9042aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  while(a < ae)
9052aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm    *a++ = *b++;
9062aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  return a0;
9072aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm  }
9082aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm
9092aa62f2bc9a9654687b377d9ca8a8c2c860a3852darylm#endif /* NO_STRING_H */
910