Index: src/ia32/codegen-ia32.cc |
=================================================================== |
--- src/ia32/codegen-ia32.cc (revision 5015) |
+++ src/ia32/codegen-ia32.cc (working copy) |
@@ -7583,9 +7583,12 @@ |
frame_->Push(&value); |
} else { |
Load(node->expression()); |
- 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(); |
switch (op) { |
case Token::NOT: |
case Token::DELETE: |
@@ -7594,7 +7597,10 @@ |
break; |
case Token::SUB: { |
- GenericUnaryOpStub stub(Token::SUB, overwrite); |
+ GenericUnaryOpStub stub( |
+ Token::SUB, |
+ overwrite, |
+ no_negative_zero ? kIgnoreNegativeZero : kStrictNegativeZero); |
Result operand = frame_->Pop(); |
Result answer = frame_->CallStub(&stub, &operand); |
answer.set_type_info(TypeInfo::Number()); |
@@ -10934,10 +10940,12 @@ |
__ test(eax, Immediate(kSmiTagMask)); |
__ j(not_zero, &try_float, not_taken); |
- // Go slow case if the value of the expression is zero |
- // to make sure that we switch between 0 and -0. |
- __ test(eax, Operand(eax)); |
- __ j(zero, &slow, not_taken); |
+ if (negative_zero_ == kStrictNegativeZero) { |
+ // Go slow case if the value of the expression is zero |
+ // to make sure that we switch between 0 and -0. |
+ __ test(eax, Operand(eax)); |
+ __ j(zero, &slow, not_taken); |
+ } |
// The value of the expression is a smi that is not zero. Try |
// optimistic subtraction '0 - value'. |
@@ -10945,12 +10953,8 @@ |
__ mov(edx, Operand(eax)); |
__ Set(eax, Immediate(0)); |
__ sub(eax, Operand(edx)); |
- __ j(overflow, &undo, not_taken); |
+ __ j(no_overflow, &done, taken); |
- // If result is a smi we are done. |
- __ test(eax, Immediate(kSmiTagMask)); |
- __ j(zero, &done, taken); |
- |
// Restore eax and go slow case. |
__ bind(&undo); |
__ mov(eax, Operand(edx)); |
@@ -10961,7 +10965,7 @@ |
__ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); |
__ cmp(edx, Factory::heap_number_map()); |
__ j(not_equal, &slow); |
- if (overwrite_) { |
+ if (overwrite_ == UNARY_OVERWRITE) { |
__ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset)); |
__ xor_(edx, HeapNumber::kSignMask); // Flip sign. |
__ mov(FieldOperand(eax, HeapNumber::kExponentOffset), edx); |
@@ -11002,7 +11006,7 @@ |
// Try to store the result in a heap number. |
__ bind(&try_float); |
- if (!overwrite_) { |
+ if (overwrite_ == UNARY_NO_OVERWRITE) { |
// Allocate a fresh heap number, but don't overwrite eax until |
// we're sure we can do it without going through the slow case |
// that needs the value in eax. |