Chromium Code Reviews| Index: src/ia32/codegen-ia32.cc |
| =================================================================== |
| --- src/ia32/codegen-ia32.cc (revision 3485) |
| +++ src/ia32/codegen-ia32.cc (working copy) |
| @@ -818,9 +818,83 @@ |
| void DeferredInlineBinaryOperation::Generate() { |
| + Label done; |
| + if (CpuFeatures::IsSupported(SSE2) && ((op_ == Token::ADD) || |
| + (op_ ==Token::SUB) || |
| + (op_ == Token::MUL) || |
| + (op_ == Token::DIV))) { |
| + CpuFeatures::Scope use_sse2(SSE2); |
| + Label call_runtime, after_alloc_failure; |
| + Label left_smi, right_smi, load_right, do_op; |
| + __ test(left_, Immediate(kSmiTagMask)); |
| + __ j(zero, &left_smi); |
| + __ cmp(FieldOperand(left_, HeapObject::kMapOffset), |
| + Factory::heap_number_map()); |
| + __ j(not_equal, &call_runtime); |
| + __ movdbl(xmm0, FieldOperand(left_, HeapNumber::kValueOffset)); |
| + if (mode_ == OVERWRITE_LEFT) { |
| + __ mov(dst_, left_); |
| + } |
| + __ jmp(&load_right); |
| + |
| + __ bind(&left_smi); |
| + __ sar(left_, 1); |
|
Kasper Lund
2009/12/18 07:23:13
1 -> kSmiTagSize
|
| + __ cvtsi2sd(xmm0, Operand(left_)); |
| + __ shl(left_, 1); |
|
Kasper Lund
2009/12/18 07:23:13
1 -> kSmiTagSize
|
| + if (mode_ == OVERWRITE_LEFT) { |
| + Label alloc_failure; |
| + __ push(left_); |
| + __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); |
| + __ pop(left_); |
| + } |
| + |
| + __ bind(&load_right); |
| + __ test(right_, Immediate(kSmiTagMask)); |
| + __ j(zero, &right_smi); |
| + __ cmp(FieldOperand(right_, HeapObject::kMapOffset), |
| + Factory::heap_number_map()); |
| + __ j(not_equal, &call_runtime); |
| + __ movdbl(xmm1, FieldOperand(right_, HeapNumber::kValueOffset)); |
| + if (mode_ == OVERWRITE_RIGHT) { |
| + __ mov(dst_, right_); |
| + } else if (mode_ == NO_OVERWRITE) { |
| + Label alloc_failure; |
| + __ push(left_); |
| + __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); |
| + __ pop(left_); |
| + } |
| + __ jmp(&do_op); |
| + |
| + __ bind(&right_smi); |
| + __ sar(right_, 1); |
|
Kasper Lund
2009/12/18 07:23:13
1 -> kSmiTagSize
|
| + __ cvtsi2sd(xmm1, Operand(right_)); |
| + __ shl(right_, 1); |
|
Kasper Lund
2009/12/18 07:23:13
1 -> kSmiTagSize
|
| + if (mode_ == OVERWRITE_RIGHT || mode_ == NO_OVERWRITE) { |
| + Label alloc_failure; |
| + __ push(left_); |
| + __ AllocateHeapNumber(dst_, left_, no_reg, &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(); |
| + } |
| + __ movdbl(FieldOperand(dst_, HeapNumber::kValueOffset), xmm0); |
| + __ jmp(&done); |
|
Kasper Lund
2009/12/18 07:23:13
Could this be a jmp(exit_label())?
|
| + |
| + __ 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(eax)) __ mov(dst_, eax); |
| + __ bind(&done); |
| } |