| Index: src/ia32/codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/codegen-ia32.cc (revision 5030)
|
| +++ 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());
|
| @@ -9860,6 +9866,7 @@
|
| // the four basic operations. The stub stays in the DEFAULT state
|
| // forever for all other operations (also if smi code is skipped).
|
| GenerateTypeTransition(masm);
|
| + break;
|
| }
|
|
|
| Label not_floats;
|
| @@ -10207,51 +10214,28 @@
|
|
|
|
|
| void GenericBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
|
| - Label get_result;
|
| -
|
| - // Keep a copy of operands on the stack and make sure they are also in
|
| - // edx, eax.
|
| + // Ensure the operands are on the stack.
|
| if (HasArgsInRegisters()) {
|
| GenerateRegisterArgsPush(masm);
|
| - } else {
|
| - GenerateLoadArguments(masm);
|
| }
|
|
|
| - // Internal frame is necessary to handle exceptions properly.
|
| - __ EnterInternalFrame();
|
| + __ pop(ecx); // Save return address.
|
|
|
| - // Push arguments on stack if the stub expects them there.
|
| - if (!HasArgsInRegisters()) {
|
| - __ push(edx);
|
| - __ push(eax);
|
| - }
|
| - // Call the stub proper to get the result in eax.
|
| - __ call(&get_result);
|
| - __ LeaveInternalFrame();
|
| -
|
| - __ pop(ecx); // Return address.
|
| // Left and right arguments are now on top.
|
| - // Push the operation result. The tail call to BinaryOp_Patch will
|
| - // return it to the original caller.
|
| - __ push(eax);
|
| // Push this stub's key. Although the operation and the type info are
|
| // encoded into the key, the encoding is opaque, so push them too.
|
| __ push(Immediate(Smi::FromInt(MinorKey())));
|
| __ push(Immediate(Smi::FromInt(op_)));
|
| __ push(Immediate(Smi::FromInt(runtime_operands_type_)));
|
|
|
| - __ push(ecx); // Return address.
|
| + __ push(ecx); // Push return address.
|
|
|
| - // Patch the caller to an appropriate specialized stub
|
| - // and return the operation result.
|
| + // Patch the caller to an appropriate specialized stub and return the
|
| + // operation result to the caller of the stub.
|
| __ TailCallExternalReference(
|
| ExternalReference(IC_Utility(IC::kBinaryOp_Patch)),
|
| - 6,
|
| + 5,
|
| 1);
|
| -
|
| - // The entry point for the result calculation is assumed to be immediately
|
| - // after this sequence.
|
| - __ bind(&get_result);
|
| }
|
|
|
|
|
| @@ -10934,10 +10918,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 +10931,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 +10943,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 +10984,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.
|
|
|