1*f14fb602SLionel Sambuc /* $NetBSD: smisc.c,v 1.5 2012/03/13 21:13:34 christos Exp $ */
22fe8fb19SBen Gras
32fe8fb19SBen Gras /****************************************************************
42fe8fb19SBen Gras
52fe8fb19SBen Gras The author of this software is David M. Gay.
62fe8fb19SBen Gras
72fe8fb19SBen Gras Copyright (C) 1998, 1999 by Lucent Technologies
82fe8fb19SBen Gras All Rights Reserved
92fe8fb19SBen Gras
102fe8fb19SBen Gras Permission to use, copy, modify, and distribute this software and
112fe8fb19SBen Gras its documentation for any purpose and without fee is hereby
122fe8fb19SBen Gras granted, provided that the above copyright notice appear in all
132fe8fb19SBen Gras copies and that both that the copyright notice and this
142fe8fb19SBen Gras permission notice and warranty disclaimer appear in supporting
152fe8fb19SBen Gras documentation, and that the name of Lucent or any of its entities
162fe8fb19SBen Gras not be used in advertising or publicity pertaining to
172fe8fb19SBen Gras distribution of the software without specific, written prior
182fe8fb19SBen Gras permission.
192fe8fb19SBen Gras
202fe8fb19SBen Gras LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
212fe8fb19SBen Gras INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
222fe8fb19SBen Gras IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
232fe8fb19SBen Gras SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
242fe8fb19SBen Gras WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
252fe8fb19SBen Gras IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
262fe8fb19SBen Gras ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
272fe8fb19SBen Gras THIS SOFTWARE.
282fe8fb19SBen Gras
292fe8fb19SBen Gras ****************************************************************/
302fe8fb19SBen Gras
312fe8fb19SBen Gras /* Please send bug reports to David M. Gay (dmg at acm dot org,
322fe8fb19SBen Gras * with " at " changed at "@" and " dot " changed to "."). */
332fe8fb19SBen Gras
342fe8fb19SBen Gras #include "gdtoaimp.h"
352fe8fb19SBen Gras
362fe8fb19SBen Gras Bigint *
s2b(s,nd0,nd,y9,dplen)372fe8fb19SBen Gras s2b
382fe8fb19SBen Gras #ifdef KR_headers
39*f14fb602SLionel Sambuc (s, nd0, nd, y9, dplen) CONST char *s; int dplen, nd0, nd; ULong y9;
402fe8fb19SBen Gras #else
41*f14fb602SLionel Sambuc (CONST char *s, int nd0, int nd, ULong y9, size_t dplen)
422fe8fb19SBen Gras #endif
432fe8fb19SBen Gras {
442fe8fb19SBen Gras Bigint *b;
452fe8fb19SBen Gras int i, k;
462fe8fb19SBen Gras Long x, y;
472fe8fb19SBen Gras
482fe8fb19SBen Gras x = (nd + 8) / 9;
492fe8fb19SBen Gras for(k = 0, y = 1; x > y; y <<= 1, k++) ;
502fe8fb19SBen Gras #ifdef Pack_32
512fe8fb19SBen Gras b = Balloc(k);
522fe8fb19SBen Gras if (b == NULL)
532fe8fb19SBen Gras return NULL;
542fe8fb19SBen Gras b->x[0] = y9;
552fe8fb19SBen Gras b->wds = 1;
562fe8fb19SBen Gras #else
572fe8fb19SBen Gras b = Balloc(k+1);
582fe8fb19SBen Gras if (b == NULL)
592fe8fb19SBen Gras return NULL;
602fe8fb19SBen Gras b->x[0] = y9 & 0xffff;
612fe8fb19SBen Gras b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
622fe8fb19SBen Gras #endif
632fe8fb19SBen Gras
642fe8fb19SBen Gras i = 9;
652fe8fb19SBen Gras if (9 < nd0) {
662fe8fb19SBen Gras s += 9;
672fe8fb19SBen Gras do {
682fe8fb19SBen Gras b = multadd(b, 10, *s++ - '0');
692fe8fb19SBen Gras if (b == NULL)
702fe8fb19SBen Gras return NULL;
712fe8fb19SBen Gras } while(++i < nd0);
72*f14fb602SLionel Sambuc s += dplen;
732fe8fb19SBen Gras }
742fe8fb19SBen Gras else
75*f14fb602SLionel Sambuc s += dplen + 9;
762fe8fb19SBen Gras for(; i < nd; i++) {
772fe8fb19SBen Gras b = multadd(b, 10, *s++ - '0');
782fe8fb19SBen Gras if (b == NULL)
792fe8fb19SBen Gras return NULL;
802fe8fb19SBen Gras }
812fe8fb19SBen Gras return b;
822fe8fb19SBen Gras }
832fe8fb19SBen Gras double
ratio(a,b)842fe8fb19SBen Gras ratio
852fe8fb19SBen Gras #ifdef KR_headers
862fe8fb19SBen Gras (a, b) Bigint *a, *b;
872fe8fb19SBen Gras #else
882fe8fb19SBen Gras (Bigint *a, Bigint *b)
892fe8fb19SBen Gras #endif
902fe8fb19SBen Gras {
91*f14fb602SLionel Sambuc U da, db;
922fe8fb19SBen Gras int k, ka, kb;
932fe8fb19SBen Gras
94*f14fb602SLionel Sambuc dval(&da) = b2d(a, &ka);
95*f14fb602SLionel Sambuc dval(&db) = b2d(b, &kb);
962fe8fb19SBen Gras k = ka - kb + ULbits*(a->wds - b->wds);
972fe8fb19SBen Gras #ifdef IBM
982fe8fb19SBen Gras if (k > 0) {
99*f14fb602SLionel Sambuc word0(&da) += (k >> 2)*Exp_msk1;
1002fe8fb19SBen Gras if (k &= 3)
101*f14fb602SLionel Sambuc dval(&da) *= 1 << k;
1022fe8fb19SBen Gras }
1032fe8fb19SBen Gras else {
1042fe8fb19SBen Gras k = -k;
105*f14fb602SLionel Sambuc word0(&db) += (k >> 2)*Exp_msk1;
1062fe8fb19SBen Gras if (k &= 3)
107*f14fb602SLionel Sambuc dval(&db) *= 1 << k;
1082fe8fb19SBen Gras }
1092fe8fb19SBen Gras #else
1102fe8fb19SBen Gras if (k > 0)
111*f14fb602SLionel Sambuc word0(&da) += k*Exp_msk1;
1122fe8fb19SBen Gras else {
1132fe8fb19SBen Gras k = -k;
114*f14fb602SLionel Sambuc word0(&db) += k*Exp_msk1;
1152fe8fb19SBen Gras }
1162fe8fb19SBen Gras #endif
117*f14fb602SLionel Sambuc return dval(&da) / dval(&db);
1182fe8fb19SBen Gras }
1192fe8fb19SBen Gras
1202fe8fb19SBen Gras #ifdef INFNAN_CHECK
1212fe8fb19SBen Gras
1222fe8fb19SBen Gras int
match(sp,t)1232fe8fb19SBen Gras match
1242fe8fb19SBen Gras #ifdef KR_headers
1252fe8fb19SBen Gras (sp, t) CONST char **sp, *t;
1262fe8fb19SBen Gras #else
1272fe8fb19SBen Gras (CONST char **sp, CONST char *t)
1282fe8fb19SBen Gras #endif
1292fe8fb19SBen Gras {
1302fe8fb19SBen Gras int c, d;
1312fe8fb19SBen Gras CONST char *s = *sp;
1322fe8fb19SBen Gras
1332fe8fb19SBen Gras while( (d = *t++) !=0) {
1342fe8fb19SBen Gras if ((c = *++s) >= 'A' && c <= 'Z')
1352fe8fb19SBen Gras c += 'a' - 'A';
1362fe8fb19SBen Gras if (c != d)
1372fe8fb19SBen Gras return 0;
1382fe8fb19SBen Gras }
1392fe8fb19SBen Gras *sp = s + 1;
1402fe8fb19SBen Gras return 1;
1412fe8fb19SBen Gras }
1422fe8fb19SBen Gras #endif /* INFNAN_CHECK */
1432fe8fb19SBen Gras
1442fe8fb19SBen Gras void
1452fe8fb19SBen Gras #ifdef KR_headers
copybits(c,n,b)1462fe8fb19SBen Gras copybits(c, n, b) ULong *c; int n; Bigint *b;
1472fe8fb19SBen Gras #else
1482fe8fb19SBen Gras copybits(ULong *c, int n, Bigint *b)
1492fe8fb19SBen Gras #endif
1502fe8fb19SBen Gras {
1512fe8fb19SBen Gras ULong *ce, *x, *xe;
1522fe8fb19SBen Gras #ifdef Pack_16
1532fe8fb19SBen Gras int nw, nw1;
1542fe8fb19SBen Gras #endif
1552fe8fb19SBen Gras
1562fe8fb19SBen Gras ce = c + ((unsigned int)(n-1) >> kshift) + 1;
1572fe8fb19SBen Gras x = b->x;
1582fe8fb19SBen Gras #ifdef Pack_32
1592fe8fb19SBen Gras xe = x + b->wds;
1602fe8fb19SBen Gras while(x < xe)
1612fe8fb19SBen Gras *c++ = *x++;
1622fe8fb19SBen Gras #else
1632fe8fb19SBen Gras nw = b->wds;
1642fe8fb19SBen Gras nw1 = nw & 1;
1652fe8fb19SBen Gras for(xe = x + (nw - nw1); x < xe; x += 2)
1662fe8fb19SBen Gras Storeinc(c, x[1], x[0]);
1672fe8fb19SBen Gras if (nw1)
1682fe8fb19SBen Gras *c++ = *x;
1692fe8fb19SBen Gras #endif
1702fe8fb19SBen Gras while(c < ce)
1712fe8fb19SBen Gras *c++ = 0;
1722fe8fb19SBen Gras }
1732fe8fb19SBen Gras
1742fe8fb19SBen Gras ULong
1752fe8fb19SBen Gras #ifdef KR_headers
any_on(b,k)1762fe8fb19SBen Gras any_on(b, k) Bigint *b; int k;
1772fe8fb19SBen Gras #else
1782fe8fb19SBen Gras any_on(Bigint *b, int k)
1792fe8fb19SBen Gras #endif
1802fe8fb19SBen Gras {
1812fe8fb19SBen Gras int n, nwds;
1822fe8fb19SBen Gras ULong *x, *x0, x1, x2;
1832fe8fb19SBen Gras
1842fe8fb19SBen Gras x = b->x;
1852fe8fb19SBen Gras nwds = b->wds;
1862fe8fb19SBen Gras n = (unsigned int)k >> kshift;
1872fe8fb19SBen Gras if (n > nwds)
1882fe8fb19SBen Gras n = nwds;
1892fe8fb19SBen Gras else if (n < nwds && (k &= kmask)) {
1902fe8fb19SBen Gras x1 = x2 = x[n];
1912fe8fb19SBen Gras x1 >>= k;
1922fe8fb19SBen Gras x1 <<= k;
1932fe8fb19SBen Gras if (x1 != x2)
1942fe8fb19SBen Gras return 1;
1952fe8fb19SBen Gras }
1962fe8fb19SBen Gras x0 = x;
1972fe8fb19SBen Gras x += n;
1982fe8fb19SBen Gras while(x > x0)
1992fe8fb19SBen Gras if (*--x)
2002fe8fb19SBen Gras return 1;
2012fe8fb19SBen Gras return 0;
2022fe8fb19SBen Gras }
203