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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11381 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0f590eb4
...@@ -1681,6 +1681,11 @@ void BinaryOpStub::GenerateBothStringStub(MacroAssembler* masm) { ...@@ -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) { void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
Label call_runtime; Label call_runtime;
ASSERT(operands_type_ == BinaryOpIC::INT32); ASSERT(operands_type_ == BinaryOpIC::INT32);
...@@ -1690,13 +1695,18 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { ...@@ -1690,13 +1695,18 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
case Token::ADD: case Token::ADD:
case Token::SUB: case Token::SUB:
case Token::MUL: case Token::MUL:
case Token::DIV: { case Token::DIV:
case Token::MOD: {
Label not_floats; Label not_floats;
Label not_int32; Label not_int32;
if (CpuFeatures::IsSupported(SSE2)) { if (CpuFeatures::IsSupported(SSE2)) {
CpuFeatures::Scope use_sse2(SSE2); CpuFeatures::Scope use_sse2(SSE2);
FloatingPointHelper::LoadSSE2Operands(masm, &not_floats); FloatingPointHelper::LoadSSE2Operands(masm, &not_floats);
FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, &not_int32, ecx); FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, &not_int32, ecx);
if (op_ == Token::MOD) {
GenerateRegisterArgsPush(masm);
__ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
} else {
switch (op_) { switch (op_) {
case Token::ADD: __ addsd(xmm0, xmm1); break; case Token::ADD: __ addsd(xmm0, xmm1); break;
case Token::SUB: __ subsd(xmm0, xmm1); break; case Token::SUB: __ subsd(xmm0, xmm1); break;
...@@ -1715,6 +1725,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { ...@@ -1715,6 +1725,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
GenerateHeapResultAllocation(masm, &call_runtime); GenerateHeapResultAllocation(masm, &call_runtime);
__ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
__ ret(0); __ ret(0);
}
} else { // SSE2 not available, use FPU. } else { // SSE2 not available, use FPU.
FloatingPointHelper::CheckFloatOperands(masm, &not_floats, ebx); FloatingPointHelper::CheckFloatOperands(masm, &not_floats, ebx);
FloatingPointHelper::LoadFloatOperands( FloatingPointHelper::LoadFloatOperands(
...@@ -1722,6 +1733,10 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { ...@@ -1722,6 +1733,10 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
ecx, ecx,
FloatingPointHelper::ARGS_IN_REGISTERS); FloatingPointHelper::ARGS_IN_REGISTERS);
FloatingPointHelper::CheckFloatOperandsAreInt32(masm, &not_int32); FloatingPointHelper::CheckFloatOperandsAreInt32(masm, &not_int32);
if (op_ == Token::MOD) {
GenerateRegisterArgsPush(masm);
__ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
} else {
switch (op_) { switch (op_) {
case Token::ADD: __ faddp(1); break; case Token::ADD: __ faddp(1); break;
case Token::SUB: __ fsubp(1); break; case Token::SUB: __ fsubp(1); break;
...@@ -1737,6 +1752,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { ...@@ -1737,6 +1752,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
__ fstp(0); // Pop FPU stack before calling runtime. __ fstp(0); // Pop FPU stack before calling runtime.
__ jmp(&call_runtime); __ jmp(&call_runtime);
} }
}
__ bind(&not_floats); __ bind(&not_floats);
__ bind(&not_int32); __ bind(&not_int32);
...@@ -1744,10 +1760,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { ...@@ -1744,10 +1760,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
break; break;
} }
case Token::MOD: {
// For MOD we go directly to runtime in the non-smi case.
break;
}
case Token::BIT_OR: case Token::BIT_OR:
case Token::BIT_AND: case Token::BIT_AND:
case Token::BIT_XOR: case Token::BIT_XOR:
...@@ -1758,11 +1770,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { ...@@ -1758,11 +1770,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
Label not_floats; Label not_floats;
Label not_int32; Label not_int32;
Label non_smi_result; Label non_smi_result;
/* {
CpuFeatures::Scope use_sse2(SSE2);
FloatingPointHelper::LoadSSE2Operands(masm, &not_floats);
FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, &not_int32, ecx);
}*/
FloatingPointHelper::LoadUnknownsAsIntegers(masm, FloatingPointHelper::LoadUnknownsAsIntegers(masm,
use_sse3_, use_sse3_,
&not_floats); &not_floats);
...@@ -1833,8 +1840,8 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { ...@@ -1833,8 +1840,8 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
default: UNREACHABLE(); break; default: UNREACHABLE(); break;
} }
// If an allocation fails, or SHR or MOD hit a hard case, // If an allocation fails, or SHR hits a hard case, use the runtime system to
// use the runtime system to get the correct result. // get the correct result.
__ bind(&call_runtime); __ bind(&call_runtime);
switch (op_) { switch (op_) {
...@@ -1855,8 +1862,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { ...@@ -1855,8 +1862,6 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
__ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION); __ InvokeBuiltin(Builtins::DIV, JUMP_FUNCTION);
break; break;
case Token::MOD: case Token::MOD:
GenerateRegisterArgsPush(masm);
__ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
break; break;
case Token::BIT_OR: case Token::BIT_OR:
__ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION); __ InvokeBuiltin(Builtins::BIT_OR, JUMP_FUNCTION);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment