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 |