Chromium Code Reviews| Index: src/assembler.cc |
| =================================================================== |
| --- src/assembler.cc (revision 5940) |
| +++ src/assembler.cc (working copy) |
| @@ -66,6 +66,7 @@ |
| const double DoubleConstant::min_int = kMinInt; |
| const double DoubleConstant::one_half = 0.5; |
| +const double DoubleConstant::negative_infinity = -V8_INFINITY; |
| // ----------------------------------------------------------------------------- |
| @@ -722,6 +723,12 @@ |
| } |
| +ExternalReference ExternalReference::address_of_negative_infinity() { |
| + return ExternalReference(reinterpret_cast<void*>( |
| + const_cast<double*>(&DoubleConstant::negative_infinity))); |
| +} |
| + |
| + |
| #ifndef V8_INTERPRETED_REGEXP |
| ExternalReference ExternalReference::re_check_stack_guard_state() { |
| @@ -793,6 +800,58 @@ |
| } |
|
fschneider
2010/12/08 11:27:07
It would be good to not duplicate code between her
William Hesse
2010/12/08 13:37:00
Done.
|
| +// Helper function to compute x^y, where y is known to be an |
| +// integer. Uses binary decomposition to limit the number of |
| +// multiplications; see the discussion in "Hacker's Delight" by Henry |
| +// S. Warren, Jr., figure 11-6, page 213. |
| +static double powi(double x, int y) { |
| + unsigned n = (y < 0) ? -y : y; |
| + double m = x; |
| + double p = 1; |
| + while (n != 0) { |
| + if ((n & 1) != 0) p *= m; |
| + m *= m; |
| + if ((n & 2) != 0) p *= m; |
| + m *= m; |
| + n >>= 2; |
| + } |
| + if (y < 0) { |
| + // Unfortunately, we have to be careful when p has reached |
| + // infinity in the computation, because sometimes the higher |
| + // internal precision in the pow() implementation would have |
| + // given us a finite p. This happens very rarely. |
| + double result = 1.0 / p; |
| + return (result == 0 && isinf(p)) |
| + ? pow(x, static_cast<double>(y)) // Avoid pow(double, int). |
| + : result; |
| + } else { |
| + return p; |
| + } |
| +} |
| + |
| + |
| +static double power_two_doubles(double x, double y) { |
| + int y_int = static_cast<int>(y); |
| + if (y == y_int) { |
| + return powi(x, y_int); |
| + } |
| + if (!isinf(x)) { |
| + if (y == 0.5) return sqrt(x); |
| + if (y == -0.5) return 1.0 / sqrt(x); |
| + } |
| + if (y == 0) return 1.0; |
| + if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { |
| + return OS::nan_value(); |
| + } |
| + return pow(x, y); |
| +} |
| + |
| + |
| +static double power_double_int(double x, int y) { |
| + return powi(x, y); |
| +} |
| + |
| + |
| static int native_compare_doubles(double y, double x) { |
| if (x == y) return EQUAL; |
| return x < y ? LESS : GREATER; |
| @@ -819,6 +878,12 @@ |
| case Token::MOD: |
| function = &mod_two_doubles; |
| break; |
| + case Token::BIT_XOR: |
|
Kevin Millikin (Chromium)
2010/12/08 10:01:46
Don't repurpose these tokens this way, it's a bug
William Hesse
2010/12/08 13:37:00
I removed the power case. Did not change the exis
|
| + function = &power_two_doubles; |
| + break; |
| + case Token::BIT_OR: |
| + function = reinterpret_cast<BinaryFPOperation*>(&power_double_int); |
| + break; |
| default: |
| UNREACHABLE(); |
| } |