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
This commit is contained in:
parent
0f590eb45f
commit
73814e7500
@ -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();
|
||||
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);
|
||||
}
|
||||
// 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 @@ 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);
|
||||
|
Loading…
Reference in New Issue
Block a user