| Index: src/arm/codegen-arm.cc
|
| ===================================================================
|
| --- src/arm/codegen-arm.cc (revision 5015)
|
| +++ src/arm/codegen-arm.cc (working copy)
|
| @@ -5423,9 +5423,13 @@
|
| frame_->EmitPush(r0); // r0 has result
|
|
|
| } else {
|
| - bool overwrite =
|
| + bool can_overwrite =
|
| (node->expression()->AsBinaryOperation() != NULL &&
|
| node->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
|
| + UnaryOverwriteMode overwrite =
|
| + can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
|
| +
|
| + bool no_negative_zero = node->expression()->no_negative_zero();
|
| Load(node->expression());
|
| switch (op) {
|
| case Token::NOT:
|
| @@ -5436,7 +5440,10 @@
|
|
|
| case Token::SUB: {
|
| frame_->PopToR0();
|
| - GenericUnaryOpStub stub(Token::SUB, overwrite);
|
| + GenericUnaryOpStub stub(
|
| + Token::SUB,
|
| + overwrite,
|
| + no_negative_zero ? kIgnoreNegativeZero : kStrictNegativeZero);
|
| frame_->CallStub(&stub, 0);
|
| frame_->EmitPush(r0); // r0 has result
|
| break;
|
| @@ -8899,24 +8906,31 @@
|
|
|
| // Go slow case if the value of the expression is zero
|
| // to make sure that we switch between 0 and -0.
|
| - __ cmp(r0, Operand(0));
|
| - __ b(eq, &slow);
|
| + if (negative_zero_ == kStrictNegativeZero) {
|
| + // If we have to check for zero, then we can check for the max negative
|
| + // smi while we are at it.
|
| + __ bic(ip, r0, Operand(0x80000000), SetCC);
|
| + __ b(eq, &slow);
|
| + __ rsb(r0, r0, Operand(0));
|
| + __ StubReturn(1);
|
| + } else {
|
| + // The value of the expression is a smi and 0 is OK for -0. Try
|
| + // optimistic subtraction '0 - value'.
|
| + __ rsb(r0, r0, Operand(0), SetCC);
|
| + __ StubReturn(1, vc);
|
| + // We don't have to reverse the optimistic neg since the only case
|
| + // where we fall through is the minimum negative Smi, which is the case
|
| + // where the neg leaves the register unchanged.
|
| + __ jmp(&slow); // Go slow on max negative Smi.
|
| + }
|
|
|
| - // The value of the expression is a smi that is not zero. Try
|
| - // optimistic subtraction '0 - value'.
|
| - __ rsb(r1, r0, Operand(0), SetCC);
|
| - __ b(vs, &slow);
|
| -
|
| - __ mov(r0, Operand(r1)); // Set r0 to result.
|
| - __ b(&done);
|
| -
|
| __ bind(&try_float);
|
| __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
|
| __ AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
|
| __ cmp(r1, heap_number_map);
|
| __ b(ne, &slow);
|
| // r0 is a heap number. Get a new heap number in r1.
|
| - if (overwrite_) {
|
| + if (overwrite_ == UNARY_OVERWRITE) {
|
| __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
|
| __ eor(r2, r2, Operand(HeapNumber::kSignMask)); // Flip sign.
|
| __ str(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
|
| @@ -8949,7 +8963,7 @@
|
| __ b(&done);
|
|
|
| __ bind(&try_float);
|
| - if (!overwrite_) {
|
| + if (!overwrite_ == UNARY_OVERWRITE) {
|
| // Allocate a fresh heap number, but don't overwrite r0 until
|
| // we're sure we can do it without going through the slow case
|
| // that needs the value in r0.
|
|
|