|
|
@@ -162,6 +162,33 @@ namespace Js
|
|
|
return Is_NoTaggedIntCheck(object) && TryGetInt32Value(GetValue(object), &i) ? i : 0;
|
|
|
}
|
|
|
|
|
|
+ double JavascriptNumber::DirectPowDoubleInt(double x, int32 y)
|
|
|
+ {
|
|
|
+ // For exponent in [-8, 8], aggregate the product according to binary representation
|
|
|
+ // of exponent. This acceleration may lead to significant deviation for larger exponent
|
|
|
+ if (y >= -8 && y <= 8)
|
|
|
+ {
|
|
|
+ uint32 uexp = static_cast<uint32>(y >= 0 ? y : -y);
|
|
|
+ for (double result = 1.0; ; x *= x)
|
|
|
+ {
|
|
|
+ if ((uexp & 1) != 0)
|
|
|
+ {
|
|
|
+ result *= x;
|
|
|
+ }
|
|
|
+ if ((uexp >>= 1) == 0)
|
|
|
+ {
|
|
|
+ return (y < 0 ? (1.0 / result) : result);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+#if _M_IX86
|
|
|
+ return JavascriptNumber::DirectPow(x, static_cast<double>(y));
|
|
|
+#else
|
|
|
+ return ::pow(x, y);
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
#if _M_IX86
|
|
|
|
|
|
extern "C" double __cdecl __libm_sse2_pow(double, double);
|
|
|
@@ -209,7 +236,6 @@ namespace Js
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
#elif defined(_M_AMD64) || defined(_M_ARM32_OR_ARM64)
|
|
|
|
|
|
double JavascriptNumber::DirectPow(double x, double y)
|
|
|
@@ -222,7 +248,6 @@ namespace Js
|
|
|
// For AMD64/ARM calling convention already uses SSE2/VFP registers so we don't have to use assembler.
|
|
|
// We can't just use "if (0 == y)" because NaN compares
|
|
|
// equal to 0 according to our compilers.
|
|
|
- int32 intY;
|
|
|
if (0 == NumberUtilities::LuLoDbl(y) && 0 == (NumberUtilities::LuHiDbl(y) & 0x7FFFFFFF))
|
|
|
{
|
|
|
// pow(x, 0) = 1 even if x is NaN.
|
|
|
@@ -233,30 +258,6 @@ namespace Js
|
|
|
// pow([+/-] 1, Infinity) = NaN according to javascript, but not for CRT pow.
|
|
|
return JavascriptNumber::NaN;
|
|
|
}
|
|
|
- else if(TryGetInt32Value(y, &intY))
|
|
|
- {
|
|
|
- // For exponent in [-8, 8], aggregate the product according to binary representation
|
|
|
- // of exponent. This acceleration may lead to significant deviation for larger exponent
|
|
|
- if (intY >= -8 && intY <= 8)
|
|
|
- {
|
|
|
- uint32 uexp = static_cast<uint32>(intY >= 0 ? intY : -intY);
|
|
|
- for (double result = 1.0; ; x *= x)
|
|
|
- {
|
|
|
- if ((uexp & 1) != 0)
|
|
|
- {
|
|
|
- result *= x;
|
|
|
- }
|
|
|
- if ((uexp >>= 1) == 0)
|
|
|
- {
|
|
|
- return (intY < 0 ? (1.0 / result) : result);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- return ::pow(x, intY);
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
return ::pow(x, y);
|
|
|
}
|