From 74c01fdc5043a2410081ff119ec94beebf8fe4a9 Mon Sep 17 00:00:00 2001 From: "lrn@chromium.org" Date: Fri, 21 May 2010 09:08:14 +0000 Subject: [PATCH] X64: Added inline conversion of double to smi for LikelySmiBinaryOp shifts. Review URL: http://codereview.chromium.org/2078028 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4697 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x64/codegen-x64.cc | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc index 97702db..6f6670a 100644 --- a/src/x64/codegen-x64.cc +++ b/src/x64/codegen-x64.cc @@ -7057,7 +7057,43 @@ Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr, left->reg(), rcx, overwrite_mode); - __ JumpIfNotBothSmi(left->reg(), rcx, deferred->entry_label()); + + Label do_op; + if (right_type_info.IsSmi()) { + if (FLAG_debug_code) { + __ AbortIfNotSmi(right->reg()); + } + __ movq(answer.reg(), left->reg()); + // If left is not known to be a smi, check if it is. + // If left is not known to be a number, and it isn't a smi, check if + // it is a HeapNumber. + if (!left_type_info.IsSmi()) { + __ JumpIfSmi(answer.reg(), &do_op); + if (!left_type_info.IsNumber()) { + // 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 might have overflowed. + // (False negative for Smi::kMinValue) + __ cmpq(answer.reg(), Immediate(0x80000000)); + deferred->Branch(equal); + // TODO(lrn): Inline shifts on int32 here instead of first smi-tagging. + __ Integer32ToSmi(answer.reg(), answer.reg()); + } else { + // Fast case - both are actually smis. + if (FLAG_debug_code) { + __ AbortIfNotSmi(left->reg()); + } + } + } else { + __ JumpIfNotBothSmi(left->reg(), rcx, deferred->entry_label()); + } + __ bind(&do_op); // Perform the operation. switch (op) { -- 2.7.4