Index: src/ia32/code-stubs-ia32.cc |
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc |
index 471114cbe4f219e04cb4b921de79326f6d3bebff..229e8fc536599476abb765d3f82835cab8a3e455 100644 |
--- a/src/ia32/code-stubs-ia32.cc |
+++ b/src/ia32/code-stubs-ia32.cc |
@@ -1681,6 +1681,11 @@ void BinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) { |
} |
+// Input: |
+// edx: left operand (tagged) |
+// eax: right operand (tagged) |
+// Output: |
+// eax: result (tagged) |
void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
Label call_runtime; |
ASSERT(operands_type_ == BinaryOpIC::INT32); |
@@ -1690,31 +1695,37 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
case Token::ADD: |
case Token::SUB: |
case Token::MUL: |
- case Token::DIV: { |
+ case Token::DIV: |
+ case Token::MOD: { |
Label not_floats; |
Label not_int32; |
if (CpuFeatures::IsSupported(SSE2)) { |
CpuFeatures::Scope use_sse2(SSE2); |
FloatingPointHelper::LoadSSE2Operands(masm, ¬_floats); |
FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, ¬_int32, ecx); |
- switch (op_) { |
- case Token::ADD: __ addsd(xmm0, xmm1); break; |
- case Token::SUB: __ subsd(xmm0, xmm1); break; |
- case Token::MUL: __ mulsd(xmm0, xmm1); break; |
- case Token::DIV: __ divsd(xmm0, xmm1); break; |
- default: UNREACHABLE(); |
- } |
- // Check result type if it is currently Int32. |
- if (result_type_ <= BinaryOpIC::INT32) { |
- __ cvttsd2si(ecx, Operand(xmm0)); |
- __ cvtsi2sd(xmm2, ecx); |
- __ ucomisd(xmm0, xmm2); |
- __ j(not_zero, ¬_int32); |
- __ j(carry, ¬_int32); |
+ if (op_ == Token::MOD) { |
+ GenerateRegisterArgsPush(masm); |
+ __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); |
+ } else { |
+ switch (op_) { |
+ case Token::ADD: __ addsd(xmm0, xmm1); break; |
+ case Token::SUB: __ subsd(xmm0, xmm1); break; |
+ case Token::MUL: __ mulsd(xmm0, xmm1); break; |
+ case Token::DIV: __ divsd(xmm0, xmm1); break; |
+ default: UNREACHABLE(); |
+ } |
+ // Check result type if it is currently Int32. |
+ if (result_type_ <= BinaryOpIC::INT32) { |
+ __ cvttsd2si(ecx, Operand(xmm0)); |
+ __ cvtsi2sd(xmm2, ecx); |
+ __ ucomisd(xmm0, xmm2); |
+ __ j(not_zero, ¬_int32); |
+ __ j(carry, ¬_int32); |
+ } |
+ GenerateHeapResultAllocation(masm, &call_runtime); |
+ __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
+ __ ret(0); |
} |
- GenerateHeapResultAllocation(masm, &call_runtime); |
- __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
- __ ret(0); |
} else { // SSE2 not available, use FPU. |
FloatingPointHelper::CheckFloatOperands(masm, ¬_floats, ebx); |
FloatingPointHelper::LoadFloatOperands( |
@@ -1722,20 +1733,25 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
ecx, |
FloatingPointHelper::ARGS_IN_REGISTERS); |
FloatingPointHelper::CheckFloatOperandsAreInt32(masm, ¬_int32); |
- switch (op_) { |
- case Token::ADD: __ faddp(1); break; |
- case Token::SUB: __ fsubp(1); break; |
- case Token::MUL: __ fmulp(1); break; |
- case Token::DIV: __ fdivp(1); break; |
- default: UNREACHABLE(); |
+ if (op_ == Token::MOD) { |
+ GenerateRegisterArgsPush(masm); |
+ __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); |
+ } else { |
+ switch (op_) { |
+ case Token::ADD: __ faddp(1); break; |
+ case Token::SUB: __ fsubp(1); break; |
+ case Token::MUL: __ fmulp(1); break; |
+ case Token::DIV: __ fdivp(1); break; |
+ default: UNREACHABLE(); |
+ } |
+ Label after_alloc_failure; |
+ GenerateHeapResultAllocation(masm, &after_alloc_failure); |
+ __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
+ __ ret(0); |
+ __ bind(&after_alloc_failure); |
+ __ fstp(0); // Pop FPU stack before calling runtime. |
+ __ jmp(&call_runtime); |
} |
- Label after_alloc_failure; |
- GenerateHeapResultAllocation(masm, &after_alloc_failure); |
- __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
- __ ret(0); |
- __ bind(&after_alloc_failure); |
- __ fstp(0); // Pop FPU stack before calling runtime. |
- __ jmp(&call_runtime); |
} |
__ bind(¬_floats); |
@@ -1744,10 +1760,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
break; |
} |
- case Token::MOD: { |
- // For MOD we go directly to runtime in the non-smi case. |
- break; |
- } |
case Token::BIT_OR: |
case Token::BIT_AND: |
case Token::BIT_XOR: |
@@ -1758,11 +1770,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
Label not_floats; |
Label not_int32; |
Label non_smi_result; |
- /* { |
- CpuFeatures::Scope use_sse2(SSE2); |
- FloatingPointHelper::LoadSSE2Operands(masm, ¬_floats); |
- FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, ¬_int32, ecx); |
- }*/ |
FloatingPointHelper::LoadUnknownsAsIntegers(masm, |
use_sse3_, |
¬_floats); |
@@ -1833,8 +1840,8 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
default: UNREACHABLE(); break; |
} |
- // If an allocation fails, or SHR or MOD hit a hard case, |
- // use the runtime system to get the correct result. |
+ // If an allocation fails, or SHR hits a hard case, use the runtime system to |
+ // get the correct result. |
__ bind(&call_runtime); |
switch (op_) { |
@@ -1855,8 +1862,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
__ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); |
break; |
case Token::MOD: |
- GenerateRegisterArgsPush(masm); |
- __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION); |
break; |
case Token::BIT_OR: |
__ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION); |