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

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

Issue 18014003: Add X32 port into V8 (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 7 years, 5 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
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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 * int start_index, 108 * int start_index,
109 * Address start, 109 * Address start,
110 * Address end, 110 * Address end,
111 * int* capture_output_array, 111 * int* capture_output_array,
112 * bool at_start, 112 * bool at_start,
113 * byte* stack_area_base, 113 * byte* stack_area_base,
114 * bool direct_call) 114 * bool direct_call)
115 */ 115 */
116 116
117 #define __ ACCESS_MASM((&masm_)) 117 #define __ ACCESS_MASM((&masm_))
118 #define __k __
118 119
119 RegExpMacroAssemblerX64::RegExpMacroAssemblerX64( 120 RegExpMacroAssemblerX64::RegExpMacroAssemblerX64(
120 Mode mode, 121 Mode mode,
121 int registers_to_save, 122 int registers_to_save,
122 Zone* zone) 123 Zone* zone)
123 : NativeRegExpMacroAssembler(zone), 124 : NativeRegExpMacroAssembler(zone),
124 masm_(zone->isolate(), NULL, kRegExpCodeSize), 125 masm_(zone->isolate(), NULL, kRegExpCodeSize),
125 no_root_array_scope_(&masm_), 126 no_root_array_scope_(&masm_),
126 code_relative_fixup_positions_(4, zone), 127 code_relative_fixup_positions_(4, zone),
127 mode_(mode), 128 mode_(mode),
(...skipping 22 matching lines...) Expand all
150 } 151 }
151 152
152 153
153 int RegExpMacroAssemblerX64::stack_limit_slack() { 154 int RegExpMacroAssemblerX64::stack_limit_slack() {
154 return RegExpStack::kStackLimitSlack; 155 return RegExpStack::kStackLimitSlack;
155 } 156 }
156 157
157 158
158 void RegExpMacroAssemblerX64::AdvanceCurrentPosition(int by) { 159 void RegExpMacroAssemblerX64::AdvanceCurrentPosition(int by) {
159 if (by != 0) { 160 if (by != 0) {
160 __ addq(rdi, Immediate(by * char_size())); 161 __k addq(rdi, Immediate(by * char_size()));
161 } 162 }
162 } 163 }
163 164
164 165
165 void RegExpMacroAssemblerX64::AdvanceRegister(int reg, int by) { 166 void RegExpMacroAssemblerX64::AdvanceRegister(int reg, int by) {
166 ASSERT(reg >= 0); 167 ASSERT(reg >= 0);
167 ASSERT(reg < num_registers_); 168 ASSERT(reg < num_registers_);
168 if (by != 0) { 169 if (by != 0) {
169 __ addq(register_location(reg), Immediate(by)); 170 __ addq(register_location(reg), Immediate(by));
170 } 171 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 Drop(); 235 Drop();
235 BranchOrBacktrack(no_condition, on_equal); 236 BranchOrBacktrack(no_condition, on_equal);
236 __ bind(&fallthrough); 237 __ bind(&fallthrough);
237 } 238 }
238 239
239 240
240 void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( 241 void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase(
241 int start_reg, 242 int start_reg,
242 Label* on_no_match) { 243 Label* on_no_match) {
243 Label fallthrough; 244 Label fallthrough;
245 #ifndef V8_TARGET_ARCH_X32
244 __ movq(rdx, register_location(start_reg)); // Offset of start of capture 246 __ movq(rdx, register_location(start_reg)); // Offset of start of capture
245 __ movq(rbx, register_location(start_reg + 1)); // Offset of end of capture 247 __ movq(rbx, register_location(start_reg + 1)); // Offset of end of capture
248 #else
249 __ movsxlq(rdx, register_location(start_reg)); // Offset of start of capture
250 // Offset of end of capture
251 __ movsxlq(rbx, register_location(start_reg + 1));
252 #endif
246 __ subq(rbx, rdx); // Length of capture. 253 __ subq(rbx, rdx); // Length of capture.
247 254
248 // ----------------------- 255 // -----------------------
249 // rdx = Start offset of capture. 256 // rdx = Start offset of capture.
250 // rbx = Length of capture 257 // rbx = Length of capture
251 258
252 // If length is negative, this code will fail (it's a symptom of a partial or 259 // If length is negative, this code will fail (it's a symptom of a partial or
253 // illegal capture where start of capture after end of capture). 260 // illegal capture where start of capture after end of capture).
254 // This must not happen (no back-reference can reference a capture that wasn't 261 // This must not happen (no back-reference can reference a capture that wasn't
255 // closed before in the reg-exp, and we must not generate code that can cause 262 // closed before in the reg-exp, and we must not generate code that can cause
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 __ bind(&loop_increment); 316 __ bind(&loop_increment);
310 // Increment pointers into match and capture strings. 317 // Increment pointers into match and capture strings.
311 __ addq(r11, Immediate(1)); 318 __ addq(r11, Immediate(1));
312 __ addq(r9, Immediate(1)); 319 __ addq(r9, Immediate(1));
313 // Compare to end of capture, and loop if not done. 320 // Compare to end of capture, and loop if not done.
314 __ cmpq(r9, rbx); 321 __ cmpq(r9, rbx);
315 __ j(below, &loop); 322 __ j(below, &loop);
316 323
317 // Compute new value of character position after the matched part. 324 // Compute new value of character position after the matched part.
318 __ movq(rdi, r11); 325 __ movq(rdi, r11);
319 __ subq(rdi, rsi); 326 __k subq(rdi, rsi);
320 } else { 327 } else {
321 ASSERT(mode_ == UC16); 328 ASSERT(mode_ == UC16);
322 // Save important/volatile registers before calling C function. 329 // Save important/volatile registers before calling C function.
323 #ifndef _WIN64 330 #ifndef _WIN64
324 // Caller save on Linux and callee save in Windows. 331 // Caller save on Linux and callee save in Windows.
325 __ push(rsi); 332 __k push(rsi);
326 __ push(rdi); 333 __k push(rdi);
327 #endif 334 #endif
328 __ push(backtrack_stackpointer()); 335 __k push(backtrack_stackpointer());
329 336
330 static const int num_arguments = 4; 337 static const int num_arguments = 4;
331 __ PrepareCallCFunction(num_arguments); 338 __ PrepareCallCFunction(num_arguments);
332 339
333 // Put arguments into parameter registers. Parameters are 340 // Put arguments into parameter registers. Parameters are
334 // Address byte_offset1 - Address captured substring's start. 341 // Address byte_offset1 - Address captured substring's start.
335 // Address byte_offset2 - Address of current character position. 342 // Address byte_offset2 - Address of current character position.
336 // size_t byte_length - length of capture in bytes(!) 343 // size_t byte_length - length of capture in bytes(!)
337 // Isolate* isolate 344 // Isolate* isolate
338 #ifdef _WIN64 345 #ifdef _WIN64
(...skipping 21 matching lines...) Expand all
360 { // NOLINT: Can't find a way to open this scope without confusing the 367 { // NOLINT: Can't find a way to open this scope without confusing the
361 // linter. 368 // linter.
362 AllowExternalCallThatCantCauseGC scope(&masm_); 369 AllowExternalCallThatCantCauseGC scope(&masm_);
363 ExternalReference compare = 370 ExternalReference compare =
364 ExternalReference::re_case_insensitive_compare_uc16(isolate()); 371 ExternalReference::re_case_insensitive_compare_uc16(isolate());
365 __ CallCFunction(compare, num_arguments); 372 __ CallCFunction(compare, num_arguments);
366 } 373 }
367 374
368 // Restore original values before reacting on result value. 375 // Restore original values before reacting on result value.
369 __ Move(code_object_pointer(), masm_.CodeObject()); 376 __ Move(code_object_pointer(), masm_.CodeObject());
370 __ pop(backtrack_stackpointer()); 377 __k pop(backtrack_stackpointer());
371 #ifndef _WIN64 378 #ifndef _WIN64
372 __ pop(rdi); 379 __k pop(rdi);
373 __ pop(rsi); 380 __k pop(rsi);
374 #endif 381 #endif
375 382
376 // Check if function returned non-zero for success or zero for failure. 383 // Check if function returned non-zero for success or zero for failure.
377 __ testq(rax, rax); 384 __ testq(rax, rax);
378 BranchOrBacktrack(zero, on_no_match); 385 BranchOrBacktrack(zero, on_no_match);
379 // On success, increment position by length of capture. 386 // On success, increment position by length of capture.
380 // Requires that rbx is callee save (true for both Win64 and AMD64 ABIs). 387 // Requires that rbx is callee save (true for both Win64 and AMD64 ABIs).
381 __ addq(rdi, rbx); 388 __k addq(rdi, rbx);
382 } 389 }
383 __ bind(&fallthrough); 390 __ bind(&fallthrough);
384 } 391 }
385 392
386 393
387 void RegExpMacroAssemblerX64::CheckNotBackReference( 394 void RegExpMacroAssemblerX64::CheckNotBackReference(
388 int start_reg, 395 int start_reg,
389 Label* on_no_match) { 396 Label* on_no_match) {
390 Label fallthrough; 397 Label fallthrough;
391 398
392 // Find length of back-referenced capture. 399 // Find length of back-referenced capture.
400 #ifndef V8_TARGET_ARCH_X32
393 __ movq(rdx, register_location(start_reg)); 401 __ movq(rdx, register_location(start_reg));
394 __ movq(rax, register_location(start_reg + 1)); 402 __ movq(rax, register_location(start_reg + 1));
403 #else
404 __ movsxlq(rdx, register_location(start_reg));
405 __ movsxlq(rax, register_location(start_reg + 1));
406 #endif
395 __ subq(rax, rdx); // Length to check. 407 __ subq(rax, rdx); // Length to check.
396 408
397 // Fail on partial or illegal capture (start of capture after end of capture). 409 // Fail on partial or illegal capture (start of capture after end of capture).
398 // This must not happen (no back-reference can reference a capture that wasn't 410 // This must not happen (no back-reference can reference a capture that wasn't
399 // closed before in the reg-exp). 411 // closed before in the reg-exp).
400 __ Check(greater_equal, "Invalid capture referenced"); 412 __ Check(greater_equal, "Invalid capture referenced");
401 413
402 // Succeed on empty capture (including non-participating capture) 414 // Succeed on empty capture (including non-participating capture)
403 __ j(equal, &fallthrough); 415 __ j(equal, &fallthrough);
404 416
(...skipping 30 matching lines...) Expand all
435 // Increment pointers into capture and match string. 447 // Increment pointers into capture and match string.
436 __ addq(rbx, Immediate(char_size())); 448 __ addq(rbx, Immediate(char_size()));
437 __ addq(rdx, Immediate(char_size())); 449 __ addq(rdx, Immediate(char_size()));
438 // Check if we have reached end of match area. 450 // Check if we have reached end of match area.
439 __ cmpq(rdx, r9); 451 __ cmpq(rdx, r9);
440 __ j(below, &loop); 452 __ j(below, &loop);
441 453
442 // Success. 454 // Success.
443 // Set current character position to position after match. 455 // Set current character position to position after match.
444 __ movq(rdi, rbx); 456 __ movq(rdi, rbx);
445 __ subq(rdi, rsi); 457 __k subq(rdi, rsi);
446 458
447 __ bind(&fallthrough); 459 __ bind(&fallthrough);
448 } 460 }
449 461
450 462
451 void RegExpMacroAssemblerX64::CheckNotCharacter(uint32_t c, 463 void RegExpMacroAssemblerX64::CheckNotCharacter(uint32_t c,
452 Label* on_not_equal) { 464 Label* on_not_equal) {
453 __ cmpl(current_character(), Immediate(c)); 465 __ cmpl(current_character(), Immediate(c));
454 BranchOrBacktrack(not_equal, on_not_equal); 466 BranchOrBacktrack(not_equal, on_not_equal);
455 } 467 }
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 FrameScope scope(&masm_, StackFrame::MANUAL); 686 FrameScope scope(&masm_, StackFrame::MANUAL);
675 687
676 // Actually emit code to start a new stack frame. 688 // Actually emit code to start a new stack frame.
677 __ push(rbp); 689 __ push(rbp);
678 __ movq(rbp, rsp); 690 __ movq(rbp, rsp);
679 // Save parameters and callee-save registers. Order here should correspond 691 // Save parameters and callee-save registers. Order here should correspond
680 // to order of kBackup_ebx etc. 692 // to order of kBackup_ebx etc.
681 #ifdef _WIN64 693 #ifdef _WIN64
682 // MSVC passes arguments in rcx, rdx, r8, r9, with backing stack slots. 694 // MSVC passes arguments in rcx, rdx, r8, r9, with backing stack slots.
683 // Store register parameters in pre-allocated stack slots, 695 // Store register parameters in pre-allocated stack slots,
684 __ movq(Operand(rbp, kInputString), rcx); 696 __k movq(Operand(rbp, kInputString), rcx);
685 __ movq(Operand(rbp, kStartIndex), rdx); // Passed as int32 in edx. 697 __k movq(Operand(rbp, kStartIndex), rdx); // Passed as int32 in edx.
686 __ movq(Operand(rbp, kInputStart), r8); 698 __k movq(Operand(rbp, kInputStart), r8);
687 __ movq(Operand(rbp, kInputEnd), r9); 699 __k movq(Operand(rbp, kInputEnd), r9);
688 // Callee-save on Win64. 700 // Callee-save on Win64.
689 __ push(rsi); 701 __k push(rsi);
690 __ push(rdi); 702 __k push(rdi);
691 __ push(rbx); 703 __k push(rbx);
692 #else 704 #else
693 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9 (and then on stack). 705 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9 (and then on stack).
694 // Push register parameters on stack for reference. 706 // Push register parameters on stack for reference.
707 #ifndef V8_TARGET_ARCH_X32
695 ASSERT_EQ(kInputString, -1 * kPointerSize); 708 ASSERT_EQ(kInputString, -1 * kPointerSize);
696 ASSERT_EQ(kStartIndex, -2 * kPointerSize); 709 ASSERT_EQ(kStartIndex, -2 * kPointerSize);
697 ASSERT_EQ(kInputStart, -3 * kPointerSize); 710 ASSERT_EQ(kInputStart, -3 * kPointerSize);
698 ASSERT_EQ(kInputEnd, -4 * kPointerSize); 711 ASSERT_EQ(kInputEnd, -4 * kPointerSize);
699 ASSERT_EQ(kRegisterOutput, -5 * kPointerSize); 712 ASSERT_EQ(kRegisterOutput, -5 * kPointerSize);
700 ASSERT_EQ(kNumOutputRegisters, -6 * kPointerSize); 713 ASSERT_EQ(kNumOutputRegisters, -6 * kPointerSize);
701 __ push(rdi); 714 #else
702 __ push(rsi); 715 ASSERT_EQ(kInputString, -1 * kHWRegSize);
703 __ push(rdx); 716 ASSERT_EQ(kStartIndex, -2 * kHWRegSize);
704 __ push(rcx); 717 ASSERT_EQ(kInputStart, -3 * kHWRegSize);
705 __ push(r8); 718 ASSERT_EQ(kInputEnd, -4 * kHWRegSize);
706 __ push(r9); 719 ASSERT_EQ(kRegisterOutput, -5 * kHWRegSize);
720 ASSERT_EQ(kNumOutputRegisters, -6 * kHWRegSize);
721 #endif
722 __k push(rdi);
723 __k push(rsi);
724 __k push(rdx);
725 __k push(rcx);
726 __k push(r8);
727 __k push(r9);
707 728
708 __ push(rbx); // Callee-save 729 __k push(rbx); // Callee-save
709 #endif 730 #endif
710 731
711 __ push(Immediate(0)); // Number of successful matches in a global regexp. 732 __ push(Immediate(0)); // Number of successful matches in a global regexp.
712 __ push(Immediate(0)); // Make room for "input start - 1" constant. 733 __ push(Immediate(0)); // Make room for "input start - 1" constant.
713 734
714 // Check if we have space on the stack for registers. 735 // Check if we have space on the stack for registers.
715 Label stack_limit_hit; 736 Label stack_limit_hit;
716 Label stack_ok; 737 Label stack_ok;
717 738
718 ExternalReference stack_limit = 739 ExternalReference stack_limit =
(...skipping 21 matching lines...) Expand all
740 761
741 __ bind(&stack_ok); 762 __ bind(&stack_ok);
742 763
743 // Allocate space on stack for registers. 764 // Allocate space on stack for registers.
744 __ subq(rsp, Immediate(num_registers_ * kPointerSize)); 765 __ subq(rsp, Immediate(num_registers_ * kPointerSize));
745 // Load string length. 766 // Load string length.
746 __ movq(rsi, Operand(rbp, kInputEnd)); 767 __ movq(rsi, Operand(rbp, kInputEnd));
747 // Load input position. 768 // Load input position.
748 __ movq(rdi, Operand(rbp, kInputStart)); 769 __ movq(rdi, Operand(rbp, kInputStart));
749 // Set up rdi to be negative offset from string end. 770 // Set up rdi to be negative offset from string end.
750 __ subq(rdi, rsi); 771 __k subq(rdi, rsi);
751 // Set rax to address of char before start of the string 772 // Set rax to address of char before start of the string
752 // (effectively string position -1). 773 // (effectively string position -1).
753 __ movq(rbx, Operand(rbp, kStartIndex)); 774 __ movq(rbx, Operand(rbp, kStartIndex));
754 __ neg(rbx); 775 __k neg(rbx);
755 if (mode_ == UC16) { 776 if (mode_ == UC16) {
756 __ lea(rax, Operand(rdi, rbx, times_2, -char_size())); 777 __ lea(rax, Operand(rdi, rbx, times_2, -char_size()));
757 } else { 778 } else {
758 __ lea(rax, Operand(rdi, rbx, times_1, -char_size())); 779 __ lea(rax, Operand(rdi, rbx, times_1, -char_size()));
759 } 780 }
760 // Store this value in a local variable, for use when clearing 781 // Store this value in a local variable, for use when clearing
761 // position registers. 782 // position registers.
762 __ movq(Operand(rbp, kInputStartMinusOne), rax); 783 __ movq(Operand(rbp, kInputStartMinusOne), rax);
763 784
764 #ifdef WIN32 785 #ifdef WIN32
(...skipping 27 matching lines...) Expand all
792 // Initialize on-stack registers. 813 // Initialize on-stack registers.
793 if (num_saved_registers_ > 0) { 814 if (num_saved_registers_ > 0) {
794 // Fill saved registers with initial value = start offset - 1 815 // Fill saved registers with initial value = start offset - 1
795 // Fill in stack push order, to avoid accessing across an unwritten 816 // Fill in stack push order, to avoid accessing across an unwritten
796 // page (a problem on Windows). 817 // page (a problem on Windows).
797 if (num_saved_registers_ > 8) { 818 if (num_saved_registers_ > 8) {
798 __ Set(rcx, kRegisterZero); 819 __ Set(rcx, kRegisterZero);
799 Label init_loop; 820 Label init_loop;
800 __ bind(&init_loop); 821 __ bind(&init_loop);
801 __ movq(Operand(rbp, rcx, times_1, 0), rax); 822 __ movq(Operand(rbp, rcx, times_1, 0), rax);
802 __ subq(rcx, Immediate(kPointerSize)); 823 __k subq(rcx, Immediate(kPointerSize));
803 __ cmpq(rcx, 824 __k cmpq(rcx,
804 Immediate(kRegisterZero - num_saved_registers_ * kPointerSize)); 825 Immediate(kRegisterZero - num_saved_registers_ * kPointerSize));
805 __ j(greater, &init_loop); 826 __ j(greater, &init_loop);
806 } else { // Unroll the loop. 827 } else { // Unroll the loop.
807 for (int i = 0; i < num_saved_registers_; i++) { 828 for (int i = 0; i < num_saved_registers_; i++) {
808 __ movq(register_location(i), rax); 829 __ movq(register_location(i), rax);
809 } 830 }
810 } 831 }
811 } 832 }
812 833
813 // Initialize backtrack stack pointer. 834 // Initialize backtrack stack pointer.
(...skipping 10 matching lines...) Expand all
824 __ movq(rdx, Operand(rbp, kStartIndex)); 845 __ movq(rdx, Operand(rbp, kStartIndex));
825 __ movq(rbx, Operand(rbp, kRegisterOutput)); 846 __ movq(rbx, Operand(rbp, kRegisterOutput));
826 __ movq(rcx, Operand(rbp, kInputEnd)); 847 __ movq(rcx, Operand(rbp, kInputEnd));
827 __ subq(rcx, Operand(rbp, kInputStart)); 848 __ subq(rcx, Operand(rbp, kInputStart));
828 if (mode_ == UC16) { 849 if (mode_ == UC16) {
829 __ lea(rcx, Operand(rcx, rdx, times_2, 0)); 850 __ lea(rcx, Operand(rcx, rdx, times_2, 0));
830 } else { 851 } else {
831 __ addq(rcx, rdx); 852 __ addq(rcx, rdx);
832 } 853 }
833 for (int i = 0; i < num_saved_registers_; i++) { 854 for (int i = 0; i < num_saved_registers_; i++) {
855 #ifndef V8_TARGET_ARCH_X32
834 __ movq(rax, register_location(i)); 856 __ movq(rax, register_location(i));
857 #else
858 __ movsxlq(rax, register_location(i));
859 #endif
835 if (i == 0 && global_with_zero_length_check()) { 860 if (i == 0 && global_with_zero_length_check()) {
836 // Keep capture start in rdx for the zero-length check later. 861 // Keep capture start in rdx for the zero-length check later.
837 __ movq(rdx, rax); 862 __ movq(rdx, rax);
838 } 863 }
839 __ addq(rax, rcx); // Convert to index from start, not end. 864 __ addq(rax, rcx); // Convert to index from start, not end.
840 if (mode_ == UC16) { 865 if (mode_ == UC16) {
841 __ sar(rax, Immediate(1)); // Convert byte index to character index. 866 __ sar(rax, Immediate(1)); // Convert byte index to character index.
842 } 867 }
843 __ movl(Operand(rbx, i * kIntSize), rax); 868 __ movl(Operand(rbx, i * kIntSize), rax);
844 } 869 }
(...skipping 23 matching lines...) Expand all
868 // Special case for zero-length matches. 893 // Special case for zero-length matches.
869 // rdx: capture start index 894 // rdx: capture start index
870 __ cmpq(rdi, rdx); 895 __ cmpq(rdi, rdx);
871 // Not a zero-length match, restart. 896 // Not a zero-length match, restart.
872 __ j(not_equal, &load_char_start_regexp); 897 __ j(not_equal, &load_char_start_regexp);
873 // rdi (offset from the end) is zero if we already reached the end. 898 // rdi (offset from the end) is zero if we already reached the end.
874 __ testq(rdi, rdi); 899 __ testq(rdi, rdi);
875 __ j(zero, &exit_label_, Label::kNear); 900 __ j(zero, &exit_label_, Label::kNear);
876 // Advance current position after a zero-length match. 901 // Advance current position after a zero-length match.
877 if (mode_ == UC16) { 902 if (mode_ == UC16) {
878 __ addq(rdi, Immediate(2)); 903 __k addq(rdi, Immediate(2));
879 } else { 904 } else {
880 __ incq(rdi); 905 __k incq(rdi);
881 } 906 }
882 } 907 }
883 908
884 __ jmp(&load_char_start_regexp); 909 __ jmp(&load_char_start_regexp);
885 } else { 910 } else {
886 __ movq(rax, Immediate(SUCCESS)); 911 __ movq(rax, Immediate(SUCCESS));
887 } 912 }
888 } 913 }
889 914
890 __ bind(&exit_label_); 915 __ bind(&exit_label_);
891 if (global()) { 916 if (global()) {
892 // Return the number of successful captures. 917 // Return the number of successful captures.
893 __ movq(rax, Operand(rbp, kSuccessfulCaptures)); 918 __ movq(rax, Operand(rbp, kSuccessfulCaptures));
894 } 919 }
895 920
896 __ bind(&return_rax); 921 __ bind(&return_rax);
897 #ifdef _WIN64 922 #ifdef _WIN64
898 // Restore callee save registers. 923 // Restore callee save registers.
899 __ lea(rsp, Operand(rbp, kLastCalleeSaveRegister)); 924 __ lea(rsp, Operand(rbp, kLastCalleeSaveRegister));
900 __ pop(rbx); 925 __k pop(rbx);
901 __ pop(rdi); 926 __k pop(rdi);
902 __ pop(rsi); 927 __k pop(rsi);
903 // Stack now at rbp. 928 // Stack now at rbp.
904 #else 929 #else
905 // Restore callee save register. 930 // Restore callee save register.
906 __ movq(rbx, Operand(rbp, kBackup_rbx)); 931 __ movq(rbx, Operand(rbp, kBackup_rbx));
907 // Skip rsp to rbp. 932 // Skip rsp to rbp.
908 __ movq(rsp, rbp); 933 __ movq(rsp, rbp);
909 #endif 934 #endif
910 // Exit function frame, restore previous one. 935 // Exit function frame, restore previous one.
911 __ pop(rbp); 936 __ pop(rbp);
912 __ ret(0); 937 __ ret(0);
913 938
914 // Backtrack code (branch target for conditional backtracks). 939 // Backtrack code (branch target for conditional backtracks).
915 if (backtrack_label_.is_linked()) { 940 if (backtrack_label_.is_linked()) {
916 __ bind(&backtrack_label_); 941 __ bind(&backtrack_label_);
917 Backtrack(); 942 Backtrack();
918 } 943 }
919 944
920 Label exit_with_exception; 945 Label exit_with_exception;
921 946
922 // Preempt-code 947 // Preempt-code
923 if (check_preempt_label_.is_linked()) { 948 if (check_preempt_label_.is_linked()) {
924 SafeCallTarget(&check_preempt_label_); 949 SafeCallTarget(&check_preempt_label_);
925 950
926 __ push(backtrack_stackpointer()); 951 __k push(backtrack_stackpointer());
927 __ push(rdi); 952 __k push(rdi);
928 953
929 CallCheckStackGuardState(); 954 CallCheckStackGuardState();
930 __ testq(rax, rax); 955 __ testq(rax, rax);
931 // If returning non-zero, we should end execution with the given 956 // If returning non-zero, we should end execution with the given
932 // result as return value. 957 // result as return value.
933 __ j(not_zero, &return_rax); 958 __ j(not_zero, &return_rax);
934 959
935 // Restore registers. 960 // Restore registers.
936 __ Move(code_object_pointer(), masm_.CodeObject()); 961 __ Move(code_object_pointer(), masm_.CodeObject());
937 __ pop(rdi); 962 __k pop(rdi);
938 __ pop(backtrack_stackpointer()); 963 __k pop(backtrack_stackpointer());
939 // String might have moved: Reload esi from frame. 964 // String might have moved: Reload esi from frame.
940 __ movq(rsi, Operand(rbp, kInputEnd)); 965 __ movq(rsi, Operand(rbp, kInputEnd));
941 SafeReturn(); 966 SafeReturn();
942 } 967 }
943 968
944 // Backtrack stack overflow code. 969 // Backtrack stack overflow code.
945 if (stack_overflow_label_.is_linked()) { 970 if (stack_overflow_label_.is_linked()) {
946 SafeCallTarget(&stack_overflow_label_); 971 SafeCallTarget(&stack_overflow_label_);
947 // Reached if the backtrack-stack limit has been hit. 972 // Reached if the backtrack-stack limit has been hit.
948 973
949 Label grow_failed; 974 Label grow_failed;
950 // Save registers before calling C function 975 // Save registers before calling C function
951 #ifndef _WIN64 976 #ifndef _WIN64
952 // Callee-save in Microsoft 64-bit ABI, but not in AMD64 ABI. 977 // Callee-save in Microsoft 64-bit ABI, but not in AMD64 ABI.
953 __ push(rsi); 978 __k push(rsi);
954 __ push(rdi); 979 __k push(rdi);
955 #endif 980 #endif
956 981
957 // Call GrowStack(backtrack_stackpointer()) 982 // Call GrowStack(backtrack_stackpointer())
958 static const int num_arguments = 3; 983 static const int num_arguments = 3;
959 __ PrepareCallCFunction(num_arguments); 984 __ PrepareCallCFunction(num_arguments);
960 #ifdef _WIN64 985 #ifdef _WIN64
961 // Microsoft passes parameters in rcx, rdx, r8. 986 // Microsoft passes parameters in rcx, rdx, r8.
962 // First argument, backtrack stackpointer, is already in rcx. 987 // First argument, backtrack stackpointer, is already in rcx.
963 __ lea(rdx, Operand(rbp, kStackHighEnd)); // Second argument 988 __ lea(rdx, Operand(rbp, kStackHighEnd)); // Second argument
964 __ LoadAddress(r8, ExternalReference::isolate_address(isolate())); 989 __ LoadAddress(r8, ExternalReference::isolate_address(isolate()));
965 #else 990 #else
966 // AMD64 ABI passes parameters in rdi, rsi, rdx. 991 // AMD64 ABI passes parameters in rdi, rsi, rdx.
967 __ movq(rdi, backtrack_stackpointer()); // First argument. 992 __ movq(rdi, backtrack_stackpointer()); // First argument.
968 __ lea(rsi, Operand(rbp, kStackHighEnd)); // Second argument. 993 __ lea(rsi, Operand(rbp, kStackHighEnd)); // Second argument.
969 __ LoadAddress(rdx, ExternalReference::isolate_address(isolate())); 994 __ LoadAddress(rdx, ExternalReference::isolate_address(isolate()));
970 #endif 995 #endif
971 ExternalReference grow_stack = 996 ExternalReference grow_stack =
972 ExternalReference::re_grow_stack(isolate()); 997 ExternalReference::re_grow_stack(isolate());
973 __ CallCFunction(grow_stack, num_arguments); 998 __ CallCFunction(grow_stack, num_arguments);
974 // If return NULL, we have failed to grow the stack, and 999 // If return NULL, we have failed to grow the stack, and
975 // must exit with a stack-overflow exception. 1000 // must exit with a stack-overflow exception.
976 __ testq(rax, rax); 1001 __ testq(rax, rax);
977 __ j(equal, &exit_with_exception); 1002 __ j(equal, &exit_with_exception);
978 // Otherwise use return value as new stack pointer. 1003 // Otherwise use return value as new stack pointer.
979 __ movq(backtrack_stackpointer(), rax); 1004 __ movq(backtrack_stackpointer(), rax);
980 // Restore saved registers and continue. 1005 // Restore saved registers and continue.
981 __ Move(code_object_pointer(), masm_.CodeObject()); 1006 __ Move(code_object_pointer(), masm_.CodeObject());
982 #ifndef _WIN64 1007 #ifndef _WIN64
983 __ pop(rdi); 1008 __k pop(rdi);
984 __ pop(rsi); 1009 __k pop(rsi);
985 #endif 1010 #endif
986 SafeReturn(); 1011 SafeReturn();
987 } 1012 }
988 1013
989 if (exit_with_exception.is_linked()) { 1014 if (exit_with_exception.is_linked()) {
990 // If any of the code above needed to exit with an exception. 1015 // If any of the code above needed to exit with an exception.
991 __ bind(&exit_with_exception); 1016 __ bind(&exit_with_exception);
992 // Exit with Result EXCEPTION(-1) to signal thrown exception. 1017 // Exit with Result EXCEPTION(-1) to signal thrown exception.
993 __ Set(rax, EXCEPTION); 1018 __ Set(rax, EXCEPTION);
994 __ jmp(&return_rax); 1019 __ jmp(&return_rax);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 1103
1079 void RegExpMacroAssemblerX64::PushRegister(int register_index, 1104 void RegExpMacroAssemblerX64::PushRegister(int register_index,
1080 StackCheckFlag check_stack_limit) { 1105 StackCheckFlag check_stack_limit) {
1081 __ movq(rax, register_location(register_index)); 1106 __ movq(rax, register_location(register_index));
1082 Push(rax); 1107 Push(rax);
1083 if (check_stack_limit) CheckStackLimit(); 1108 if (check_stack_limit) CheckStackLimit();
1084 } 1109 }
1085 1110
1086 1111
1087 void RegExpMacroAssemblerX64::ReadCurrentPositionFromRegister(int reg) { 1112 void RegExpMacroAssemblerX64::ReadCurrentPositionFromRegister(int reg) {
1113 #ifndef V8_TARGET_ARCH_X32
1088 __ movq(rdi, register_location(reg)); 1114 __ movq(rdi, register_location(reg));
1115 #else
1116 __ movsxlq(rdi, register_location(reg));
1117 #endif
1089 } 1118 }
1090 1119
1091 1120
1092 void RegExpMacroAssemblerX64::ReadStackPointerFromRegister(int reg) { 1121 void RegExpMacroAssemblerX64::ReadStackPointerFromRegister(int reg) {
1122 #ifndef V8_TARGET_ARCH_X32
1093 __ movq(backtrack_stackpointer(), register_location(reg)); 1123 __ movq(backtrack_stackpointer(), register_location(reg));
1094 __ addq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); 1124 __ addq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
1125 #else
1126 __ movsxlq(backtrack_stackpointer(), register_location(reg));
1127 __ addl(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
1128 #endif
1095 } 1129 }
1096 1130
1097 1131
1098 void RegExpMacroAssemblerX64::SetCurrentPositionFromEnd(int by) { 1132 void RegExpMacroAssemblerX64::SetCurrentPositionFromEnd(int by) {
1099 Label after_position; 1133 Label after_position;
1100 __ cmpq(rdi, Immediate(-by * char_size())); 1134 __ cmpq(rdi, Immediate(-by * char_size()));
1101 __ j(greater_equal, &after_position, Label::kNear); 1135 __ j(greater_equal, &after_position, Label::kNear);
1102 __ movq(rdi, Immediate(-by * char_size())); 1136 __k movq(rdi, Immediate(-by * char_size()));
1103 // On RegExp code entry (where this operation is used), the character before 1137 // On RegExp code entry (where this operation is used), the character before
1104 // the current position is expected to be already loaded. 1138 // the current position is expected to be already loaded.
1105 // We have advanced the position, so it's safe to read backwards. 1139 // We have advanced the position, so it's safe to read backwards.
1106 LoadCurrentCharacterUnchecked(-1, 1); 1140 LoadCurrentCharacterUnchecked(-1, 1);
1107 __ bind(&after_position); 1141 __ bind(&after_position);
1108 } 1142 }
1109 1143
1110 1144
1111 void RegExpMacroAssemblerX64::SetRegister(int register_index, int to) { 1145 void RegExpMacroAssemblerX64::SetRegister(int register_index, int to) {
1112 ASSERT(register_index >= num_saved_registers_); // Reserved for positions! 1146 ASSERT(register_index >= num_saved_registers_); // Reserved for positions!
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 // First argument: Next address on the stack (will be address of 1196 // First argument: Next address on the stack (will be address of
1163 // return address). 1197 // return address).
1164 __ lea(rcx, Operand(rsp, -kPointerSize)); 1198 __ lea(rcx, Operand(rsp, -kPointerSize));
1165 #else 1199 #else
1166 // Third argument: RegExp code frame pointer. 1200 // Third argument: RegExp code frame pointer.
1167 __ movq(rdx, rbp); 1201 __ movq(rdx, rbp);
1168 // Second argument: Code* of self. 1202 // Second argument: Code* of self.
1169 __ movq(rsi, code_object_pointer()); 1203 __ movq(rsi, code_object_pointer());
1170 // First argument: Next address on the stack (will be address of 1204 // First argument: Next address on the stack (will be address of
1171 // return address). 1205 // return address).
1206 #ifndef V8_TARGET_ARCH_X32
1172 __ lea(rdi, Operand(rsp, -kPointerSize)); 1207 __ lea(rdi, Operand(rsp, -kPointerSize));
1208 #else
1209 __ leal(rdi, Operand(rsp, -kHWRegSize));
1210 #endif
1173 #endif 1211 #endif
1174 ExternalReference stack_check = 1212 ExternalReference stack_check =
1175 ExternalReference::re_check_stack_guard_state(isolate()); 1213 ExternalReference::re_check_stack_guard_state(isolate());
1176 __ CallCFunction(stack_check, num_arguments); 1214 __ CallCFunction(stack_check, num_arguments);
1177 } 1215 }
1178 1216
1179 1217
1180 // Helper function for reading a value out of a stack frame. 1218 // Helper function for reading a value out of a stack frame.
1181 template <typename T> 1219 template <typename T>
1182 static T& frame_entry(Address re_frame, int frame_offset) { 1220 static T& frame_entry(Address re_frame, int frame_offset) {
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 1407
1370 void RegExpMacroAssemblerX64::Push(Label* backtrack_target) { 1408 void RegExpMacroAssemblerX64::Push(Label* backtrack_target) {
1371 __ subq(backtrack_stackpointer(), Immediate(kIntSize)); 1409 __ subq(backtrack_stackpointer(), Immediate(kIntSize));
1372 __ movl(Operand(backtrack_stackpointer(), 0), backtrack_target); 1410 __ movl(Operand(backtrack_stackpointer(), 0), backtrack_target);
1373 MarkPositionForCodeRelativeFixup(); 1411 MarkPositionForCodeRelativeFixup();
1374 } 1412 }
1375 1413
1376 1414
1377 void RegExpMacroAssemblerX64::Pop(Register target) { 1415 void RegExpMacroAssemblerX64::Pop(Register target) {
1378 ASSERT(!target.is(backtrack_stackpointer())); 1416 ASSERT(!target.is(backtrack_stackpointer()));
1379 __ movsxlq(target, Operand(backtrack_stackpointer(), 0)); 1417 __k movsxlq(target, Operand(backtrack_stackpointer(), 0));
1380 // Notice: This updates flags, unlike normal Pop. 1418 // Notice: This updates flags, unlike normal Pop.
1381 __ addq(backtrack_stackpointer(), Immediate(kIntSize)); 1419 __ addq(backtrack_stackpointer(), Immediate(kIntSize));
1382 } 1420 }
1383 1421
1384 1422
1385 void RegExpMacroAssemblerX64::Drop() { 1423 void RegExpMacroAssemblerX64::Drop() {
1386 __ addq(backtrack_stackpointer(), Immediate(kIntSize)); 1424 __ addq(backtrack_stackpointer(), Immediate(kIntSize));
1387 } 1425 }
1388 1426
1389 1427
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 __ movl(current_character(), 1471 __ movl(current_character(),
1434 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16))); 1472 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16)));
1435 } else { 1473 } else {
1436 ASSERT(characters == 1); 1474 ASSERT(characters == 1);
1437 __ movzxwl(current_character(), 1475 __ movzxwl(current_character(),
1438 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16))); 1476 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16)));
1439 } 1477 }
1440 } 1478 }
1441 } 1479 }
1442 1480
1481 #undef __k
1443 #undef __ 1482 #undef __
1444 1483
1445 #endif // V8_INTERPRETED_REGEXP 1484 #endif // V8_INTERPRETED_REGEXP
1446 1485
1447 }} // namespace v8::internal 1486 }} // namespace v8::internal
1448 1487
1449 #endif // V8_TARGET_ARCH_X64 1488 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698