Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(434)

Unified Diff: src/ia32/code-stubs-ia32.cc

Issue 8821019: Porting Math.pow changes to x64. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: . Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/ia32/lithium-codegen-ia32.cc » ('j') | src/ia32/lithium-codegen-ia32.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..35c24e2f8989e0868be09cdd872290e8b5eedb14 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 = xmm2;
+ const XMMRegister double_exponent = xmm1;
+ 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);
- __ 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, &not_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(&not_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.
+ __ 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.
__ 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);
}
« no previous file with comments | « no previous file | src/ia32/lithium-codegen-ia32.cc » ('j') | src/ia32/lithium-codegen-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698