Commit a32540e7 authored by whesse@chromium.org's avatar whesse@chromium.org

Add code to ia32 TypeRecordingBinaryOpStub to handle SHR Smi overflow.

BUG=v8:1395

TEST=

Review URL: http://codereview.chromium.org/7039013

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7937 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 30ecaa2f
......@@ -1083,7 +1083,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
// Smi tagging these two cases can only happen with shifts
// by 0 or 1 when handed a valid smi.
__ test(left, Immediate(0xc0000000));
__ j(not_zero, slow);
__ j(not_zero, &use_fp_on_smis);
// Tag the result and store it in register eax.
__ SmiTag(left);
__ mov(eax, left);
......@@ -1219,26 +1219,35 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
} else {
ASSERT(allow_heapnumber_results == ALLOW_HEAPNUMBER_RESULTS);
switch (op_) {
case Token::SHL: {
case Token::SHL:
case Token::SHR: {
Comment perform_float(masm, "-- Perform float operation on smis");
__ bind(&use_fp_on_smis);
// Result we want is in left == edx, so we can put the allocated heap
// number in eax.
__ AllocateHeapNumber(eax, ecx, ebx, slow);
// Store the result in the HeapNumber and return.
if (CpuFeatures::IsSupported(SSE2)) {
CpuFeatures::Scope use_sse2(SSE2);
__ cvtsi2sd(xmm0, Operand(left));
__ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
} else {
// It's OK to overwrite the right argument on the stack because we
// are about to return.
// It's OK to overwrite the arguments on the stack because we
// are about to return.
if (op_ == Token::SHR) {
__ mov(Operand(esp, 1 * kPointerSize), left);
__ fild_s(Operand(esp, 1 * kPointerSize));
__ mov(Operand(esp, 2 * kPointerSize), Immediate(0));
__ fild_d(Operand(esp, 1 * kPointerSize));
__ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
} else {
ASSERT_EQ(Token::SHL, op_);
if (CpuFeatures::IsSupported(SSE2)) {
CpuFeatures::Scope use_sse2(SSE2);
__ cvtsi2sd(xmm0, Operand(left));
__ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
} else {
__ mov(Operand(esp, 1 * kPointerSize), left);
__ fild_s(Operand(esp, 1 * kPointerSize));
__ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
}
}
__ ret(2 * kPointerSize);
break;
__ ret(2 * kPointerSize);
break;
}
case Token::ADD:
......
......@@ -2379,7 +2379,10 @@ RUNTIME_FUNCTION(MaybeObject*, TypeRecordingBinaryOp_Patch) {
type = TRBinaryOpIC::GENERIC;
}
if (type == TRBinaryOpIC::SMI && previous_type == TRBinaryOpIC::SMI) {
if (op == Token::DIV || op == Token::MUL || kSmiValueSize == 32) {
if (op == Token::DIV ||
op == Token::MUL ||
op == Token::SHR ||
kSmiValueSize == 32) {
// Arithmetic on two Smi inputs has yielded a heap number.
// That is the only way to get here from the Smi stub.
// With 32-bit Smis, all overflows give heap numbers, but with
......
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