Chromium Code Reviews| Index: src/ia32/code-stubs-ia32.cc |
| diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc |
| index 08bbbc036d638c065bb0c71585259644d579f435..210d8cf320108e8f0eafd4c74317c2c29e80a23a 100644 |
| --- a/src/ia32/code-stubs-ia32.cc |
| +++ b/src/ia32/code-stubs-ia32.cc |
| @@ -2948,8 +2948,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { |
| const XMMRegister double_exponent = xmm1; |
| const XMMRegister double_scratch = xmm4; |
| - Label double_int_runtime, generic_runtime, done; |
| - Label exponent_not_smi, int_exponent; |
| + Label call_runtime, done, exponent_not_smi, int_exponent; |
| // Save 1 in double_result - we need this several times later on. |
| __ mov(scratch, Immediate(1)); |
| @@ -2966,7 +2965,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { |
| __ JumpIfSmi(base, &base_is_smi, Label::kNear); |
| __ cmp(FieldOperand(base, HeapObject::kMapOffset), |
| factory->heap_number_map()); |
| - __ j(not_equal, &generic_runtime); |
| + __ j(not_equal, &call_runtime); |
| __ movdbl(double_base, FieldOperand(base, HeapNumber::kValueOffset)); |
| __ jmp(&unpack_exponent, Label::kNear); |
| @@ -2983,7 +2982,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { |
| __ bind(&exponent_not_smi); |
| __ cmp(FieldOperand(exponent, HeapObject::kMapOffset), |
| factory->heap_number_map()); |
| - __ j(not_equal, &generic_runtime); |
| + __ j(not_equal, &call_runtime); |
| __ movdbl(double_exponent, |
| FieldOperand(exponent, HeapNumber::kValueOffset)); |
| } else if (exponent_type_ == TAGGED) { |
| @@ -3002,7 +3001,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { |
| __ cvttsd2si(exponent, Operand(double_exponent)); |
| // Skip to runtime if possibly NaN (indicated by the indefinite integer). |
| __ cmp(exponent, Immediate(0x80000000u)); |
| - __ j(equal, &generic_runtime); |
| + __ j(equal, &call_runtime); |
| __ cvtsi2sd(double_scratch, exponent); |
| // Already ruled out NaNs for exponent. |
| __ ucomisd(double_exponent, double_scratch); |
| @@ -3119,33 +3118,35 @@ void MathPowStub::Generate(MacroAssembler* masm) { |
| __ bind(&fast_power_failed); |
| __ fninit(); |
| __ add(esp, Immediate(kDoubleSize)); |
| - __ jmp(&generic_runtime); |
| + __ jmp(&call_runtime); |
| } |
| // Calculate power with integer exponent. |
| __ bind(&int_exponent); |
| const XMMRegister double_scratch2 = double_exponent; |
| - __ mov(scratch, exponent); // Back up exponent. |
| + __ mov(scratch, exponent); // Back up exponent. |
| __ movsd(double_scratch, double_base); // Back up base. |
| __ movsd(double_scratch2, double_result); // Load double_exponent with 1. |
| // Get absolute value of exponent. |
| - Label while_true, no_multiply; |
| - const uint32_t kClearSignBitMask = 0x7FFFFFFF; |
| - __ and_(exponent, Immediate(kClearSignBitMask)); |
|
Yang
2011/12/07 15:07:50
This is a screw-up I did earlier. Obviously this c
|
| + Label no_neg, while_true, no_multiply; |
| + __ test(scratch, scratch); |
| + __ j(positive, &no_neg, Label::kNear); |
| + __ neg(scratch); |
| + __ bind(&no_neg); |
| __ bind(&while_true); |
| - __ shr(exponent, 1); |
| + __ shr(scratch, 1); |
| __ j(not_carry, &no_multiply, Label::kNear); |
| - __ mulsd(double_result, double_base); |
| + __ mulsd(double_result, double_scratch); |
| __ bind(&no_multiply); |
| - __ mulsd(double_base, double_base); |
| + __ mulsd(double_scratch, double_scratch); |
| __ j(not_zero, &while_true); |
| // scratch has the original value of the exponent - if the exponent is |
| // negative, return 1/result. |
| - __ test(scratch, scratch); |
| + __ test(exponent, exponent); |
| __ j(positive, &done); |
| __ divsd(double_scratch2, double_result); |
| __ movsd(double_result, double_scratch2); |
| @@ -3153,47 +3154,33 @@ void MathPowStub::Generate(MacroAssembler* masm) { |
| // Due to subnormals, x^-y == (1/x)^y does not hold in all cases. |
| __ xorps(double_scratch2, double_scratch2); |
| __ ucomisd(double_scratch2, double_result); // Result cannot be NaN. |
| - __ j(equal, &double_int_runtime); |
| + __ j(not_equal, &done); |
| + __ cvtsi2sd(double_exponent, exponent); |
| // Returning or bailing out. |
| + Counters* counters = masm->isolate()->counters(); |
| if (exponent_type_ == ON_STACK) { |
| + // The arguments are still on the stack. |
| + __ bind(&call_runtime); |
| + __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1); |
| + |
| // The stub is called from non-optimized code, which expects the result |
| // as heap number in exponent. |
| __ bind(&done); |
| - __ AllocateHeapNumber(exponent, scratch, base, &generic_runtime); |
| - __ movdbl(FieldOperand(exponent, HeapNumber::kValueOffset), double_result); |
| + __ AllocateHeapNumber(eax, scratch, base, &call_runtime); |
| + __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), double_result); |
| + __ IncrementCounter(counters->math_pow(), 1); |
| __ ret(2 * kPointerSize); |
| - |
| - // The arguments are still on the stack. |
| - __ bind(&generic_runtime); |
| - __ bind(&double_int_runtime); |
| - __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1); |
| } else { |
| - __ jmp(&done); |
| - |
| - Label return_from_runtime; |
| - __ bind(&generic_runtime); |
| + __ bind(&call_runtime); |
| { |
| AllowExternalCallThatCantCauseGC scope(masm); |
| - __ PrepareCallCFunction(4, exponent); |
| + __ PrepareCallCFunction(4, scratch); |
| __ movdbl(Operand(esp, 0 * kDoubleSize), double_base); |
| __ movdbl(Operand(esp, 1 * kDoubleSize), double_exponent); |
| __ CallCFunction( |
| ExternalReference::power_double_double_function(masm->isolate()), 4); |
| } |
| - __ jmp(&return_from_runtime, Label::kNear); |
| - |
| - __ bind(&double_int_runtime); |
| - { |
| - AllowExternalCallThatCantCauseGC scope(masm); |
| - __ PrepareCallCFunction(4, exponent); |
| - __ movdbl(Operand(esp, 0 * kDoubleSize), double_scratch); |
| - __ mov(Operand(esp, 1 * kDoubleSize), scratch); |
| - __ CallCFunction( |
| - ExternalReference::power_double_int_function(masm->isolate()), 4); |
| - } |
| - |
| - __ bind(&return_from_runtime); |
| // Return value is in st(0) on ia32. |
| // Store it into the (fixed) result register. |
| __ sub(esp, Immediate(kDoubleSize)); |
| @@ -3202,6 +3189,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { |
| __ add(esp, Immediate(kDoubleSize)); |
| __ bind(&done); |
| + __ IncrementCounter(counters->math_pow(), 1); |
| __ ret(0); |
| } |
| } |