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 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 | 728 |
729 // On entry a1 and a2 are the values to be compared. | 729 // On entry a1 and a2 are the values to be compared. |
730 // On exit a0 is 0, positive or negative to indicate the result of | 730 // On exit a0 is 0, positive or negative to indicate the result of |
731 // the comparison. | 731 // the comparison. |
732 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { | 732 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { |
733 Register lhs = a1; | 733 Register lhs = a1; |
734 Register rhs = a0; | 734 Register rhs = a0; |
735 Condition cc = GetCondition(); | 735 Condition cc = GetCondition(); |
736 | 736 |
737 Label miss; | 737 Label miss; |
738 ICCompareStub_CheckInputType(masm, lhs, a2, left_, &miss); | 738 ICCompareStub_CheckInputType(masm, lhs, a2, left(), &miss); |
739 ICCompareStub_CheckInputType(masm, rhs, a3, right_, &miss); | 739 ICCompareStub_CheckInputType(masm, rhs, a3, right(), &miss); |
740 | 740 |
741 Label slow; // Call builtin. | 741 Label slow; // Call builtin. |
742 Label not_smis, both_loaded_as_doubles; | 742 Label not_smis, both_loaded_as_doubles; |
743 | 743 |
744 Label not_two_smis, smi_done; | 744 Label not_two_smis, smi_done; |
745 __ Or(a2, a1, a0); | 745 __ Or(a2, a1, a0); |
746 __ JumpIfNotSmi(a2, ¬_two_smis); | 746 __ JumpIfNotSmi(a2, ¬_two_smis); |
747 __ SmiUntag(a1); | 747 __ SmiUntag(a1); |
748 __ SmiUntag(a0); | 748 __ SmiUntag(a0); |
749 | 749 |
(...skipping 2927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3677 } | 3677 } |
3678 | 3678 |
3679 // Tail call into the stub that handles binary operations with allocation | 3679 // Tail call into the stub that handles binary operations with allocation |
3680 // sites. | 3680 // sites. |
3681 BinaryOpWithAllocationSiteStub stub(isolate(), state()); | 3681 BinaryOpWithAllocationSiteStub stub(isolate(), state()); |
3682 __ TailCallStub(&stub); | 3682 __ TailCallStub(&stub); |
3683 } | 3683 } |
3684 | 3684 |
3685 | 3685 |
3686 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { | 3686 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { |
3687 DCHECK(state_ == CompareIC::SMI); | 3687 DCHECK(state() == CompareIC::SMI); |
3688 Label miss; | 3688 Label miss; |
3689 __ Or(a2, a1, a0); | 3689 __ Or(a2, a1, a0); |
3690 __ JumpIfNotSmi(a2, &miss); | 3690 __ JumpIfNotSmi(a2, &miss); |
3691 | 3691 |
3692 if (GetCondition() == eq) { | 3692 if (GetCondition() == eq) { |
3693 // For equality we do not care about the sign of the result. | 3693 // For equality we do not care about the sign of the result. |
3694 __ Ret(USE_DELAY_SLOT); | 3694 __ Ret(USE_DELAY_SLOT); |
3695 __ Dsubu(v0, a0, a1); | 3695 __ Dsubu(v0, a0, a1); |
3696 } else { | 3696 } else { |
3697 // Untag before subtracting to avoid handling overflow. | 3697 // Untag before subtracting to avoid handling overflow. |
3698 __ SmiUntag(a1); | 3698 __ SmiUntag(a1); |
3699 __ SmiUntag(a0); | 3699 __ SmiUntag(a0); |
3700 __ Ret(USE_DELAY_SLOT); | 3700 __ Ret(USE_DELAY_SLOT); |
3701 __ Dsubu(v0, a1, a0); | 3701 __ Dsubu(v0, a1, a0); |
3702 } | 3702 } |
3703 | 3703 |
3704 __ bind(&miss); | 3704 __ bind(&miss); |
3705 GenerateMiss(masm); | 3705 GenerateMiss(masm); |
3706 } | 3706 } |
3707 | 3707 |
3708 | 3708 |
3709 void ICCompareStub::GenerateNumbers(MacroAssembler* masm) { | 3709 void ICCompareStub::GenerateNumbers(MacroAssembler* masm) { |
3710 DCHECK(state_ == CompareIC::NUMBER); | 3710 DCHECK(state() == CompareIC::NUMBER); |
3711 | 3711 |
3712 Label generic_stub; | 3712 Label generic_stub; |
3713 Label unordered, maybe_undefined1, maybe_undefined2; | 3713 Label unordered, maybe_undefined1, maybe_undefined2; |
3714 Label miss; | 3714 Label miss; |
3715 | 3715 |
3716 if (left_ == CompareIC::SMI) { | 3716 if (left() == CompareIC::SMI) { |
3717 __ JumpIfNotSmi(a1, &miss); | 3717 __ JumpIfNotSmi(a1, &miss); |
3718 } | 3718 } |
3719 if (right_ == CompareIC::SMI) { | 3719 if (right() == CompareIC::SMI) { |
3720 __ JumpIfNotSmi(a0, &miss); | 3720 __ JumpIfNotSmi(a0, &miss); |
3721 } | 3721 } |
3722 | 3722 |
3723 // Inlining the double comparison and falling back to the general compare | 3723 // Inlining the double comparison and falling back to the general compare |
3724 // stub if NaN is involved. | 3724 // stub if NaN is involved. |
3725 // Load left and right operand. | 3725 // Load left and right operand. |
3726 Label done, left, left_smi, right_smi; | 3726 Label done, left, left_smi, right_smi; |
3727 __ JumpIfSmi(a0, &right_smi); | 3727 __ JumpIfSmi(a0, &right_smi); |
3728 __ CheckMap(a0, a2, Heap::kHeapNumberMapRootIndex, &maybe_undefined1, | 3728 __ CheckMap(a0, a2, Heap::kHeapNumberMapRootIndex, &maybe_undefined1, |
3729 DONT_DO_SMI_CHECK); | 3729 DONT_DO_SMI_CHECK); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3767 __ bind(&fpu_eq); | 3767 __ bind(&fpu_eq); |
3768 __ Ret(USE_DELAY_SLOT); | 3768 __ Ret(USE_DELAY_SLOT); |
3769 __ li(v0, Operand(EQUAL)); | 3769 __ li(v0, Operand(EQUAL)); |
3770 | 3770 |
3771 __ bind(&fpu_lt); | 3771 __ bind(&fpu_lt); |
3772 __ Ret(USE_DELAY_SLOT); | 3772 __ Ret(USE_DELAY_SLOT); |
3773 __ li(v0, Operand(LESS)); | 3773 __ li(v0, Operand(LESS)); |
3774 | 3774 |
3775 __ bind(&unordered); | 3775 __ bind(&unordered); |
3776 __ bind(&generic_stub); | 3776 __ bind(&generic_stub); |
3777 ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC, | 3777 ICCompareStub stub(isolate(), op(), CompareIC::GENERIC, CompareIC::GENERIC, |
3778 CompareIC::GENERIC); | 3778 CompareIC::GENERIC); |
3779 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | 3779 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); |
3780 | 3780 |
3781 __ bind(&maybe_undefined1); | 3781 __ bind(&maybe_undefined1); |
3782 if (Token::IsOrderedRelationalCompareOp(op_)) { | 3782 if (Token::IsOrderedRelationalCompareOp(op())) { |
3783 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 3783 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
3784 __ Branch(&miss, ne, a0, Operand(at)); | 3784 __ Branch(&miss, ne, a0, Operand(at)); |
3785 __ JumpIfSmi(a1, &unordered); | 3785 __ JumpIfSmi(a1, &unordered); |
3786 __ GetObjectType(a1, a2, a2); | 3786 __ GetObjectType(a1, a2, a2); |
3787 __ Branch(&maybe_undefined2, ne, a2, Operand(HEAP_NUMBER_TYPE)); | 3787 __ Branch(&maybe_undefined2, ne, a2, Operand(HEAP_NUMBER_TYPE)); |
3788 __ jmp(&unordered); | 3788 __ jmp(&unordered); |
3789 } | 3789 } |
3790 | 3790 |
3791 __ bind(&maybe_undefined2); | 3791 __ bind(&maybe_undefined2); |
3792 if (Token::IsOrderedRelationalCompareOp(op_)) { | 3792 if (Token::IsOrderedRelationalCompareOp(op())) { |
3793 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 3793 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
3794 __ Branch(&unordered, eq, a1, Operand(at)); | 3794 __ Branch(&unordered, eq, a1, Operand(at)); |
3795 } | 3795 } |
3796 | 3796 |
3797 __ bind(&miss); | 3797 __ bind(&miss); |
3798 GenerateMiss(masm); | 3798 GenerateMiss(masm); |
3799 } | 3799 } |
3800 | 3800 |
3801 | 3801 |
3802 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) { | 3802 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) { |
3803 DCHECK(state_ == CompareIC::INTERNALIZED_STRING); | 3803 DCHECK(state() == CompareIC::INTERNALIZED_STRING); |
3804 Label miss; | 3804 Label miss; |
3805 | 3805 |
3806 // Registers containing left and right operands respectively. | 3806 // Registers containing left and right operands respectively. |
3807 Register left = a1; | 3807 Register left = a1; |
3808 Register right = a0; | 3808 Register right = a0; |
3809 Register tmp1 = a2; | 3809 Register tmp1 = a2; |
3810 Register tmp2 = a3; | 3810 Register tmp2 = a3; |
3811 | 3811 |
3812 // Check that both operands are heap objects. | 3812 // Check that both operands are heap objects. |
3813 __ JumpIfEitherSmi(left, right, &miss); | 3813 __ JumpIfEitherSmi(left, right, &miss); |
(...skipping 19 matching lines...) Expand all Loading... |
3833 DCHECK(is_int16(EQUAL)); | 3833 DCHECK(is_int16(EQUAL)); |
3834 __ Ret(USE_DELAY_SLOT); | 3834 __ Ret(USE_DELAY_SLOT); |
3835 __ li(v0, Operand(Smi::FromInt(EQUAL))); | 3835 __ li(v0, Operand(Smi::FromInt(EQUAL))); |
3836 | 3836 |
3837 __ bind(&miss); | 3837 __ bind(&miss); |
3838 GenerateMiss(masm); | 3838 GenerateMiss(masm); |
3839 } | 3839 } |
3840 | 3840 |
3841 | 3841 |
3842 void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) { | 3842 void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) { |
3843 DCHECK(state_ == CompareIC::UNIQUE_NAME); | 3843 DCHECK(state() == CompareIC::UNIQUE_NAME); |
3844 DCHECK(GetCondition() == eq); | 3844 DCHECK(GetCondition() == eq); |
3845 Label miss; | 3845 Label miss; |
3846 | 3846 |
3847 // Registers containing left and right operands respectively. | 3847 // Registers containing left and right operands respectively. |
3848 Register left = a1; | 3848 Register left = a1; |
3849 Register right = a0; | 3849 Register right = a0; |
3850 Register tmp1 = a2; | 3850 Register tmp1 = a2; |
3851 Register tmp2 = a3; | 3851 Register tmp2 = a3; |
3852 | 3852 |
3853 // Check that both operands are heap objects. | 3853 // Check that both operands are heap objects. |
(...skipping 23 matching lines...) Expand all Loading... |
3877 __ li(v0, Operand(Smi::FromInt(EQUAL))); | 3877 __ li(v0, Operand(Smi::FromInt(EQUAL))); |
3878 __ bind(&done); | 3878 __ bind(&done); |
3879 __ Ret(); | 3879 __ Ret(); |
3880 | 3880 |
3881 __ bind(&miss); | 3881 __ bind(&miss); |
3882 GenerateMiss(masm); | 3882 GenerateMiss(masm); |
3883 } | 3883 } |
3884 | 3884 |
3885 | 3885 |
3886 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { | 3886 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { |
3887 DCHECK(state_ == CompareIC::STRING); | 3887 DCHECK(state() == CompareIC::STRING); |
3888 Label miss; | 3888 Label miss; |
3889 | 3889 |
3890 bool equality = Token::IsEqualityOp(op_); | 3890 bool equality = Token::IsEqualityOp(op()); |
3891 | 3891 |
3892 // Registers containing left and right operands respectively. | 3892 // Registers containing left and right operands respectively. |
3893 Register left = a1; | 3893 Register left = a1; |
3894 Register right = a0; | 3894 Register right = a0; |
3895 Register tmp1 = a2; | 3895 Register tmp1 = a2; |
3896 Register tmp2 = a3; | 3896 Register tmp2 = a3; |
3897 Register tmp3 = a4; | 3897 Register tmp3 = a4; |
3898 Register tmp4 = a5; | 3898 Register tmp4 = a5; |
3899 Register tmp5 = a6; | 3899 Register tmp5 = a6; |
3900 | 3900 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3963 } else { | 3963 } else { |
3964 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3964 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3965 } | 3965 } |
3966 | 3966 |
3967 __ bind(&miss); | 3967 __ bind(&miss); |
3968 GenerateMiss(masm); | 3968 GenerateMiss(masm); |
3969 } | 3969 } |
3970 | 3970 |
3971 | 3971 |
3972 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { | 3972 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { |
3973 DCHECK(state_ == CompareIC::OBJECT); | 3973 DCHECK(state() == CompareIC::OBJECT); |
3974 Label miss; | 3974 Label miss; |
3975 __ And(a2, a1, Operand(a0)); | 3975 __ And(a2, a1, Operand(a0)); |
3976 __ JumpIfSmi(a2, &miss); | 3976 __ JumpIfSmi(a2, &miss); |
3977 | 3977 |
3978 __ GetObjectType(a0, a2, a2); | 3978 __ GetObjectType(a0, a2, a2); |
3979 __ Branch(&miss, ne, a2, Operand(JS_OBJECT_TYPE)); | 3979 __ Branch(&miss, ne, a2, Operand(JS_OBJECT_TYPE)); |
3980 __ GetObjectType(a1, a2, a2); | 3980 __ GetObjectType(a1, a2, a2); |
3981 __ Branch(&miss, ne, a2, Operand(JS_OBJECT_TYPE)); | 3981 __ Branch(&miss, ne, a2, Operand(JS_OBJECT_TYPE)); |
3982 | 3982 |
3983 DCHECK(GetCondition() == eq); | 3983 DCHECK(GetCondition() == eq); |
(...skipping 23 matching lines...) Expand all Loading... |
4007 | 4007 |
4008 | 4008 |
4009 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { | 4009 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { |
4010 { | 4010 { |
4011 // Call the runtime system in a fresh internal frame. | 4011 // Call the runtime system in a fresh internal frame. |
4012 ExternalReference miss = | 4012 ExternalReference miss = |
4013 ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate()); | 4013 ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate()); |
4014 FrameScope scope(masm, StackFrame::INTERNAL); | 4014 FrameScope scope(masm, StackFrame::INTERNAL); |
4015 __ Push(a1, a0); | 4015 __ Push(a1, a0); |
4016 __ Push(ra, a1, a0); | 4016 __ Push(ra, a1, a0); |
4017 __ li(a4, Operand(Smi::FromInt(op_))); | 4017 __ li(a4, Operand(Smi::FromInt(op()))); |
4018 __ daddiu(sp, sp, -kPointerSize); | 4018 __ daddiu(sp, sp, -kPointerSize); |
4019 __ CallExternalReference(miss, 3, USE_DELAY_SLOT); | 4019 __ CallExternalReference(miss, 3, USE_DELAY_SLOT); |
4020 __ sd(a4, MemOperand(sp)); // In the delay slot. | 4020 __ sd(a4, MemOperand(sp)); // In the delay slot. |
4021 // Compute the entry point of the rewritten stub. | 4021 // Compute the entry point of the rewritten stub. |
4022 __ Daddu(a2, v0, Operand(Code::kHeaderSize - kHeapObjectTag)); | 4022 __ Daddu(a2, v0, Operand(Code::kHeaderSize - kHeapObjectTag)); |
4023 // Restore registers. | 4023 // Restore registers. |
4024 __ Pop(a1, a0, ra); | 4024 __ Pop(a1, a0, ra); |
4025 } | 4025 } |
4026 __ Jump(a2); | 4026 __ Jump(a2); |
4027 } | 4027 } |
(...skipping 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5101 MemOperand(fp, 6 * kPointerSize), | 5101 MemOperand(fp, 6 * kPointerSize), |
5102 NULL); | 5102 NULL); |
5103 } | 5103 } |
5104 | 5104 |
5105 | 5105 |
5106 #undef __ | 5106 #undef __ |
5107 | 5107 |
5108 } } // namespace v8::internal | 5108 } } // namespace v8::internal |
5109 | 5109 |
5110 #endif // V8_TARGET_ARCH_MIPS64 | 5110 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |