| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
| 8 | 8 |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 __ ld(a3, FieldMemOperand(lhs, HeapObject::kMapOffset)); | 595 __ ld(a3, FieldMemOperand(lhs, HeapObject::kMapOffset)); |
| 596 __ lbu(a2, FieldMemOperand(a2, Map::kBitFieldOffset)); | 596 __ lbu(a2, FieldMemOperand(a2, Map::kBitFieldOffset)); |
| 597 __ lbu(a3, FieldMemOperand(a3, Map::kBitFieldOffset)); | 597 __ lbu(a3, FieldMemOperand(a3, Map::kBitFieldOffset)); |
| 598 __ and_(a0, a2, a3); | 598 __ and_(a0, a2, a3); |
| 599 __ And(a0, a0, Operand(1 << Map::kIsUndetectable)); | 599 __ And(a0, a0, Operand(1 << Map::kIsUndetectable)); |
| 600 __ Ret(USE_DELAY_SLOT); | 600 __ Ret(USE_DELAY_SLOT); |
| 601 __ xori(v0, a0, 1 << Map::kIsUndetectable); | 601 __ xori(v0, a0, 1 << Map::kIsUndetectable); |
| 602 } | 602 } |
| 603 | 603 |
| 604 | 604 |
| 605 static void ICCompareStub_CheckInputType(MacroAssembler* masm, | 605 static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input, |
| 606 Register input, | |
| 607 Register scratch, | 606 Register scratch, |
| 608 CompareIC::State expected, | 607 CompareIC::State expected, |
| 609 Label* fail) { | 608 Label* fail) { |
| 610 Label ok; | 609 Label ok; |
| 611 if (expected == CompareIC::SMI) { | 610 if (expected == CompareIC::SMI) { |
| 612 __ JumpIfNotSmi(input, fail); | 611 __ JumpIfNotSmi(input, fail); |
| 613 } else if (expected == CompareIC::NUMBER) { | 612 } else if (expected == CompareIC::NUMBER) { |
| 614 __ JumpIfSmi(input, &ok); | 613 __ JumpIfSmi(input, &ok); |
| 615 __ CheckMap(input, scratch, Heap::kHeapNumberMapRootIndex, fail, | 614 __ CheckMap(input, scratch, Heap::kHeapNumberMapRootIndex, fail, |
| 616 DONT_DO_SMI_CHECK); | 615 DONT_DO_SMI_CHECK); |
| 617 } | 616 } |
| 618 // We could be strict about internalized/string here, but as long as | 617 // We could be strict about internalized/string here, but as long as |
| 619 // hydrogen doesn't care, the stub doesn't have to care either. | 618 // hydrogen doesn't care, the stub doesn't have to care either. |
| 620 __ bind(&ok); | 619 __ bind(&ok); |
| 621 } | 620 } |
| 622 | 621 |
| 623 | 622 |
| 624 // On entry a1 and a2 are the values to be compared. | 623 // On entry a1 and a2 are the values to be compared. |
| 625 // On exit a0 is 0, positive or negative to indicate the result of | 624 // On exit a0 is 0, positive or negative to indicate the result of |
| 626 // the comparison. | 625 // the comparison. |
| 627 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { | 626 void CompareICStub::GenerateGeneric(MacroAssembler* masm) { |
| 628 Register lhs = a1; | 627 Register lhs = a1; |
| 629 Register rhs = a0; | 628 Register rhs = a0; |
| 630 Condition cc = GetCondition(); | 629 Condition cc = GetCondition(); |
| 631 | 630 |
| 632 Label miss; | 631 Label miss; |
| 633 ICCompareStub_CheckInputType(masm, lhs, a2, left(), &miss); | 632 CompareICStub_CheckInputType(masm, lhs, a2, left(), &miss); |
| 634 ICCompareStub_CheckInputType(masm, rhs, a3, right(), &miss); | 633 CompareICStub_CheckInputType(masm, rhs, a3, right(), &miss); |
| 635 | 634 |
| 636 Label slow; // Call builtin. | 635 Label slow; // Call builtin. |
| 637 Label not_smis, both_loaded_as_doubles; | 636 Label not_smis, both_loaded_as_doubles; |
| 638 | 637 |
| 639 Label not_two_smis, smi_done; | 638 Label not_two_smis, smi_done; |
| 640 __ Or(a2, a1, a0); | 639 __ Or(a2, a1, a0); |
| 641 __ JumpIfNotSmi(a2, ¬_two_smis); | 640 __ JumpIfNotSmi(a2, ¬_two_smis); |
| 642 __ SmiUntag(a1); | 641 __ SmiUntag(a1); |
| 643 __ SmiUntag(a0); | 642 __ SmiUntag(a0); |
| 644 | 643 |
| (...skipping 2906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3551 __ Assert(eq, kExpectedAllocationSite, a4, Operand(at)); | 3550 __ Assert(eq, kExpectedAllocationSite, a4, Operand(at)); |
| 3552 } | 3551 } |
| 3553 | 3552 |
| 3554 // Tail call into the stub that handles binary operations with allocation | 3553 // Tail call into the stub that handles binary operations with allocation |
| 3555 // sites. | 3554 // sites. |
| 3556 BinaryOpWithAllocationSiteStub stub(isolate(), state()); | 3555 BinaryOpWithAllocationSiteStub stub(isolate(), state()); |
| 3557 __ TailCallStub(&stub); | 3556 __ TailCallStub(&stub); |
| 3558 } | 3557 } |
| 3559 | 3558 |
| 3560 | 3559 |
| 3561 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { | 3560 void CompareICStub::GenerateSmis(MacroAssembler* masm) { |
| 3562 DCHECK(state() == CompareIC::SMI); | 3561 DCHECK(state() == CompareIC::SMI); |
| 3563 Label miss; | 3562 Label miss; |
| 3564 __ Or(a2, a1, a0); | 3563 __ Or(a2, a1, a0); |
| 3565 __ JumpIfNotSmi(a2, &miss); | 3564 __ JumpIfNotSmi(a2, &miss); |
| 3566 | 3565 |
| 3567 if (GetCondition() == eq) { | 3566 if (GetCondition() == eq) { |
| 3568 // For equality we do not care about the sign of the result. | 3567 // For equality we do not care about the sign of the result. |
| 3569 __ Ret(USE_DELAY_SLOT); | 3568 __ Ret(USE_DELAY_SLOT); |
| 3570 __ Dsubu(v0, a0, a1); | 3569 __ Dsubu(v0, a0, a1); |
| 3571 } else { | 3570 } else { |
| 3572 // Untag before subtracting to avoid handling overflow. | 3571 // Untag before subtracting to avoid handling overflow. |
| 3573 __ SmiUntag(a1); | 3572 __ SmiUntag(a1); |
| 3574 __ SmiUntag(a0); | 3573 __ SmiUntag(a0); |
| 3575 __ Ret(USE_DELAY_SLOT); | 3574 __ Ret(USE_DELAY_SLOT); |
| 3576 __ Dsubu(v0, a1, a0); | 3575 __ Dsubu(v0, a1, a0); |
| 3577 } | 3576 } |
| 3578 | 3577 |
| 3579 __ bind(&miss); | 3578 __ bind(&miss); |
| 3580 GenerateMiss(masm); | 3579 GenerateMiss(masm); |
| 3581 } | 3580 } |
| 3582 | 3581 |
| 3583 | 3582 |
| 3584 void ICCompareStub::GenerateNumbers(MacroAssembler* masm) { | 3583 void CompareICStub::GenerateNumbers(MacroAssembler* masm) { |
| 3585 DCHECK(state() == CompareIC::NUMBER); | 3584 DCHECK(state() == CompareIC::NUMBER); |
| 3586 | 3585 |
| 3587 Label generic_stub; | 3586 Label generic_stub; |
| 3588 Label unordered, maybe_undefined1, maybe_undefined2; | 3587 Label unordered, maybe_undefined1, maybe_undefined2; |
| 3589 Label miss; | 3588 Label miss; |
| 3590 | 3589 |
| 3591 if (left() == CompareIC::SMI) { | 3590 if (left() == CompareIC::SMI) { |
| 3592 __ JumpIfNotSmi(a1, &miss); | 3591 __ JumpIfNotSmi(a1, &miss); |
| 3593 } | 3592 } |
| 3594 if (right() == CompareIC::SMI) { | 3593 if (right() == CompareIC::SMI) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3642 __ bind(&fpu_eq); | 3641 __ bind(&fpu_eq); |
| 3643 __ Ret(USE_DELAY_SLOT); | 3642 __ Ret(USE_DELAY_SLOT); |
| 3644 __ li(v0, Operand(EQUAL)); | 3643 __ li(v0, Operand(EQUAL)); |
| 3645 | 3644 |
| 3646 __ bind(&fpu_lt); | 3645 __ bind(&fpu_lt); |
| 3647 __ Ret(USE_DELAY_SLOT); | 3646 __ Ret(USE_DELAY_SLOT); |
| 3648 __ li(v0, Operand(LESS)); | 3647 __ li(v0, Operand(LESS)); |
| 3649 | 3648 |
| 3650 __ bind(&unordered); | 3649 __ bind(&unordered); |
| 3651 __ bind(&generic_stub); | 3650 __ bind(&generic_stub); |
| 3652 ICCompareStub stub(isolate(), op(), CompareIC::GENERIC, CompareIC::GENERIC, | 3651 CompareICStub stub(isolate(), op(), CompareIC::GENERIC, CompareIC::GENERIC, |
| 3653 CompareIC::GENERIC); | 3652 CompareIC::GENERIC); |
| 3654 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | 3653 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 3655 | 3654 |
| 3656 __ bind(&maybe_undefined1); | 3655 __ bind(&maybe_undefined1); |
| 3657 if (Token::IsOrderedRelationalCompareOp(op())) { | 3656 if (Token::IsOrderedRelationalCompareOp(op())) { |
| 3658 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 3657 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 3659 __ Branch(&miss, ne, a0, Operand(at)); | 3658 __ Branch(&miss, ne, a0, Operand(at)); |
| 3660 __ JumpIfSmi(a1, &unordered); | 3659 __ JumpIfSmi(a1, &unordered); |
| 3661 __ GetObjectType(a1, a2, a2); | 3660 __ GetObjectType(a1, a2, a2); |
| 3662 __ Branch(&maybe_undefined2, ne, a2, Operand(HEAP_NUMBER_TYPE)); | 3661 __ Branch(&maybe_undefined2, ne, a2, Operand(HEAP_NUMBER_TYPE)); |
| 3663 __ jmp(&unordered); | 3662 __ jmp(&unordered); |
| 3664 } | 3663 } |
| 3665 | 3664 |
| 3666 __ bind(&maybe_undefined2); | 3665 __ bind(&maybe_undefined2); |
| 3667 if (Token::IsOrderedRelationalCompareOp(op())) { | 3666 if (Token::IsOrderedRelationalCompareOp(op())) { |
| 3668 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 3667 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 3669 __ Branch(&unordered, eq, a1, Operand(at)); | 3668 __ Branch(&unordered, eq, a1, Operand(at)); |
| 3670 } | 3669 } |
| 3671 | 3670 |
| 3672 __ bind(&miss); | 3671 __ bind(&miss); |
| 3673 GenerateMiss(masm); | 3672 GenerateMiss(masm); |
| 3674 } | 3673 } |
| 3675 | 3674 |
| 3676 | 3675 |
| 3677 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) { | 3676 void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) { |
| 3678 DCHECK(state() == CompareIC::INTERNALIZED_STRING); | 3677 DCHECK(state() == CompareIC::INTERNALIZED_STRING); |
| 3679 Label miss; | 3678 Label miss; |
| 3680 | 3679 |
| 3681 // Registers containing left and right operands respectively. | 3680 // Registers containing left and right operands respectively. |
| 3682 Register left = a1; | 3681 Register left = a1; |
| 3683 Register right = a0; | 3682 Register right = a0; |
| 3684 Register tmp1 = a2; | 3683 Register tmp1 = a2; |
| 3685 Register tmp2 = a3; | 3684 Register tmp2 = a3; |
| 3686 | 3685 |
| 3687 // Check that both operands are heap objects. | 3686 // Check that both operands are heap objects. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3707 __ Ret(ne, left, Operand(right)); | 3706 __ Ret(ne, left, Operand(right)); |
| 3708 DCHECK(is_int16(EQUAL)); | 3707 DCHECK(is_int16(EQUAL)); |
| 3709 __ Ret(USE_DELAY_SLOT); | 3708 __ Ret(USE_DELAY_SLOT); |
| 3710 __ li(v0, Operand(Smi::FromInt(EQUAL))); | 3709 __ li(v0, Operand(Smi::FromInt(EQUAL))); |
| 3711 | 3710 |
| 3712 __ bind(&miss); | 3711 __ bind(&miss); |
| 3713 GenerateMiss(masm); | 3712 GenerateMiss(masm); |
| 3714 } | 3713 } |
| 3715 | 3714 |
| 3716 | 3715 |
| 3717 void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) { | 3716 void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) { |
| 3718 DCHECK(state() == CompareIC::UNIQUE_NAME); | 3717 DCHECK(state() == CompareIC::UNIQUE_NAME); |
| 3719 DCHECK(GetCondition() == eq); | 3718 DCHECK(GetCondition() == eq); |
| 3720 Label miss; | 3719 Label miss; |
| 3721 | 3720 |
| 3722 // Registers containing left and right operands respectively. | 3721 // Registers containing left and right operands respectively. |
| 3723 Register left = a1; | 3722 Register left = a1; |
| 3724 Register right = a0; | 3723 Register right = a0; |
| 3725 Register tmp1 = a2; | 3724 Register tmp1 = a2; |
| 3726 Register tmp2 = a3; | 3725 Register tmp2 = a3; |
| 3727 | 3726 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3751 STATIC_ASSERT(kSmiTag == 0); | 3750 STATIC_ASSERT(kSmiTag == 0); |
| 3752 __ li(v0, Operand(Smi::FromInt(EQUAL))); | 3751 __ li(v0, Operand(Smi::FromInt(EQUAL))); |
| 3753 __ bind(&done); | 3752 __ bind(&done); |
| 3754 __ Ret(); | 3753 __ Ret(); |
| 3755 | 3754 |
| 3756 __ bind(&miss); | 3755 __ bind(&miss); |
| 3757 GenerateMiss(masm); | 3756 GenerateMiss(masm); |
| 3758 } | 3757 } |
| 3759 | 3758 |
| 3760 | 3759 |
| 3761 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { | 3760 void CompareICStub::GenerateStrings(MacroAssembler* masm) { |
| 3762 DCHECK(state() == CompareIC::STRING); | 3761 DCHECK(state() == CompareIC::STRING); |
| 3763 Label miss; | 3762 Label miss; |
| 3764 | 3763 |
| 3765 bool equality = Token::IsEqualityOp(op()); | 3764 bool equality = Token::IsEqualityOp(op()); |
| 3766 | 3765 |
| 3767 // Registers containing left and right operands respectively. | 3766 // Registers containing left and right operands respectively. |
| 3768 Register left = a1; | 3767 Register left = a1; |
| 3769 Register right = a0; | 3768 Register right = a0; |
| 3770 Register tmp1 = a2; | 3769 Register tmp1 = a2; |
| 3771 Register tmp2 = a3; | 3770 Register tmp2 = a3; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3837 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 3836 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
| 3838 } else { | 3837 } else { |
| 3839 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3838 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 3840 } | 3839 } |
| 3841 | 3840 |
| 3842 __ bind(&miss); | 3841 __ bind(&miss); |
| 3843 GenerateMiss(masm); | 3842 GenerateMiss(masm); |
| 3844 } | 3843 } |
| 3845 | 3844 |
| 3846 | 3845 |
| 3847 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { | 3846 void CompareICStub::GenerateObjects(MacroAssembler* masm) { |
| 3848 DCHECK(state() == CompareIC::OBJECT); | 3847 DCHECK(state() == CompareIC::OBJECT); |
| 3849 Label miss; | 3848 Label miss; |
| 3850 __ And(a2, a1, Operand(a0)); | 3849 __ And(a2, a1, Operand(a0)); |
| 3851 __ JumpIfSmi(a2, &miss); | 3850 __ JumpIfSmi(a2, &miss); |
| 3852 | 3851 |
| 3853 __ GetObjectType(a0, a2, a2); | 3852 __ GetObjectType(a0, a2, a2); |
| 3854 __ Branch(&miss, ne, a2, Operand(JS_OBJECT_TYPE)); | 3853 __ Branch(&miss, ne, a2, Operand(JS_OBJECT_TYPE)); |
| 3855 __ GetObjectType(a1, a2, a2); | 3854 __ GetObjectType(a1, a2, a2); |
| 3856 __ Branch(&miss, ne, a2, Operand(JS_OBJECT_TYPE)); | 3855 __ Branch(&miss, ne, a2, Operand(JS_OBJECT_TYPE)); |
| 3857 | 3856 |
| 3858 DCHECK(GetCondition() == eq); | 3857 DCHECK(GetCondition() == eq); |
| 3859 __ Ret(USE_DELAY_SLOT); | 3858 __ Ret(USE_DELAY_SLOT); |
| 3860 __ dsubu(v0, a0, a1); | 3859 __ dsubu(v0, a0, a1); |
| 3861 | 3860 |
| 3862 __ bind(&miss); | 3861 __ bind(&miss); |
| 3863 GenerateMiss(masm); | 3862 GenerateMiss(masm); |
| 3864 } | 3863 } |
| 3865 | 3864 |
| 3866 | 3865 |
| 3867 void ICCompareStub::GenerateKnownObjects(MacroAssembler* masm) { | 3866 void CompareICStub::GenerateKnownObjects(MacroAssembler* masm) { |
| 3868 Label miss; | 3867 Label miss; |
| 3869 __ And(a2, a1, a0); | 3868 __ And(a2, a1, a0); |
| 3870 __ JumpIfSmi(a2, &miss); | 3869 __ JumpIfSmi(a2, &miss); |
| 3871 __ ld(a2, FieldMemOperand(a0, HeapObject::kMapOffset)); | 3870 __ ld(a2, FieldMemOperand(a0, HeapObject::kMapOffset)); |
| 3872 __ ld(a3, FieldMemOperand(a1, HeapObject::kMapOffset)); | 3871 __ ld(a3, FieldMemOperand(a1, HeapObject::kMapOffset)); |
| 3873 __ Branch(&miss, ne, a2, Operand(known_map_)); | 3872 __ Branch(&miss, ne, a2, Operand(known_map_)); |
| 3874 __ Branch(&miss, ne, a3, Operand(known_map_)); | 3873 __ Branch(&miss, ne, a3, Operand(known_map_)); |
| 3875 | 3874 |
| 3876 __ Ret(USE_DELAY_SLOT); | 3875 __ Ret(USE_DELAY_SLOT); |
| 3877 __ dsubu(v0, a0, a1); | 3876 __ dsubu(v0, a0, a1); |
| 3878 | 3877 |
| 3879 __ bind(&miss); | 3878 __ bind(&miss); |
| 3880 GenerateMiss(masm); | 3879 GenerateMiss(masm); |
| 3881 } | 3880 } |
| 3882 | 3881 |
| 3883 | 3882 |
| 3884 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { | 3883 void CompareICStub::GenerateMiss(MacroAssembler* masm) { |
| 3885 { | 3884 { |
| 3886 // Call the runtime system in a fresh internal frame. | 3885 // Call the runtime system in a fresh internal frame. |
| 3887 ExternalReference miss = | 3886 ExternalReference miss = |
| 3888 ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate()); | 3887 ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate()); |
| 3889 FrameScope scope(masm, StackFrame::INTERNAL); | 3888 FrameScope scope(masm, StackFrame::INTERNAL); |
| 3890 __ Push(a1, a0); | 3889 __ Push(a1, a0); |
| 3891 __ Push(ra, a1, a0); | 3890 __ Push(ra, a1, a0); |
| 3892 __ li(a4, Operand(Smi::FromInt(op()))); | 3891 __ li(a4, Operand(Smi::FromInt(op()))); |
| 3893 __ daddiu(sp, sp, -kPointerSize); | 3892 __ daddiu(sp, sp, -kPointerSize); |
| 3894 __ CallExternalReference(miss, 3, USE_DELAY_SLOT); | 3893 __ CallExternalReference(miss, 3, USE_DELAY_SLOT); |
| (...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4976 MemOperand(fp, 6 * kPointerSize), | 4975 MemOperand(fp, 6 * kPointerSize), |
| 4977 NULL); | 4976 NULL); |
| 4978 } | 4977 } |
| 4979 | 4978 |
| 4980 | 4979 |
| 4981 #undef __ | 4980 #undef __ |
| 4982 | 4981 |
| 4983 } } // namespace v8::internal | 4982 } } // namespace v8::internal |
| 4984 | 4983 |
| 4985 #endif // V8_TARGET_ARCH_MIPS64 | 4984 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |