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 |