OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) { | 197 void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) { |
198 __ cmp(current_character(), Operand(limit)); | 198 __ cmp(current_character(), Operand(limit)); |
199 BranchOrBacktrack(gt, on_greater); | 199 BranchOrBacktrack(gt, on_greater); |
200 } | 200 } |
201 | 201 |
202 | 202 |
203 void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) { | 203 void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) { |
204 Label not_at_start; | 204 Label not_at_start; |
205 // Did we start the match at the start of the string at all? | 205 // Did we start the match at the start of the string at all? |
206 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); | 206 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); |
207 __ cmp(r0, Operand(0, RelocInfo::NONE)); | 207 __ cmp(r0, Operand(0, RelocInfo::NONE32)); |
208 BranchOrBacktrack(ne, ¬_at_start); | 208 BranchOrBacktrack(ne, ¬_at_start); |
209 | 209 |
210 // If we did, are we still at the start of the input? | 210 // If we did, are we still at the start of the input? |
211 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); | 211 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); |
212 __ add(r0, end_of_input_address(), Operand(current_input_offset())); | 212 __ add(r0, end_of_input_address(), Operand(current_input_offset())); |
213 __ cmp(r0, r1); | 213 __ cmp(r0, r1); |
214 BranchOrBacktrack(eq, on_at_start); | 214 BranchOrBacktrack(eq, on_at_start); |
215 __ bind(¬_at_start); | 215 __ bind(¬_at_start); |
216 } | 216 } |
217 | 217 |
218 | 218 |
219 void RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) { | 219 void RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) { |
220 // Did we start the match at the start of the string at all? | 220 // Did we start the match at the start of the string at all? |
221 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); | 221 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); |
222 __ cmp(r0, Operand(0, RelocInfo::NONE)); | 222 __ cmp(r0, Operand(0, RelocInfo::NONE32)); |
223 BranchOrBacktrack(ne, on_not_at_start); | 223 BranchOrBacktrack(ne, on_not_at_start); |
224 // If we did, are we still at the start of the input? | 224 // If we did, are we still at the start of the input? |
225 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); | 225 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); |
226 __ add(r0, end_of_input_address(), Operand(current_input_offset())); | 226 __ add(r0, end_of_input_address(), Operand(current_input_offset())); |
227 __ cmp(r0, r1); | 227 __ cmp(r0, r1); |
228 BranchOrBacktrack(ne, on_not_at_start); | 228 BranchOrBacktrack(ne, on_not_at_start); |
229 } | 229 } |
230 | 230 |
231 | 231 |
232 void RegExpMacroAssemblerARM::CheckCharacterLT(uc16 limit, Label* on_less) { | 232 void RegExpMacroAssemblerARM::CheckCharacterLT(uc16 limit, Label* on_less) { |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 __ mov(r3, Operand(ExternalReference::isolate_address())); | 378 __ mov(r3, Operand(ExternalReference::isolate_address())); |
379 | 379 |
380 { | 380 { |
381 AllowExternalCallThatCantCauseGC scope(masm_); | 381 AllowExternalCallThatCantCauseGC scope(masm_); |
382 ExternalReference function = | 382 ExternalReference function = |
383 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate()); | 383 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate()); |
384 __ CallCFunction(function, argument_count); | 384 __ CallCFunction(function, argument_count); |
385 } | 385 } |
386 | 386 |
387 // Check if function returned non-zero for success or zero for failure. | 387 // Check if function returned non-zero for success or zero for failure. |
388 __ cmp(r0, Operand(0, RelocInfo::NONE)); | 388 __ cmp(r0, Operand(0, RelocInfo::NONE32)); |
389 BranchOrBacktrack(eq, on_no_match); | 389 BranchOrBacktrack(eq, on_no_match); |
390 // On success, increment position by length of capture. | 390 // On success, increment position by length of capture. |
391 __ add(current_input_offset(), current_input_offset(), Operand(r4)); | 391 __ add(current_input_offset(), current_input_offset(), Operand(r4)); |
392 } | 392 } |
393 | 393 |
394 __ bind(&fallthrough); | 394 __ bind(&fallthrough); |
395 } | 395 } |
396 | 396 |
397 | 397 |
398 void RegExpMacroAssemblerARM::CheckNotBackReference( | 398 void RegExpMacroAssemblerARM::CheckNotBackReference( |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 // Start new stack frame. | 668 // Start new stack frame. |
669 // Store link register in existing stack-cell. | 669 // Store link register in existing stack-cell. |
670 // Order here should correspond to order of offset constants in header file. | 670 // Order here should correspond to order of offset constants in header file. |
671 RegList registers_to_retain = r4.bit() | r5.bit() | r6.bit() | | 671 RegList registers_to_retain = r4.bit() | r5.bit() | r6.bit() | |
672 r7.bit() | r8.bit() | r9.bit() | r10.bit() | fp.bit(); | 672 r7.bit() | r8.bit() | r9.bit() | r10.bit() | fp.bit(); |
673 RegList argument_registers = r0.bit() | r1.bit() | r2.bit() | r3.bit(); | 673 RegList argument_registers = r0.bit() | r1.bit() | r2.bit() | r3.bit(); |
674 __ stm(db_w, sp, argument_registers | registers_to_retain | lr.bit()); | 674 __ stm(db_w, sp, argument_registers | registers_to_retain | lr.bit()); |
675 // Set frame pointer in space for it if this is not a direct call | 675 // Set frame pointer in space for it if this is not a direct call |
676 // from generated code. | 676 // from generated code. |
677 __ add(frame_pointer(), sp, Operand(4 * kPointerSize)); | 677 __ add(frame_pointer(), sp, Operand(4 * kPointerSize)); |
678 __ mov(r0, Operand(0, RelocInfo::NONE)); | 678 __ mov(r0, Operand(0, RelocInfo::NONE32)); |
679 __ push(r0); // Make room for success counter and initialize it to 0. | 679 __ push(r0); // Make room for success counter and initialize it to 0. |
680 __ push(r0); // Make room for "position - 1" constant (value is irrelevant). | 680 __ push(r0); // Make room for "position - 1" constant (value is irrelevant). |
681 // Check if we have space on the stack for registers. | 681 // Check if we have space on the stack for registers. |
682 Label stack_limit_hit; | 682 Label stack_limit_hit; |
683 Label stack_ok; | 683 Label stack_ok; |
684 | 684 |
685 ExternalReference stack_limit = | 685 ExternalReference stack_limit = |
686 ExternalReference::address_of_stack_limit(masm_->isolate()); | 686 ExternalReference::address_of_stack_limit(masm_->isolate()); |
687 __ mov(r0, Operand(stack_limit)); | 687 __ mov(r0, Operand(stack_limit)); |
688 __ ldr(r0, MemOperand(r0)); | 688 __ ldr(r0, MemOperand(r0)); |
689 __ sub(r0, sp, r0, SetCC); | 689 __ sub(r0, sp, r0, SetCC); |
690 // Handle it if the stack pointer is already below the stack limit. | 690 // Handle it if the stack pointer is already below the stack limit. |
691 __ b(ls, &stack_limit_hit); | 691 __ b(ls, &stack_limit_hit); |
692 // Check if there is room for the variable number of registers above | 692 // Check if there is room for the variable number of registers above |
693 // the stack limit. | 693 // the stack limit. |
694 __ cmp(r0, Operand(num_registers_ * kPointerSize)); | 694 __ cmp(r0, Operand(num_registers_ * kPointerSize)); |
695 __ b(hs, &stack_ok); | 695 __ b(hs, &stack_ok); |
696 // Exit with OutOfMemory exception. There is not enough space on the stack | 696 // Exit with OutOfMemory exception. There is not enough space on the stack |
697 // for our working registers. | 697 // for our working registers. |
698 __ mov(r0, Operand(EXCEPTION)); | 698 __ mov(r0, Operand(EXCEPTION)); |
699 __ jmp(&return_r0); | 699 __ jmp(&return_r0); |
700 | 700 |
701 __ bind(&stack_limit_hit); | 701 __ bind(&stack_limit_hit); |
702 CallCheckStackGuardState(r0); | 702 CallCheckStackGuardState(r0); |
703 __ cmp(r0, Operand(0, RelocInfo::NONE)); | 703 __ cmp(r0, Operand(0, RelocInfo::NONE32)); |
704 // If returned value is non-zero, we exit with the returned value as result. | 704 // If returned value is non-zero, we exit with the returned value as result. |
705 __ b(ne, &return_r0); | 705 __ b(ne, &return_r0); |
706 | 706 |
707 __ bind(&stack_ok); | 707 __ bind(&stack_ok); |
708 | 708 |
709 // Allocate space on stack for registers. | 709 // Allocate space on stack for registers. |
710 __ sub(sp, sp, Operand(num_registers_ * kPointerSize)); | 710 __ sub(sp, sp, Operand(num_registers_ * kPointerSize)); |
711 // Load string end. | 711 // Load string end. |
712 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); | 712 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); |
713 // Load input start. | 713 // Load input start. |
714 __ ldr(r0, MemOperand(frame_pointer(), kInputStart)); | 714 __ ldr(r0, MemOperand(frame_pointer(), kInputStart)); |
715 // Find negative length (offset of start relative to end). | 715 // Find negative length (offset of start relative to end). |
716 __ sub(current_input_offset(), r0, end_of_input_address()); | 716 __ sub(current_input_offset(), r0, end_of_input_address()); |
717 // Set r0 to address of char before start of the input string | 717 // Set r0 to address of char before start of the input string |
718 // (effectively string position -1). | 718 // (effectively string position -1). |
719 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); | 719 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); |
720 __ sub(r0, current_input_offset(), Operand(char_size())); | 720 __ sub(r0, current_input_offset(), Operand(char_size())); |
721 __ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0)); | 721 __ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0)); |
722 // Store this value in a local variable, for use when clearing | 722 // Store this value in a local variable, for use when clearing |
723 // position registers. | 723 // position registers. |
724 __ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); | 724 __ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); |
725 | 725 |
726 // Initialize code pointer register | 726 // Initialize code pointer register |
727 __ mov(code_pointer(), Operand(masm_->CodeObject())); | 727 __ mov(code_pointer(), Operand(masm_->CodeObject())); |
728 | 728 |
729 Label load_char_start_regexp, start_regexp; | 729 Label load_char_start_regexp, start_regexp; |
730 // Load newline if index is at start, previous character otherwise. | 730 // Load newline if index is at start, previous character otherwise. |
731 __ cmp(r1, Operand(0, RelocInfo::NONE)); | 731 __ cmp(r1, Operand(0, RelocInfo::NONE32)); |
732 __ b(ne, &load_char_start_regexp); | 732 __ b(ne, &load_char_start_regexp); |
733 __ mov(current_character(), Operand('\n'), LeaveCC, eq); | 733 __ mov(current_character(), Operand('\n'), LeaveCC, eq); |
734 __ jmp(&start_regexp); | 734 __ jmp(&start_regexp); |
735 | 735 |
736 // Global regexp restarts matching here. | 736 // Global regexp restarts matching here. |
737 __ bind(&load_char_start_regexp); | 737 __ bind(&load_char_start_regexp); |
738 // Load previous char as initial value of current character register. | 738 // Load previous char as initial value of current character register. |
739 LoadCurrentCharacterUnchecked(-1, 1); | 739 LoadCurrentCharacterUnchecked(-1, 1); |
740 __ bind(&start_regexp); | 740 __ bind(&start_regexp); |
741 | 741 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 Backtrack(); | 866 Backtrack(); |
867 } | 867 } |
868 | 868 |
869 Label exit_with_exception; | 869 Label exit_with_exception; |
870 | 870 |
871 // Preempt-code | 871 // Preempt-code |
872 if (check_preempt_label_.is_linked()) { | 872 if (check_preempt_label_.is_linked()) { |
873 SafeCallTarget(&check_preempt_label_); | 873 SafeCallTarget(&check_preempt_label_); |
874 | 874 |
875 CallCheckStackGuardState(r0); | 875 CallCheckStackGuardState(r0); |
876 __ cmp(r0, Operand(0, RelocInfo::NONE)); | 876 __ cmp(r0, Operand(0, RelocInfo::NONE32)); |
877 // If returning non-zero, we should end execution with the given | 877 // If returning non-zero, we should end execution with the given |
878 // result as return value. | 878 // result as return value. |
879 __ b(ne, &return_r0); | 879 __ b(ne, &return_r0); |
880 | 880 |
881 // String might have moved: Reload end of string from frame. | 881 // String might have moved: Reload end of string from frame. |
882 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); | 882 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); |
883 SafeReturn(); | 883 SafeReturn(); |
884 } | 884 } |
885 | 885 |
886 // Backtrack stack overflow code. | 886 // Backtrack stack overflow code. |
887 if (stack_overflow_label_.is_linked()) { | 887 if (stack_overflow_label_.is_linked()) { |
888 SafeCallTarget(&stack_overflow_label_); | 888 SafeCallTarget(&stack_overflow_label_); |
889 // Reached if the backtrack-stack limit has been hit. | 889 // Reached if the backtrack-stack limit has been hit. |
890 Label grow_failed; | 890 Label grow_failed; |
891 | 891 |
892 // Call GrowStack(backtrack_stackpointer(), &stack_base) | 892 // Call GrowStack(backtrack_stackpointer(), &stack_base) |
893 static const int num_arguments = 3; | 893 static const int num_arguments = 3; |
894 __ PrepareCallCFunction(num_arguments, r0); | 894 __ PrepareCallCFunction(num_arguments, r0); |
895 __ mov(r0, backtrack_stackpointer()); | 895 __ mov(r0, backtrack_stackpointer()); |
896 __ add(r1, frame_pointer(), Operand(kStackHighEnd)); | 896 __ add(r1, frame_pointer(), Operand(kStackHighEnd)); |
897 __ mov(r2, Operand(ExternalReference::isolate_address())); | 897 __ mov(r2, Operand(ExternalReference::isolate_address())); |
898 ExternalReference grow_stack = | 898 ExternalReference grow_stack = |
899 ExternalReference::re_grow_stack(masm_->isolate()); | 899 ExternalReference::re_grow_stack(masm_->isolate()); |
900 __ CallCFunction(grow_stack, num_arguments); | 900 __ CallCFunction(grow_stack, num_arguments); |
901 // If return NULL, we have failed to grow the stack, and | 901 // If return NULL, we have failed to grow the stack, and |
902 // must exit with a stack-overflow exception. | 902 // must exit with a stack-overflow exception. |
903 __ cmp(r0, Operand(0, RelocInfo::NONE)); | 903 __ cmp(r0, Operand(0, RelocInfo::NONE32)); |
904 __ b(eq, &exit_with_exception); | 904 __ b(eq, &exit_with_exception); |
905 // Otherwise use return value as new stack pointer. | 905 // Otherwise use return value as new stack pointer. |
906 __ mov(backtrack_stackpointer(), r0); | 906 __ mov(backtrack_stackpointer(), r0); |
907 // Restore saved registers and continue. | 907 // Restore saved registers and continue. |
908 SafeReturn(); | 908 SafeReturn(); |
909 } | 909 } |
910 | 910 |
911 if (exit_with_exception.is_linked()) { | 911 if (exit_with_exception.is_linked()) { |
912 // If any of the code above needed to exit with an exception. | 912 // If any of the code above needed to exit with an exception. |
913 __ bind(&exit_with_exception); | 913 __ bind(&exit_with_exception); |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1411 __ ldr(pc, MemOperand(sp, stack_alignment, PostIndex)); | 1411 __ ldr(pc, MemOperand(sp, stack_alignment, PostIndex)); |
1412 } | 1412 } |
1413 | 1413 |
1414 #undef __ | 1414 #undef __ |
1415 | 1415 |
1416 #endif // V8_INTERPRETED_REGEXP | 1416 #endif // V8_INTERPRETED_REGEXP |
1417 | 1417 |
1418 }} // namespace v8::internal | 1418 }} // namespace v8::internal |
1419 | 1419 |
1420 #endif // V8_TARGET_ARCH_ARM | 1420 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |