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