1112158Sdas/****************************************************************
2112158Sdas
3112158SdasThe author of this software is David M. Gay.
4112158Sdas
5112158SdasCopyright (C) 1998, 1999 by Lucent Technologies
6112158SdasAll Rights Reserved
7112158Sdas
8112158SdasPermission to use, copy, modify, and distribute this software and
9112158Sdasits documentation for any purpose and without fee is hereby
10112158Sdasgranted, provided that the above copyright notice appear in all
11112158Sdascopies and that both that the copyright notice and this
12112158Sdaspermission notice and warranty disclaimer appear in supporting
13112158Sdasdocumentation, and that the name of Lucent or any of its entities
14112158Sdasnot be used in advertising or publicity pertaining to
15112158Sdasdistribution of the software without specific, written prior
16112158Sdaspermission.
17112158Sdas
18112158SdasLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19112158SdasINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20112158SdasIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21112158SdasSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22112158SdasWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23112158SdasIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24112158SdasARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25112158SdasTHIS SOFTWARE.
26112158Sdas
27112158Sdas****************************************************************/
28112158Sdas
29165743Sdas/* Please send bug reports to David M. Gay (dmg at acm dot org,
30165743Sdas * with " at " changed at "@" and " dot " changed to ".").	*/
31112158Sdas
32112158Sdas#include "gdtoaimp.h"
33112158Sdas
34112158Sdas Bigint *
35112158Sdass2b
36112158Sdas#ifdef KR_headers
37187808Sdas	(s, nd0, nd, y9, dplen) CONST char *s; int dplen, nd0, nd; ULong y9;
38112158Sdas#else
39187808Sdas	(CONST char *s, int nd0, int nd, ULong y9, int dplen)
40112158Sdas#endif
41112158Sdas{
42112158Sdas	Bigint *b;
43112158Sdas	int i, k;
44112158Sdas	Long x, y;
45112158Sdas
46112158Sdas	x = (nd + 8) / 9;
47112158Sdas	for(k = 0, y = 1; x > y; y <<= 1, k++) ;
48112158Sdas#ifdef Pack_32
49112158Sdas	b = Balloc(k);
50112158Sdas	b->x[0] = y9;
51112158Sdas	b->wds = 1;
52112158Sdas#else
53112158Sdas	b = Balloc(k+1);
54112158Sdas	b->x[0] = y9 & 0xffff;
55112158Sdas	b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
56112158Sdas#endif
57112158Sdas
58112158Sdas	i = 9;
59112158Sdas	if (9 < nd0) {
60112158Sdas		s += 9;
61112158Sdas		do b = multadd(b, 10, *s++ - '0');
62112158Sdas			while(++i < nd0);
63187808Sdas		s += dplen;
64112158Sdas		}
65112158Sdas	else
66187808Sdas		s += dplen + 9;
67112158Sdas	for(; i < nd; i++)
68112158Sdas		b = multadd(b, 10, *s++ - '0');
69112158Sdas	return b;
70112158Sdas	}
71112158Sdas
72112158Sdas double
73112158Sdasratio
74112158Sdas#ifdef KR_headers
75112158Sdas	(a, b) Bigint *a, *b;
76112158Sdas#else
77112158Sdas	(Bigint *a, Bigint *b)
78112158Sdas#endif
79112158Sdas{
80219557Sdas	U da, db;
81112158Sdas	int k, ka, kb;
82112158Sdas
83219557Sdas	dval(&da) = b2d(a, &ka);
84219557Sdas	dval(&db) = b2d(b, &kb);
85112158Sdas	k = ka - kb + ULbits*(a->wds - b->wds);
86112158Sdas#ifdef IBM
87112158Sdas	if (k > 0) {
88219557Sdas		word0(&da) += (k >> 2)*Exp_msk1;
89112158Sdas		if (k &= 3)
90219557Sdas			dval(&da) *= 1 << k;
91112158Sdas		}
92112158Sdas	else {
93112158Sdas		k = -k;
94219557Sdas		word0(&db) += (k >> 2)*Exp_msk1;
95112158Sdas		if (k &= 3)
96219557Sdas			dval(&db) *= 1 << k;
97112158Sdas		}
98112158Sdas#else
99112158Sdas	if (k > 0)
100219557Sdas		word0(&da) += k*Exp_msk1;
101112158Sdas	else {
102112158Sdas		k = -k;
103219557Sdas		word0(&db) += k*Exp_msk1;
104112158Sdas		}
105112158Sdas#endif
106219557Sdas	return dval(&da) / dval(&db);
107112158Sdas	}
108112158Sdas
109112158Sdas#ifdef INFNAN_CHECK
110112158Sdas
111112158Sdas int
112112158Sdasmatch
113112158Sdas#ifdef KR_headers
114112158Sdas	(sp, t) char **sp, *t;
115112158Sdas#else
116112158Sdas	(CONST char **sp, char *t)
117112158Sdas#endif
118112158Sdas{
119112158Sdas	int c, d;
120112158Sdas	CONST char *s = *sp;
121112158Sdas
122112158Sdas	while( (d = *t++) !=0) {
123112158Sdas		if ((c = *++s) >= 'A' && c <= 'Z')
124112158Sdas			c += 'a' - 'A';
125112158Sdas		if (c != d)
126112158Sdas			return 0;
127112158Sdas		}
128112158Sdas	*sp = s + 1;
129112158Sdas	return 1;
130112158Sdas	}
131112158Sdas#endif /* INFNAN_CHECK */
132112158Sdas
133112158Sdas void
134112158Sdas#ifdef KR_headers
135112158Sdascopybits(c, n, b) ULong *c; int n; Bigint *b;
136112158Sdas#else
137112158Sdascopybits(ULong *c, int n, Bigint *b)
138112158Sdas#endif
139112158Sdas{
140112158Sdas	ULong *ce, *x, *xe;
141112158Sdas#ifdef Pack_16
142112158Sdas	int nw, nw1;
143112158Sdas#endif
144112158Sdas
145112158Sdas	ce = c + ((n-1) >> kshift) + 1;
146112158Sdas	x = b->x;
147112158Sdas#ifdef Pack_32
148112158Sdas	xe = x + b->wds;
149112158Sdas	while(x < xe)
150112158Sdas		*c++ = *x++;
151112158Sdas#else
152112158Sdas	nw = b->wds;
153112158Sdas	nw1 = nw & 1;
154112158Sdas	for(xe = x + (nw - nw1); x < xe; x += 2)
155112158Sdas		Storeinc(c, x[1], x[0]);
156112158Sdas	if (nw1)
157112158Sdas		*c++ = *x;
158112158Sdas#endif
159112158Sdas	while(c < ce)
160112158Sdas		*c++ = 0;
161112158Sdas	}
162112158Sdas
163112158Sdas ULong
164112158Sdas#ifdef KR_headers
165112158Sdasany_on(b, k) Bigint *b; int k;
166112158Sdas#else
167112158Sdasany_on(Bigint *b, int k)
168112158Sdas#endif
169112158Sdas{
170112158Sdas	int n, nwds;
171112158Sdas	ULong *x, *x0, x1, x2;
172112158Sdas
173112158Sdas	x = b->x;
174112158Sdas	nwds = b->wds;
175112158Sdas	n = k >> kshift;
176112158Sdas	if (n > nwds)
177112158Sdas		n = nwds;
178112158Sdas	else if (n < nwds && (k &= kmask)) {
179112158Sdas		x1 = x2 = x[n];
180112158Sdas		x1 >>= k;
181112158Sdas		x1 <<= k;
182112158Sdas		if (x1 != x2)
183112158Sdas			return 1;
184112158Sdas		}
185112158Sdas	x0 = x;
186112158Sdas	x += n;
187112158Sdas	while(x > x0)
188112158Sdas		if (*--x)
189112158Sdas			return 1;
190112158Sdas	return 0;
191112158Sdas	}
192