Chromium Code Reviews| Index: src/assembler.cc |
| =================================================================== |
| --- src/assembler.cc (revision 5948) |
| +++ 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,51 @@ |
| } |
| +// 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. |
| +double power_double_int(double x, int y) { |
| + double m = (y < 0) ? 1/x : x; |
|
Florian Schneider
2010/12/08 14:09:27
--> 1 / x
William Hesse
2010/12/08 14:53:16
Done.
|
| + unsigned n = (y < 0) ? -y : y; |
| + double p = 1; |
| + while (n != 0) { |
| + if ((n & 1) != 0) p *= m; |
| + m *= m; |
| + if ((n & 2) != 0) p *= m; |
| + m *= m; |
| + n >>= 2; |
| + } |
| + return p; |
| +} |
| + |
| + |
| +double power_double_double(double x, double y) { |
| + int y_int = static_cast<int>(y); |
| + if (y == y_int) { |
| + return power_double_int(x, y_int); // Returns 1.0 for exponent 0. |
| + } |
| + if (!isinf(x)) { |
| + if (y == 0.5) return sqrt(x); |
| + if (y == -0.5) return 1.0 / sqrt(x); |
| + } |
| + if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { |
| + return OS::nan_value(); |
| + } |
| + return pow(x, y); |
| +} |
| + |
| + |
| +ExternalReference ExternalReference::power_double_double_function() { |
| + return ExternalReference(Redirect(FUNCTION_ADDR(power_double_double))); |
| +} |
| + |
| + |
| +ExternalReference ExternalReference::power_double_int_function() { |
| + return ExternalReference(Redirect(FUNCTION_ADDR(power_double_int))); |
| +} |
| + |
| + |
| static int native_compare_doubles(double y, double x) { |
| if (x == y) return EQUAL; |
| return x < y ? LESS : GREATER; |