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_ARM | 7 #if V8_TARGET_ARCH_ARM |
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 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
803 | 803 |
804 // Check for both being sequential ASCII strings, and inline if that is the | 804 // Check for both being sequential ASCII strings, and inline if that is the |
805 // case. | 805 // case. |
806 __ bind(&flat_string_check); | 806 __ bind(&flat_string_check); |
807 | 807 |
808 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, r2, r3, &slow); | 808 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, r2, r3, &slow); |
809 | 809 |
810 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, r2, | 810 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, r2, |
811 r3); | 811 r3); |
812 if (cc == eq) { | 812 if (cc == eq) { |
813 StringCompareStub::GenerateFlatAsciiStringEquals(masm, | 813 StringHelper::GenerateFlatAsciiStringEquals(masm, lhs, rhs, r2, r3, r4); |
814 lhs, | |
815 rhs, | |
816 r2, | |
817 r3, | |
818 r4); | |
819 } else { | 814 } else { |
820 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, | 815 StringHelper::GenerateCompareFlatAsciiStrings(masm, lhs, rhs, r2, r3, r4, |
821 lhs, | 816 r5); |
822 rhs, | |
823 r2, | |
824 r3, | |
825 r4, | |
826 r5); | |
827 } | 817 } |
828 // Never falls through to here. | 818 // Never falls through to here. |
829 | 819 |
830 __ bind(&slow); | 820 __ bind(&slow); |
831 | 821 |
832 __ Push(lhs, rhs); | 822 __ Push(lhs, rhs); |
833 // Figure out which native to call and setup the arguments. | 823 // Figure out which native to call and setup the arguments. |
834 Builtins::JavaScript native; | 824 Builtins::JavaScript native; |
835 if (cc == eq) { | 825 if (cc == eq) { |
836 native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS; | 826 native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS; |
(...skipping 20 matching lines...) Expand all Loading... | |
857 | 847 |
858 | 848 |
859 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { | 849 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { |
860 // We don't allow a GC during a store buffer overflow so there is no need to | 850 // We don't allow a GC during a store buffer overflow so there is no need to |
861 // store the registers in any particular way, but we do have to store and | 851 // store the registers in any particular way, but we do have to store and |
862 // restore them. | 852 // restore them. |
863 __ stm(db_w, sp, kCallerSaved | lr.bit()); | 853 __ stm(db_w, sp, kCallerSaved | lr.bit()); |
864 | 854 |
865 const Register scratch = r1; | 855 const Register scratch = r1; |
866 | 856 |
867 if (save_doubles_ == kSaveFPRegs) { | 857 if (save_doubles()) { |
mvstanton
2014/09/02 12:38:35
This is a nice thing to do.
| |
868 __ SaveFPRegs(sp, scratch); | 858 __ SaveFPRegs(sp, scratch); |
869 } | 859 } |
870 const int argument_count = 1; | 860 const int argument_count = 1; |
871 const int fp_argument_count = 0; | 861 const int fp_argument_count = 0; |
872 | 862 |
873 AllowExternalCallThatCantCauseGC scope(masm); | 863 AllowExternalCallThatCantCauseGC scope(masm); |
874 __ PrepareCallCFunction(argument_count, fp_argument_count, scratch); | 864 __ PrepareCallCFunction(argument_count, fp_argument_count, scratch); |
875 __ mov(r0, Operand(ExternalReference::isolate_address(isolate()))); | 865 __ mov(r0, Operand(ExternalReference::isolate_address(isolate()))); |
876 __ CallCFunction( | 866 __ CallCFunction( |
877 ExternalReference::store_buffer_overflow_function(isolate()), | 867 ExternalReference::store_buffer_overflow_function(isolate()), |
878 argument_count); | 868 argument_count); |
879 if (save_doubles_ == kSaveFPRegs) { | 869 if (save_doubles()) { |
880 __ RestoreFPRegs(sp, scratch); | 870 __ RestoreFPRegs(sp, scratch); |
881 } | 871 } |
882 __ ldm(ia_w, sp, kCallerSaved | pc.bit()); // Also pop pc to get Ret(0). | 872 __ ldm(ia_w, sp, kCallerSaved | pc.bit()); // Also pop pc to get Ret(0). |
883 } | 873 } |
884 | 874 |
885 | 875 |
886 void MathPowStub::Generate(MacroAssembler* masm) { | 876 void MathPowStub::Generate(MacroAssembler* masm) { |
887 const Register base = r1; | 877 const Register base = r1; |
888 const Register exponent = r2; | 878 const Register exponent = r2; |
889 const Register heapnumbermap = r5; | 879 const Register heapnumbermap = r5; |
(...skipping 2398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3288 __ SmiTag(r3, r3); | 3278 __ SmiTag(r3, r3); |
3289 StringCharAtGenerator generator( | 3279 StringCharAtGenerator generator( |
3290 r0, r3, r2, r0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); | 3280 r0, r3, r2, r0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); |
3291 generator.GenerateFast(masm); | 3281 generator.GenerateFast(masm); |
3292 __ Drop(3); | 3282 __ Drop(3); |
3293 __ Ret(); | 3283 __ Ret(); |
3294 generator.SkipSlow(masm, &runtime); | 3284 generator.SkipSlow(masm, &runtime); |
3295 } | 3285 } |
3296 | 3286 |
3297 | 3287 |
3298 void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm, | 3288 void StringHelper::GenerateFlatAsciiStringEquals(MacroAssembler* masm, |
3299 Register left, | 3289 Register left, Register right, |
3300 Register right, | 3290 Register scratch1, |
3301 Register scratch1, | 3291 Register scratch2, |
3302 Register scratch2, | 3292 Register scratch3) { |
3303 Register scratch3) { | |
3304 Register length = scratch1; | 3293 Register length = scratch1; |
3305 | 3294 |
3306 // Compare lengths. | 3295 // Compare lengths. |
3307 Label strings_not_equal, check_zero_length; | 3296 Label strings_not_equal, check_zero_length; |
3308 __ ldr(length, FieldMemOperand(left, String::kLengthOffset)); | 3297 __ ldr(length, FieldMemOperand(left, String::kLengthOffset)); |
3309 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); | 3298 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); |
3310 __ cmp(length, scratch2); | 3299 __ cmp(length, scratch2); |
3311 __ b(eq, &check_zero_length); | 3300 __ b(eq, &check_zero_length); |
3312 __ bind(&strings_not_equal); | 3301 __ bind(&strings_not_equal); |
3313 __ mov(r0, Operand(Smi::FromInt(NOT_EQUAL))); | 3302 __ mov(r0, Operand(Smi::FromInt(NOT_EQUAL))); |
(...skipping 13 matching lines...) Expand all Loading... | |
3327 GenerateAsciiCharsCompareLoop(masm, | 3316 GenerateAsciiCharsCompareLoop(masm, |
3328 left, right, length, scratch2, scratch3, | 3317 left, right, length, scratch2, scratch3, |
3329 &strings_not_equal); | 3318 &strings_not_equal); |
3330 | 3319 |
3331 // Characters are equal. | 3320 // Characters are equal. |
3332 __ mov(r0, Operand(Smi::FromInt(EQUAL))); | 3321 __ mov(r0, Operand(Smi::FromInt(EQUAL))); |
3333 __ Ret(); | 3322 __ Ret(); |
3334 } | 3323 } |
3335 | 3324 |
3336 | 3325 |
3337 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 3326 void StringHelper::GenerateCompareFlatAsciiStrings( |
3338 Register left, | 3327 MacroAssembler* masm, Register left, Register right, Register scratch1, |
3339 Register right, | 3328 Register scratch2, Register scratch3, Register scratch4) { |
3340 Register scratch1, | |
3341 Register scratch2, | |
3342 Register scratch3, | |
3343 Register scratch4) { | |
3344 Label result_not_equal, compare_lengths; | 3329 Label result_not_equal, compare_lengths; |
3345 // Find minimum length and length difference. | 3330 // Find minimum length and length difference. |
3346 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset)); | 3331 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset)); |
3347 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); | 3332 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); |
3348 __ sub(scratch3, scratch1, Operand(scratch2), SetCC); | 3333 __ sub(scratch3, scratch1, Operand(scratch2), SetCC); |
3349 Register length_delta = scratch3; | 3334 Register length_delta = scratch3; |
3350 __ mov(scratch1, scratch2, LeaveCC, gt); | 3335 __ mov(scratch1, scratch2, LeaveCC, gt); |
3351 Register min_length = scratch1; | 3336 Register min_length = scratch1; |
3352 STATIC_ASSERT(kSmiTag == 0); | 3337 STATIC_ASSERT(kSmiTag == 0); |
3353 __ cmp(min_length, Operand::Zero()); | 3338 __ cmp(min_length, Operand::Zero()); |
(...skipping 11 matching lines...) Expand all Loading... | |
3365 __ mov(r0, Operand(length_delta), SetCC); | 3350 __ mov(r0, Operand(length_delta), SetCC); |
3366 __ bind(&result_not_equal); | 3351 __ bind(&result_not_equal); |
3367 // Conditionally update the result based either on length_delta or | 3352 // Conditionally update the result based either on length_delta or |
3368 // the last comparion performed in the loop above. | 3353 // the last comparion performed in the loop above. |
3369 __ mov(r0, Operand(Smi::FromInt(GREATER)), LeaveCC, gt); | 3354 __ mov(r0, Operand(Smi::FromInt(GREATER)), LeaveCC, gt); |
3370 __ mov(r0, Operand(Smi::FromInt(LESS)), LeaveCC, lt); | 3355 __ mov(r0, Operand(Smi::FromInt(LESS)), LeaveCC, lt); |
3371 __ Ret(); | 3356 __ Ret(); |
3372 } | 3357 } |
3373 | 3358 |
3374 | 3359 |
3375 void StringCompareStub::GenerateAsciiCharsCompareLoop( | 3360 void StringHelper::GenerateAsciiCharsCompareLoop( |
3376 MacroAssembler* masm, | 3361 MacroAssembler* masm, Register left, Register right, Register length, |
3377 Register left, | 3362 Register scratch1, Register scratch2, Label* chars_not_equal) { |
3378 Register right, | |
3379 Register length, | |
3380 Register scratch1, | |
3381 Register scratch2, | |
3382 Label* chars_not_equal) { | |
3383 // Change index to run from -length to -1 by adding length to string | 3363 // Change index to run from -length to -1 by adding length to string |
3384 // start. This means that loop ends when index reaches zero, which | 3364 // start. This means that loop ends when index reaches zero, which |
3385 // doesn't need an additional compare. | 3365 // doesn't need an additional compare. |
3386 __ SmiUntag(length); | 3366 __ SmiUntag(length); |
3387 __ add(scratch1, length, | 3367 __ add(scratch1, length, |
3388 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); | 3368 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); |
3389 __ add(left, left, Operand(scratch1)); | 3369 __ add(left, left, Operand(scratch1)); |
3390 __ add(right, right, Operand(scratch1)); | 3370 __ add(right, right, Operand(scratch1)); |
3391 __ rsb(length, length, Operand::Zero()); | 3371 __ rsb(length, length, Operand::Zero()); |
3392 Register index = length; // index = -length; | 3372 Register index = length; // index = -length; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3424 __ Ret(); | 3404 __ Ret(); |
3425 | 3405 |
3426 __ bind(¬_same); | 3406 __ bind(¬_same); |
3427 | 3407 |
3428 // Check that both objects are sequential ASCII strings. | 3408 // Check that both objects are sequential ASCII strings. |
3429 __ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime); | 3409 __ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime); |
3430 | 3410 |
3431 // Compare flat ASCII strings natively. Remove arguments from stack first. | 3411 // Compare flat ASCII strings natively. Remove arguments from stack first. |
3432 __ IncrementCounter(counters->string_compare_native(), 1, r2, r3); | 3412 __ IncrementCounter(counters->string_compare_native(), 1, r2, r3); |
3433 __ add(sp, sp, Operand(2 * kPointerSize)); | 3413 __ add(sp, sp, Operand(2 * kPointerSize)); |
3434 GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5); | 3414 StringHelper::GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5); |
3435 | 3415 |
3436 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 3416 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
3437 // tagged as a small integer. | 3417 // tagged as a small integer. |
3438 __ bind(&runtime); | 3418 __ bind(&runtime); |
3439 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3419 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3440 } | 3420 } |
3441 | 3421 |
3442 | 3422 |
3443 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { | 3423 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { |
3444 // ----------- S t a t e ------------- | 3424 // ----------- S t a t e ------------- |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3697 __ Ret(eq); | 3677 __ Ret(eq); |
3698 } | 3678 } |
3699 | 3679 |
3700 // Check that both strings are sequential ASCII. | 3680 // Check that both strings are sequential ASCII. |
3701 Label runtime; | 3681 Label runtime; |
3702 __ JumpIfBothInstanceTypesAreNotSequentialAscii( | 3682 __ JumpIfBothInstanceTypesAreNotSequentialAscii( |
3703 tmp1, tmp2, tmp3, tmp4, &runtime); | 3683 tmp1, tmp2, tmp3, tmp4, &runtime); |
3704 | 3684 |
3705 // Compare flat ASCII strings. Returns when done. | 3685 // Compare flat ASCII strings. Returns when done. |
3706 if (equality) { | 3686 if (equality) { |
3707 StringCompareStub::GenerateFlatAsciiStringEquals( | 3687 StringHelper::GenerateFlatAsciiStringEquals(masm, left, right, tmp1, tmp2, |
3708 masm, left, right, tmp1, tmp2, tmp3); | 3688 tmp3); |
3709 } else { | 3689 } else { |
3710 StringCompareStub::GenerateCompareFlatAsciiStrings( | 3690 StringHelper::GenerateCompareFlatAsciiStrings(masm, left, right, tmp1, tmp2, |
3711 masm, left, right, tmp1, tmp2, tmp3, tmp4); | 3691 tmp3, tmp4); |
3712 } | 3692 } |
3713 | 3693 |
3714 // Handle more complex cases in runtime. | 3694 // Handle more complex cases in runtime. |
3715 __ bind(&runtime); | 3695 __ bind(&runtime); |
3716 __ Push(left, right); | 3696 __ Push(left, right); |
3717 if (equality) { | 3697 if (equality) { |
3718 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); | 3698 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); |
3719 } else { | 3699 } else { |
3720 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 3700 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
3721 } | 3701 } |
(...skipping 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4853 MemOperand(fp, 6 * kPointerSize), | 4833 MemOperand(fp, 6 * kPointerSize), |
4854 NULL); | 4834 NULL); |
4855 } | 4835 } |
4856 | 4836 |
4857 | 4837 |
4858 #undef __ | 4838 #undef __ |
4859 | 4839 |
4860 } } // namespace v8::internal | 4840 } } // namespace v8::internal |
4861 | 4841 |
4862 #endif // V8_TARGET_ARCH_ARM | 4842 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |