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); |
} |