Index: src/arm/code-stubs-arm.cc |
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc |
index c25d44522c6e24bf093daab5c42a2353364229c0..441adfe3af3eeeae6951cfa44176ad72e885b5ba 100644 |
--- a/src/arm/code-stubs-arm.cc |
+++ b/src/arm/code-stubs-arm.cc |
@@ -2884,6 +2884,9 @@ void TypeRecordingBinaryOpStub::Generate(MacroAssembler* masm) { |
case TRBinaryOpIC::HEAP_NUMBER: |
GenerateHeapNumberStub(masm); |
break; |
+ case TRBinaryOpIC::ODDBALL: |
+ GenerateOddballStub(masm); |
+ break; |
case TRBinaryOpIC::STRING: |
GenerateStringStub(masm); |
break; |
@@ -3426,9 +3429,20 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
__ add(scratch2, scratch1, Operand(0x40000000), SetCC); |
// If not try to return a heap number. |
__ b(mi, &return_heap_number); |
+ // Check for minus zero. Return heap number for minus zero. |
+ Label not_zero; |
+ __ cmp(scratch1, Operand(0)); |
+ __ b(ne, ¬_zero); |
+ __ vmov(scratch2, d5.high()); |
+ __ tst(scratch2, Operand(HeapNumber::kSignMask)); |
+ __ b(ne, &return_heap_number); |
+ __ bind(¬_zero); |
+ |
// Tag the result and return. |
__ SmiTag(r0, scratch1); |
__ Ret(); |
+ } else { |
+ // DIV just falls through to allocating a heap number. |
} |
if (result_type_ >= (op_ == Token::DIV) ? TRBinaryOpIC::HEAP_NUMBER |
@@ -3606,10 +3620,41 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
} |
-void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { |
+void TypeRecordingBinaryOpStub::GenerateOddballStub(MacroAssembler* masm) { |
Label call_runtime; |
- ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER); |
+ if (op_ == Token::ADD) { |
+ // Handle string addition here, because it is the only operation |
+ // that does not do a ToNumber conversion on the operands. |
+ GenerateAddStrings(masm); |
+ } |
+ |
+ // Convert oddball arguments to numbers. |
+ Label check, done; |
+ __ CompareRoot(r1, Heap::kUndefinedValueRootIndex); |
+ __ b(ne, &check); |
+ if (Token::IsBitOp(op_)) { |
+ __ mov(r1, Operand(Smi::FromInt(0))); |
+ } else { |
+ __ LoadRoot(r1, Heap::kNanValueRootIndex); |
+ } |
+ __ jmp(&done); |
+ __ bind(&check); |
+ __ CompareRoot(r0, Heap::kUndefinedValueRootIndex); |
+ __ b(ne, &done); |
+ if (Token::IsBitOp(op_)) { |
+ __ mov(r0, Operand(Smi::FromInt(0))); |
+ } else { |
+ __ LoadRoot(r0, Heap::kNanValueRootIndex); |
+ } |
+ __ bind(&done); |
+ |
+ GenerateHeapNumberStub(masm); |
+} |
+ |
+ |
+void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { |
+ Label call_runtime; |
GenerateFPOperation(masm, false, &call_runtime, &call_runtime); |
__ bind(&call_runtime); |