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 6bea2dc685c8329dcb53eab5cd7cf3b0f7d6d859..83d0720539c6c8737a067ee0480adbec1746f770 100644 |
| --- a/src/ia32/code-stubs-ia32.cc |
| +++ b/src/ia32/code-stubs-ia32.cc |
| @@ -2940,64 +2940,72 @@ void FloatingPointHelper::CheckFloatOperandsAreInt32(MacroAssembler* masm, |
| void MathPowStub::Generate(MacroAssembler* masm) { |
| CpuFeatures::Scope use_sse2(SSE2); |
| Factory* factory = masm->isolate()->factory(); |
| + const Register exponent = eax; |
| + const Register base = edx; |
| + const Register scratch = ecx; |
| + const XMMRegister double_result = xmm3; |
| + const XMMRegister double_base = xmm1; |
| + const XMMRegister double_exponent = xmm2; |
| + const XMMRegister double_scratch = xmm4; |
| + |
| Label double_int_runtime, generic_runtime, done; |
| - Label base_is_smi, unpack_exponent, exponent_not_smi, int_exponent; |
| - // Save 1 in xmm3 - we need this several times later on. |
| - __ mov(ecx, Immediate(1)); |
| - __ cvtsi2sd(xmm3, ecx); |
| + Label exponent_not_smi, int_exponent; |
| + |
| + // Save 1 in double_result - we need this several times later on. |
| + __ mov(scratch, Immediate(1)); |
| + __ cvtsi2sd(double_result, scratch); |
| if (exponent_type_ == ON_STACK) { |
| - // The exponent (and base) are supplied as arguments on the 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 |
| - __ mov(edx, Operand(esp, 2 * kPointerSize)); |
| - __ mov(eax, Operand(esp, 1 * kPointerSize)); |
| - // edx: base (smi or heap number) |
| - // eax: exponent (smi or heap number) |
| - __ JumpIfSmi(edx, &base_is_smi, Label::kNear); |
| - __ cmp(FieldOperand(edx, HeapObject::kMapOffset), |
| + // Load input parameters from stack. |
| + __ mov(base, Operand(esp, 2 * kPointerSize)); |
| + __ mov(exponent, Operand(esp, 1 * kPointerSize)); |
| + |
| + __ JumpIfSmi(base, &base_is_smi, Label::kNear); |
| + __ cmp(FieldOperand(base, HeapObject::kMapOffset), |
| factory->heap_number_map()); |
| __ j(not_equal, &generic_runtime); |
| - __ movdbl(xmm1, FieldOperand(edx, HeapNumber::kValueOffset)); |
| + __ movdbl(double_base, FieldOperand(base, HeapNumber::kValueOffset)); |
| __ jmp(&unpack_exponent, Label::kNear); |
| __ bind(&base_is_smi); |
| - __ SmiUntag(edx); |
| - __ cvtsi2sd(xmm1, edx); |
| + __ SmiUntag(base); |
| + __ cvtsi2sd(double_base, base); |
| __ bind(&unpack_exponent); |
|
ulan
2011/12/06 17:38:04
Moving the empty line before the bind would be bet
|
| - __ JumpIfNotSmi(eax, &exponent_not_smi, Label::kNear); |
| - __ SmiUntag(eax); |
| + __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear); |
| + __ SmiUntag(exponent); |
| __ jmp(&int_exponent); |
| __ bind(&exponent_not_smi); |
| - __ cmp(FieldOperand(eax, HeapObject::kMapOffset), |
| + __ cmp(FieldOperand(exponent, HeapObject::kMapOffset), |
| factory->heap_number_map()); |
| __ j(not_equal, &generic_runtime); |
| - __ movdbl(xmm2, FieldOperand(eax, HeapNumber::kValueOffset)); |
| + __ movdbl(double_exponent, |
| + FieldOperand(exponent, HeapNumber::kValueOffset)); |
| } else if (exponent_type_ == TAGGED) { |
| - // xmm1: base as double |
| - // eax: exponent (smi or heap number) |
| - __ JumpIfNotSmi(eax, &exponent_not_smi, Label::kNear); |
| - __ SmiUntag(eax); |
| + __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear); |
| + __ SmiUntag(exponent); |
| __ jmp(&int_exponent); |
| __ bind(&exponent_not_smi); |
| - __ movdbl(xmm2, FieldOperand(eax, HeapNumber::kValueOffset)); |
| + __ movdbl(double_exponent, |
| + FieldOperand(exponent, HeapNumber::kValueOffset)); |
| } |
| if (exponent_type_ != INTEGER) { |
| Label fast_power; |
| - // xmm1: base as double that is not +/- Infinity or NaN |
| - // xmm2: exponent as double |
| // Detect integer exponents stored as double. |
| - __ cvttsd2si(eax, Operand(xmm2)); |
| + __ cvttsd2si(exponent, Operand(double_exponent)); |
| // Skip to runtime if possibly NaN (indicated by the indefinite integer). |
| - __ cmp(eax, Immediate(0x80000000u)); |
| + __ cmp(exponent, Immediate(0x80000000u)); |
| __ j(equal, &generic_runtime); |
| - __ cvtsi2sd(xmm4, eax); |
| - __ ucomisd(xmm2, xmm4); // Already ruled out NaNs for exponent. |
| + __ cvtsi2sd(double_scratch, exponent); |
| + // Already ruled out NaNs for exponent. |
| + __ ucomisd(double_exponent, double_scratch); |
| __ j(equal, &int_exponent); |
| if (exponent_type_ == ON_STACK) { |
| @@ -3006,71 +3014,70 @@ void MathPowStub::Generate(MacroAssembler* masm) { |
| // for non-constant cases of +/-0.5 as these hardly occur. |
| Label continue_sqrt, continue_rsqrt, not_plus_half; |
| // Test for 0.5. |
| - // Load xmm4 with 0.5. |
| - __ mov(ecx, Immediate(0x3F000000u)); |
| - __ movd(xmm4, ecx); |
| - __ cvtss2sd(xmm4, xmm4); |
| - // xmm4 now has 0.5. |
| - __ ucomisd(xmm4, xmm2); // Already ruled out NaNs for exponent. |
| + // Load double_scratch with 0.5. |
| + __ mov(scratch, Immediate(0x3F000000u)); |
| + __ movd(double_scratch, scratch); |
| + __ cvtss2sd(double_scratch, double_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, single-precision -Infinity has the highest |
| // 9 bits set and the lowest 23 bits cleared. |
| - __ mov(ecx, 0xFF800000u); |
| - __ movd(xmm4, ecx); |
| - __ cvtss2sd(xmm4, xmm4); |
| - __ ucomisd(xmm1, xmm4); |
| + __ mov(scratch, 0xFF800000u); |
| + __ movd(double_scratch, scratch); |
| + __ cvtss2sd(double_scratch, double_scratch); |
| + __ ucomisd(double_base, double_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, &continue_sqrt, Label::kNear); |
| __ j(carry, &continue_sqrt, Label::kNear); |
| // Set result to Infinity in the special case. |
| - __ xorps(xmm3, xmm3); |
| - __ subsd(xmm3, xmm4); |
| + __ xorps(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. |
| - __ xorps(xmm4, xmm4); |
| - __ addsd(xmm4, xmm1); // Convert -0 to +0. |
| - __ sqrtsd(xmm3, xmm4); |
| + __ xorps(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 xmm2 with -0.5. |
| - // Since xmm3 is 1 and xmm4 is 0.5 this is simply xmm4 - xmm3. |
| - __ subsd(xmm4, xmm3); |
| - // xmm4 now has -0.5. |
| - __ ucomisd(xmm4, xmm2); // Already ruled out NaNs for exponent. |
| + // Load double_exponent 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, single-precision -Infinity has the highest |
| // 9 bits set and the lowest 23 bits cleared. |
| - __ mov(ecx, 0xFF800000u); |
| - __ movd(xmm4, ecx); |
| - __ cvtss2sd(xmm4, xmm4); |
| - __ ucomisd(xmm1, xmm4); |
| + __ mov(scratch, 0xFF800000u); |
| + __ movd(double_scratch, scratch); |
| + __ cvtss2sd(double_scratch, double_scratch); |
| + __ ucomisd(double_base, double_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, &continue_rsqrt, Label::kNear); |
| __ j(carry, &continue_rsqrt, Label::kNear); |
| // Set result to 0 in the special case. |
| - __ xorps(xmm3, xmm3); |
| + __ xorps(double_result, double_result); |
| __ jmp(&done); |
| __ bind(&continue_rsqrt); |
| // sqrtsd returns -0 when input is -0. ECMA spec requires +0. |
| - __ xorps(xmm2, xmm2); |
| - __ addsd(xmm2, xmm1); // Convert -0 to +0. |
| - __ sqrtsd(xmm2, xmm2); |
| - __ divsd(xmm3, xmm2); |
| + __ xorps(double_exponent, double_exponent); |
| + __ addsd(double_exponent, double_base); // Convert -0 to +0. |
|
ulan
2011/12/06 17:38:04
addsd(double_base, double_exponent) would allow yo
|
| + __ sqrtsd(double_exponent, double_exponent); |
| + __ divsd(double_result, double_exponent); |
| __ jmp(&done); |
| } |
| @@ -3080,9 +3087,9 @@ void MathPowStub::Generate(MacroAssembler* masm) { |
| __ fnclex(); // Clear flags to catch exceptions later. |
| // Transfer (B)ase and (E)xponent onto the FPU register stack. |
| __ sub(esp, Immediate(kDoubleSize)); |
| - __ movdbl(Operand(esp, 0), xmm2); |
| + __ movdbl(Operand(esp, 0), double_exponent); |
| __ fld_d(Operand(esp, 0)); // E |
| - __ movdbl(Operand(esp, 0), xmm1); |
| + __ movdbl(Operand(esp, 0), double_base); |
| __ fld_d(Operand(esp, 0)); // B, E |
| // Exponent is in st(1) and base is in st(0) |
| @@ -3102,10 +3109,10 @@ void MathPowStub::Generate(MacroAssembler* masm) { |
| __ fstp(1); |
| // Bail out to runtime in case of exceptions in the status word. |
| __ fnstsw_ax(); |
| - __ test_b(eax, 0x5F); // We check for all but precision exception. |
| + __ test_b(exponent, 0x5F); // We check for all but precision exception. |
|
ulan
2011/12/06 17:38:04
Assuming that exponent == eax.
|
| __ j(not_zero, &fast_power_failed, Label::kNear); |
| __ fstp_d(Operand(esp, 0)); |
| - __ movdbl(xmm3, Operand(esp, 0)); |
| + __ movdbl(double_result, Operand(esp, 0)); |
| __ add(esp, Immediate(kDoubleSize)); |
| __ jmp(&done); |
| @@ -3117,49 +3124,46 @@ void MathPowStub::Generate(MacroAssembler* masm) { |
| // Calculate power with integer exponent. |
| __ bind(&int_exponent); |
| - // xmm1: base as double that is not +/- Infinity or NaN |
| - // eax: exponent as untagged integer |
| - __ mov(ecx, eax); // Back up exponent. |
| - __ movsd(xmm4, xmm1); // Back up base. |
| - __ movsd(xmm2, xmm3); // Load xmm2 with 1. |
| - |
| + const XMMRegister double_scratch2 = double_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 no_neg, while_true, no_multiply; |
| - __ cmp(eax, 0); |
| + __ cmp(exponent, 0); |
| __ j(greater_equal, &no_neg, Label::kNear); |
| - __ neg(eax); |
| + __ neg(exponent); |
| __ bind(&no_neg); |
| __ bind(&while_true); |
| - __ shr(eax, 1); |
| + __ shr(exponent, 1); |
| __ j(not_carry, &no_multiply, Label::kNear); |
| - __ mulsd(xmm3, xmm1); |
| + __ mulsd(double_result, double_base); |
| __ bind(&no_multiply); |
| - __ mulsd(xmm1, xmm1); |
| + __ mulsd(double_base, double_base); |
| __ j(not_zero, &while_true); |
| - // base has the original value of the exponent - if the exponent is |
| - // negative return 1/result. |
| - __ test(ecx, ecx); |
| + // scratch has the original value of the exponent - if the exponent is |
| + // negative, return 1/result. |
| + __ test(scratch, scratch); |
| __ j(positive, &done); |
| - __ divsd(xmm2, xmm3); |
| - __ movsd(xmm3, xmm2); |
| + __ divsd(double_scratch2, double_result); |
| + __ movsd(double_result, double_scratch2); |
| // 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. |
| - __ xorps(xmm2, xmm2); |
| - __ ucomisd(xmm2, xmm3); // Result cannot be NaN. |
| + __ xorps(double_scratch2, double_scratch2); |
| + __ ucomisd(double_scratch2, double_result); // Result cannot be NaN. |
| __ j(equal, &double_int_runtime); |
| // Returning or bailing out. |
| if (exponent_type_ == ON_STACK) { |
| // The stub is called from non-optimized code, which expects the result |
| - // as heap number in eax. |
| + // as heap number in exponent. |
| __ bind(&done); |
| - // xmm3: result |
| - __ AllocateHeapNumber(eax, ecx, edx, &generic_runtime); |
| - __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm3); |
| + __ AllocateHeapNumber(exponent, scratch, base, &generic_runtime); |
| + __ movdbl(FieldOperand(exponent, HeapNumber::kValueOffset), double_result); |
| __ ret(2 * kPointerSize); |
| // The arguments are still on the stack. |
| @@ -3170,28 +3174,23 @@ void MathPowStub::Generate(MacroAssembler* masm) { |
| __ jmp(&done); |
| Label return_from_runtime; |
| - StubRuntimeCallHelper callhelper; |
| __ bind(&generic_runtime); |
| - // xmm1: base |
| - // xmm2: exponent |
| { |
| AllowExternalCallThatCantCauseGC scope(masm); |
| - __ PrepareCallCFunction(4, eax); |
| - __ movdbl(Operand(esp, 0 * kDoubleSize), xmm1); |
| - __ movdbl(Operand(esp, 1 * kDoubleSize), xmm2); |
| + __ PrepareCallCFunction(4, exponent); |
| + __ 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); |
| - // xmm4: base |
| - // ecx: exponent |
| { |
| AllowExternalCallThatCantCauseGC scope(masm); |
| - __ PrepareCallCFunction(4, eax); |
| - __ movdbl(Operand(esp, 0 * kDoubleSize), xmm4); |
| - __ mov(Operand(esp, 1 * kDoubleSize), ecx); |
| + __ 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); |
| } |
| @@ -3201,10 +3200,9 @@ void MathPowStub::Generate(MacroAssembler* masm) { |
| // Store it into the (fixed) result register. |
| __ sub(esp, Immediate(kDoubleSize)); |
| __ fstp_d(Operand(esp, 0)); |
| - __ movdbl(xmm3, Operand(esp, 0)); |
| + __ movdbl(double_result, Operand(esp, 0)); |
| __ add(esp, Immediate(kDoubleSize)); |
| - // xmm3: result |
| __ bind(&done); |
| __ ret(0); |
| } |