| 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 |