Commit 72827079 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Fixing mozilla test failures regarding Math.pow.

BUG=
TEST=

Review URL: http://codereview.chromium.org/8820011

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10177 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 32ee3c27
...@@ -2997,7 +2997,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -2997,7 +2997,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ cmp(eax, Immediate(0x80000000u)); __ cmp(eax, Immediate(0x80000000u));
__ j(equal, &generic_runtime); __ j(equal, &generic_runtime);
__ cvtsi2sd(xmm4, eax); __ cvtsi2sd(xmm4, eax);
__ ucomisd(xmm2, xmm4); __ ucomisd(xmm2, xmm4); // Already ruled out NaNs for exponent.
__ j(equal, &int_exponent); __ j(equal, &int_exponent);
if (exponent_type_ == ON_STACK) { if (exponent_type_ == ON_STACK) {
...@@ -3011,7 +3011,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -3011,7 +3011,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ movd(xmm4, ecx); __ movd(xmm4, ecx);
__ cvtss2sd(xmm4, xmm4); __ cvtss2sd(xmm4, xmm4);
// xmm4 now has 0.5. // xmm4 now has 0.5.
__ ucomisd(xmm4, xmm2); __ ucomisd(xmm4, xmm2); // Already ruled out NaNs for exponent.
__ j(not_equal, &not_plus_half, Label::kNear); __ j(not_equal, &not_plus_half, Label::kNear);
// Calculates square root of base. Check for the special case of // Calculates square root of base. Check for the special case of
...@@ -3022,7 +3022,10 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -3022,7 +3022,10 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ movd(xmm4, ecx); __ movd(xmm4, ecx);
__ cvtss2sd(xmm4, xmm4); __ cvtss2sd(xmm4, xmm4);
__ ucomisd(xmm1, xmm4); __ ucomisd(xmm1, xmm4);
// Comparing -Infinity with NaN results in "unordered", which sets the
// zero flag as if both were equal. However, it also sets the carry flag.
__ j(not_equal, &continue_sqrt, Label::kNear); __ j(not_equal, &continue_sqrt, Label::kNear);
__ j(carry, &continue_sqrt, Label::kNear);
// Set result to Infinity in the special case. // Set result to Infinity in the special case.
__ xorps(xmm3, xmm3); __ xorps(xmm3, xmm3);
...@@ -3042,7 +3045,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -3042,7 +3045,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
// Since xmm3 is 1 and xmm4 is 0.5 this is simply xmm4 - xmm3. // Since xmm3 is 1 and xmm4 is 0.5 this is simply xmm4 - xmm3.
__ subsd(xmm4, xmm3); __ subsd(xmm4, xmm3);
// xmm4 now has -0.5. // xmm4 now has -0.5.
__ ucomisd(xmm4, xmm2); __ ucomisd(xmm4, xmm2); // Already ruled out NaNs for exponent.
__ j(not_equal, &fast_power, Label::kNear); __ j(not_equal, &fast_power, Label::kNear);
// Calculates reciprocal of square root of base. Check for the special // Calculates reciprocal of square root of base. Check for the special
...@@ -3053,7 +3056,10 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -3053,7 +3056,10 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ movd(xmm4, ecx); __ movd(xmm4, ecx);
__ cvtss2sd(xmm4, xmm4); __ cvtss2sd(xmm4, xmm4);
__ ucomisd(xmm1, xmm4); __ ucomisd(xmm1, xmm4);
// Comparing -Infinity with NaN results in "unordered", which sets the
// zero flag as if both were equal. However, it also sets the carry flag.
__ j(not_equal, &continue_rsqrt, Label::kNear); __ j(not_equal, &continue_rsqrt, Label::kNear);
__ j(carry, &continue_rsqrt, Label::kNear);
// Set result to 0 in the special case. // Set result to 0 in the special case.
__ xorps(xmm3, xmm3); __ xorps(xmm3, xmm3);
...@@ -3143,7 +3149,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -3143,7 +3149,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
// Test whether result is zero. Bail out to check for subnormal result. // Test whether result is zero. Bail out to check for subnormal result.
// Due to subnormals, x^-y == (1/x)^y does not hold in all cases. // Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
__ xorps(xmm2, xmm2); __ xorps(xmm2, xmm2);
__ ucomisd(xmm2, xmm3); __ ucomisd(xmm2, xmm3); // Result cannot be NaN.
__ j(equal, &double_int_runtime); __ j(equal, &double_int_runtime);
// Returning or bailing out. // Returning or bailing out.
......
...@@ -2970,7 +2970,10 @@ void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { ...@@ -2970,7 +2970,10 @@ void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
__ movd(xmm_scratch, scratch); __ movd(xmm_scratch, scratch);
__ cvtss2sd(xmm_scratch, xmm_scratch); __ cvtss2sd(xmm_scratch, xmm_scratch);
__ ucomisd(input_reg, xmm_scratch); __ ucomisd(input_reg, xmm_scratch);
// Comparing -Infinity with NaN results in "unordered", which sets the
// zero flag as if both were equal. However, it also sets the carry flag.
__ j(not_equal, &sqrt, Label::kNear); __ j(not_equal, &sqrt, Label::kNear);
__ j(carry, &sqrt, Label::kNear);
// If input is -Infinity, return Infinity. // If input is -Infinity, return Infinity.
__ xorps(input_reg, input_reg); __ xorps(input_reg, input_reg);
__ subsd(input_reg, xmm_scratch); __ subsd(input_reg, xmm_scratch);
......
...@@ -2861,7 +2861,10 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { ...@@ -2861,7 +2861,10 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
__ movq(kScratchRegister, V8_INT64_C(0xFFF0000000000000), RelocInfo::NONE); __ movq(kScratchRegister, V8_INT64_C(0xFFF0000000000000), RelocInfo::NONE);
__ movq(xmm_scratch, kScratchRegister); __ movq(xmm_scratch, kScratchRegister);
__ ucomisd(xmm_scratch, input_reg); __ ucomisd(xmm_scratch, input_reg);
// Comparing -Infinity with NaN results in "unordered", which sets the
// zero flag as if both were equal. However, it also sets the carry flag.
__ j(not_equal, &sqrt, Label::kNear); __ j(not_equal, &sqrt, Label::kNear);
__ j(carry, &sqrt, Label::kNear);
// If input is -Infinity, return Infinity. // If input is -Infinity, return Infinity.
__ xorps(input_reg, input_reg); __ xorps(input_reg, input_reg);
__ subsd(input_reg, xmm_scratch); __ subsd(input_reg, xmm_scratch);
......
...@@ -140,6 +140,20 @@ function test() { ...@@ -140,6 +140,20 @@ function test() {
assertEquals(NaN, Math.pow(-16, 0.5)); assertEquals(NaN, Math.pow(-16, 0.5));
assertEquals(0.25, Math.pow(16, -0.5)); assertEquals(0.25, Math.pow(16, -0.5));
assertEquals(NaN, Math.pow(-16, -0.5)); assertEquals(NaN, Math.pow(-16, -0.5));
// Tests from Mozilla 15.8.2.13.
assertEquals(2, Math.pow.length);
assertEquals(NaN, Math.pow());
assertEquals(1, Math.pow(null, null));
assertEquals(NaN, Math.pow(void 0, void 0));
assertEquals(1, Math.pow(true, false));
assertEquals(0, Math.pow(false, true));
assertEquals(Infinity, Math.pow(-Infinity, Infinity));
assertEquals(0, Math.pow(-Infinity, -Infinity));
assertEquals(1, Math.pow(0, 0));
assertEquals(0, Math.pow(0, Infinity));
assertEquals(NaN, Math.pow(NaN, 0.5));
assertEquals(NaN, Math.pow(NaN, -0.5));
// Tests from Sputnik S8.5_A13_T1. // Tests from Sputnik S8.5_A13_T1.
assertTrue( assertTrue(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment