smisc.c revision 1.3
11.3Schristos/* $NetBSD: smisc.c,v 1.3 2008/03/21 23:13:48 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.1Skleink	(s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
401.1Skleink#else
411.1Skleink	(CONST char *s, int nd0, int nd, ULong y9)
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.3Schristos		do  {
681.3Schristos			b = multadd(b, 10, *s++ - '0');
691.3Schristos			if (b == NULL)
701.3Schristos				return NULL;
711.3Schristos			} while(++i < nd0);
721.1Skleink		s++;
731.1Skleink		}
741.1Skleink	else
751.1Skleink		s += 10;
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
841.1Skleink double
851.1Skleinkratio
861.1Skleink#ifdef KR_headers
871.1Skleink	(a, b) Bigint *a, *b;
881.1Skleink#else
891.1Skleink	(Bigint *a, Bigint *b)
901.1Skleink#endif
911.1Skleink{
921.1Skleink	double da, db;
931.1Skleink	int k, ka, kb;
941.1Skleink
951.1Skleink	dval(da) = b2d(a, &ka);
961.1Skleink	dval(db) = b2d(b, &kb);
971.1Skleink	k = ka - kb + ULbits*(a->wds - b->wds);
981.1Skleink#ifdef IBM
991.1Skleink	if (k > 0) {
1001.1Skleink		word0(da) += (k >> 2)*Exp_msk1;
1011.1Skleink		if (k &= 3)
1021.1Skleink			dval(da) *= 1 << k;
1031.1Skleink		}
1041.1Skleink	else {
1051.1Skleink		k = -k;
1061.1Skleink		word0(db) += (k >> 2)*Exp_msk1;
1071.1Skleink		if (k &= 3)
1081.1Skleink			dval(db) *= 1 << k;
1091.1Skleink		}
1101.1Skleink#else
1111.1Skleink	if (k > 0)
1121.1Skleink		word0(da) += k*Exp_msk1;
1131.1Skleink	else {
1141.1Skleink		k = -k;
1151.1Skleink		word0(db) += k*Exp_msk1;
1161.1Skleink		}
1171.1Skleink#endif
1181.1Skleink	return dval(da) / dval(db);
1191.1Skleink	}
1201.1Skleink
1211.1Skleink#ifdef INFNAN_CHECK
1221.1Skleink
1231.1Skleink int
1241.1Skleinkmatch
1251.1Skleink#ifdef KR_headers
1261.2Skleink	(sp, t) CONST char **sp, *t;
1271.1Skleink#else
1281.2Skleink	(CONST char **sp, CONST char *t)
1291.1Skleink#endif
1301.1Skleink{
1311.1Skleink	int c, d;
1321.1Skleink	CONST char *s = *sp;
1331.1Skleink
1341.1Skleink	while( (d = *t++) !=0) {
1351.1Skleink		if ((c = *++s) >= 'A' && c <= 'Z')
1361.1Skleink			c += 'a' - 'A';
1371.1Skleink		if (c != d)
1381.1Skleink			return 0;
1391.1Skleink		}
1401.1Skleink	*sp = s + 1;
1411.1Skleink	return 1;
1421.1Skleink	}
1431.1Skleink#endif /* INFNAN_CHECK */
1441.1Skleink
1451.1Skleink void
1461.1Skleink#ifdef KR_headers
1471.1Skleinkcopybits(c, n, b) ULong *c; int n; Bigint *b;
1481.1Skleink#else
1491.1Skleinkcopybits(ULong *c, int n, Bigint *b)
1501.1Skleink#endif
1511.1Skleink{
1521.1Skleink	ULong *ce, *x, *xe;
1531.1Skleink#ifdef Pack_16
1541.1Skleink	int nw, nw1;
1551.1Skleink#endif
1561.1Skleink
1571.2Skleink	ce = c + ((unsigned int)(n-1) >> kshift) + 1;
1581.1Skleink	x = b->x;
1591.1Skleink#ifdef Pack_32
1601.1Skleink	xe = x + b->wds;
1611.1Skleink	while(x < xe)
1621.1Skleink		*c++ = *x++;
1631.1Skleink#else
1641.1Skleink	nw = b->wds;
1651.1Skleink	nw1 = nw & 1;
1661.1Skleink	for(xe = x + (nw - nw1); x < xe; x += 2)
1671.1Skleink		Storeinc(c, x[1], x[0]);
1681.1Skleink	if (nw1)
1691.1Skleink		*c++ = *x;
1701.1Skleink#endif
1711.1Skleink	while(c < ce)
1721.1Skleink		*c++ = 0;
1731.1Skleink	}
1741.1Skleink
1751.1Skleink ULong
1761.1Skleink#ifdef KR_headers
1771.1Skleinkany_on(b, k) Bigint *b; int k;
1781.1Skleink#else
1791.1Skleinkany_on(Bigint *b, int k)
1801.1Skleink#endif
1811.1Skleink{
1821.1Skleink	int n, nwds;
1831.1Skleink	ULong *x, *x0, x1, x2;
1841.1Skleink
1851.1Skleink	x = b->x;
1861.1Skleink	nwds = b->wds;
1871.2Skleink	n = (unsigned int)k >> kshift;
1881.1Skleink	if (n > nwds)
1891.1Skleink		n = nwds;
1901.1Skleink	else if (n < nwds && (k &= kmask)) {
1911.1Skleink		x1 = x2 = x[n];
1921.1Skleink		x1 >>= k;
1931.1Skleink		x1 <<= k;
1941.1Skleink		if (x1 != x2)
1951.1Skleink			return 1;
1961.1Skleink		}
1971.1Skleink	x0 = x;
1981.1Skleink	x += n;
1991.1Skleink	while(x > x0)
2001.1Skleink		if (*--x)
2011.1Skleink			return 1;
2021.1Skleink	return 0;
2031.1Skleink	}
204