| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1571 left->reg(), | 1571 left->reg(), |
| 1572 ecx, | 1572 ecx, |
| 1573 left->number_info(), | 1573 left->number_info(), |
| 1574 right->number_info(), | 1574 right->number_info(), |
| 1575 overwrite_mode); | 1575 overwrite_mode); |
| 1576 | 1576 |
| 1577 Label do_op, left_nonsmi; | 1577 Label do_op, left_nonsmi; |
| 1578 // if right is a smi we make a fast case if left is either a smi | 1578 // if right is a smi we make a fast case if left is either a smi |
| 1579 // or a heapnumber. | 1579 // or a heapnumber. |
| 1580 if (CpuFeatures::IsSupported(SSE2) && right->number_info().IsSmi()) { | 1580 if (CpuFeatures::IsSupported(SSE2) && right->number_info().IsSmi()) { |
| 1581 CpuFeatures::Scope use_sse2(SSE2); |
| 1581 __ mov(answer.reg(), left->reg()); | 1582 __ mov(answer.reg(), left->reg()); |
| 1582 // Fast case - both are actually smis. | 1583 // Fast case - both are actually smis. |
| 1583 if (!left->number_info().IsSmi()) { | 1584 if (!left->number_info().IsSmi()) { |
| 1584 __ test(answer.reg(), Immediate(kSmiTagMask)); | 1585 __ test(answer.reg(), Immediate(kSmiTagMask)); |
| 1585 __ j(not_zero, &left_nonsmi); | 1586 __ j(not_zero, &left_nonsmi); |
| 1586 } | 1587 } |
| 1587 __ SmiUntag(answer.reg()); | 1588 __ SmiUntag(answer.reg()); |
| 1588 __ jmp(&do_op); | 1589 __ jmp(&do_op); |
| 1589 | 1590 |
| 1590 __ bind(&left_nonsmi); | 1591 __ bind(&left_nonsmi); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1601 deferred->Branch(negative); | 1602 deferred->Branch(negative); |
| 1602 } else { | 1603 } else { |
| 1603 CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(), | 1604 CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(), |
| 1604 left->number_info(), right->number_info(), deferred); | 1605 left->number_info(), right->number_info(), deferred); |
| 1605 | 1606 |
| 1606 // Untag both operands. | 1607 // Untag both operands. |
| 1607 __ mov(answer.reg(), left->reg()); | 1608 __ mov(answer.reg(), left->reg()); |
| 1608 __ SmiUntag(answer.reg()); | 1609 __ SmiUntag(answer.reg()); |
| 1609 } | 1610 } |
| 1610 | 1611 |
| 1612 __ bind(&do_op); |
| 1611 __ SmiUntag(ecx); | 1613 __ SmiUntag(ecx); |
| 1612 // Perform the operation. | 1614 // Perform the operation. |
| 1613 switch (op) { | 1615 switch (op) { |
| 1614 case Token::SAR: | 1616 case Token::SAR: |
| 1615 __ sar_cl(answer.reg()); | 1617 __ sar_cl(answer.reg()); |
| 1616 // No checks of result necessary | 1618 // No checks of result necessary |
| 1617 break; | 1619 break; |
| 1618 case Token::SHR: { | 1620 case Token::SHR: { |
| 1619 Label result_ok; | 1621 Label result_ok; |
| 1620 __ shr_cl(answer.reg()); | 1622 __ shr_cl(answer.reg()); |
| (...skipping 5024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6645 } | 6647 } |
| 6646 case Token::ADD: { | 6648 case Token::ADD: { |
| 6647 // Unary plus has no effect on int32 values. | 6649 // Unary plus has no effect on int32 values. |
| 6648 break; | 6650 break; |
| 6649 } | 6651 } |
| 6650 default: | 6652 default: |
| 6651 UNREACHABLE(); | 6653 UNREACHABLE(); |
| 6652 break; | 6654 break; |
| 6653 } | 6655 } |
| 6654 frame_->Push(&value); | 6656 frame_->Push(&value); |
| 6655 | |
| 6656 } else { | 6657 } else { |
| 6657 Load(node->expression()); | 6658 Load(node->expression()); |
| 6658 bool overwrite = | 6659 bool overwrite = |
| 6659 (node->expression()->AsBinaryOperation() != NULL && | 6660 (node->expression()->AsBinaryOperation() != NULL && |
| 6660 node->expression()->AsBinaryOperation()->ResultOverwriteAllowed()); | 6661 node->expression()->AsBinaryOperation()->ResultOverwriteAllowed()); |
| 6661 switch (op) { | 6662 switch (op) { |
| 6662 case Token::SUB: { | 6663 case Token::SUB: { |
| 6663 GenericUnaryOpStub stub(Token::SUB, overwrite); | 6664 GenericUnaryOpStub stub(Token::SUB, overwrite); |
| 6664 Result operand = frame_->Pop(); | 6665 Result operand = frame_->Pop(); |
| 6665 Result answer = frame_->CallStub(&stub, &operand); | 6666 Result answer = frame_->CallStub(&stub, &operand); |
| 6667 answer.set_number_info(NumberInfo::Number()); |
| 6666 frame_->Push(&answer); | 6668 frame_->Push(&answer); |
| 6667 break; | 6669 break; |
| 6668 } | 6670 } |
| 6669 | |
| 6670 case Token::BIT_NOT: { | 6671 case Token::BIT_NOT: { |
| 6671 // Smi check. | 6672 // Smi check. |
| 6672 JumpTarget smi_label; | 6673 JumpTarget smi_label; |
| 6673 JumpTarget continue_label; | 6674 JumpTarget continue_label; |
| 6674 Result operand = frame_->Pop(); | 6675 Result operand = frame_->Pop(); |
| 6676 NumberInfo operand_info = operand.number_info(); |
| 6675 operand.ToRegister(); | 6677 operand.ToRegister(); |
| 6676 __ test(operand.reg(), Immediate(kSmiTagMask)); | 6678 if (operand_info.IsSmi()) { |
| 6677 smi_label.Branch(zero, &operand, taken); | 6679 if (FLAG_debug_code) { |
| 6680 __ AbortIfNotSmi(operand.reg(), "Operand not a smi."); |
| 6681 } |
| 6682 frame_->Spill(operand.reg()); |
| 6683 // Set smi tag bit. It will be reset by the not operation. |
| 6684 __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask)); |
| 6685 __ not_(operand.reg()); |
| 6686 Result answer = operand; |
| 6687 answer.set_number_info(NumberInfo::Smi()); |
| 6688 frame_->Push(&answer); |
| 6689 } else { |
| 6690 __ test(operand.reg(), Immediate(kSmiTagMask)); |
| 6691 smi_label.Branch(zero, &operand, taken); |
| 6678 | 6692 |
| 6679 GenericUnaryOpStub stub(Token::BIT_NOT, overwrite); | 6693 GenericUnaryOpStub stub(Token::BIT_NOT, overwrite); |
| 6680 Result answer = frame_->CallStub(&stub, &operand); | 6694 Result answer = frame_->CallStub(&stub, &operand); |
| 6681 continue_label.Jump(&answer); | 6695 continue_label.Jump(&answer); |
| 6682 | 6696 |
| 6683 smi_label.Bind(&answer); | 6697 smi_label.Bind(&answer); |
| 6684 answer.ToRegister(); | 6698 answer.ToRegister(); |
| 6685 frame_->Spill(answer.reg()); | 6699 frame_->Spill(answer.reg()); |
| 6686 __ not_(answer.reg()); | 6700 // Set smi tag bit. It will be reset by the not operation. |
| 6687 __ and_(answer.reg(), ~kSmiTagMask); // Remove inverted smi-tag. | 6701 __ lea(answer.reg(), Operand(answer.reg(), kSmiTagMask)); |
| 6702 __ not_(answer.reg()); |
| 6688 | 6703 |
| 6689 continue_label.Bind(&answer); | 6704 continue_label.Bind(&answer); |
| 6690 frame_->Push(&answer); | 6705 if (operand_info.IsInteger32()) { |
| 6706 answer.set_number_info(NumberInfo::Integer32()); |
| 6707 } else { |
| 6708 answer.set_number_info(NumberInfo::Number()); |
| 6709 } |
| 6710 frame_->Push(&answer); |
| 6711 } |
| 6691 break; | 6712 break; |
| 6692 } | 6713 } |
| 6693 | |
| 6694 case Token::ADD: { | 6714 case Token::ADD: { |
| 6695 // Smi check. | 6715 // Smi check. |
| 6696 JumpTarget continue_label; | 6716 JumpTarget continue_label; |
| 6697 Result operand = frame_->Pop(); | 6717 Result operand = frame_->Pop(); |
| 6718 NumberInfo operand_info = operand.number_info(); |
| 6698 operand.ToRegister(); | 6719 operand.ToRegister(); |
| 6699 __ test(operand.reg(), Immediate(kSmiTagMask)); | 6720 __ test(operand.reg(), Immediate(kSmiTagMask)); |
| 6700 continue_label.Branch(zero, &operand, taken); | 6721 continue_label.Branch(zero, &operand, taken); |
| 6701 | 6722 |
| 6702 frame_->Push(&operand); | 6723 frame_->Push(&operand); |
| 6703 Result answer = frame_->InvokeBuiltin(Builtins::TO_NUMBER, | 6724 Result answer = frame_->InvokeBuiltin(Builtins::TO_NUMBER, |
| 6704 CALL_FUNCTION, 1); | 6725 CALL_FUNCTION, 1); |
| 6705 | 6726 |
| 6706 continue_label.Bind(&answer); | 6727 continue_label.Bind(&answer); |
| 6728 if (operand_info.IsSmi()) { |
| 6729 answer.set_number_info(NumberInfo::Smi()); |
| 6730 } else if (operand_info.IsInteger32()) { |
| 6731 answer.set_number_info(NumberInfo::Integer32()); |
| 6732 } else { |
| 6733 answer.set_number_info(NumberInfo::Number()); |
| 6734 } |
| 6707 frame_->Push(&answer); | 6735 frame_->Push(&answer); |
| 6708 break; | 6736 break; |
| 6709 } | 6737 } |
| 6710 | |
| 6711 default: | 6738 default: |
| 6712 // NOT, DELETE, TYPEOF, and VOID are handled outside the | 6739 // NOT, DELETE, TYPEOF, and VOID are handled outside the |
| 6713 // switch. | 6740 // switch. |
| 6714 UNREACHABLE(); | 6741 UNREACHABLE(); |
| 6715 } | 6742 } |
| 6716 } | 6743 } |
| 6717 } | 6744 } |
| 6718 } | 6745 } |
| 6719 | 6746 |
| 6720 | 6747 |
| (...skipping 5472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12193 | 12220 |
| 12194 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 12221 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 12195 // tagged as a small integer. | 12222 // tagged as a small integer. |
| 12196 __ bind(&runtime); | 12223 __ bind(&runtime); |
| 12197 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 12224 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 12198 } | 12225 } |
| 12199 | 12226 |
| 12200 #undef __ | 12227 #undef __ |
| 12201 | 12228 |
| 12202 } } // namespace v8::internal | 12229 } } // namespace v8::internal |
| OLD | NEW |