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 857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
868 | 868 |
869 // Check for both being sequential ASCII strings, and inline if that is the | 869 // Check for both being sequential ASCII strings, and inline if that is the |
870 // case. | 870 // case. |
871 __ bind(&flat_string_check); | 871 __ bind(&flat_string_check); |
872 | 872 |
873 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, a2, a3, &slow); | 873 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, a2, a3, &slow); |
874 | 874 |
875 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, a2, | 875 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, a2, |
876 a3); | 876 a3); |
877 if (cc == eq) { | 877 if (cc == eq) { |
878 StringCompareStub::GenerateFlatAsciiStringEquals(masm, | 878 StringHelper::GenerateFlatAsciiStringEquals(masm, lhs, rhs, a2, a3, t0); |
879 lhs, | |
880 rhs, | |
881 a2, | |
882 a3, | |
883 t0); | |
884 } else { | 879 } else { |
885 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, | 880 StringHelper::GenerateCompareFlatAsciiStrings(masm, lhs, rhs, a2, a3, t0, |
886 lhs, | 881 t1); |
887 rhs, | |
888 a2, | |
889 a3, | |
890 t0, | |
891 t1); | |
892 } | 882 } |
893 // Never falls through to here. | 883 // Never falls through to here. |
894 | 884 |
895 __ bind(&slow); | 885 __ bind(&slow); |
896 // Prepare for call to builtin. Push object pointers, a0 (lhs) first, | 886 // Prepare for call to builtin. Push object pointers, a0 (lhs) first, |
897 // a1 (rhs) second. | 887 // a1 (rhs) second. |
898 __ Push(lhs, rhs); | 888 __ Push(lhs, rhs); |
899 // Figure out which native to call and setup the arguments. | 889 // Figure out which native to call and setup the arguments. |
900 Builtins::JavaScript native; | 890 Builtins::JavaScript native; |
901 if (cc == eq) { | 891 if (cc == eq) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
936 __ PopSafepointRegisters(); | 926 __ PopSafepointRegisters(); |
937 __ Jump(t9); | 927 __ Jump(t9); |
938 } | 928 } |
939 | 929 |
940 | 930 |
941 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { | 931 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { |
942 // We don't allow a GC during a store buffer overflow so there is no need to | 932 // We don't allow a GC during a store buffer overflow so there is no need to |
943 // store the registers in any particular way, but we do have to store and | 933 // store the registers in any particular way, but we do have to store and |
944 // restore them. | 934 // restore them. |
945 __ MultiPush(kJSCallerSaved | ra.bit()); | 935 __ MultiPush(kJSCallerSaved | ra.bit()); |
946 if (save_doubles_ == kSaveFPRegs) { | 936 if (save_doubles()) { |
947 __ MultiPushFPU(kCallerSavedFPU); | 937 __ MultiPushFPU(kCallerSavedFPU); |
948 } | 938 } |
949 const int argument_count = 1; | 939 const int argument_count = 1; |
950 const int fp_argument_count = 0; | 940 const int fp_argument_count = 0; |
951 const Register scratch = a1; | 941 const Register scratch = a1; |
952 | 942 |
953 AllowExternalCallThatCantCauseGC scope(masm); | 943 AllowExternalCallThatCantCauseGC scope(masm); |
954 __ PrepareCallCFunction(argument_count, fp_argument_count, scratch); | 944 __ PrepareCallCFunction(argument_count, fp_argument_count, scratch); |
955 __ li(a0, Operand(ExternalReference::isolate_address(isolate()))); | 945 __ li(a0, Operand(ExternalReference::isolate_address(isolate()))); |
956 __ CallCFunction( | 946 __ CallCFunction( |
957 ExternalReference::store_buffer_overflow_function(isolate()), | 947 ExternalReference::store_buffer_overflow_function(isolate()), |
958 argument_count); | 948 argument_count); |
959 if (save_doubles_ == kSaveFPRegs) { | 949 if (save_doubles()) { |
960 __ MultiPopFPU(kCallerSavedFPU); | 950 __ MultiPopFPU(kCallerSavedFPU); |
961 } | 951 } |
962 | 952 |
963 __ MultiPop(kJSCallerSaved | ra.bit()); | 953 __ MultiPop(kJSCallerSaved | ra.bit()); |
964 __ Ret(); | 954 __ Ret(); |
965 } | 955 } |
966 | 956 |
967 | 957 |
968 void MathPowStub::Generate(MacroAssembler* masm) { | 958 void MathPowStub::Generate(MacroAssembler* masm) { |
969 const Register base = a1; | 959 const Register base = a1; |
(...skipping 2490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3460 // a3: from index (untagged) | 3450 // a3: from index (untagged) |
3461 __ SmiTag(a3, a3); | 3451 __ SmiTag(a3, a3); |
3462 StringCharAtGenerator generator( | 3452 StringCharAtGenerator generator( |
3463 v0, a3, a2, v0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); | 3453 v0, a3, a2, v0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); |
3464 generator.GenerateFast(masm); | 3454 generator.GenerateFast(masm); |
3465 __ DropAndRet(3); | 3455 __ DropAndRet(3); |
3466 generator.SkipSlow(masm, &runtime); | 3456 generator.SkipSlow(masm, &runtime); |
3467 } | 3457 } |
3468 | 3458 |
3469 | 3459 |
3470 void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm, | 3460 void StringHelper::GenerateFlatAsciiStringEquals(MacroAssembler* masm, |
3471 Register left, | 3461 Register left, Register right, |
3472 Register right, | 3462 Register scratch1, |
3473 Register scratch1, | 3463 Register scratch2, |
3474 Register scratch2, | 3464 Register scratch3) { |
3475 Register scratch3) { | |
3476 Register length = scratch1; | 3465 Register length = scratch1; |
3477 | 3466 |
3478 // Compare lengths. | 3467 // Compare lengths. |
3479 Label strings_not_equal, check_zero_length; | 3468 Label strings_not_equal, check_zero_length; |
3480 __ lw(length, FieldMemOperand(left, String::kLengthOffset)); | 3469 __ lw(length, FieldMemOperand(left, String::kLengthOffset)); |
3481 __ lw(scratch2, FieldMemOperand(right, String::kLengthOffset)); | 3470 __ lw(scratch2, FieldMemOperand(right, String::kLengthOffset)); |
3482 __ Branch(&check_zero_length, eq, length, Operand(scratch2)); | 3471 __ Branch(&check_zero_length, eq, length, Operand(scratch2)); |
3483 __ bind(&strings_not_equal); | 3472 __ bind(&strings_not_equal); |
3484 DCHECK(is_int16(NOT_EQUAL)); | 3473 DCHECK(is_int16(NOT_EQUAL)); |
3485 __ Ret(USE_DELAY_SLOT); | 3474 __ Ret(USE_DELAY_SLOT); |
(...skipping 14 matching lines...) Expand all Loading... |
3500 GenerateAsciiCharsCompareLoop(masm, | 3489 GenerateAsciiCharsCompareLoop(masm, |
3501 left, right, length, scratch2, scratch3, v0, | 3490 left, right, length, scratch2, scratch3, v0, |
3502 &strings_not_equal); | 3491 &strings_not_equal); |
3503 | 3492 |
3504 // Characters are equal. | 3493 // Characters are equal. |
3505 __ Ret(USE_DELAY_SLOT); | 3494 __ Ret(USE_DELAY_SLOT); |
3506 __ li(v0, Operand(Smi::FromInt(EQUAL))); | 3495 __ li(v0, Operand(Smi::FromInt(EQUAL))); |
3507 } | 3496 } |
3508 | 3497 |
3509 | 3498 |
3510 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 3499 void StringHelper::GenerateCompareFlatAsciiStrings( |
3511 Register left, | 3500 MacroAssembler* masm, Register left, Register right, Register scratch1, |
3512 Register right, | 3501 Register scratch2, Register scratch3, Register scratch4) { |
3513 Register scratch1, | |
3514 Register scratch2, | |
3515 Register scratch3, | |
3516 Register scratch4) { | |
3517 Label result_not_equal, compare_lengths; | 3502 Label result_not_equal, compare_lengths; |
3518 // Find minimum length and length difference. | 3503 // Find minimum length and length difference. |
3519 __ lw(scratch1, FieldMemOperand(left, String::kLengthOffset)); | 3504 __ lw(scratch1, FieldMemOperand(left, String::kLengthOffset)); |
3520 __ lw(scratch2, FieldMemOperand(right, String::kLengthOffset)); | 3505 __ lw(scratch2, FieldMemOperand(right, String::kLengthOffset)); |
3521 __ Subu(scratch3, scratch1, Operand(scratch2)); | 3506 __ Subu(scratch3, scratch1, Operand(scratch2)); |
3522 Register length_delta = scratch3; | 3507 Register length_delta = scratch3; |
3523 __ slt(scratch4, scratch2, scratch1); | 3508 __ slt(scratch4, scratch2, scratch1); |
3524 __ Movn(scratch1, scratch2, scratch4); | 3509 __ Movn(scratch1, scratch2, scratch4); |
3525 Register min_length = scratch1; | 3510 Register min_length = scratch1; |
3526 STATIC_ASSERT(kSmiTag == 0); | 3511 STATIC_ASSERT(kSmiTag == 0); |
(...skipping 18 matching lines...) Expand all Loading... |
3545 Label ret; | 3530 Label ret; |
3546 __ Branch(&ret, eq, scratch2, Operand(scratch4)); | 3531 __ Branch(&ret, eq, scratch2, Operand(scratch4)); |
3547 __ li(v0, Operand(Smi::FromInt(GREATER))); | 3532 __ li(v0, Operand(Smi::FromInt(GREATER))); |
3548 __ Branch(&ret, gt, scratch2, Operand(scratch4)); | 3533 __ Branch(&ret, gt, scratch2, Operand(scratch4)); |
3549 __ li(v0, Operand(Smi::FromInt(LESS))); | 3534 __ li(v0, Operand(Smi::FromInt(LESS))); |
3550 __ bind(&ret); | 3535 __ bind(&ret); |
3551 __ Ret(); | 3536 __ Ret(); |
3552 } | 3537 } |
3553 | 3538 |
3554 | 3539 |
3555 void StringCompareStub::GenerateAsciiCharsCompareLoop( | 3540 void StringHelper::GenerateAsciiCharsCompareLoop( |
3556 MacroAssembler* masm, | 3541 MacroAssembler* masm, Register left, Register right, Register length, |
3557 Register left, | 3542 Register scratch1, Register scratch2, Register scratch3, |
3558 Register right, | |
3559 Register length, | |
3560 Register scratch1, | |
3561 Register scratch2, | |
3562 Register scratch3, | |
3563 Label* chars_not_equal) { | 3543 Label* chars_not_equal) { |
3564 // Change index to run from -length to -1 by adding length to string | 3544 // Change index to run from -length to -1 by adding length to string |
3565 // start. This means that loop ends when index reaches zero, which | 3545 // start. This means that loop ends when index reaches zero, which |
3566 // doesn't need an additional compare. | 3546 // doesn't need an additional compare. |
3567 __ SmiUntag(length); | 3547 __ SmiUntag(length); |
3568 __ Addu(scratch1, length, | 3548 __ Addu(scratch1, length, |
3569 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); | 3549 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); |
3570 __ Addu(left, left, Operand(scratch1)); | 3550 __ Addu(left, left, Operand(scratch1)); |
3571 __ Addu(right, right, Operand(scratch1)); | 3551 __ Addu(right, right, Operand(scratch1)); |
3572 __ Subu(length, zero_reg, length); | 3552 __ Subu(length, zero_reg, length); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3606 __ DropAndRet(2); | 3586 __ DropAndRet(2); |
3607 | 3587 |
3608 __ bind(¬_same); | 3588 __ bind(¬_same); |
3609 | 3589 |
3610 // Check that both objects are sequential ASCII strings. | 3590 // Check that both objects are sequential ASCII strings. |
3611 __ JumpIfNotBothSequentialAsciiStrings(a1, a0, a2, a3, &runtime); | 3591 __ JumpIfNotBothSequentialAsciiStrings(a1, a0, a2, a3, &runtime); |
3612 | 3592 |
3613 // Compare flat ASCII strings natively. Remove arguments from stack first. | 3593 // Compare flat ASCII strings natively. Remove arguments from stack first. |
3614 __ IncrementCounter(counters->string_compare_native(), 1, a2, a3); | 3594 __ IncrementCounter(counters->string_compare_native(), 1, a2, a3); |
3615 __ Addu(sp, sp, Operand(2 * kPointerSize)); | 3595 __ Addu(sp, sp, Operand(2 * kPointerSize)); |
3616 GenerateCompareFlatAsciiStrings(masm, a1, a0, a2, a3, t0, t1); | 3596 StringHelper::GenerateCompareFlatAsciiStrings(masm, a1, a0, a2, a3, t0, t1); |
3617 | 3597 |
3618 __ bind(&runtime); | 3598 __ bind(&runtime); |
3619 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3599 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3620 } | 3600 } |
3621 | 3601 |
3622 | 3602 |
3623 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { | 3603 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { |
3624 // ----------- S t a t e ------------- | 3604 // ----------- S t a t e ------------- |
3625 // -- a1 : left | 3605 // -- a1 : left |
3626 // -- a0 : right | 3606 // -- a0 : right |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3906 __ bind(&is_symbol); | 3886 __ bind(&is_symbol); |
3907 } | 3887 } |
3908 | 3888 |
3909 // Check that both strings are sequential ASCII. | 3889 // Check that both strings are sequential ASCII. |
3910 Label runtime; | 3890 Label runtime; |
3911 __ JumpIfBothInstanceTypesAreNotSequentialAscii( | 3891 __ JumpIfBothInstanceTypesAreNotSequentialAscii( |
3912 tmp1, tmp2, tmp3, tmp4, &runtime); | 3892 tmp1, tmp2, tmp3, tmp4, &runtime); |
3913 | 3893 |
3914 // Compare flat ASCII strings. Returns when done. | 3894 // Compare flat ASCII strings. Returns when done. |
3915 if (equality) { | 3895 if (equality) { |
3916 StringCompareStub::GenerateFlatAsciiStringEquals( | 3896 StringHelper::GenerateFlatAsciiStringEquals(masm, left, right, tmp1, tmp2, |
3917 masm, left, right, tmp1, tmp2, tmp3); | 3897 tmp3); |
3918 } else { | 3898 } else { |
3919 StringCompareStub::GenerateCompareFlatAsciiStrings( | 3899 StringHelper::GenerateCompareFlatAsciiStrings(masm, left, right, tmp1, tmp2, |
3920 masm, left, right, tmp1, tmp2, tmp3, tmp4); | 3900 tmp3, tmp4); |
3921 } | 3901 } |
3922 | 3902 |
3923 // Handle more complex cases in runtime. | 3903 // Handle more complex cases in runtime. |
3924 __ bind(&runtime); | 3904 __ bind(&runtime); |
3925 __ Push(left, right); | 3905 __ Push(left, right); |
3926 if (equality) { | 3906 if (equality) { |
3927 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 3907 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
3928 } else { | 3908 } else { |
3929 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3909 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3930 } | 3910 } |
(...skipping 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5065 MemOperand(fp, 6 * kPointerSize), | 5045 MemOperand(fp, 6 * kPointerSize), |
5066 NULL); | 5046 NULL); |
5067 } | 5047 } |
5068 | 5048 |
5069 | 5049 |
5070 #undef __ | 5050 #undef __ |
5071 | 5051 |
5072 } } // namespace v8::internal | 5052 } } // namespace v8::internal |
5073 | 5053 |
5074 #endif // V8_TARGET_ARCH_MIPS | 5054 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |