| 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_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 __ lw(a3, FieldMemOperand(lhs, HeapObject::kMapOffset)); | 602 __ lw(a3, FieldMemOperand(lhs, HeapObject::kMapOffset)); |
| 603 __ lbu(a2, FieldMemOperand(a2, Map::kBitFieldOffset)); | 603 __ lbu(a2, FieldMemOperand(a2, Map::kBitFieldOffset)); |
| 604 __ lbu(a3, FieldMemOperand(a3, Map::kBitFieldOffset)); | 604 __ lbu(a3, FieldMemOperand(a3, Map::kBitFieldOffset)); |
| 605 __ and_(a0, a2, a3); | 605 __ and_(a0, a2, a3); |
| 606 __ And(a0, a0, Operand(1 << Map::kIsUndetectable)); | 606 __ And(a0, a0, Operand(1 << Map::kIsUndetectable)); |
| 607 __ Ret(USE_DELAY_SLOT); | 607 __ Ret(USE_DELAY_SLOT); |
| 608 __ xori(v0, a0, 1 << Map::kIsUndetectable); | 608 __ xori(v0, a0, 1 << Map::kIsUndetectable); |
| 609 } | 609 } |
| 610 | 610 |
| 611 | 611 |
| 612 static void ICCompareStub_CheckInputType(MacroAssembler* masm, | 612 static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input, |
| 613 Register input, | |
| 614 Register scratch, | 613 Register scratch, |
| 615 CompareIC::State expected, | 614 CompareIC::State expected, |
| 616 Label* fail) { | 615 Label* fail) { |
| 617 Label ok; | 616 Label ok; |
| 618 if (expected == CompareIC::SMI) { | 617 if (expected == CompareIC::SMI) { |
| 619 __ JumpIfNotSmi(input, fail); | 618 __ JumpIfNotSmi(input, fail); |
| 620 } else if (expected == CompareIC::NUMBER) { | 619 } else if (expected == CompareIC::NUMBER) { |
| 621 __ JumpIfSmi(input, &ok); | 620 __ JumpIfSmi(input, &ok); |
| 622 __ CheckMap(input, scratch, Heap::kHeapNumberMapRootIndex, fail, | 621 __ CheckMap(input, scratch, Heap::kHeapNumberMapRootIndex, fail, |
| 623 DONT_DO_SMI_CHECK); | 622 DONT_DO_SMI_CHECK); |
| 624 } | 623 } |
| 625 // We could be strict about internalized/string here, but as long as | 624 // We could be strict about internalized/string here, but as long as |
| 626 // hydrogen doesn't care, the stub doesn't have to care either. | 625 // hydrogen doesn't care, the stub doesn't have to care either. |
| 627 __ bind(&ok); | 626 __ bind(&ok); |
| 628 } | 627 } |
| 629 | 628 |
| 630 | 629 |
| 631 // On entry a1 and a2 are the values to be compared. | 630 // On entry a1 and a2 are the values to be compared. |
| 632 // On exit a0 is 0, positive or negative to indicate the result of | 631 // On exit a0 is 0, positive or negative to indicate the result of |
| 633 // the comparison. | 632 // the comparison. |
| 634 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { | 633 void CompareICStub::GenerateGeneric(MacroAssembler* masm) { |
| 635 Register lhs = a1; | 634 Register lhs = a1; |
| 636 Register rhs = a0; | 635 Register rhs = a0; |
| 637 Condition cc = GetCondition(); | 636 Condition cc = GetCondition(); |
| 638 | 637 |
| 639 Label miss; | 638 Label miss; |
| 640 ICCompareStub_CheckInputType(masm, lhs, a2, left(), &miss); | 639 CompareICStub_CheckInputType(masm, lhs, a2, left(), &miss); |
| 641 ICCompareStub_CheckInputType(masm, rhs, a3, right(), &miss); | 640 CompareICStub_CheckInputType(masm, rhs, a3, right(), &miss); |
| 642 | 641 |
| 643 Label slow; // Call builtin. | 642 Label slow; // Call builtin. |
| 644 Label not_smis, both_loaded_as_doubles; | 643 Label not_smis, both_loaded_as_doubles; |
| 645 | 644 |
| 646 Label not_two_smis, smi_done; | 645 Label not_two_smis, smi_done; |
| 647 __ Or(a2, a1, a0); | 646 __ Or(a2, a1, a0); |
| 648 __ JumpIfNotSmi(a2, ¬_two_smis); | 647 __ JumpIfNotSmi(a2, ¬_two_smis); |
| 649 __ sra(a1, a1, 1); | 648 __ sra(a1, a1, 1); |
| 650 __ sra(a0, a0, 1); | 649 __ sra(a0, a0, 1); |
| 651 __ Ret(USE_DELAY_SLOT); | 650 __ Ret(USE_DELAY_SLOT); |
| (...skipping 2863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3515 __ Assert(eq, kExpectedAllocationSite, t0, Operand(at)); | 3514 __ Assert(eq, kExpectedAllocationSite, t0, Operand(at)); |
| 3516 } | 3515 } |
| 3517 | 3516 |
| 3518 // Tail call into the stub that handles binary operations with allocation | 3517 // Tail call into the stub that handles binary operations with allocation |
| 3519 // sites. | 3518 // sites. |
| 3520 BinaryOpWithAllocationSiteStub stub(isolate(), state()); | 3519 BinaryOpWithAllocationSiteStub stub(isolate(), state()); |
| 3521 __ TailCallStub(&stub); | 3520 __ TailCallStub(&stub); |
| 3522 } | 3521 } |
| 3523 | 3522 |
| 3524 | 3523 |
| 3525 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { | 3524 void CompareICStub::GenerateSmis(MacroAssembler* masm) { |
| 3526 DCHECK(state() == CompareIC::SMI); | 3525 DCHECK(state() == CompareIC::SMI); |
| 3527 Label miss; | 3526 Label miss; |
| 3528 __ Or(a2, a1, a0); | 3527 __ Or(a2, a1, a0); |
| 3529 __ JumpIfNotSmi(a2, &miss); | 3528 __ JumpIfNotSmi(a2, &miss); |
| 3530 | 3529 |
| 3531 if (GetCondition() == eq) { | 3530 if (GetCondition() == eq) { |
| 3532 // For equality we do not care about the sign of the result. | 3531 // For equality we do not care about the sign of the result. |
| 3533 __ Ret(USE_DELAY_SLOT); | 3532 __ Ret(USE_DELAY_SLOT); |
| 3534 __ Subu(v0, a0, a1); | 3533 __ Subu(v0, a0, a1); |
| 3535 } else { | 3534 } else { |
| 3536 // Untag before subtracting to avoid handling overflow. | 3535 // Untag before subtracting to avoid handling overflow. |
| 3537 __ SmiUntag(a1); | 3536 __ SmiUntag(a1); |
| 3538 __ SmiUntag(a0); | 3537 __ SmiUntag(a0); |
| 3539 __ Ret(USE_DELAY_SLOT); | 3538 __ Ret(USE_DELAY_SLOT); |
| 3540 __ Subu(v0, a1, a0); | 3539 __ Subu(v0, a1, a0); |
| 3541 } | 3540 } |
| 3542 | 3541 |
| 3543 __ bind(&miss); | 3542 __ bind(&miss); |
| 3544 GenerateMiss(masm); | 3543 GenerateMiss(masm); |
| 3545 } | 3544 } |
| 3546 | 3545 |
| 3547 | 3546 |
| 3548 void ICCompareStub::GenerateNumbers(MacroAssembler* masm) { | 3547 void CompareICStub::GenerateNumbers(MacroAssembler* masm) { |
| 3549 DCHECK(state() == CompareIC::NUMBER); | 3548 DCHECK(state() == CompareIC::NUMBER); |
| 3550 | 3549 |
| 3551 Label generic_stub; | 3550 Label generic_stub; |
| 3552 Label unordered, maybe_undefined1, maybe_undefined2; | 3551 Label unordered, maybe_undefined1, maybe_undefined2; |
| 3553 Label miss; | 3552 Label miss; |
| 3554 | 3553 |
| 3555 if (left() == CompareIC::SMI) { | 3554 if (left() == CompareIC::SMI) { |
| 3556 __ JumpIfNotSmi(a1, &miss); | 3555 __ JumpIfNotSmi(a1, &miss); |
| 3557 } | 3556 } |
| 3558 if (right() == CompareIC::SMI) { | 3557 if (right() == CompareIC::SMI) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3606 __ bind(&fpu_eq); | 3605 __ bind(&fpu_eq); |
| 3607 __ Ret(USE_DELAY_SLOT); | 3606 __ Ret(USE_DELAY_SLOT); |
| 3608 __ li(v0, Operand(EQUAL)); | 3607 __ li(v0, Operand(EQUAL)); |
| 3609 | 3608 |
| 3610 __ bind(&fpu_lt); | 3609 __ bind(&fpu_lt); |
| 3611 __ Ret(USE_DELAY_SLOT); | 3610 __ Ret(USE_DELAY_SLOT); |
| 3612 __ li(v0, Operand(LESS)); | 3611 __ li(v0, Operand(LESS)); |
| 3613 | 3612 |
| 3614 __ bind(&unordered); | 3613 __ bind(&unordered); |
| 3615 __ bind(&generic_stub); | 3614 __ bind(&generic_stub); |
| 3616 ICCompareStub stub(isolate(), op(), CompareIC::GENERIC, CompareIC::GENERIC, | 3615 CompareICStub stub(isolate(), op(), CompareIC::GENERIC, CompareIC::GENERIC, |
| 3617 CompareIC::GENERIC); | 3616 CompareIC::GENERIC); |
| 3618 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); | 3617 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 3619 | 3618 |
| 3620 __ bind(&maybe_undefined1); | 3619 __ bind(&maybe_undefined1); |
| 3621 if (Token::IsOrderedRelationalCompareOp(op())) { | 3620 if (Token::IsOrderedRelationalCompareOp(op())) { |
| 3622 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 3621 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 3623 __ Branch(&miss, ne, a0, Operand(at)); | 3622 __ Branch(&miss, ne, a0, Operand(at)); |
| 3624 __ JumpIfSmi(a1, &unordered); | 3623 __ JumpIfSmi(a1, &unordered); |
| 3625 __ GetObjectType(a1, a2, a2); | 3624 __ GetObjectType(a1, a2, a2); |
| 3626 __ Branch(&maybe_undefined2, ne, a2, Operand(HEAP_NUMBER_TYPE)); | 3625 __ Branch(&maybe_undefined2, ne, a2, Operand(HEAP_NUMBER_TYPE)); |
| 3627 __ jmp(&unordered); | 3626 __ jmp(&unordered); |
| 3628 } | 3627 } |
| 3629 | 3628 |
| 3630 __ bind(&maybe_undefined2); | 3629 __ bind(&maybe_undefined2); |
| 3631 if (Token::IsOrderedRelationalCompareOp(op())) { | 3630 if (Token::IsOrderedRelationalCompareOp(op())) { |
| 3632 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 3631 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 3633 __ Branch(&unordered, eq, a1, Operand(at)); | 3632 __ Branch(&unordered, eq, a1, Operand(at)); |
| 3634 } | 3633 } |
| 3635 | 3634 |
| 3636 __ bind(&miss); | 3635 __ bind(&miss); |
| 3637 GenerateMiss(masm); | 3636 GenerateMiss(masm); |
| 3638 } | 3637 } |
| 3639 | 3638 |
| 3640 | 3639 |
| 3641 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) { | 3640 void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) { |
| 3642 DCHECK(state() == CompareIC::INTERNALIZED_STRING); | 3641 DCHECK(state() == CompareIC::INTERNALIZED_STRING); |
| 3643 Label miss; | 3642 Label miss; |
| 3644 | 3643 |
| 3645 // Registers containing left and right operands respectively. | 3644 // Registers containing left and right operands respectively. |
| 3646 Register left = a1; | 3645 Register left = a1; |
| 3647 Register right = a0; | 3646 Register right = a0; |
| 3648 Register tmp1 = a2; | 3647 Register tmp1 = a2; |
| 3649 Register tmp2 = a3; | 3648 Register tmp2 = a3; |
| 3650 | 3649 |
| 3651 // Check that both operands are heap objects. | 3650 // Check that both operands are heap objects. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3671 __ Ret(ne, left, Operand(right)); | 3670 __ Ret(ne, left, Operand(right)); |
| 3672 DCHECK(is_int16(EQUAL)); | 3671 DCHECK(is_int16(EQUAL)); |
| 3673 __ Ret(USE_DELAY_SLOT); | 3672 __ Ret(USE_DELAY_SLOT); |
| 3674 __ li(v0, Operand(Smi::FromInt(EQUAL))); | 3673 __ li(v0, Operand(Smi::FromInt(EQUAL))); |
| 3675 | 3674 |
| 3676 __ bind(&miss); | 3675 __ bind(&miss); |
| 3677 GenerateMiss(masm); | 3676 GenerateMiss(masm); |
| 3678 } | 3677 } |
| 3679 | 3678 |
| 3680 | 3679 |
| 3681 void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) { | 3680 void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) { |
| 3682 DCHECK(state() == CompareIC::UNIQUE_NAME); | 3681 DCHECK(state() == CompareIC::UNIQUE_NAME); |
| 3683 DCHECK(GetCondition() == eq); | 3682 DCHECK(GetCondition() == eq); |
| 3684 Label miss; | 3683 Label miss; |
| 3685 | 3684 |
| 3686 // Registers containing left and right operands respectively. | 3685 // Registers containing left and right operands respectively. |
| 3687 Register left = a1; | 3686 Register left = a1; |
| 3688 Register right = a0; | 3687 Register right = a0; |
| 3689 Register tmp1 = a2; | 3688 Register tmp1 = a2; |
| 3690 Register tmp2 = a3; | 3689 Register tmp2 = a3; |
| 3691 | 3690 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3715 STATIC_ASSERT(kSmiTag == 0); | 3714 STATIC_ASSERT(kSmiTag == 0); |
| 3716 __ li(v0, Operand(Smi::FromInt(EQUAL))); | 3715 __ li(v0, Operand(Smi::FromInt(EQUAL))); |
| 3717 __ bind(&done); | 3716 __ bind(&done); |
| 3718 __ Ret(); | 3717 __ Ret(); |
| 3719 | 3718 |
| 3720 __ bind(&miss); | 3719 __ bind(&miss); |
| 3721 GenerateMiss(masm); | 3720 GenerateMiss(masm); |
| 3722 } | 3721 } |
| 3723 | 3722 |
| 3724 | 3723 |
| 3725 void ICCompareStub::GenerateStrings(MacroAssembler* masm) { | 3724 void CompareICStub::GenerateStrings(MacroAssembler* masm) { |
| 3726 DCHECK(state() == CompareIC::STRING); | 3725 DCHECK(state() == CompareIC::STRING); |
| 3727 Label miss; | 3726 Label miss; |
| 3728 | 3727 |
| 3729 bool equality = Token::IsEqualityOp(op()); | 3728 bool equality = Token::IsEqualityOp(op()); |
| 3730 | 3729 |
| 3731 // Registers containing left and right operands respectively. | 3730 // Registers containing left and right operands respectively. |
| 3732 Register left = a1; | 3731 Register left = a1; |
| 3733 Register right = a0; | 3732 Register right = a0; |
| 3734 Register tmp1 = a2; | 3733 Register tmp1 = a2; |
| 3735 Register tmp2 = a3; | 3734 Register tmp2 = a3; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3801 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 3800 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
| 3802 } else { | 3801 } else { |
| 3803 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3802 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 3804 } | 3803 } |
| 3805 | 3804 |
| 3806 __ bind(&miss); | 3805 __ bind(&miss); |
| 3807 GenerateMiss(masm); | 3806 GenerateMiss(masm); |
| 3808 } | 3807 } |
| 3809 | 3808 |
| 3810 | 3809 |
| 3811 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { | 3810 void CompareICStub::GenerateObjects(MacroAssembler* masm) { |
| 3812 DCHECK(state() == CompareIC::OBJECT); | 3811 DCHECK(state() == CompareIC::OBJECT); |
| 3813 Label miss; | 3812 Label miss; |
| 3814 __ And(a2, a1, Operand(a0)); | 3813 __ And(a2, a1, Operand(a0)); |
| 3815 __ JumpIfSmi(a2, &miss); | 3814 __ JumpIfSmi(a2, &miss); |
| 3816 | 3815 |
| 3817 __ GetObjectType(a0, a2, a2); | 3816 __ GetObjectType(a0, a2, a2); |
| 3818 __ Branch(&miss, ne, a2, Operand(JS_OBJECT_TYPE)); | 3817 __ Branch(&miss, ne, a2, Operand(JS_OBJECT_TYPE)); |
| 3819 __ GetObjectType(a1, a2, a2); | 3818 __ GetObjectType(a1, a2, a2); |
| 3820 __ Branch(&miss, ne, a2, Operand(JS_OBJECT_TYPE)); | 3819 __ Branch(&miss, ne, a2, Operand(JS_OBJECT_TYPE)); |
| 3821 | 3820 |
| 3822 DCHECK(GetCondition() == eq); | 3821 DCHECK(GetCondition() == eq); |
| 3823 __ Ret(USE_DELAY_SLOT); | 3822 __ Ret(USE_DELAY_SLOT); |
| 3824 __ subu(v0, a0, a1); | 3823 __ subu(v0, a0, a1); |
| 3825 | 3824 |
| 3826 __ bind(&miss); | 3825 __ bind(&miss); |
| 3827 GenerateMiss(masm); | 3826 GenerateMiss(masm); |
| 3828 } | 3827 } |
| 3829 | 3828 |
| 3830 | 3829 |
| 3831 void ICCompareStub::GenerateKnownObjects(MacroAssembler* masm) { | 3830 void CompareICStub::GenerateKnownObjects(MacroAssembler* masm) { |
| 3832 Label miss; | 3831 Label miss; |
| 3833 __ And(a2, a1, a0); | 3832 __ And(a2, a1, a0); |
| 3834 __ JumpIfSmi(a2, &miss); | 3833 __ JumpIfSmi(a2, &miss); |
| 3835 __ lw(a2, FieldMemOperand(a0, HeapObject::kMapOffset)); | 3834 __ lw(a2, FieldMemOperand(a0, HeapObject::kMapOffset)); |
| 3836 __ lw(a3, FieldMemOperand(a1, HeapObject::kMapOffset)); | 3835 __ lw(a3, FieldMemOperand(a1, HeapObject::kMapOffset)); |
| 3837 __ Branch(&miss, ne, a2, Operand(known_map_)); | 3836 __ Branch(&miss, ne, a2, Operand(known_map_)); |
| 3838 __ Branch(&miss, ne, a3, Operand(known_map_)); | 3837 __ Branch(&miss, ne, a3, Operand(known_map_)); |
| 3839 | 3838 |
| 3840 __ Ret(USE_DELAY_SLOT); | 3839 __ Ret(USE_DELAY_SLOT); |
| 3841 __ subu(v0, a0, a1); | 3840 __ subu(v0, a0, a1); |
| 3842 | 3841 |
| 3843 __ bind(&miss); | 3842 __ bind(&miss); |
| 3844 GenerateMiss(masm); | 3843 GenerateMiss(masm); |
| 3845 } | 3844 } |
| 3846 | 3845 |
| 3847 | 3846 |
| 3848 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { | 3847 void CompareICStub::GenerateMiss(MacroAssembler* masm) { |
| 3849 { | 3848 { |
| 3850 // Call the runtime system in a fresh internal frame. | 3849 // Call the runtime system in a fresh internal frame. |
| 3851 ExternalReference miss = | 3850 ExternalReference miss = |
| 3852 ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate()); | 3851 ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate()); |
| 3853 FrameScope scope(masm, StackFrame::INTERNAL); | 3852 FrameScope scope(masm, StackFrame::INTERNAL); |
| 3854 __ Push(a1, a0); | 3853 __ Push(a1, a0); |
| 3855 __ Push(ra, a1, a0); | 3854 __ Push(ra, a1, a0); |
| 3856 __ li(t0, Operand(Smi::FromInt(op()))); | 3855 __ li(t0, Operand(Smi::FromInt(op()))); |
| 3857 __ addiu(sp, sp, -kPointerSize); | 3856 __ addiu(sp, sp, -kPointerSize); |
| 3858 __ CallExternalReference(miss, 3, USE_DELAY_SLOT); | 3857 __ CallExternalReference(miss, 3, USE_DELAY_SLOT); |
| (...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4939 MemOperand(fp, 6 * kPointerSize), | 4938 MemOperand(fp, 6 * kPointerSize), |
| 4940 NULL); | 4939 NULL); |
| 4941 } | 4940 } |
| 4942 | 4941 |
| 4943 | 4942 |
| 4944 #undef __ | 4943 #undef __ |
| 4945 | 4944 |
| 4946 } } // namespace v8::internal | 4945 } } // namespace v8::internal |
| 4947 | 4946 |
| 4948 #endif // V8_TARGET_ARCH_MIPS | 4947 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |