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 850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 | 861 |
862 // Check for both being sequential ASCII strings, and inline if that is the | 862 // Check for both being sequential ASCII strings, and inline if that is the |
863 // case. | 863 // case. |
864 __ bind(&flat_string_check); | 864 __ bind(&flat_string_check); |
865 | 865 |
866 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, a2, a3, &slow); | 866 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, a2, a3, &slow); |
867 | 867 |
868 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, a2, | 868 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, a2, |
869 a3); | 869 a3); |
870 if (cc == eq) { | 870 if (cc == eq) { |
871 StringCompareStub::GenerateFlatAsciiStringEquals(masm, | 871 StringHelper::GenerateFlatAsciiStringEquals(masm, lhs, rhs, a2, a3, a4); |
872 lhs, | |
873 rhs, | |
874 a2, | |
875 a3, | |
876 a4); | |
877 } else { | 872 } else { |
878 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, | 873 StringHelper::GenerateCompareFlatAsciiStrings(masm, lhs, rhs, a2, a3, a4, |
879 lhs, | 874 a5); |
880 rhs, | |
881 a2, | |
882 a3, | |
883 a4, | |
884 a5); | |
885 } | 875 } |
886 // Never falls through to here. | 876 // Never falls through to here. |
887 | 877 |
888 __ bind(&slow); | 878 __ bind(&slow); |
889 // Prepare for call to builtin. Push object pointers, a0 (lhs) first, | 879 // Prepare for call to builtin. Push object pointers, a0 (lhs) first, |
890 // a1 (rhs) second. | 880 // a1 (rhs) second. |
891 __ Push(lhs, rhs); | 881 __ Push(lhs, rhs); |
892 // Figure out which native to call and setup the arguments. | 882 // Figure out which native to call and setup the arguments. |
893 Builtins::JavaScript native; | 883 Builtins::JavaScript native; |
894 if (cc == eq) { | 884 if (cc == eq) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 __ PopSafepointRegisters(); | 919 __ PopSafepointRegisters(); |
930 __ Jump(t9); | 920 __ Jump(t9); |
931 } | 921 } |
932 | 922 |
933 | 923 |
934 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { | 924 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { |
935 // We don't allow a GC during a store buffer overflow so there is no need to | 925 // We don't allow a GC during a store buffer overflow so there is no need to |
936 // store the registers in any particular way, but we do have to store and | 926 // store the registers in any particular way, but we do have to store and |
937 // restore them. | 927 // restore them. |
938 __ MultiPush(kJSCallerSaved | ra.bit()); | 928 __ MultiPush(kJSCallerSaved | ra.bit()); |
939 if (save_doubles_ == kSaveFPRegs) { | 929 if (save_doubles()) { |
940 __ MultiPushFPU(kCallerSavedFPU); | 930 __ MultiPushFPU(kCallerSavedFPU); |
941 } | 931 } |
942 const int argument_count = 1; | 932 const int argument_count = 1; |
943 const int fp_argument_count = 0; | 933 const int fp_argument_count = 0; |
944 const Register scratch = a1; | 934 const Register scratch = a1; |
945 | 935 |
946 AllowExternalCallThatCantCauseGC scope(masm); | 936 AllowExternalCallThatCantCauseGC scope(masm); |
947 __ PrepareCallCFunction(argument_count, fp_argument_count, scratch); | 937 __ PrepareCallCFunction(argument_count, fp_argument_count, scratch); |
948 __ li(a0, Operand(ExternalReference::isolate_address(isolate()))); | 938 __ li(a0, Operand(ExternalReference::isolate_address(isolate()))); |
949 __ CallCFunction( | 939 __ CallCFunction( |
950 ExternalReference::store_buffer_overflow_function(isolate()), | 940 ExternalReference::store_buffer_overflow_function(isolate()), |
951 argument_count); | 941 argument_count); |
952 if (save_doubles_ == kSaveFPRegs) { | 942 if (save_doubles()) { |
953 __ MultiPopFPU(kCallerSavedFPU); | 943 __ MultiPopFPU(kCallerSavedFPU); |
954 } | 944 } |
955 | 945 |
956 __ MultiPop(kJSCallerSaved | ra.bit()); | 946 __ MultiPop(kJSCallerSaved | ra.bit()); |
957 __ Ret(); | 947 __ Ret(); |
958 } | 948 } |
959 | 949 |
960 | 950 |
961 void MathPowStub::Generate(MacroAssembler* masm) { | 951 void MathPowStub::Generate(MacroAssembler* masm) { |
962 const Register base = a1; | 952 const Register base = a1; |
(...skipping 2532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3495 // a2: length | 3485 // a2: length |
3496 // a3: from index (untagged) | 3486 // a3: from index (untagged) |
3497 StringCharAtGenerator generator( | 3487 StringCharAtGenerator generator( |
3498 v0, a3, a2, v0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); | 3488 v0, a3, a2, v0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); |
3499 generator.GenerateFast(masm); | 3489 generator.GenerateFast(masm); |
3500 __ DropAndRet(3); | 3490 __ DropAndRet(3); |
3501 generator.SkipSlow(masm, &runtime); | 3491 generator.SkipSlow(masm, &runtime); |
3502 } | 3492 } |
3503 | 3493 |
3504 | 3494 |
3505 void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm, | 3495 void StringHelper::GenerateFlatAsciiStringEquals(MacroAssembler* masm, |
3506 Register left, | 3496 Register left, Register right, |
3507 Register right, | 3497 Register scratch1, |
3508 Register scratch1, | 3498 Register scratch2, |
3509 Register scratch2, | 3499 Register scratch3) { |
3510 Register scratch3) { | |
3511 Register length = scratch1; | 3500 Register length = scratch1; |
3512 | 3501 |
3513 // Compare lengths. | 3502 // Compare lengths. |
3514 Label strings_not_equal, check_zero_length; | 3503 Label strings_not_equal, check_zero_length; |
3515 __ ld(length, FieldMemOperand(left, String::kLengthOffset)); | 3504 __ ld(length, FieldMemOperand(left, String::kLengthOffset)); |
3516 __ ld(scratch2, FieldMemOperand(right, String::kLengthOffset)); | 3505 __ ld(scratch2, FieldMemOperand(right, String::kLengthOffset)); |
3517 __ Branch(&check_zero_length, eq, length, Operand(scratch2)); | 3506 __ Branch(&check_zero_length, eq, length, Operand(scratch2)); |
3518 __ bind(&strings_not_equal); | 3507 __ bind(&strings_not_equal); |
3519 // Can not put li in delayslot, it has multi instructions. | 3508 // Can not put li in delayslot, it has multi instructions. |
3520 __ li(v0, Operand(Smi::FromInt(NOT_EQUAL))); | 3509 __ li(v0, Operand(Smi::FromInt(NOT_EQUAL))); |
(...skipping 14 matching lines...) Expand all Loading... |
3535 GenerateAsciiCharsCompareLoop(masm, | 3524 GenerateAsciiCharsCompareLoop(masm, |
3536 left, right, length, scratch2, scratch3, v0, | 3525 left, right, length, scratch2, scratch3, v0, |
3537 &strings_not_equal); | 3526 &strings_not_equal); |
3538 | 3527 |
3539 // Characters are equal. | 3528 // Characters are equal. |
3540 __ Ret(USE_DELAY_SLOT); | 3529 __ Ret(USE_DELAY_SLOT); |
3541 __ li(v0, Operand(Smi::FromInt(EQUAL))); | 3530 __ li(v0, Operand(Smi::FromInt(EQUAL))); |
3542 } | 3531 } |
3543 | 3532 |
3544 | 3533 |
3545 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 3534 void StringHelper::GenerateCompareFlatAsciiStrings( |
3546 Register left, | 3535 MacroAssembler* masm, Register left, Register right, Register scratch1, |
3547 Register right, | 3536 Register scratch2, Register scratch3, Register scratch4) { |
3548 Register scratch1, | |
3549 Register scratch2, | |
3550 Register scratch3, | |
3551 Register scratch4) { | |
3552 Label result_not_equal, compare_lengths; | 3537 Label result_not_equal, compare_lengths; |
3553 // Find minimum length and length difference. | 3538 // Find minimum length and length difference. |
3554 __ ld(scratch1, FieldMemOperand(left, String::kLengthOffset)); | 3539 __ ld(scratch1, FieldMemOperand(left, String::kLengthOffset)); |
3555 __ ld(scratch2, FieldMemOperand(right, String::kLengthOffset)); | 3540 __ ld(scratch2, FieldMemOperand(right, String::kLengthOffset)); |
3556 __ Dsubu(scratch3, scratch1, Operand(scratch2)); | 3541 __ Dsubu(scratch3, scratch1, Operand(scratch2)); |
3557 Register length_delta = scratch3; | 3542 Register length_delta = scratch3; |
3558 __ slt(scratch4, scratch2, scratch1); | 3543 __ slt(scratch4, scratch2, scratch1); |
3559 __ Movn(scratch1, scratch2, scratch4); | 3544 __ Movn(scratch1, scratch2, scratch4); |
3560 Register min_length = scratch1; | 3545 Register min_length = scratch1; |
3561 STATIC_ASSERT(kSmiTag == 0); | 3546 STATIC_ASSERT(kSmiTag == 0); |
(...skipping 18 matching lines...) Expand all Loading... |
3580 Label ret; | 3565 Label ret; |
3581 __ Branch(&ret, eq, scratch2, Operand(scratch4)); | 3566 __ Branch(&ret, eq, scratch2, Operand(scratch4)); |
3582 __ li(v0, Operand(Smi::FromInt(GREATER))); | 3567 __ li(v0, Operand(Smi::FromInt(GREATER))); |
3583 __ Branch(&ret, gt, scratch2, Operand(scratch4)); | 3568 __ Branch(&ret, gt, scratch2, Operand(scratch4)); |
3584 __ li(v0, Operand(Smi::FromInt(LESS))); | 3569 __ li(v0, Operand(Smi::FromInt(LESS))); |
3585 __ bind(&ret); | 3570 __ bind(&ret); |
3586 __ Ret(); | 3571 __ Ret(); |
3587 } | 3572 } |
3588 | 3573 |
3589 | 3574 |
3590 void StringCompareStub::GenerateAsciiCharsCompareLoop( | 3575 void StringHelper::GenerateAsciiCharsCompareLoop( |
3591 MacroAssembler* masm, | 3576 MacroAssembler* masm, Register left, Register right, Register length, |
3592 Register left, | 3577 Register scratch1, Register scratch2, Register scratch3, |
3593 Register right, | |
3594 Register length, | |
3595 Register scratch1, | |
3596 Register scratch2, | |
3597 Register scratch3, | |
3598 Label* chars_not_equal) { | 3578 Label* chars_not_equal) { |
3599 // Change index to run from -length to -1 by adding length to string | 3579 // Change index to run from -length to -1 by adding length to string |
3600 // start. This means that loop ends when index reaches zero, which | 3580 // start. This means that loop ends when index reaches zero, which |
3601 // doesn't need an additional compare. | 3581 // doesn't need an additional compare. |
3602 __ SmiUntag(length); | 3582 __ SmiUntag(length); |
3603 __ Daddu(scratch1, length, | 3583 __ Daddu(scratch1, length, |
3604 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); | 3584 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); |
3605 __ Daddu(left, left, Operand(scratch1)); | 3585 __ Daddu(left, left, Operand(scratch1)); |
3606 __ Daddu(right, right, Operand(scratch1)); | 3586 __ Daddu(right, right, Operand(scratch1)); |
3607 __ Dsubu(length, zero_reg, length); | 3587 __ Dsubu(length, zero_reg, length); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3641 __ DropAndRet(2); | 3621 __ DropAndRet(2); |
3642 | 3622 |
3643 __ bind(¬_same); | 3623 __ bind(¬_same); |
3644 | 3624 |
3645 // Check that both objects are sequential ASCII strings. | 3625 // Check that both objects are sequential ASCII strings. |
3646 __ JumpIfNotBothSequentialAsciiStrings(a1, a0, a2, a3, &runtime); | 3626 __ JumpIfNotBothSequentialAsciiStrings(a1, a0, a2, a3, &runtime); |
3647 | 3627 |
3648 // Compare flat ASCII strings natively. Remove arguments from stack first. | 3628 // Compare flat ASCII strings natively. Remove arguments from stack first. |
3649 __ IncrementCounter(counters->string_compare_native(), 1, a2, a3); | 3629 __ IncrementCounter(counters->string_compare_native(), 1, a2, a3); |
3650 __ Daddu(sp, sp, Operand(2 * kPointerSize)); | 3630 __ Daddu(sp, sp, Operand(2 * kPointerSize)); |
3651 GenerateCompareFlatAsciiStrings(masm, a1, a0, a2, a3, a4, a5); | 3631 StringHelper::GenerateCompareFlatAsciiStrings(masm, a1, a0, a2, a3, a4, a5); |
3652 | 3632 |
3653 __ bind(&runtime); | 3633 __ bind(&runtime); |
3654 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3634 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3655 } | 3635 } |
3656 | 3636 |
3657 | 3637 |
3658 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { | 3638 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { |
3659 // ----------- S t a t e ------------- | 3639 // ----------- S t a t e ------------- |
3660 // -- a1 : left | 3640 // -- a1 : left |
3661 // -- a0 : right | 3641 // -- a0 : right |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3941 __ bind(&is_symbol); | 3921 __ bind(&is_symbol); |
3942 } | 3922 } |
3943 | 3923 |
3944 // Check that both strings are sequential ASCII. | 3924 // Check that both strings are sequential ASCII. |
3945 Label runtime; | 3925 Label runtime; |
3946 __ JumpIfBothInstanceTypesAreNotSequentialAscii( | 3926 __ JumpIfBothInstanceTypesAreNotSequentialAscii( |
3947 tmp1, tmp2, tmp3, tmp4, &runtime); | 3927 tmp1, tmp2, tmp3, tmp4, &runtime); |
3948 | 3928 |
3949 // Compare flat ASCII strings. Returns when done. | 3929 // Compare flat ASCII strings. Returns when done. |
3950 if (equality) { | 3930 if (equality) { |
3951 StringCompareStub::GenerateFlatAsciiStringEquals( | 3931 StringHelper::GenerateFlatAsciiStringEquals(masm, left, right, tmp1, tmp2, |
3952 masm, left, right, tmp1, tmp2, tmp3); | 3932 tmp3); |
3953 } else { | 3933 } else { |
3954 StringCompareStub::GenerateCompareFlatAsciiStrings( | 3934 StringHelper::GenerateCompareFlatAsciiStrings(masm, left, right, tmp1, tmp2, |
3955 masm, left, right, tmp1, tmp2, tmp3, tmp4); | 3935 tmp3, tmp4); |
3956 } | 3936 } |
3957 | 3937 |
3958 // Handle more complex cases in runtime. | 3938 // Handle more complex cases in runtime. |
3959 __ bind(&runtime); | 3939 __ bind(&runtime); |
3960 __ Push(left, right); | 3940 __ Push(left, right); |
3961 if (equality) { | 3941 if (equality) { |
3962 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 3942 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
3963 } else { | 3943 } else { |
3964 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3944 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3965 } | 3945 } |
(...skipping 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5101 MemOperand(fp, 6 * kPointerSize), | 5081 MemOperand(fp, 6 * kPointerSize), |
5102 NULL); | 5082 NULL); |
5103 } | 5083 } |
5104 | 5084 |
5105 | 5085 |
5106 #undef __ | 5086 #undef __ |
5107 | 5087 |
5108 } } // namespace v8::internal | 5088 } } // namespace v8::internal |
5109 | 5089 |
5110 #endif // V8_TARGET_ARCH_MIPS64 | 5090 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |