diff options
author | Leon Clarke <leonclarke@google.com> | 2010-06-03 14:33:32 +0100 |
---|---|---|
committer | Leon Clarke <leonclarke@google.com> | 2010-06-08 12:24:51 +0100 |
commit | 5af96e2c7b73ebc627c6894727826a7576d31758 (patch) | |
tree | f9d5e6f6175ccd7e3d14de9b290f08937a0d17ba /JavaScriptCore/wtf/dtoa.cpp | |
parent | 8cc4fcf4f6adcbc0e0aebfc24fbad9a4cddf2cfb (diff) | |
download | external_webkit-5af96e2c7b73ebc627c6894727826a7576d31758.zip external_webkit-5af96e2c7b73ebc627c6894727826a7576d31758.tar.gz external_webkit-5af96e2c7b73ebc627c6894727826a7576d31758.tar.bz2 |
Merge webkit.org at r60469 : Initial merge by git.
Change-Id: I66a0047aa2af802f66bb0c7f2a8b02247a596234
Diffstat (limited to 'JavaScriptCore/wtf/dtoa.cpp')
-rw-r--r-- | JavaScriptCore/wtf/dtoa.cpp | 283 |
1 files changed, 150 insertions, 133 deletions
diff --git a/JavaScriptCore/wtf/dtoa.cpp b/JavaScriptCore/wtf/dtoa.cpp index 6289d04..9edc2a0 100644 --- a/JavaScriptCore/wtf/dtoa.cpp +++ b/JavaScriptCore/wtf/dtoa.cpp @@ -142,16 +142,15 @@ #endif #include <math.h> #include <stdint.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <wtf/AlwaysInline.h> #include <wtf/Assertions.h> #include <wtf/FastMalloc.h> #include <wtf/MathExtras.h> -#include <wtf/Vector.h> #include <wtf/Threading.h> - -#include <stdio.h> +#include <wtf/Vector.h> #if COMPILER(MSVC) #pragma warning(disable: 4244) @@ -179,7 +178,10 @@ namespace WTF { Mutex* s_dtoaP5Mutex; #endif -typedef union { double d; uint32_t L[2]; } U; +typedef union { + double d; + uint32_t L[2]; +} U; #ifdef YES_ALIAS #define dval(x) x @@ -203,13 +205,20 @@ typedef union { double d; uint32_t L[2]; } U; /* The following definition of Storeinc is appropriate for MIPS processors. * An alternative that might be better on some machines is - * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + * *p++ = high << 16 | low & 0xffff; */ +static ALWAYS_INLINE uint32_t* storeInc(uint32_t* p, uint16_t high, uint16_t low) +{ + uint16_t* p16 = reinterpret_cast<uint16_t*>(p); #if defined(IEEE_8087) || defined(IEEE_ARM) -#define Storeinc(a,b,c) (((unsigned short*)a)[1] = (unsigned short)b, ((unsigned short*)a)[0] = (unsigned short)c, a++) + p16[1] = high; + p16[0] = low; #else -#define Storeinc(a,b,c) (((unsigned short*)a)[0] = (unsigned short)b, ((unsigned short*)a)[1] = (unsigned short)c, a++) + p16[0] = high; + p16[1] = low; #endif + return p + 1; +} #define Exp_shift 20 #define Exp_shift1 20 @@ -247,11 +256,11 @@ typedef union { double d; uint32_t L[2]; } U; #else #define Flt_Rounds 1 #endif -#endif /*Flt_Rounds*/ +#endif /* Flt_Rounds */ -#define rounded_product(a,b) a *= b -#define rounded_quotient(a,b) a /= b +#define rounded_product(a, b) a *= b +#define rounded_quotient(a, b) a /= b #define Big0 (Frac_mask1 | Exp_msk1 * (DBL_MAX_EXP + Bias - 1)) #define Big1 0xffffffff @@ -413,7 +422,7 @@ static int hi0bits(uint32_t x) return k; } -static int lo0bits (uint32_t* y) +static int lo0bits(uint32_t* y) { int k; uint32_t x = *y; @@ -468,8 +477,13 @@ static void mult(BigInt& aRef, const BigInt& bRef) const BigInt* b = &bRef; BigInt c; int wa, wb, wc; - const uint32_t *x = 0, *xa, *xb, *xae, *xbe; - uint32_t *xc, *xc0; + const uint32_t* x = 0; + const uint32_t* xa; + const uint32_t* xb; + const uint32_t* xae; + const uint32_t* xbe; + uint32_t* xc; + uint32_t* xc0; uint32_t y; #ifdef USE_LONG_LONG unsigned long long carry, z; @@ -521,7 +535,7 @@ static void mult(BigInt& aRef, const BigInt& bRef) carry = z >> 16; uint32_t z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; carry = z2 >> 16; - Storeinc(xc, z2, z); + xc = storeInc(xc, z2, z); } while (x < xae); *xc = carry; } @@ -533,7 +547,7 @@ static void mult(BigInt& aRef, const BigInt& bRef) do { z = (*x & 0xffff) * y + (*xc >> 16) + carry; carry = z >> 16; - Storeinc(xc, z, z2); + xc = storeInc(xc, z, z2); z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; carry = z2 >> 16; } while (x < xae); @@ -541,7 +555,7 @@ static void mult(BigInt& aRef, const BigInt& bRef) } } #else - for(; xb < xbe; xc0++) { + for (; xb < xbe; xc0++) { if ((y = *xb++)) { x = xa; xc = xc0; @@ -567,7 +581,7 @@ struct P5Node : Noncopyable { }; static P5Node* p5s; -static int p5s_count; +static int p5sCount; static ALWAYS_INLINE void pow5mult(BigInt& b, int k) { @@ -590,14 +604,14 @@ static ALWAYS_INLINE void pow5mult(BigInt& b, int k) i2b(p5->val, 625); p5->next = 0; p5s = p5; - p5s_count = 1; + p5sCount = 1; } - int p5s_count_local = p5s_count; + int p5sCountLocal = p5sCount; #if ENABLE(JSC_MULTIPLE_THREADS) s_dtoaP5Mutex->unlock(); #endif - int p5s_used = 0; + int p5sUsed = 0; for (;;) { if (k & 1) @@ -606,20 +620,20 @@ static ALWAYS_INLINE void pow5mult(BigInt& b, int k) if (!(k >>= 1)) break; - if (++p5s_used == p5s_count_local) { + if (++p5sUsed == p5sCountLocal) { #if ENABLE(JSC_MULTIPLE_THREADS) s_dtoaP5Mutex->lock(); #endif - if (p5s_used == p5s_count) { + if (p5sUsed == p5sCount) { ASSERT(!p5->next); p5->next = new P5Node; p5->next->next = 0; p5->next->val = p5->val; mult(p5->next->val, p5->next->val); - ++p5s_count; + ++p5sCount; } - p5s_count_local = p5s_count; + p5sCountLocal = p5sCount; #if ENABLE(JSC_MULTIPLE_THREADS) s_dtoaP5Mutex->unlock(); #endif @@ -659,7 +673,7 @@ static ALWAYS_INLINE void lshift(BigInt& b, int k) *dst = hiSubword; ASSERT(dst == dstStart + n); - b.resize(origSize + n + (b.words()[n1 - 1] != 0)); + b.resize(origSize + n + !!b.words()[n1 - 1]); } #else if (k &= 0xf) { @@ -671,9 +685,9 @@ static ALWAYS_INLINE void lshift(BigInt& b, int k) } *dst = hiSubword; ASSERT(dst == dstStart + n); - result->wds = b->wds + n + (result->x[n1 - 1] != 0); + result->wds = b->wds + n + !!result->x[n1 - 1]; } - #endif +#endif else { do { *--dst = *src--; @@ -714,7 +728,7 @@ static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef const BigInt* a = &aRef; const BigInt* b = &bRef; int i, wa, wb; - uint32_t *xc; + uint32_t* xc; i = cmp(*a, *b); if (!i) { @@ -761,14 +775,14 @@ static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef borrow = (y & 0x10000) >> 16; uint32_t z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); + xc = storeInc(xc, z, y); } while (xb < xbe); while (xa < xae) { uint32_t y = (*xa & 0xffff) - borrow; borrow = (y & 0x10000) >> 16; uint32_t z = (*xa++ >> 16) - borrow; borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); + xc = storeInc(xc, z, y); } #else do { @@ -843,7 +857,7 @@ static double b2d(const BigInt& a, int* e) d0 = Exp_1 | (y >> (Ebits - k)); w = xa > xa0 ? *--xa : 0; d1 = (y << (32 - Ebits + k)) | (w >> (Ebits - k)); - goto ret_d; + goto returnD; } z = xa > xa0 ? *--xa : 0; if (k -= Ebits) { @@ -861,7 +875,7 @@ static double b2d(const BigInt& a, int* e) w = xa > xa0 ? *--xa : 0; y = xa > xa0 ? *--xa : 0; d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; - goto ret_d; + goto returnD; } z = xa > xa0 ? *--xa : 0; w = xa > xa0 ? *--xa : 0; @@ -870,7 +884,7 @@ static double b2d(const BigInt& a, int* e) y = xa > xa0 ? *--xa : 0; d1 = w << k + 16 | y << k; #endif -ret_d: +returnD: #undef d0 #undef d1 return dval(&d); @@ -879,7 +893,8 @@ ret_d: static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits) { int de, k; - uint32_t *x, y, z; + uint32_t* x; + uint32_t y, z; #ifndef Sudden_Underflow int i; #endif @@ -1115,27 +1130,28 @@ double strtod(const char* s00, char** se) sign = nz0 = nz = 0; dval(&rv) = 0; - for (s = s00; ; s++) + for (s = s00; ; s++) { switch (*s) { - case '-': - sign = 1; - /* no break */ - case '+': - if (*++s) - goto break2; - /* no break */ - case 0: - goto ret0; - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - case ' ': - continue; - default: + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) goto break2; + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; } + } break2: if (*s == '0') { nz0 = 1; @@ -1160,12 +1176,12 @@ break2: s0 = s; nf += nz; nz = 0; - goto have_dig; + goto haveDig; } - goto dig_done; + goto digDone; } for (; c >= '0' && c <= '9'; c = *++s) { -have_dig: +haveDig: nz++; if (c -= '0') { nf += nz; @@ -1182,19 +1198,18 @@ have_dig: } } } -dig_done: +digDone: e = 0; if (c == 'e' || c == 'E') { - if (!nd && !nz && !nz0) { + if (!nd && !nz && !nz0) goto ret0; - } s00 = s; esign = 0; switch (c = *++s) { - case '-': - esign = 1; - case '+': - c = *++s; + case '-': + esign = 1; + case '+': + c = *++s; } if (c >= '0' && c <= '9') { while (c == '0') @@ -1222,29 +1237,29 @@ dig_done: if (!nz && !nz0) { #ifdef INFNAN_CHECK /* Check for Nan and Infinity */ - switch(c) { - case 'i': - case 'I': - if (match(&s,"nf")) { - --s; - if (!match(&s,"inity")) - ++s; - word0(&rv) = 0x7ff00000; - word1(&rv) = 0; - goto ret; - } - break; - case 'n': - case 'N': - if (match(&s, "an")) { - word0(&rv) = NAN_WORD0; - word1(&rv) = NAN_WORD1; + switch (c) { + case 'i': + case 'I': + if (match(&s, "nf")) { + --s; + if (!match(&s, "inity")) + ++s; + word0(&rv) = 0x7ff00000; + word1(&rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + word0(&rv) = NAN_WORD0; + word1(&rv) = NAN_WORD1; #ifndef No_Hex_NaN - if (*s == '(') /*)*/ - hexnan(&rv, &s); + if (*s == '(') /*)*/ + hexnan(&rv, &s); #endif - goto ret; - } + goto ret; + } } #endif /* INFNAN_CHECK */ ret0: @@ -1498,10 +1513,10 @@ undfl: } lshift(delta, Log2P); if (cmp(delta, bs) > 0) - goto drop_down; + goto dropDown; break; } - if (i == 0) { + if (!i) { /* exactly half-way between */ if (dsign) { if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 @@ -1520,7 +1535,7 @@ undfl: break; } } else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { -drop_down: +dropDown: /* boundary case -- decrement exponent */ #ifdef Sudden_Underflow /*{{*/ L = word0(&rv) & Exp_mask; @@ -1592,15 +1607,15 @@ drop_down: aadj1 = dsign ? aadj : -aadj; #ifdef Check_FLT_ROUNDS switch (Rounding) { - case 2: /* towards +infinity */ - aadj1 -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - aadj1 += 0.5; + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; } #else - if (Flt_Rounds == 0) + if (!Flt_Rounds) aadj1 += 0.5; #endif /*Check_FLT_ROUNDS*/ } @@ -1619,8 +1634,8 @@ drop_down: word0(&rv) = Big0; word1(&rv) = Big1; goto cont; - } else - word0(&rv) += P * Exp_msk1; + } + word0(&rv) += P * Exp_msk1; } else { #ifdef Avoid_Underflow if (scale && y <= 2 * P * Exp_msk1) { @@ -1643,16 +1658,14 @@ drop_down: word0(&rv) += P * Exp_msk1; adj.d = aadj1 * ulp(&rv); dval(&rv) += adj.d; - if ((word0(&rv) & Exp_mask) <= P * Exp_msk1) - { + if ((word0(&rv) & Exp_mask) <= P * Exp_msk1) { if (word0(&rv0) == Tiny0 && word1(&rv0) == Tiny1) goto undfl; word0(&rv) = Tiny0; word1(&rv) = Tiny1; goto cont; } - else - word0(&rv) -= P * Exp_msk1; + word0(&rv) -= P * Exp_msk1; } else { adj.d = aadj1 * ulp(&rv); dval(&rv) += adj.d; @@ -1693,7 +1706,7 @@ drop_down: } #endif cont: - ; + {} } #ifdef SET_INEXACT if (inexact) { @@ -1712,7 +1725,7 @@ cont: dval(&rv) *= dval(&rv0); #ifndef NO_ERRNO /* try to avoid the bug of testing an 8087 register value */ - if (word0(&rv) == 0 && word1(&rv) == 0) + if (!word0(&rv) && !word1(&rv)) errno = ERANGE; #endif } @@ -1733,7 +1746,11 @@ ret: static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) { size_t n; - uint32_t *bx, *bxe, q, *sx, *sxe; + uint32_t* bx; + uint32_t* bxe; + uint32_t q; + uint32_t* sx; + uint32_t* sxe; #ifdef USE_LONG_LONG unsigned long long borrow, carry, y, ys; #else @@ -1775,7 +1792,7 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) borrow = (y & 0x10000) >> 16; z = (*bx >> 16) - (zs & 0xffff) - borrow; borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); + bx = storeInc(bx, z, y); #else ys = *sx++ * q + carry; carry = ys >> 16; @@ -1815,7 +1832,7 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) borrow = (y & 0x10000) >> 16; z = (*bx >> 16) - (zs & 0xffff) - borrow; borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); + bx = storeInc(bx, z, y); #else ys = *sx++ + carry; carry = ys >> 16; @@ -1892,7 +1909,8 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char BigInt b, b1, delta, mlo, mhi, S; U d2, eps, u; double ds; - char *s, *s0; + char* s; + char* s0; #ifdef SET_INEXACT int inexact, oldinexact; #endif @@ -1905,8 +1923,7 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char } else *sign = 0; - if ((word0(&u) & Exp_mask) == Exp_mask) - { + if ((word0(&u) & Exp_mask) == Exp_mask) { /* Infinity or NaN */ *decpt = 9999; if (!word1(&u) && !(word0(&u) & 0xfffff)) { @@ -2059,7 +2076,7 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char } if (k_check && dval(&u) < 1. && ilim > 0) { if (ilim1 <= 0) - goto fast_failed; + goto fastFailed; ilim = ilim1; k--; dval(&u) *= 10.; @@ -2067,15 +2084,15 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char } dval(&eps) = (ieps * dval(&u)) + 7.; word0(&eps) -= (P - 1) * Exp_msk1; - if (ilim == 0) { + if (!ilim) { S.clear(); mhi.clear(); dval(&u) -= 5.; if (dval(&u) > dval(&eps)) - goto one_digit; + goto oneDigit; if (dval(&u) < -dval(&eps)) - goto no_digits; - goto fast_failed; + goto noDigits; + goto fastFailed; } #ifndef No_leftright if (leftright) { @@ -2090,7 +2107,7 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char if (dval(&u) < dval(&eps)) goto ret; if (1. - dval(&u) < dval(&eps)) - goto bump_up; + goto bumpUp; if (++i >= ilim) break; dval(&eps) *= 10.; @@ -2107,8 +2124,8 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char *s++ = '0' + (int)L; if (i == ilim) { if (dval(&u) > 0.5 + dval(&eps)) - goto bump_up; - else if (dval(&u) < 0.5 - dval(&eps)) { + goto bumpUp; + if (dval(&u) < 0.5 - dval(&eps)) { while (*--s == '0') { } s++; goto ret; @@ -2119,7 +2136,7 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char #ifndef No_leftright } #endif -fast_failed: +fastFailed: s = s0; dval(&u) = dval(&d2); k = k0; @@ -2135,8 +2152,8 @@ fast_failed: S.clear(); mhi.clear(); if (ilim < 0 || dval(&u) <= 5 * ds) - goto no_digits; - goto one_digit; + goto noDigits; + goto oneDigit; } for (i = 1;; i++, dval(&u) *= 10.) { L = (int32_t)(dval(&u) / ds); @@ -2158,7 +2175,7 @@ fast_failed: if (i == ilim) { dval(&u) += dval(&u); if (dval(&u) > ds || (dval(&u) == ds && (L & 1))) { -bump_up: +bumpUp: while (*--s == '9') if (s == s0) { k++; @@ -2252,7 +2269,7 @@ bump_up: if (s2 > 0) lshift(S, s2); if (k_check) { - if (cmp(b,S) < 0) { + if (cmp(b, S) < 0) { k--; multadd(b, 10, 0); /* we botched the k estimate */ if (leftright) @@ -2276,16 +2293,16 @@ bump_up: } for (i = 1;;i++) { - dig = quorem(b,S) + '0'; + dig = quorem(b, S) + '0'; /* Do we yet have the shortest decimal string * that will round to d? */ j = cmp(b, mlo); diff(delta, S, mhi); j1 = delta.sign ? 1 : cmp(b, delta); - if (j1 == 0 && !(word1(&u) & 1)) { + if (!j1 && !(word1(&u) & 1)) { if (dig == '9') - goto round_9_up; + goto round9up; if (j > 0) dig++; #ifdef SET_INEXACT @@ -2295,26 +2312,26 @@ bump_up: *s++ = dig; goto ret; } - if (j < 0 || (j == 0 && !(word1(&u) & 1))) { + if (j < 0 || (!j && !(word1(&u) & 1))) { if (!b.words()[0] && b.size() <= 1) { #ifdef SET_INEXACT inexact = 0; #endif - goto accept_dig; + goto acceptDig; } if (j1 > 0) { lshift(b, 1); j1 = cmp(b, S); - if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ == '9') - goto round_9_up; + if ((j1 > 0 || (!j1 && (dig & 1))) && dig++ == '9') + goto round9up; } -accept_dig: +acceptDig: *s++ = dig; goto ret; } if (j1 > 0) { if (dig == '9') { /* possible if i == 1 */ -round_9_up: +round9up: *s++ = '9'; goto roundoff; } @@ -2330,7 +2347,7 @@ round_9_up: } } else for (i = 1;; i++) { - *s++ = dig = quorem(b,S) + '0'; + *s++ = dig = quorem(b, S) + '0'; if (!b.words()[0] && b.size() <= 1) { #ifdef SET_INEXACT inexact = 0; @@ -2346,7 +2363,7 @@ round_9_up: lshift(b, 1); j = cmp(b, S); - if (j > 0 || (j == 0 && (dig & 1))) { + if (j > 0 || (!j && (dig & 1))) { roundoff: while (*--s == '9') if (s == s0) { @@ -2360,10 +2377,10 @@ roundoff: s++; } goto ret; -no_digits: +noDigits: k = -1 - ndigits; goto ret; -one_digit: +oneDigit: *s++ = '1'; k++; goto ret; |