gdtoa-hexnan.c.patch [plain text]
--- gdtoa-hexnan.c.orig 2005-01-20 20:12:36.000000000 -0800
+++ gdtoa-hexnan.c 2005-06-10 17:43:17.000000000 -0700
@@ -30,6 +30,7 @@
* with " at " changed at "@" and " dot " changed to "."). */
#include "gdtoaimp.h"
+#include <fpmath.h>
static void
#ifdef KR_headers
@@ -57,75 +58,53 @@
hexnan( CONST char **sp, FPI *fpi, ULong *x0)
#endif
{
- ULong c, h, *x, *x1, *xe;
+ int nbits, len;
+ char *cp;
CONST char *s;
- int havedig, hd0, i, nbits;
- if (!hexdig['0'])
- hexdig_init_D2A();
- nbits = fpi->nbits;
- x = x0 + (nbits >> kshift);
- if (nbits & kmask)
- x++;
- *--x = 0;
- x1 = xe = x;
- havedig = hd0 = i = 0;
+ if (sp == NULL || *sp == NULL || **sp != '(')
+ return STRTOG_NaN;
s = *sp;
- while(c = *(CONST unsigned char*)++s) {
- if (!(h = hexdig[c])) {
- if (c <= ' ') {
- if (hd0 < havedig) {
- if (x < x1 && i < 8)
- L_shift(x, x1, i);
- if (x <= x0) {
- i = 8;
- continue;
- }
- hd0 = havedig;
- *--x = 0;
- x1 = x;
- i = 0;
- }
- continue;
- }
- if (/*(*/ c == ')' && havedig) {
- *sp = s + 1;
- break;
- }
+ if ((cp = strchr(s + 1, ')')) == NULL) {
+ *sp += strlen(s);
+ cp = s + 1;
+ }
+ else {
+ len = cp - (s + 1);
+ cp = alloca(len + 1);
+ if (!cp)
return STRTOG_NaN;
- }
- havedig++;
- if (++i > 8) {
- if (x <= x0)
- continue;
- i = 1;
- *--x = 0;
- }
- *x = (*x << 4) | h & 0xf;
+ strlcpy(cp, s + 1, len + 1);
+ *sp += len + 2;
}
- if (!havedig)
- return STRTOG_NaN;
- if (x < x1 && i < 8)
- L_shift(x, x1, i);
- if (x > x0) {
- x1 = x0;
- do *x1++ = *x++;
- while(x <= xe);
- do *x1++ = 0;
- while(x1 <= xe);
+ nbits = fpi->nbits;
+ /* a hack */
+ if (nbits == 52) { /* double */
+ union IEEEd2bits u;
+ u.d = nan(cp);
+ x0[1] = u.bits.manh;
+ x0[0] = u.bits.manl;
}
- else {
- /* truncate high-order word if necessary */
- if ( (i = nbits & (ULbits-1)) !=0)
- *xe &= ((ULong)0xffffffff) >> (ULbits - i);
+ else if (nbits < 52) { /* float */
+ union IEEEf2bits u;
+ u.f = nanf(cp);
+ x0[0] = u.bits.man;
}
- for(x1 = xe;; --x1) {
- if (*x1 != 0)
- break;
- if (x1 == x0) {
- *x1 = 1;
- break;
- }
+ else { /* long double */
+ union IEEEl2bits u;
+ u.e = nanl(cp);
+#if defined(__ppc__) || defined(__ppc64__)
+ x0[3] = (ULong)(u.bits.manh >> 44);
+ x0[2] = (ULong)(u.bits.manh >> 12);
+ x0[1] = ((ULong)u.bits.manh & 0xfff) << 20 | (ULong)(u.bits.manl >> 32);
+ x0[0] = (ULong)u.bits.manl;
+#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__)
+ x0[1] = (ULong)u.bits.manh;
+ x0[0] = (ULong)u.bits.manl;
+#else
+#error unsupported architecture
+#endif
}
+
return STRTOG_NaNbits;
}