Chromium Code Reviews| Index: src/x64/codegen-x64.cc |
| =================================================================== |
| --- src/x64/codegen-x64.cc (revision 4543) |
| +++ src/x64/codegen-x64.cc (working copy) |
| @@ -4050,8 +4050,7 @@ |
| Label base_not_smi; |
| Label handle_special_cases; |
| - __ testl(base.reg(), Immediate(kSmiTagMask)); |
| - __ j(not_zero, &base_not_smi); |
| + __ JumpIfNotSmi(base.reg(), &base_not_smi); |
| __ SmiToInteger32(base.reg(), base.reg()); |
| __ cvtlsi2sd(xmm0, base.reg()); |
| __ jmp(&handle_special_cases); |
| @@ -5895,9 +5894,80 @@ |
| void DeferredInlineBinaryOperation::Generate() { |
| + Label done; |
| + if ((op_ == Token::ADD) |
| + || (op_ ==Token::SUB) |
| + || (op_ == Token::MUL) |
| + || (op_ == Token::DIV)) { |
| + Label call_runtime, after_alloc_failure; |
| + Label left_smi, right_smi, load_right, do_op; |
| + __ JumpIfSmi(left_, &left_smi); |
| + __ CompareRoot(FieldOperand(left_, HeapObject::kMapOffset), |
| + Heap::kHeapNumberMapRootIndex); |
| + __ j(not_equal, &call_runtime); |
| + __ movsd(xmm0, FieldOperand(left_, HeapNumber::kValueOffset)); |
| + if (mode_ == OVERWRITE_LEFT) { |
| + __ movq(dst_, left_); |
| + } |
| + __ jmp(&load_right); |
| + |
| + __ bind(&left_smi); |
| + __ SmiToInteger32(left_, left_); |
|
Lasse Reichstein
2010/04/29 12:36:40
If you have a spare register here, you could conve
Mads Ager (chromium)
2010/05/03 08:47:09
I can convert the smi into an integer in kScratchR
|
| + __ cvtlsi2sd(xmm0, left_); |
| + __ Integer32ToSmi(left_, left_); |
| + if (mode_ == OVERWRITE_LEFT) { |
| + Label alloc_failure; |
| + __ push(left_); |
| + __ AllocateHeapNumber(dst_, left_, &after_alloc_failure); |
|
Lasse Reichstein
2010/04/29 12:36:40
I'll bet I can make a version of AllocateHeapNumbe
|
| + __ pop(left_); |
| + } |
| + |
| + __ bind(&load_right); |
| + __ JumpIfSmi(right_, &right_smi); |
| + __ CompareRoot(FieldOperand(right_, HeapObject::kMapOffset), |
| + Heap::kHeapNumberMapRootIndex); |
| + __ j(not_equal, &call_runtime); |
| + __ movsd(xmm1, FieldOperand(right_, HeapNumber::kValueOffset)); |
| + if (mode_ == OVERWRITE_RIGHT) { |
| + __ movq(dst_, right_); |
| + } else if (mode_ == NO_OVERWRITE) { |
| + Label alloc_failure; |
| + __ push(left_); |
| + __ AllocateHeapNumber(dst_, left_, &after_alloc_failure); |
| + __ pop(left_); |
| + } |
| + __ jmp(&do_op); |
| + |
| + __ bind(&right_smi); |
| + __ SmiToInteger32(right_, right_); |
| + __ cvtlsi2sd(xmm1, right_); |
| + __ Integer32ToSmi(right_, right_); |
| + if (mode_ == OVERWRITE_RIGHT || mode_ == NO_OVERWRITE) { |
| + Label alloc_failure; |
| + __ push(left_); |
| + __ AllocateHeapNumber(dst_, left_, &after_alloc_failure); |
| + __ pop(left_); |
| + } |
| + |
| + __ bind(&do_op); |
| + 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(); |
| + } |
| + __ movsd(FieldOperand(dst_, HeapNumber::kValueOffset), xmm0); |
| + __ jmp(&done); |
| + |
| + __ bind(&after_alloc_failure); |
| + __ pop(left_); |
| + __ bind(&call_runtime); |
| + } |
| GenericBinaryOpStub stub(op_, mode_, NO_SMI_CODE_IN_STUB); |
| stub.GenerateCall(masm_, left_, right_); |
| if (!dst_.is(rax)) __ movq(dst_, rax); |
| + __ bind(&done); |
| } |