]>
Commit | Line | Data |
---|---|---|
224c7076 A |
1 | /**************************************************************** |
2 | ||
3 | The author of this software is David M. Gay. | |
4 | ||
5 | Copyright (C) 2000 by Lucent Technologies | |
6 | All Rights Reserved | |
7 | ||
8 | Permission to use, copy, modify, and distribute this software and | |
9 | its documentation for any purpose and without fee is hereby | |
10 | granted, provided that the above copyright notice appear in all | |
11 | copies and that both that the copyright notice and this | |
12 | permission notice and warranty disclaimer appear in supporting | |
13 | documentation, and that the name of Lucent or any of its entities | |
14 | not be used in advertising or publicity pertaining to | |
15 | distribution of the software without specific, written prior | |
16 | permission. | |
17 | ||
18 | LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
19 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. | |
20 | IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY | |
21 | SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
22 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |
23 | IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
24 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | |
25 | THIS SOFTWARE. | |
26 | ||
27 | ****************************************************************/ | |
28 | ||
29 | /* Please send bug reports to David M. Gay (dmg at acm dot org, | |
30 | * with " at " changed at "@" and " dot " changed to "."). */ | |
31 | ||
32 | #include "gdtoaimp.h" | |
33 | #include <fpmath.h> | |
34 | ||
1f2f436a | 35 | #ifndef __APPLE__ |
224c7076 A |
36 | static void |
37 | #ifdef KR_headers | |
38 | L_shift(x, x1, i) ULong *x; ULong *x1; int i; | |
39 | #else | |
40 | L_shift(ULong *x, ULong *x1, int i) | |
41 | #endif | |
42 | { | |
43 | int j; | |
44 | ||
45 | i = 8 - i; | |
46 | i <<= 2; | |
47 | j = ULbits - i; | |
48 | do { | |
49 | *x |= x[1] << j; | |
50 | x[1] >>= i; | |
51 | } while(++x < x1); | |
52 | } | |
1f2f436a | 53 | #endif /* !__APPLE__ */ |
224c7076 A |
54 | |
55 | int | |
56 | #ifdef KR_headers | |
57 | hexnan(sp, fpi, x0) | |
58 | CONST char **sp; FPI *fpi; ULong *x0; | |
59 | #else | |
60 | hexnan( CONST char **sp, FPI *fpi, ULong *x0) | |
61 | #endif | |
62 | { | |
1f2f436a | 63 | #ifdef __APPLE__ |
224c7076 A |
64 | int nbits, len; |
65 | char *cp; | |
1f2f436a A |
66 | #else /* !__APPLE__ */ |
67 | ULong c, h, *x, *x1, *xe; | |
68 | #endif /* __APPLE__ */ | |
224c7076 | 69 | CONST char *s; |
1f2f436a A |
70 | #ifndef __APPLE__ |
71 | int havedig, hd0, i, nbits; | |
72 | #endif /* !__APPLE__ */ | |
224c7076 | 73 | |
1f2f436a | 74 | #ifdef __APPLE__ |
224c7076 A |
75 | if (sp == NULL || *sp == NULL || **sp != '(') |
76 | return STRTOG_NaN; | |
1f2f436a A |
77 | #else /* !__APPLE__ */ |
78 | if (!hexdig['0']) | |
79 | hexdig_init_D2A(); | |
80 | nbits = fpi->nbits; | |
81 | x = x0 + (nbits >> kshift); | |
82 | if (nbits & kmask) | |
83 | x++; | |
84 | *--x = 0; | |
85 | x1 = xe = x; | |
86 | havedig = hd0 = i = 0; | |
87 | #endif /* __APPLE__ */ | |
224c7076 | 88 | s = *sp; |
1f2f436a | 89 | #ifdef __APPLE__ |
224c7076 | 90 | if ((cp = strchr(s + 1, ')')) == NULL) { |
1f2f436a | 91 | return STRTOG_NaN; |
224c7076 A |
92 | } |
93 | else { | |
94 | len = cp - (s + 1); | |
95 | cp = alloca(len + 1); | |
96 | if (!cp) | |
1f2f436a A |
97 | #else /* !__APPLE__ */ |
98 | /* allow optional initial 0x or 0X */ | |
99 | while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') | |
100 | ++s; | |
101 | if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') | |
102 | && *(CONST unsigned char*)(s+3) > ' ') | |
103 | s += 2; | |
104 | while((c = *(CONST unsigned char*)++s)) { | |
105 | if (!(h = hexdig[c])) { | |
106 | if (c <= ' ') { | |
107 | if (hd0 < havedig) { | |
108 | if (x < x1 && i < 8) | |
109 | L_shift(x, x1, i); | |
110 | if (x <= x0) { | |
111 | i = 8; | |
112 | continue; | |
113 | } | |
114 | hd0 = havedig; | |
115 | *--x = 0; | |
116 | x1 = x; | |
117 | i = 0; | |
118 | } | |
119 | while(*(CONST unsigned char*)(s+1) <= ' ') | |
120 | ++s; | |
121 | if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') | |
122 | && *(CONST unsigned char*)(s+3) > ' ') | |
123 | s += 2; | |
124 | continue; | |
125 | } | |
126 | if (/*(*/ c == ')' && havedig) { | |
127 | *sp = s + 1; | |
128 | break; | |
129 | } | |
130 | #ifndef GDTOA_NON_PEDANTIC_NANCHECK | |
131 | do { | |
132 | if (/*(*/ c == ')') { | |
133 | *sp = s + 1; | |
134 | break; | |
135 | } | |
136 | } while((c = *++s)); | |
137 | #endif | |
138 | #endif /* __APPLE__ */ | |
224c7076 | 139 | return STRTOG_NaN; |
1f2f436a | 140 | #ifdef __APPLE__ |
224c7076 A |
141 | strlcpy(cp, s + 1, len + 1); |
142 | *sp += len + 2; | |
1f2f436a A |
143 | #else /* !__APPLE__ */ |
144 | } | |
145 | havedig++; | |
146 | if (++i > 8) { | |
147 | if (x <= x0) | |
148 | continue; | |
149 | i = 1; | |
150 | *--x = 0; | |
151 | } | |
152 | *x = (*x << 4) | (h & 0xf); | |
153 | #endif /* __APPLE__ */ | |
224c7076 | 154 | } |
1f2f436a | 155 | #ifdef __APPLE__ |
224c7076 A |
156 | nbits = fpi->nbits; |
157 | /* a hack */ | |
158 | if (nbits == 52) { /* double */ | |
159 | union IEEEd2bits u; | |
160 | u.d = nan(cp); | |
161 | x0[1] = u.bits.manh; | |
162 | x0[0] = u.bits.manl; | |
1f2f436a A |
163 | #else /* !__APPLE__ */ |
164 | if (!havedig) | |
165 | return STRTOG_NaN; | |
166 | if (x < x1 && i < 8) | |
167 | L_shift(x, x1, i); | |
168 | if (x > x0) { | |
169 | x1 = x0; | |
170 | do *x1++ = *x++; | |
171 | while(x <= xe); | |
172 | do *x1++ = 0; | |
173 | while(x1 <= xe); | |
174 | #endif /* __APPLE__ */ | |
224c7076 | 175 | } |
1f2f436a | 176 | #ifdef __APPLE__ |
224c7076 A |
177 | else if (nbits < 52) { /* float */ |
178 | union IEEEf2bits u; | |
179 | u.f = nanf(cp); | |
180 | x0[0] = u.bits.man; | |
1f2f436a A |
181 | #else /* !__APPLE__ */ |
182 | else { | |
183 | /* truncate high-order word if necessary */ | |
184 | if ( (i = nbits & (ULbits-1)) !=0) | |
185 | *xe &= ((ULong)0xffffffff) >> (ULbits - i); | |
186 | #endif /* __APPLE__ */ | |
224c7076 | 187 | } |
1f2f436a | 188 | #ifdef __APPLE__ |
224c7076 A |
189 | else { /* long double */ |
190 | union IEEEl2bits u; | |
191 | u.e = nanl(cp); | |
192 | #if defined(__ppc__) || defined(__ppc64__) | |
193 | x0[3] = (ULong)(u.bits.manh >> 44); | |
194 | x0[2] = (ULong)(u.bits.manh >> 12); | |
195 | x0[1] = ((ULong)u.bits.manh & 0xfff) << 20 | (ULong)(u.bits.manl >> 32); | |
196 | x0[0] = (ULong)u.bits.manl; | |
b5d655f7 | 197 | #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) |
224c7076 A |
198 | x0[1] = (ULong)u.bits.manh; |
199 | x0[0] = (ULong)u.bits.manl; | |
200 | #else | |
201 | #error unsupported architecture | |
202 | #endif | |
1f2f436a A |
203 | #else /* !__APPLE__ */ |
204 | for(x1 = xe;; --x1) { | |
205 | if (*x1 != 0) | |
206 | break; | |
207 | if (x1 == x0) { | |
208 | *x1 = 1; | |
209 | break; | |
210 | } | |
211 | #endif /* __APPLE__ */ | |
224c7076 | 212 | } |
224c7076 A |
213 | return STRTOG_NaNbits; |
214 | } |