From 5e432754b352f75c3ea0caa7287fbb3f4767950a Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Tue, 6 Dec 2011 09:20:28 +0000 Subject: [PATCH] Skip check for +/-0.5 in optimized Math.pow (ia32). Review URL: http://codereview.chromium.org/8820007 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10168 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ia32/code-stubs-ia32.cc | 65 ++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 0afc9cc6e0..c9d8cfd4d5 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -3025,38 +3025,43 @@ void MathPowStub::Generate(MacroAssembler* masm) { __ ucomisd(xmm2, xmm4); __ j(equal, &int_exponent); - // Detect square root case. - // Test for -0.5. - // Load xmm4 with -0.5. - __ mov(ecx, Immediate(0xBF000000u)); - __ movd(xmm4, ecx); - __ cvtss2sd(xmm4, xmm4); - // xmm3 now has -0.5. - __ ucomisd(xmm4, xmm2); - __ j(not_equal, ¬_minus_half, Label::kNear); + if (exponent_type_ == ON_STACK) { + // Detect square root case. Crankshaft detects constant +/-0.5 at + // compile time and uses DoMathPowHalf instead. We then skip this check + // for non-constant cases of +/-0.5 as these hardly occur. - // Calculates reciprocal of square root.eax - // sqrtsd returns -0 when input is -0. ECMA spec requires +0. - __ xorps(xmm2, xmm2); - __ addsd(xmm2, xmm1); - __ sqrtsd(xmm2, xmm2); - __ divsd(xmm3, xmm2); - __ jmp(&done); + // Test for -0.5. + // Load xmm4 with -0.5. + __ mov(ecx, Immediate(0xBF000000u)); + __ movd(xmm4, ecx); + __ cvtss2sd(xmm4, xmm4); + // xmm3 now has -0.5. + __ ucomisd(xmm4, xmm2); + __ j(not_equal, ¬_minus_half, Label::kNear); - // Test for 0.5. - __ bind(¬_minus_half); - // Load xmm2 with 0.5. - // Since xmm3 is 1 and xmm4 is -0.5 this is simply xmm4 + xmm3. - __ addsd(xmm4, xmm3); - // xmm2 now has 0.5. - __ ucomisd(xmm4, xmm2); - __ j(not_equal, &fast_power, Label::kNear); - // Calculates square root. - // sqrtsd returns -0 when input is -0. ECMA spec requires +0. - __ xorps(xmm4, xmm4); - __ addsd(xmm4, xmm1); - __ sqrtsd(xmm3, xmm4); - __ jmp(&done); + // Calculates reciprocal of square root.eax + // sqrtsd returns -0 when input is -0. ECMA spec requires +0. + __ xorps(xmm2, xmm2); + __ addsd(xmm2, xmm1); + __ sqrtsd(xmm2, xmm2); + __ divsd(xmm3, xmm2); + __ jmp(&done); + + // Test for 0.5. + __ bind(¬_minus_half); + // Load xmm2 with 0.5. + // Since xmm3 is 1 and xmm4 is -0.5 this is simply xmm4 + xmm3. + __ addsd(xmm4, xmm3); + // xmm2 now has 0.5. + __ ucomisd(xmm4, xmm2); + __ j(not_equal, &fast_power, Label::kNear); + // Calculates square root. + // sqrtsd returns -0 when input is -0. ECMA spec requires +0. + __ xorps(xmm4, xmm4); + __ addsd(xmm4, xmm1); + __ sqrtsd(xmm3, xmm4); + __ jmp(&done); + } // Using FPU instructions to calculate power. Label fast_power_failed;