| Index: src/x64/code-stubs-x64.cc
|
| diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
|
| index b89438f36572f889409230ba666569109a218b0f..b38715a0d8dbbbc6f69ac3b037f557937f068ead 100644
|
| --- a/src/x64/code-stubs-x64.cc
|
| +++ b/src/x64/code-stubs-x64.cc
|
| @@ -214,7 +214,6 @@ void FloatingPointHelper::LoadSSE2UnknownOperands(MacroAssembler* masm,
|
| void MathPowStub::Generate(MacroAssembler* masm) {
|
| const Register exponent = MathPowTaggedDescriptor::exponent();
|
| DCHECK(exponent.is(rdx));
|
| - const Register base = rax;
|
| const Register scratch = rcx;
|
| const XMMRegister double_result = xmm3;
|
| const XMMRegister double_base = xmm2;
|
| @@ -227,37 +226,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
| __ movp(scratch, Immediate(1));
|
| __ Cvtlsi2sd(double_result, scratch);
|
|
|
| - if (exponent_type() == ON_STACK) {
|
| - Label base_is_smi, unpack_exponent;
|
| - // The exponent and base are supplied as arguments on the stack.
|
| - // This can only happen if the stub is called from non-optimized code.
|
| - // Load input parameters from stack.
|
| - StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
|
| - __ movp(base, args.GetArgumentOperand(0));
|
| - __ movp(exponent, args.GetArgumentOperand(1));
|
| - __ JumpIfSmi(base, &base_is_smi, Label::kNear);
|
| - __ CompareRoot(FieldOperand(base, HeapObject::kMapOffset),
|
| - Heap::kHeapNumberMapRootIndex);
|
| - __ j(not_equal, &call_runtime);
|
| -
|
| - __ Movsd(double_base, FieldOperand(base, HeapNumber::kValueOffset));
|
| - __ jmp(&unpack_exponent, Label::kNear);
|
| -
|
| - __ bind(&base_is_smi);
|
| - __ SmiToInteger32(base, base);
|
| - __ Cvtlsi2sd(double_base, base);
|
| - __ bind(&unpack_exponent);
|
| -
|
| - __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
|
| - __ SmiToInteger32(exponent, exponent);
|
| - __ jmp(&int_exponent);
|
| -
|
| - __ bind(&exponent_not_smi);
|
| - __ CompareRoot(FieldOperand(exponent, HeapObject::kMapOffset),
|
| - Heap::kHeapNumberMapRootIndex);
|
| - __ j(not_equal, &call_runtime);
|
| - __ Movsd(double_exponent, FieldOperand(exponent, HeapNumber::kValueOffset));
|
| - } else if (exponent_type() == TAGGED) {
|
| + if (exponent_type() == TAGGED) {
|
| __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
|
| __ SmiToInteger32(exponent, exponent);
|
| __ jmp(&int_exponent);
|
| @@ -281,76 +250,6 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
| __ cmpl(exponent, Immediate(0x1));
|
| __ j(overflow, &call_runtime);
|
|
|
| - 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.
|
| - Label continue_sqrt, continue_rsqrt, not_plus_half;
|
| - // Test for 0.5.
|
| - // Load double_scratch with 0.5.
|
| - __ movq(scratch, V8_UINT64_C(0x3FE0000000000000));
|
| - __ Movq(double_scratch, scratch);
|
| - // Already ruled out NaNs for exponent.
|
| - __ Ucomisd(double_scratch, double_exponent);
|
| - __ j(not_equal, ¬_plus_half, Label::kNear);
|
| -
|
| - // Calculates square root of base. Check for the special case of
|
| - // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13).
|
| - // According to IEEE-754, double-precision -Infinity has the highest
|
| - // 12 bits set and the lowest 52 bits cleared.
|
| - __ movq(scratch, V8_UINT64_C(0xFFF0000000000000));
|
| - __ Movq(double_scratch, scratch);
|
| - __ Ucomisd(double_scratch, double_base);
|
| - // 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(carry, &continue_sqrt, Label::kNear);
|
| -
|
| - // Set result to Infinity in the special case.
|
| - __ Xorpd(double_result, double_result);
|
| - __ Subsd(double_result, double_scratch);
|
| - __ jmp(&done);
|
| -
|
| - __ bind(&continue_sqrt);
|
| - // sqrtsd returns -0 when input is -0. ECMA spec requires +0.
|
| - __ Xorpd(double_scratch, double_scratch);
|
| - __ Addsd(double_scratch, double_base); // Convert -0 to 0.
|
| - __ Sqrtsd(double_result, double_scratch);
|
| - __ jmp(&done);
|
| -
|
| - // Test for -0.5.
|
| - __ bind(¬_plus_half);
|
| - // Load double_scratch with -0.5 by substracting 1.
|
| - __ Subsd(double_scratch, double_result);
|
| - // Already ruled out NaNs for exponent.
|
| - __ Ucomisd(double_scratch, double_exponent);
|
| - __ j(not_equal, &fast_power, Label::kNear);
|
| -
|
| - // Calculates reciprocal of square root of base. Check for the special
|
| - // case of Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13).
|
| - // According to IEEE-754, double-precision -Infinity has the highest
|
| - // 12 bits set and the lowest 52 bits cleared.
|
| - __ movq(scratch, V8_UINT64_C(0xFFF0000000000000));
|
| - __ Movq(double_scratch, scratch);
|
| - __ Ucomisd(double_scratch, double_base);
|
| - // 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(carry, &continue_rsqrt, Label::kNear);
|
| -
|
| - // Set result to 0 in the special case.
|
| - __ Xorpd(double_result, double_result);
|
| - __ jmp(&done);
|
| -
|
| - __ bind(&continue_rsqrt);
|
| - // sqrtsd returns -0 when input is -0. ECMA spec requires +0.
|
| - __ Xorpd(double_exponent, double_exponent);
|
| - __ Addsd(double_exponent, double_base); // Convert -0 to +0.
|
| - __ Sqrtsd(double_exponent, double_exponent);
|
| - __ Divsd(double_result, double_exponent);
|
| - __ jmp(&done);
|
| - }
|
| -
|
| // Using FPU instructions to calculate power.
|
| Label fast_power_failed;
|
| __ bind(&fast_power);
|
| @@ -439,34 +338,21 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
| __ Cvtlsi2sd(double_exponent, exponent);
|
|
|
| // Returning or bailing out.
|
| - if (exponent_type() == ON_STACK) {
|
| - // The arguments are still on the stack.
|
| - __ bind(&call_runtime);
|
| - __ TailCallRuntime(Runtime::kMathPowRT);
|
| -
|
| - // The stub is called from non-optimized code, which expects the result
|
| - // as heap number in rax.
|
| - __ bind(&done);
|
| - __ AllocateHeapNumber(rax, rcx, &call_runtime);
|
| - __ Movsd(FieldOperand(rax, HeapNumber::kValueOffset), double_result);
|
| - __ ret(2 * kPointerSize);
|
| - } else {
|
| - __ bind(&call_runtime);
|
| - // Move base to the correct argument register. Exponent is already in xmm1.
|
| - __ Movsd(xmm0, double_base);
|
| - DCHECK(double_exponent.is(xmm1));
|
| - {
|
| - AllowExternalCallThatCantCauseGC scope(masm);
|
| - __ PrepareCallCFunction(2);
|
| - __ CallCFunction(
|
| - ExternalReference::power_double_double_function(isolate()), 2);
|
| - }
|
| - // Return value is in xmm0.
|
| - __ Movsd(double_result, xmm0);
|
| -
|
| - __ bind(&done);
|
| - __ ret(0);
|
| + __ bind(&call_runtime);
|
| + // Move base to the correct argument register. Exponent is already in xmm1.
|
| + __ Movsd(xmm0, double_base);
|
| + DCHECK(double_exponent.is(xmm1));
|
| + {
|
| + AllowExternalCallThatCantCauseGC scope(masm);
|
| + __ PrepareCallCFunction(2);
|
| + __ CallCFunction(ExternalReference::power_double_double_function(isolate()),
|
| + 2);
|
| }
|
| + // Return value is in xmm0.
|
| + __ Movsd(double_result, xmm0);
|
| +
|
| + __ bind(&done);
|
| + __ ret(0);
|
| }
|
|
|
|
|
|
|