From cf3219bc4e8fcb825824f540b9aef641af8fa681 Mon Sep 17 00:00:00 2001 From: "ricow@chromium.org" Date: Mon, 15 Mar 2010 14:24:37 +0000 Subject: [PATCH] Added fast case for shift operations when the left parameter is a double and we know that the right parameter is a smi. Review URL: http://codereview.chromium.org/955001 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4132 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ia32/codegen-ia32.cc | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc index 832e773be..7841304d7 100644 --- a/src/ia32/codegen-ia32.cc +++ b/src/ia32/codegen-ia32.cc @@ -1478,12 +1478,41 @@ Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op, left->number_info(), right->number_info(), overwrite_mode); - CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(), - left->number_info(), right->number_info(), deferred); - // Untag both operands. - __ mov(answer.reg(), left->reg()); - __ SmiUntag(answer.reg()); + Label do_op, left_nonsmi; + // if right is a smi we make a fast case if left is either a smi + // or a heapnumber. + if (CpuFeatures::IsSupported(SSE2) && right->number_info().IsSmi()) { + __ mov(answer.reg(), left->reg()); + // Fast case - both are actually smis. + if (!left->number_info().IsSmi()) { + __ test(answer.reg(), Immediate(kSmiTagMask)); + __ j(not_zero, &left_nonsmi); + } + __ SmiUntag(answer.reg()); + __ jmp(&do_op); + + __ bind(&left_nonsmi); + // Branch if not a heapnumber. + __ cmp(FieldOperand(answer.reg(), HeapObject::kMapOffset), + Factory::heap_number_map()); + deferred->Branch(not_equal); + + // Load integer value into answer register using truncation. + __ cvttsd2si(answer.reg(), + FieldOperand(answer.reg(), HeapNumber::kValueOffset)); + // Branch if we do not fit in a smi. + __ cmp(answer.reg(), 0xc0000000); + deferred->Branch(negative); + } else { + CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(), + left->number_info(), right->number_info(), deferred); + + // Untag both operands. + __ mov(answer.reg(), left->reg()); + __ SmiUntag(answer.reg()); + } + __ SmiUntag(ecx); // Perform the operation. switch (op) { -- 2.34.1