| 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);
|
|
|