Revision: 11381
Author: [email protected]
Date: Thu Apr 19 00:19:33 2012
Log: Fixed type transitions for mod on ia32.
Previously we got stuck in the int32 state, because this handled everything
without a type transition. Note that other platforms do not have this bug.
Review URL: https://chromiumcodereview.appspot.com/10083044
http://code.google.com/p/v8/source/detail?r=11381
Modified:
/branches/bleeding_edge/src/ia32/code-stubs-ia32.cc
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Tue Apr 17 03:49:15
2012
+++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Thu Apr 19 00:19:33
2012
@@ -1681,6 +1681,11 @@
}
+// 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 @@
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);
- }
- GenerateHeapResultAllocation(masm, &call_runtime);
- __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
- __ ret(0);
+ 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);
+ }
} else { // SSE2 not available, use FPU.
FloatingPointHelper::CheckFloatOperands(masm, ¬_floats, ebx);
FloatingPointHelper::LoadFloatOperands(
@@ -1722,20 +1733,25 @@
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();
- }
- 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);
+ 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);
+ }
}
__ bind(¬_floats);
@@ -1744,10 +1760,6 @@
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 @@
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 @@
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 @@
__ 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);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev