Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(415)

Side by Side Diff: src/x64/regexp-macro-assembler-x64.cc

Issue 105503006: Replace movq with movp for X64 when the operand size is kPointerSize (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased with bleeding_edge Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 __ j(equal, on_no_match); 308 __ j(equal, on_no_match);
309 __ bind(&loop_increment); 309 __ bind(&loop_increment);
310 // Increment pointers into match and capture strings. 310 // Increment pointers into match and capture strings.
311 __ addq(r11, Immediate(1)); 311 __ addq(r11, Immediate(1));
312 __ addq(r9, Immediate(1)); 312 __ addq(r9, Immediate(1));
313 // Compare to end of capture, and loop if not done. 313 // Compare to end of capture, and loop if not done.
314 __ cmpq(r9, rbx); 314 __ cmpq(r9, rbx);
315 __ j(below, &loop); 315 __ j(below, &loop);
316 316
317 // Compute new value of character position after the matched part. 317 // Compute new value of character position after the matched part.
318 __ movq(rdi, r11); 318 __ movp(rdi, r11);
319 __ subq(rdi, rsi); 319 __ subq(rdi, rsi);
320 } else { 320 } else {
321 ASSERT(mode_ == UC16); 321 ASSERT(mode_ == UC16);
322 // Save important/volatile registers before calling C function. 322 // Save important/volatile registers before calling C function.
323 #ifndef _WIN64 323 #ifndef _WIN64
324 // Caller save on Linux and callee save in Windows. 324 // Caller save on Linux and callee save in Windows.
325 __ push(rsi); 325 __ push(rsi);
326 __ push(rdi); 326 __ push(rdi);
327 #endif 327 #endif
328 __ push(backtrack_stackpointer()); 328 __ push(backtrack_stackpointer());
329 329
330 static const int num_arguments = 4; 330 static const int num_arguments = 4;
331 __ PrepareCallCFunction(num_arguments); 331 __ PrepareCallCFunction(num_arguments);
332 332
333 // Put arguments into parameter registers. Parameters are 333 // Put arguments into parameter registers. Parameters are
334 // Address byte_offset1 - Address captured substring's start. 334 // Address byte_offset1 - Address captured substring's start.
335 // Address byte_offset2 - Address of current character position. 335 // Address byte_offset2 - Address of current character position.
336 // size_t byte_length - length of capture in bytes(!) 336 // size_t byte_length - length of capture in bytes(!)
337 // Isolate* isolate 337 // Isolate* isolate
338 #ifdef _WIN64 338 #ifdef _WIN64
339 // Compute and set byte_offset1 (start of capture). 339 // Compute and set byte_offset1 (start of capture).
340 __ lea(rcx, Operand(rsi, rdx, times_1, 0)); 340 __ lea(rcx, Operand(rsi, rdx, times_1, 0));
341 // Set byte_offset2. 341 // Set byte_offset2.
342 __ lea(rdx, Operand(rsi, rdi, times_1, 0)); 342 __ lea(rdx, Operand(rsi, rdi, times_1, 0));
343 // Set byte_length. 343 // Set byte_length.
344 __ movq(r8, rbx); 344 __ movp(r8, rbx);
345 // Isolate. 345 // Isolate.
346 __ LoadAddress(r9, ExternalReference::isolate_address(isolate())); 346 __ LoadAddress(r9, ExternalReference::isolate_address(isolate()));
347 #else // AMD64 calling convention 347 #else // AMD64 calling convention
348 // Compute byte_offset2 (current position = rsi+rdi). 348 // Compute byte_offset2 (current position = rsi+rdi).
349 __ lea(rax, Operand(rsi, rdi, times_1, 0)); 349 __ lea(rax, Operand(rsi, rdi, times_1, 0));
350 // Compute and set byte_offset1 (start of capture). 350 // Compute and set byte_offset1 (start of capture).
351 __ lea(rdi, Operand(rsi, rdx, times_1, 0)); 351 __ lea(rdi, Operand(rsi, rdx, times_1, 0));
352 // Set byte_offset2. 352 // Set byte_offset2.
353 __ movq(rsi, rax); 353 __ movp(rsi, rax);
354 // Set byte_length. 354 // Set byte_length.
355 __ movq(rdx, rbx); 355 __ movp(rdx, rbx);
356 // Isolate. 356 // Isolate.
357 __ LoadAddress(rcx, ExternalReference::isolate_address(isolate())); 357 __ LoadAddress(rcx, ExternalReference::isolate_address(isolate()));
358 #endif 358 #endif
359 359
360 { // NOLINT: Can't find a way to open this scope without confusing the 360 { // NOLINT: Can't find a way to open this scope without confusing the
361 // linter. 361 // linter.
362 AllowExternalCallThatCantCauseGC scope(&masm_); 362 AllowExternalCallThatCantCauseGC scope(&masm_);
363 ExternalReference compare = 363 ExternalReference compare =
364 ExternalReference::re_case_insensitive_compare_uc16(isolate()); 364 ExternalReference::re_case_insensitive_compare_uc16(isolate());
365 __ CallCFunction(compare, num_arguments); 365 __ CallCFunction(compare, num_arguments);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 BranchOrBacktrack(not_equal, on_no_match); 434 BranchOrBacktrack(not_equal, on_no_match);
435 // Increment pointers into capture and match string. 435 // Increment pointers into capture and match string.
436 __ addq(rbx, Immediate(char_size())); 436 __ addq(rbx, Immediate(char_size()));
437 __ addq(rdx, Immediate(char_size())); 437 __ addq(rdx, Immediate(char_size()));
438 // Check if we have reached end of match area. 438 // Check if we have reached end of match area.
439 __ cmpq(rdx, r9); 439 __ cmpq(rdx, r9);
440 __ j(below, &loop); 440 __ j(below, &loop);
441 441
442 // Success. 442 // Success.
443 // Set current character position to position after match. 443 // Set current character position to position after match.
444 __ movq(rdi, rbx); 444 __ movp(rdi, rbx);
445 __ subq(rdi, rsi); 445 __ subq(rdi, rsi);
446 446
447 __ bind(&fallthrough); 447 __ bind(&fallthrough);
448 } 448 }
449 449
450 450
451 void RegExpMacroAssemblerX64::CheckNotCharacter(uint32_t c, 451 void RegExpMacroAssemblerX64::CheckNotCharacter(uint32_t c,
452 Label* on_not_equal) { 452 Label* on_not_equal) {
453 __ cmpl(current_character(), Immediate(c)); 453 __ cmpl(current_character(), Immediate(c));
454 BranchOrBacktrack(not_equal, on_not_equal); 454 BranchOrBacktrack(not_equal, on_not_equal);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 BranchOrBacktrack(above, on_not_in_range); 515 BranchOrBacktrack(above, on_not_in_range);
516 } 516 }
517 517
518 518
519 void RegExpMacroAssemblerX64::CheckBitInTable( 519 void RegExpMacroAssemblerX64::CheckBitInTable(
520 Handle<ByteArray> table, 520 Handle<ByteArray> table,
521 Label* on_bit_set) { 521 Label* on_bit_set) {
522 __ Move(rax, table); 522 __ Move(rax, table);
523 Register index = current_character(); 523 Register index = current_character();
524 if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) { 524 if (mode_ != ASCII || kTableMask != String::kMaxOneByteCharCode) {
525 __ movq(rbx, current_character()); 525 __ movp(rbx, current_character());
526 __ and_(rbx, Immediate(kTableMask)); 526 __ and_(rbx, Immediate(kTableMask));
527 index = rbx; 527 index = rbx;
528 } 528 }
529 __ cmpb(FieldOperand(rax, index, times_1, ByteArray::kHeaderSize), 529 __ cmpb(FieldOperand(rax, index, times_1, ByteArray::kHeaderSize),
530 Immediate(0)); 530 Immediate(0));
531 BranchOrBacktrack(not_equal, on_bit_set); 531 BranchOrBacktrack(not_equal, on_bit_set);
532 } 532 }
533 533
534 534
535 bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(uc16 type, 535 bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(uc16 type,
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 // registers we need. 668 // registers we need.
669 // Entry code: 669 // Entry code:
670 __ bind(&entry_label_); 670 __ bind(&entry_label_);
671 671
672 // Tell the system that we have a stack frame. Because the type is MANUAL, no 672 // Tell the system that we have a stack frame. Because the type is MANUAL, no
673 // is generated. 673 // is generated.
674 FrameScope scope(&masm_, StackFrame::MANUAL); 674 FrameScope scope(&masm_, StackFrame::MANUAL);
675 675
676 // Actually emit code to start a new stack frame. 676 // Actually emit code to start a new stack frame.
677 __ push(rbp); 677 __ push(rbp);
678 __ movq(rbp, rsp); 678 __ movp(rbp, rsp);
679 // Save parameters and callee-save registers. Order here should correspond 679 // Save parameters and callee-save registers. Order here should correspond
680 // to order of kBackup_ebx etc. 680 // to order of kBackup_ebx etc.
681 #ifdef _WIN64 681 #ifdef _WIN64
682 // MSVC passes arguments in rcx, rdx, r8, r9, with backing stack slots. 682 // MSVC passes arguments in rcx, rdx, r8, r9, with backing stack slots.
683 // Store register parameters in pre-allocated stack slots, 683 // Store register parameters in pre-allocated stack slots,
684 __ movq(Operand(rbp, kInputString), rcx); 684 __ movq(Operand(rbp, kInputString), rcx);
685 __ movq(Operand(rbp, kStartIndex), rdx); // Passed as int32 in edx. 685 __ movq(Operand(rbp, kStartIndex), rdx); // Passed as int32 in edx.
686 __ movq(Operand(rbp, kInputStart), r8); 686 __ movq(Operand(rbp, kInputStart), r8);
687 __ movq(Operand(rbp, kInputEnd), r9); 687 __ movq(Operand(rbp, kInputEnd), r9);
688 // Callee-save on Win64. 688 // Callee-save on Win64.
(...skipping 21 matching lines...) Expand all
710 710
711 __ push(Immediate(0)); // Number of successful matches in a global regexp. 711 __ push(Immediate(0)); // Number of successful matches in a global regexp.
712 __ push(Immediate(0)); // Make room for "input start - 1" constant. 712 __ push(Immediate(0)); // Make room for "input start - 1" constant.
713 713
714 // Check if we have space on the stack for registers. 714 // Check if we have space on the stack for registers.
715 Label stack_limit_hit; 715 Label stack_limit_hit;
716 Label stack_ok; 716 Label stack_ok;
717 717
718 ExternalReference stack_limit = 718 ExternalReference stack_limit =
719 ExternalReference::address_of_stack_limit(isolate()); 719 ExternalReference::address_of_stack_limit(isolate());
720 __ movq(rcx, rsp); 720 __ movp(rcx, rsp);
721 __ Move(kScratchRegister, stack_limit); 721 __ Move(kScratchRegister, stack_limit);
722 __ subq(rcx, Operand(kScratchRegister, 0)); 722 __ subq(rcx, Operand(kScratchRegister, 0));
723 // Handle it if the stack pointer is already below the stack limit. 723 // Handle it if the stack pointer is already below the stack limit.
724 __ j(below_equal, &stack_limit_hit); 724 __ j(below_equal, &stack_limit_hit);
725 // Check if there is room for the variable number of registers above 725 // Check if there is room for the variable number of registers above
726 // the stack limit. 726 // the stack limit.
727 __ cmpq(rcx, Immediate(num_registers_ * kPointerSize)); 727 __ cmpq(rcx, Immediate(num_registers_ * kPointerSize));
728 __ j(above_equal, &stack_ok); 728 __ j(above_equal, &stack_ok);
729 // Exit with OutOfMemory exception. There is not enough space on the stack 729 // Exit with OutOfMemory exception. There is not enough space on the stack
730 // for our working registers. 730 // for our working registers.
731 __ Set(rax, EXCEPTION); 731 __ Set(rax, EXCEPTION);
732 __ jmp(&return_rax); 732 __ jmp(&return_rax);
733 733
734 __ bind(&stack_limit_hit); 734 __ bind(&stack_limit_hit);
735 __ Move(code_object_pointer(), masm_.CodeObject()); 735 __ Move(code_object_pointer(), masm_.CodeObject());
736 CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp. 736 CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp.
737 __ testq(rax, rax); 737 __ testq(rax, rax);
738 // If returned value is non-zero, we exit with the returned value as result. 738 // If returned value is non-zero, we exit with the returned value as result.
739 __ j(not_zero, &return_rax); 739 __ j(not_zero, &return_rax);
740 740
741 __ bind(&stack_ok); 741 __ bind(&stack_ok);
742 742
743 // Allocate space on stack for registers. 743 // Allocate space on stack for registers.
744 __ subq(rsp, Immediate(num_registers_ * kPointerSize)); 744 __ subq(rsp, Immediate(num_registers_ * kPointerSize));
745 // Load string length. 745 // Load string length.
746 __ movq(rsi, Operand(rbp, kInputEnd)); 746 __ movp(rsi, Operand(rbp, kInputEnd));
747 // Load input position. 747 // Load input position.
748 __ movq(rdi, Operand(rbp, kInputStart)); 748 __ movp(rdi, Operand(rbp, kInputStart));
749 // Set up rdi to be negative offset from string end. 749 // Set up rdi to be negative offset from string end.
750 __ subq(rdi, rsi); 750 __ subq(rdi, rsi);
751 // Set rax to address of char before start of the string 751 // Set rax to address of char before start of the string
752 // (effectively string position -1). 752 // (effectively string position -1).
753 __ movq(rbx, Operand(rbp, kStartIndex)); 753 __ movp(rbx, Operand(rbp, kStartIndex));
754 __ neg(rbx); 754 __ neg(rbx);
755 if (mode_ == UC16) { 755 if (mode_ == UC16) {
756 __ lea(rax, Operand(rdi, rbx, times_2, -char_size())); 756 __ lea(rax, Operand(rdi, rbx, times_2, -char_size()));
757 } else { 757 } else {
758 __ lea(rax, Operand(rdi, rbx, times_1, -char_size())); 758 __ lea(rax, Operand(rdi, rbx, times_1, -char_size()));
759 } 759 }
760 // Store this value in a local variable, for use when clearing 760 // Store this value in a local variable, for use when clearing
761 // position registers. 761 // position registers.
762 __ movq(Operand(rbp, kInputStartMinusOne), rax); 762 __ movp(Operand(rbp, kInputStartMinusOne), rax);
763 763
764 #if V8_OS_WIN 764 #if V8_OS_WIN
765 // Ensure that we have written to each stack page, in order. Skipping a page 765 // Ensure that we have written to each stack page, in order. Skipping a page
766 // on Windows can cause segmentation faults. Assuming page size is 4k. 766 // on Windows can cause segmentation faults. Assuming page size is 4k.
767 const int kPageSize = 4096; 767 const int kPageSize = 4096;
768 const int kRegistersPerPage = kPageSize / kPointerSize; 768 const int kRegistersPerPage = kPageSize / kPointerSize;
769 for (int i = num_saved_registers_ + kRegistersPerPage - 1; 769 for (int i = num_saved_registers_ + kRegistersPerPage - 1;
770 i < num_registers_; 770 i < num_registers_;
771 i += kRegistersPerPage) { 771 i += kRegistersPerPage) {
772 __ movq(register_location(i), rax); // One write every page. 772 __ movp(register_location(i), rax); // One write every page.
773 } 773 }
774 #endif // V8_OS_WIN 774 #endif // V8_OS_WIN
775 775
776 // Initialize code object pointer. 776 // Initialize code object pointer.
777 __ Move(code_object_pointer(), masm_.CodeObject()); 777 __ Move(code_object_pointer(), masm_.CodeObject());
778 778
779 Label load_char_start_regexp, start_regexp; 779 Label load_char_start_regexp, start_regexp;
780 // Load newline if index is at start, previous character otherwise. 780 // Load newline if index is at start, previous character otherwise.
781 __ cmpl(Operand(rbp, kStartIndex), Immediate(0)); 781 __ cmpl(Operand(rbp, kStartIndex), Immediate(0));
782 __ j(not_equal, &load_char_start_regexp, Label::kNear); 782 __ j(not_equal, &load_char_start_regexp, Label::kNear);
783 __ Set(current_character(), '\n'); 783 __ Set(current_character(), '\n');
784 __ jmp(&start_regexp, Label::kNear); 784 __ jmp(&start_regexp, Label::kNear);
785 785
786 // Global regexp restarts matching here. 786 // Global regexp restarts matching here.
787 __ bind(&load_char_start_regexp); 787 __ bind(&load_char_start_regexp);
788 // Load previous char as initial value of current character register. 788 // Load previous char as initial value of current character register.
789 LoadCurrentCharacterUnchecked(-1, 1); 789 LoadCurrentCharacterUnchecked(-1, 1);
790 __ bind(&start_regexp); 790 __ bind(&start_regexp);
791 791
792 // Initialize on-stack registers. 792 // Initialize on-stack registers.
793 if (num_saved_registers_ > 0) { 793 if (num_saved_registers_ > 0) {
794 // Fill saved registers with initial value = start offset - 1 794 // Fill saved registers with initial value = start offset - 1
795 // Fill in stack push order, to avoid accessing across an unwritten 795 // Fill in stack push order, to avoid accessing across an unwritten
796 // page (a problem on Windows). 796 // page (a problem on Windows).
797 if (num_saved_registers_ > 8) { 797 if (num_saved_registers_ > 8) {
798 __ Set(rcx, kRegisterZero); 798 __ Set(rcx, kRegisterZero);
799 Label init_loop; 799 Label init_loop;
800 __ bind(&init_loop); 800 __ bind(&init_loop);
801 __ movq(Operand(rbp, rcx, times_1, 0), rax); 801 __ movp(Operand(rbp, rcx, times_1, 0), rax);
802 __ subq(rcx, Immediate(kPointerSize)); 802 __ subq(rcx, Immediate(kPointerSize));
803 __ cmpq(rcx, 803 __ cmpq(rcx,
804 Immediate(kRegisterZero - num_saved_registers_ * kPointerSize)); 804 Immediate(kRegisterZero - num_saved_registers_ * kPointerSize));
805 __ j(greater, &init_loop); 805 __ j(greater, &init_loop);
806 } else { // Unroll the loop. 806 } else { // Unroll the loop.
807 for (int i = 0; i < num_saved_registers_; i++) { 807 for (int i = 0; i < num_saved_registers_; i++) {
808 __ movq(register_location(i), rax); 808 __ movp(register_location(i), rax);
809 } 809 }
810 } 810 }
811 } 811 }
812 812
813 // Initialize backtrack stack pointer. 813 // Initialize backtrack stack pointer.
814 __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); 814 __ movp(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
815 815
816 __ jmp(&start_label_); 816 __ jmp(&start_label_);
817 817
818 // Exit code: 818 // Exit code:
819 if (success_label_.is_linked()) { 819 if (success_label_.is_linked()) {
820 // Save captures when successful. 820 // Save captures when successful.
821 __ bind(&success_label_); 821 __ bind(&success_label_);
822 if (num_saved_registers_ > 0) { 822 if (num_saved_registers_ > 0) {
823 // copy captures to output 823 // copy captures to output
824 __ movq(rdx, Operand(rbp, kStartIndex)); 824 __ movp(rdx, Operand(rbp, kStartIndex));
825 __ movq(rbx, Operand(rbp, kRegisterOutput)); 825 __ movp(rbx, Operand(rbp, kRegisterOutput));
826 __ movq(rcx, Operand(rbp, kInputEnd)); 826 __ movp(rcx, Operand(rbp, kInputEnd));
827 __ subq(rcx, Operand(rbp, kInputStart)); 827 __ subq(rcx, Operand(rbp, kInputStart));
828 if (mode_ == UC16) { 828 if (mode_ == UC16) {
829 __ lea(rcx, Operand(rcx, rdx, times_2, 0)); 829 __ lea(rcx, Operand(rcx, rdx, times_2, 0));
830 } else { 830 } else {
831 __ addq(rcx, rdx); 831 __ addq(rcx, rdx);
832 } 832 }
833 for (int i = 0; i < num_saved_registers_; i++) { 833 for (int i = 0; i < num_saved_registers_; i++) {
834 __ movq(rax, register_location(i)); 834 __ movq(rax, register_location(i));
835 if (i == 0 && global_with_zero_length_check()) { 835 if (i == 0 && global_with_zero_length_check()) {
836 // Keep capture start in rdx for the zero-length check later. 836 // Keep capture start in rdx for the zero-length check later.
837 __ movq(rdx, rax); 837 __ movp(rdx, rax);
838 } 838 }
839 __ addq(rax, rcx); // Convert to index from start, not end. 839 __ addq(rax, rcx); // Convert to index from start, not end.
840 if (mode_ == UC16) { 840 if (mode_ == UC16) {
841 __ sar(rax, Immediate(1)); // Convert byte index to character index. 841 __ sar(rax, Immediate(1)); // Convert byte index to character index.
842 } 842 }
843 __ movl(Operand(rbx, i * kIntSize), rax); 843 __ movl(Operand(rbx, i * kIntSize), rax);
844 } 844 }
845 } 845 }
846 846
847 if (global()) { 847 if (global()) {
848 // Restart matching if the regular expression is flagged as global. 848 // Restart matching if the regular expression is flagged as global.
849 // Increment success counter. 849 // Increment success counter.
850 __ incq(Operand(rbp, kSuccessfulCaptures)); 850 __ incq(Operand(rbp, kSuccessfulCaptures));
851 // Capture results have been stored, so the number of remaining global 851 // Capture results have been stored, so the number of remaining global
852 // output registers is reduced by the number of stored captures. 852 // output registers is reduced by the number of stored captures.
853 __ movsxlq(rcx, Operand(rbp, kNumOutputRegisters)); 853 __ movsxlq(rcx, Operand(rbp, kNumOutputRegisters));
854 __ subq(rcx, Immediate(num_saved_registers_)); 854 __ subq(rcx, Immediate(num_saved_registers_));
855 // Check whether we have enough room for another set of capture results. 855 // Check whether we have enough room for another set of capture results.
856 __ cmpq(rcx, Immediate(num_saved_registers_)); 856 __ cmpq(rcx, Immediate(num_saved_registers_));
857 __ j(less, &exit_label_); 857 __ j(less, &exit_label_);
858 858
859 __ movq(Operand(rbp, kNumOutputRegisters), rcx); 859 __ movp(Operand(rbp, kNumOutputRegisters), rcx);
860 // Advance the location for output. 860 // Advance the location for output.
861 __ addq(Operand(rbp, kRegisterOutput), 861 __ addq(Operand(rbp, kRegisterOutput),
862 Immediate(num_saved_registers_ * kIntSize)); 862 Immediate(num_saved_registers_ * kIntSize));
863 863
864 // Prepare rax to initialize registers with its value in the next run. 864 // Prepare rax to initialize registers with its value in the next run.
865 __ movq(rax, Operand(rbp, kInputStartMinusOne)); 865 __ movp(rax, Operand(rbp, kInputStartMinusOne));
866 866
867 if (global_with_zero_length_check()) { 867 if (global_with_zero_length_check()) {
868 // Special case for zero-length matches. 868 // Special case for zero-length matches.
869 // rdx: capture start index 869 // rdx: capture start index
870 __ cmpq(rdi, rdx); 870 __ cmpq(rdi, rdx);
871 // Not a zero-length match, restart. 871 // Not a zero-length match, restart.
872 __ j(not_equal, &load_char_start_regexp); 872 __ j(not_equal, &load_char_start_regexp);
873 // rdi (offset from the end) is zero if we already reached the end. 873 // rdi (offset from the end) is zero if we already reached the end.
874 __ testq(rdi, rdi); 874 __ testq(rdi, rdi);
875 __ j(zero, &exit_label_, Label::kNear); 875 __ j(zero, &exit_label_, Label::kNear);
876 // Advance current position after a zero-length match. 876 // Advance current position after a zero-length match.
877 if (mode_ == UC16) { 877 if (mode_ == UC16) {
878 __ addq(rdi, Immediate(2)); 878 __ addq(rdi, Immediate(2));
879 } else { 879 } else {
880 __ incq(rdi); 880 __ incq(rdi);
881 } 881 }
882 } 882 }
883 883
884 __ jmp(&load_char_start_regexp); 884 __ jmp(&load_char_start_regexp);
885 } else { 885 } else {
886 __ movq(rax, Immediate(SUCCESS)); 886 __ movp(rax, Immediate(SUCCESS));
887 } 887 }
888 } 888 }
889 889
890 __ bind(&exit_label_); 890 __ bind(&exit_label_);
891 if (global()) { 891 if (global()) {
892 // Return the number of successful captures. 892 // Return the number of successful captures.
893 __ movq(rax, Operand(rbp, kSuccessfulCaptures)); 893 __ movp(rax, Operand(rbp, kSuccessfulCaptures));
894 } 894 }
895 895
896 __ bind(&return_rax); 896 __ bind(&return_rax);
897 #ifdef _WIN64 897 #ifdef _WIN64
898 // Restore callee save registers. 898 // Restore callee save registers.
899 __ lea(rsp, Operand(rbp, kLastCalleeSaveRegister)); 899 __ lea(rsp, Operand(rbp, kLastCalleeSaveRegister));
900 __ pop(rbx); 900 __ pop(rbx);
901 __ pop(rdi); 901 __ pop(rdi);
902 __ pop(rsi); 902 __ pop(rsi);
903 // Stack now at rbp. 903 // Stack now at rbp.
904 #else 904 #else
905 // Restore callee save register. 905 // Restore callee save register.
906 __ movq(rbx, Operand(rbp, kBackup_rbx)); 906 __ movp(rbx, Operand(rbp, kBackup_rbx));
907 // Skip rsp to rbp. 907 // Skip rsp to rbp.
908 __ movq(rsp, rbp); 908 __ movp(rsp, rbp);
909 #endif 909 #endif
910 // Exit function frame, restore previous one. 910 // Exit function frame, restore previous one.
911 __ pop(rbp); 911 __ pop(rbp);
912 __ ret(0); 912 __ ret(0);
913 913
914 // Backtrack code (branch target for conditional backtracks). 914 // Backtrack code (branch target for conditional backtracks).
915 if (backtrack_label_.is_linked()) { 915 if (backtrack_label_.is_linked()) {
916 __ bind(&backtrack_label_); 916 __ bind(&backtrack_label_);
917 Backtrack(); 917 Backtrack();
918 } 918 }
(...skipping 11 matching lines...) Expand all
930 __ testq(rax, rax); 930 __ testq(rax, rax);
931 // If returning non-zero, we should end execution with the given 931 // If returning non-zero, we should end execution with the given
932 // result as return value. 932 // result as return value.
933 __ j(not_zero, &return_rax); 933 __ j(not_zero, &return_rax);
934 934
935 // Restore registers. 935 // Restore registers.
936 __ Move(code_object_pointer(), masm_.CodeObject()); 936 __ Move(code_object_pointer(), masm_.CodeObject());
937 __ pop(rdi); 937 __ pop(rdi);
938 __ pop(backtrack_stackpointer()); 938 __ pop(backtrack_stackpointer());
939 // String might have moved: Reload esi from frame. 939 // String might have moved: Reload esi from frame.
940 __ movq(rsi, Operand(rbp, kInputEnd)); 940 __ movp(rsi, Operand(rbp, kInputEnd));
941 SafeReturn(); 941 SafeReturn();
942 } 942 }
943 943
944 // Backtrack stack overflow code. 944 // Backtrack stack overflow code.
945 if (stack_overflow_label_.is_linked()) { 945 if (stack_overflow_label_.is_linked()) {
946 SafeCallTarget(&stack_overflow_label_); 946 SafeCallTarget(&stack_overflow_label_);
947 // Reached if the backtrack-stack limit has been hit. 947 // Reached if the backtrack-stack limit has been hit.
948 948
949 Label grow_failed; 949 Label grow_failed;
950 // Save registers before calling C function 950 // Save registers before calling C function
951 #ifndef _WIN64 951 #ifndef _WIN64
952 // Callee-save in Microsoft 64-bit ABI, but not in AMD64 ABI. 952 // Callee-save in Microsoft 64-bit ABI, but not in AMD64 ABI.
953 __ push(rsi); 953 __ push(rsi);
954 __ push(rdi); 954 __ push(rdi);
955 #endif 955 #endif
956 956
957 // Call GrowStack(backtrack_stackpointer()) 957 // Call GrowStack(backtrack_stackpointer())
958 static const int num_arguments = 3; 958 static const int num_arguments = 3;
959 __ PrepareCallCFunction(num_arguments); 959 __ PrepareCallCFunction(num_arguments);
960 #ifdef _WIN64 960 #ifdef _WIN64
961 // Microsoft passes parameters in rcx, rdx, r8. 961 // Microsoft passes parameters in rcx, rdx, r8.
962 // First argument, backtrack stackpointer, is already in rcx. 962 // First argument, backtrack stackpointer, is already in rcx.
963 __ lea(rdx, Operand(rbp, kStackHighEnd)); // Second argument 963 __ lea(rdx, Operand(rbp, kStackHighEnd)); // Second argument
964 __ LoadAddress(r8, ExternalReference::isolate_address(isolate())); 964 __ LoadAddress(r8, ExternalReference::isolate_address(isolate()));
965 #else 965 #else
966 // AMD64 ABI passes parameters in rdi, rsi, rdx. 966 // AMD64 ABI passes parameters in rdi, rsi, rdx.
967 __ movq(rdi, backtrack_stackpointer()); // First argument. 967 __ movp(rdi, backtrack_stackpointer()); // First argument.
968 __ lea(rsi, Operand(rbp, kStackHighEnd)); // Second argument. 968 __ lea(rsi, Operand(rbp, kStackHighEnd)); // Second argument.
969 __ LoadAddress(rdx, ExternalReference::isolate_address(isolate())); 969 __ LoadAddress(rdx, ExternalReference::isolate_address(isolate()));
970 #endif 970 #endif
971 ExternalReference grow_stack = 971 ExternalReference grow_stack =
972 ExternalReference::re_grow_stack(isolate()); 972 ExternalReference::re_grow_stack(isolate());
973 __ CallCFunction(grow_stack, num_arguments); 973 __ CallCFunction(grow_stack, num_arguments);
974 // If return NULL, we have failed to grow the stack, and 974 // If return NULL, we have failed to grow the stack, and
975 // must exit with a stack-overflow exception. 975 // must exit with a stack-overflow exception.
976 __ testq(rax, rax); 976 __ testq(rax, rax);
977 __ j(equal, &exit_with_exception); 977 __ j(equal, &exit_with_exception);
978 // Otherwise use return value as new stack pointer. 978 // Otherwise use return value as new stack pointer.
979 __ movq(backtrack_stackpointer(), rax); 979 __ movp(backtrack_stackpointer(), rax);
980 // Restore saved registers and continue. 980 // Restore saved registers and continue.
981 __ Move(code_object_pointer(), masm_.CodeObject()); 981 __ Move(code_object_pointer(), masm_.CodeObject());
982 #ifndef _WIN64 982 #ifndef _WIN64
983 __ pop(rdi); 983 __ pop(rdi);
984 __ pop(rsi); 984 __ pop(rsi);
985 #endif 985 #endif
986 SafeReturn(); 986 SafeReturn();
987 } 987 }
988 988
989 if (exit_with_exception.is_linked()) { 989 if (exit_with_exception.is_linked()) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 } 1054 }
1055 1055
1056 1056
1057 void RegExpMacroAssemblerX64::PopCurrentPosition() { 1057 void RegExpMacroAssemblerX64::PopCurrentPosition() {
1058 Pop(rdi); 1058 Pop(rdi);
1059 } 1059 }
1060 1060
1061 1061
1062 void RegExpMacroAssemblerX64::PopRegister(int register_index) { 1062 void RegExpMacroAssemblerX64::PopRegister(int register_index) {
1063 Pop(rax); 1063 Pop(rax);
1064 __ movq(register_location(register_index), rax); 1064 __ movp(register_location(register_index), rax);
1065 } 1065 }
1066 1066
1067 1067
1068 void RegExpMacroAssemblerX64::PushBacktrack(Label* label) { 1068 void RegExpMacroAssemblerX64::PushBacktrack(Label* label) {
1069 Push(label); 1069 Push(label);
1070 CheckStackLimit(); 1070 CheckStackLimit();
1071 } 1071 }
1072 1072
1073 1073
1074 void RegExpMacroAssemblerX64::PushCurrentPosition() { 1074 void RegExpMacroAssemblerX64::PushCurrentPosition() {
1075 Push(rdi); 1075 Push(rdi);
1076 } 1076 }
1077 1077
1078 1078
1079 void RegExpMacroAssemblerX64::PushRegister(int register_index, 1079 void RegExpMacroAssemblerX64::PushRegister(int register_index,
1080 StackCheckFlag check_stack_limit) { 1080 StackCheckFlag check_stack_limit) {
1081 __ movq(rax, register_location(register_index)); 1081 __ movp(rax, register_location(register_index));
1082 Push(rax); 1082 Push(rax);
1083 if (check_stack_limit) CheckStackLimit(); 1083 if (check_stack_limit) CheckStackLimit();
1084 } 1084 }
1085 1085
1086 1086
1087 void RegExpMacroAssemblerX64::ReadCurrentPositionFromRegister(int reg) { 1087 void RegExpMacroAssemblerX64::ReadCurrentPositionFromRegister(int reg) {
1088 __ movq(rdi, register_location(reg)); 1088 __ movq(rdi, register_location(reg));
1089 } 1089 }
1090 1090
1091 1091
(...skipping 11 matching lines...) Expand all
1103 // On RegExp code entry (where this operation is used), the character before 1103 // On RegExp code entry (where this operation is used), the character before
1104 // the current position is expected to be already loaded. 1104 // the current position is expected to be already loaded.
1105 // We have advanced the position, so it's safe to read backwards. 1105 // We have advanced the position, so it's safe to read backwards.
1106 LoadCurrentCharacterUnchecked(-1, 1); 1106 LoadCurrentCharacterUnchecked(-1, 1);
1107 __ bind(&after_position); 1107 __ bind(&after_position);
1108 } 1108 }
1109 1109
1110 1110
1111 void RegExpMacroAssemblerX64::SetRegister(int register_index, int to) { 1111 void RegExpMacroAssemblerX64::SetRegister(int register_index, int to) {
1112 ASSERT(register_index >= num_saved_registers_); // Reserved for positions! 1112 ASSERT(register_index >= num_saved_registers_); // Reserved for positions!
1113 __ movq(register_location(register_index), Immediate(to)); 1113 __ movp(register_location(register_index), Immediate(to));
1114 } 1114 }
1115 1115
1116 1116
1117 bool RegExpMacroAssemblerX64::Succeed() { 1117 bool RegExpMacroAssemblerX64::Succeed() {
1118 __ jmp(&success_label_); 1118 __ jmp(&success_label_);
1119 return global(); 1119 return global();
1120 } 1120 }
1121 1121
1122 1122
1123 void RegExpMacroAssemblerX64::WriteCurrentPositionToRegister(int reg, 1123 void RegExpMacroAssemblerX64::WriteCurrentPositionToRegister(int reg,
1124 int cp_offset) { 1124 int cp_offset) {
1125 if (cp_offset == 0) { 1125 if (cp_offset == 0) {
1126 __ movq(register_location(reg), rdi); 1126 __ movp(register_location(reg), rdi);
1127 } else { 1127 } else {
1128 __ lea(rax, Operand(rdi, cp_offset * char_size())); 1128 __ lea(rax, Operand(rdi, cp_offset * char_size()));
1129 __ movq(register_location(reg), rax); 1129 __ movp(register_location(reg), rax);
1130 } 1130 }
1131 } 1131 }
1132 1132
1133 1133
1134 void RegExpMacroAssemblerX64::ClearRegisters(int reg_from, int reg_to) { 1134 void RegExpMacroAssemblerX64::ClearRegisters(int reg_from, int reg_to) {
1135 ASSERT(reg_from <= reg_to); 1135 ASSERT(reg_from <= reg_to);
1136 __ movq(rax, Operand(rbp, kInputStartMinusOne)); 1136 __ movp(rax, Operand(rbp, kInputStartMinusOne));
1137 for (int reg = reg_from; reg <= reg_to; reg++) { 1137 for (int reg = reg_from; reg <= reg_to; reg++) {
1138 __ movq(register_location(reg), rax); 1138 __ movp(register_location(reg), rax);
1139 } 1139 }
1140 } 1140 }
1141 1141
1142 1142
1143 void RegExpMacroAssemblerX64::WriteStackPointerToRegister(int reg) { 1143 void RegExpMacroAssemblerX64::WriteStackPointerToRegister(int reg) {
1144 __ movq(rax, backtrack_stackpointer()); 1144 __ movp(rax, backtrack_stackpointer());
1145 __ subq(rax, Operand(rbp, kStackHighEnd)); 1145 __ subq(rax, Operand(rbp, kStackHighEnd));
1146 __ movq(register_location(reg), rax); 1146 __ movp(register_location(reg), rax);
1147 } 1147 }
1148 1148
1149 1149
1150 // Private methods: 1150 // Private methods:
1151 1151
1152 void RegExpMacroAssemblerX64::CallCheckStackGuardState() { 1152 void RegExpMacroAssemblerX64::CallCheckStackGuardState() {
1153 // This function call preserves no register values. Caller should 1153 // This function call preserves no register values. Caller should
1154 // store anything volatile in a C call or overwritten by this function. 1154 // store anything volatile in a C call or overwritten by this function.
1155 static const int num_arguments = 3; 1155 static const int num_arguments = 3;
1156 __ PrepareCallCFunction(num_arguments); 1156 __ PrepareCallCFunction(num_arguments);
1157 #ifdef _WIN64 1157 #ifdef _WIN64
1158 // Second argument: Code* of self. (Do this before overwriting r8). 1158 // Second argument: Code* of self. (Do this before overwriting r8).
1159 __ movq(rdx, code_object_pointer()); 1159 __ movp(rdx, code_object_pointer());
1160 // Third argument: RegExp code frame pointer. 1160 // Third argument: RegExp code frame pointer.
1161 __ movq(r8, rbp); 1161 __ movp(r8, rbp);
1162 // First argument: Next address on the stack (will be address of 1162 // First argument: Next address on the stack (will be address of
1163 // return address). 1163 // return address).
1164 __ lea(rcx, Operand(rsp, -kPointerSize)); 1164 __ lea(rcx, Operand(rsp, -kPointerSize));
1165 #else 1165 #else
1166 // Third argument: RegExp code frame pointer. 1166 // Third argument: RegExp code frame pointer.
1167 __ movq(rdx, rbp); 1167 __ movp(rdx, rbp);
1168 // Second argument: Code* of self. 1168 // Second argument: Code* of self.
1169 __ movq(rsi, code_object_pointer()); 1169 __ movp(rsi, code_object_pointer());
1170 // First argument: Next address on the stack (will be address of 1170 // First argument: Next address on the stack (will be address of
1171 // return address). 1171 // return address).
1172 __ lea(rdi, Operand(rsp, -kPointerSize)); 1172 __ lea(rdi, Operand(rsp, -kPointerSize));
1173 #endif 1173 #endif
1174 ExternalReference stack_check = 1174 ExternalReference stack_check =
1175 ExternalReference::re_check_stack_guard_state(isolate()); 1175 ExternalReference::re_check_stack_guard_state(isolate());
1176 __ CallCFunction(stack_check, num_arguments); 1176 __ CallCFunction(stack_check, num_arguments);
1177 } 1177 }
1178 1178
1179 1179
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 } 1439 }
1440 } 1440 }
1441 1441
1442 #undef __ 1442 #undef __
1443 1443
1444 #endif // V8_INTERPRETED_REGEXP 1444 #endif // V8_INTERPRETED_REGEXP
1445 1445
1446 }} // namespace v8::internal 1446 }} // namespace v8::internal
1447 1447
1448 #endif // V8_TARGET_ARCH_X64 1448 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698