11.5Schristos/* $NetBSD: smisc.c,v 1.5 2012/03/13 21:13:34 christos Exp $ */
21.1Skleink
31.1Skleink/****************************************************************
41.1Skleink
51.1SkleinkThe author of this software is David M. Gay.
61.1Skleink
71.1SkleinkCopyright (C) 1998, 1999 by Lucent Technologies
81.1SkleinkAll Rights Reserved
91.1Skleink
101.1SkleinkPermission to use, copy, modify, and distribute this software and
111.1Skleinkits documentation for any purpose and without fee is hereby
121.1Skleinkgranted, provided that the above copyright notice appear in all
131.1Skleinkcopies and that both that the copyright notice and this
141.1Skleinkpermission notice and warranty disclaimer appear in supporting
151.1Skleinkdocumentation, and that the name of Lucent or any of its entities
161.1Skleinknot be used in advertising or publicity pertaining to
171.1Skleinkdistribution of the software without specific, written prior
181.1Skleinkpermission.
191.1Skleink
201.1SkleinkLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
211.1SkleinkINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
221.1SkleinkIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
231.1SkleinkSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
241.1SkleinkWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
251.1SkleinkIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
261.1SkleinkARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
271.1SkleinkTHIS SOFTWARE.
281.1Skleink
291.1Skleink****************************************************************/
301.1Skleink
311.1Skleink/* Please send bug reports to David M. Gay (dmg at acm dot org,
321.1Skleink * with " at " changed at "@" and " dot " changed to ".").	*/
331.1Skleink
341.1Skleink#include "gdtoaimp.h"
351.1Skleink
361.1Skleink Bigint *
371.1Skleinks2b
381.1Skleink#ifdef KR_headers
391.4Schristos	(s, nd0, nd, y9, dplen) CONST char *s; int dplen, nd0, nd; ULong y9;
401.1Skleink#else
411.5Schristos	(CONST char *s, int nd0, int nd, ULong y9, size_t dplen)
421.1Skleink#endif
431.1Skleink{
441.1Skleink	Bigint *b;
451.1Skleink	int i, k;
461.1Skleink	Long x, y;
471.1Skleink
481.1Skleink	x = (nd + 8) / 9;
491.1Skleink	for(k = 0, y = 1; x > y; y <<= 1, k++) ;
501.1Skleink#ifdef Pack_32
511.1Skleink	b = Balloc(k);
521.3Schristos	if (b == NULL)
531.3Schristos		return NULL;
541.1Skleink	b->x[0] = y9;
551.1Skleink	b->wds = 1;
561.1Skleink#else
571.1Skleink	b = Balloc(k+1);
581.3Schristos	if (b == NULL)
591.3Schristos		return NULL;
601.1Skleink	b->x[0] = y9 & 0xffff;
611.1Skleink	b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
621.1Skleink#endif
631.1Skleink
641.1Skleink	i = 9;
651.1Skleink	if (9 < nd0) {
661.1Skleink		s += 9;
671.4Schristos		do {
681.3Schristos			b = multadd(b, 10, *s++ - '0');
691.3Schristos			if (b == NULL)
701.3Schristos				return NULL;
711.3Schristos			} while(++i < nd0);
721.4Schristos		s += dplen;
731.1Skleink		}
741.1Skleink	else
751.4Schristos		s += dplen + 9;
761.3Schristos	for(; i < nd; i++) {
771.1Skleink		b = multadd(b, 10, *s++ - '0');
781.3Schristos		if (b == NULL)
791.3Schristos			return NULL;
801.3Schristos		}
811.1Skleink	return b;
821.1Skleink	}
831.1Skleink double
841.1Skleinkratio
851.1Skleink#ifdef KR_headers
861.1Skleink	(a, b) Bigint *a, *b;
871.1Skleink#else
881.1Skleink	(Bigint *a, Bigint *b)
891.1Skleink#endif
901.1Skleink{
911.4Schristos	U da, db;
921.1Skleink	int k, ka, kb;
931.1Skleink
941.4Schristos	dval(&da) = b2d(a, &ka);
951.4Schristos	dval(&db) = b2d(b, &kb);
961.1Skleink	k = ka - kb + ULbits*(a->wds - b->wds);
971.1Skleink#ifdef IBM
981.1Skleink	if (k > 0) {
991.4Schristos		word0(&da) += (k >> 2)*Exp_msk1;
1001.1Skleink		if (k &= 3)
1011.4Schristos			dval(&da) *= 1 << k;
1021.1Skleink		}
1031.1Skleink	else {
1041.1Skleink		k = -k;
1051.4Schristos		word0(&db) += (k >> 2)*Exp_msk1;
1061.1Skleink		if (k &= 3)
1071.4Schristos			dval(&db) *= 1 << k;
1081.1Skleink		}
1091.1Skleink#else
1101.1Skleink	if (k > 0)
1111.4Schristos		word0(&da) += k*Exp_msk1;
1121.1Skleink	else {
1131.1Skleink		k = -k;
1141.4Schristos		word0(&db) += k*Exp_msk1;
1151.1Skleink		}
1161.1Skleink#endif
1171.4Schristos	return dval(&da) / dval(&db);
1181.1Skleink	}
1191.1Skleink
1201.1Skleink#ifdef INFNAN_CHECK
1211.1Skleink
1221.1Skleink int
1231.1Skleinkmatch
1241.1Skleink#ifdef KR_headers
1251.2Skleink	(sp, t) CONST char **sp, *t;
1261.1Skleink#else
1271.2Skleink	(CONST char **sp, CONST char *t)
1281.1Skleink#endif
1291.1Skleink{
1301.1Skleink	int c, d;
1311.1Skleink	CONST char *s = *sp;
1321.1Skleink
1331.1Skleink	while( (d = *t++) !=0) {
1341.1Skleink		if ((c = *++s) >= 'A' && c <= 'Z')
1351.1Skleink			c += 'a' - 'A';
1361.1Skleink		if (c != d)
1371.1Skleink			return 0;
1381.1Skleink		}
1391.1Skleink	*sp = s + 1;
1401.1Skleink	return 1;
1411.1Skleink	}
1421.1Skleink#endif /* INFNAN_CHECK */
1431.1Skleink
1441.1Skleink void
1451.1Skleink#ifdef KR_headers
1461.1Skleinkcopybits(c, n, b) ULong *c; int n; Bigint *b;
1471.1Skleink#else
1481.1Skleinkcopybits(ULong *c, int n, Bigint *b)
1491.1Skleink#endif
1501.1Skleink{
1511.1Skleink	ULong *ce, *x, *xe;
1521.1Skleink#ifdef Pack_16
1531.1Skleink	int nw, nw1;
1541.1Skleink#endif
1551.1Skleink
1561.2Skleink	ce = c + ((unsigned int)(n-1) >> kshift) + 1;
1571.1Skleink	x = b->x;
1581.1Skleink#ifdef Pack_32
1591.1Skleink	xe = x + b->wds;
1601.1Skleink	while(x < xe)
1611.1Skleink		*c++ = *x++;
1621.1Skleink#else
1631.1Skleink	nw = b->wds;
1641.1Skleink	nw1 = nw & 1;
1651.1Skleink	for(xe = x + (nw - nw1); x < xe; x += 2)
1661.1Skleink		Storeinc(c, x[1], x[0]);
1671.1Skleink	if (nw1)
1681.1Skleink		*c++ = *x;
1691.1Skleink#endif
1701.1Skleink	while(c < ce)
1711.1Skleink		*c++ = 0;
1721.1Skleink	}
1731.1Skleink
1741.1Skleink ULong
1751.1Skleink#ifdef KR_headers
1761.1Skleinkany_on(b, k) Bigint *b; int k;
1771.1Skleink#else
1781.1Skleinkany_on(Bigint *b, int k)
1791.1Skleink#endif
1801.1Skleink{
1811.1Skleink	int n, nwds;
1821.1Skleink	ULong *x, *x0, x1, x2;
1831.1Skleink
1841.1Skleink	x = b->x;
1851.1Skleink	nwds = b->wds;
1861.2Skleink	n = (unsigned int)k >> kshift;
1871.1Skleink	if (n > nwds)
1881.1Skleink		n = nwds;
1891.1Skleink	else if (n < nwds && (k &= kmask)) {
1901.1Skleink		x1 = x2 = x[n];
1911.1Skleink		x1 >>= k;
1921.1Skleink		x1 <<= k;
1931.1Skleink		if (x1 != x2)
1941.1Skleink			return 1;
1951.1Skleink		}
1961.1Skleink	x0 = x;
1971.1Skleink	x += n;
1981.1Skleink	while(x > x0)
1991.1Skleink		if (*--x)
2001.1Skleink			return 1;
2011.1Skleink	return 0;
2021.1Skleink	}
203