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