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

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

Issue 430503007: Rename ASSERT* to DCHECK*. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE and fixes Created 6 years, 4 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/arm64/regexp-macro-assembler-arm64.h ('k') | src/arm64/simulator-arm64.h » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_ARM64 7 #if V8_TARGET_ARCH_ARM64
8 8
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/cpu-profiler.h" 10 #include "src/cpu-profiler.h"
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)), 119 masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)),
120 mode_(mode), 120 mode_(mode),
121 num_registers_(registers_to_save), 121 num_registers_(registers_to_save),
122 num_saved_registers_(registers_to_save), 122 num_saved_registers_(registers_to_save),
123 entry_label_(), 123 entry_label_(),
124 start_label_(), 124 start_label_(),
125 success_label_(), 125 success_label_(),
126 backtrack_label_(), 126 backtrack_label_(),
127 exit_label_() { 127 exit_label_() {
128 __ SetStackPointer(csp); 128 __ SetStackPointer(csp);
129 ASSERT_EQ(0, registers_to_save % 2); 129 DCHECK_EQ(0, registers_to_save % 2);
130 // We can cache at most 16 W registers in x0-x7. 130 // We can cache at most 16 W registers in x0-x7.
131 STATIC_ASSERT(kNumCachedRegisters <= 16); 131 STATIC_ASSERT(kNumCachedRegisters <= 16);
132 STATIC_ASSERT((kNumCachedRegisters % 2) == 0); 132 STATIC_ASSERT((kNumCachedRegisters % 2) == 0);
133 __ B(&entry_label_); // We'll write the entry code later. 133 __ B(&entry_label_); // We'll write the entry code later.
134 __ Bind(&start_label_); // And then continue from here. 134 __ Bind(&start_label_); // And then continue from here.
135 } 135 }
136 136
137 137
138 RegExpMacroAssemblerARM64::~RegExpMacroAssemblerARM64() { 138 RegExpMacroAssemblerARM64::~RegExpMacroAssemblerARM64() {
139 delete masm_; 139 delete masm_;
(...skipping 14 matching lines...) Expand all
154 154
155 void RegExpMacroAssemblerARM64::AdvanceCurrentPosition(int by) { 155 void RegExpMacroAssemblerARM64::AdvanceCurrentPosition(int by) {
156 if (by != 0) { 156 if (by != 0) {
157 __ Add(current_input_offset(), 157 __ Add(current_input_offset(),
158 current_input_offset(), by * char_size()); 158 current_input_offset(), by * char_size());
159 } 159 }
160 } 160 }
161 161
162 162
163 void RegExpMacroAssemblerARM64::AdvanceRegister(int reg, int by) { 163 void RegExpMacroAssemblerARM64::AdvanceRegister(int reg, int by) {
164 ASSERT((reg >= 0) && (reg < num_registers_)); 164 DCHECK((reg >= 0) && (reg < num_registers_));
165 if (by != 0) { 165 if (by != 0) {
166 Register to_advance; 166 Register to_advance;
167 RegisterState register_state = GetRegisterState(reg); 167 RegisterState register_state = GetRegisterState(reg);
168 switch (register_state) { 168 switch (register_state) {
169 case STACKED: 169 case STACKED:
170 __ Ldr(w10, register_location(reg)); 170 __ Ldr(w10, register_location(reg));
171 __ Add(w10, w10, by); 171 __ Add(w10, w10, by);
172 __ Str(w10, register_location(reg)); 172 __ Str(w10, register_location(reg));
173 break; 173 break;
174 case CACHED_LSW: 174 case CACHED_LSW:
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 __ Add(characters_address, 255 __ Add(characters_address,
256 input_end(), 256 input_end(),
257 Operand(current_input_offset(), SXTW)); 257 Operand(current_input_offset(), SXTW));
258 if (cp_offset != 0) { 258 if (cp_offset != 0) {
259 __ Add(characters_address, characters_address, cp_offset * char_size()); 259 __ Add(characters_address, characters_address, cp_offset * char_size());
260 } 260 }
261 261
262 for (int i = 0; i < str.length(); i++) { 262 for (int i = 0; i < str.length(); i++) {
263 if (mode_ == ASCII) { 263 if (mode_ == ASCII) {
264 __ Ldrb(w10, MemOperand(characters_address, 1, PostIndex)); 264 __ Ldrb(w10, MemOperand(characters_address, 1, PostIndex));
265 ASSERT(str[i] <= String::kMaxOneByteCharCode); 265 DCHECK(str[i] <= String::kMaxOneByteCharCode);
266 } else { 266 } else {
267 __ Ldrh(w10, MemOperand(characters_address, 2, PostIndex)); 267 __ Ldrh(w10, MemOperand(characters_address, 2, PostIndex));
268 } 268 }
269 CompareAndBranchOrBacktrack(w10, str[i], ne, on_failure); 269 CompareAndBranchOrBacktrack(w10, str[i], ne, on_failure);
270 } 270 }
271 } 271 }
272 272
273 273
274 void RegExpMacroAssemblerARM64::CheckGreedyLoop(Label* on_equal) { 274 void RegExpMacroAssemblerARM64::CheckGreedyLoop(Label* on_equal) {
275 __ Ldr(w10, MemOperand(backtrack_stackpointer())); 275 __ Ldr(w10, MemOperand(backtrack_stackpointer()));
276 __ Cmp(current_input_offset(), w10); 276 __ Cmp(current_input_offset(), w10);
277 __ Cset(x11, eq); 277 __ Cset(x11, eq);
278 __ Add(backtrack_stackpointer(), 278 __ Add(backtrack_stackpointer(),
279 backtrack_stackpointer(), Operand(x11, LSL, kWRegSizeLog2)); 279 backtrack_stackpointer(), Operand(x11, LSL, kWRegSizeLog2));
280 BranchOrBacktrack(eq, on_equal); 280 BranchOrBacktrack(eq, on_equal);
281 } 281 }
282 282
283 void RegExpMacroAssemblerARM64::CheckNotBackReferenceIgnoreCase( 283 void RegExpMacroAssemblerARM64::CheckNotBackReferenceIgnoreCase(
284 int start_reg, 284 int start_reg,
285 Label* on_no_match) { 285 Label* on_no_match) {
286 Label fallthrough; 286 Label fallthrough;
287 287
288 Register capture_start_offset = w10; 288 Register capture_start_offset = w10;
289 // Save the capture length in a callee-saved register so it will 289 // Save the capture length in a callee-saved register so it will
290 // be preserved if we call a C helper. 290 // be preserved if we call a C helper.
291 Register capture_length = w19; 291 Register capture_length = w19;
292 ASSERT(kCalleeSaved.IncludesAliasOf(capture_length)); 292 DCHECK(kCalleeSaved.IncludesAliasOf(capture_length));
293 293
294 // Find length of back-referenced capture. 294 // Find length of back-referenced capture.
295 ASSERT((start_reg % 2) == 0); 295 DCHECK((start_reg % 2) == 0);
296 if (start_reg < kNumCachedRegisters) { 296 if (start_reg < kNumCachedRegisters) {
297 __ Mov(capture_start_offset.X(), GetCachedRegister(start_reg)); 297 __ Mov(capture_start_offset.X(), GetCachedRegister(start_reg));
298 __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits); 298 __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits);
299 } else { 299 } else {
300 __ Ldp(w11, capture_start_offset, capture_location(start_reg, x10)); 300 __ Ldp(w11, capture_start_offset, capture_location(start_reg, x10));
301 } 301 }
302 __ Sub(capture_length, w11, capture_start_offset); // Length to check. 302 __ Sub(capture_length, w11, capture_start_offset); // Length to check.
303 // Succeed on empty capture (including no capture). 303 // Succeed on empty capture (including no capture).
304 __ Cbz(capture_length, &fallthrough); 304 __ Cbz(capture_length, &fallthrough);
305 305
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 __ Bind(&success); 358 __ Bind(&success);
359 // Compute new value of character position after the matched part. 359 // Compute new value of character position after the matched part.
360 __ Sub(current_input_offset().X(), current_position_address, input_end()); 360 __ Sub(current_input_offset().X(), current_position_address, input_end());
361 if (masm_->emit_debug_code()) { 361 if (masm_->emit_debug_code()) {
362 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW)); 362 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW));
363 __ Ccmp(current_input_offset(), 0, NoFlag, eq); 363 __ Ccmp(current_input_offset(), 0, NoFlag, eq);
364 // The current input offset should be <= 0, and fit in a W register. 364 // The current input offset should be <= 0, and fit in a W register.
365 __ Check(le, kOffsetOutOfRange); 365 __ Check(le, kOffsetOutOfRange);
366 } 366 }
367 } else { 367 } else {
368 ASSERT(mode_ == UC16); 368 DCHECK(mode_ == UC16);
369 int argument_count = 4; 369 int argument_count = 4;
370 370
371 // The cached registers need to be retained. 371 // The cached registers need to be retained.
372 CPURegList cached_registers(CPURegister::kRegister, kXRegSizeInBits, 0, 7); 372 CPURegList cached_registers(CPURegister::kRegister, kXRegSizeInBits, 0, 7);
373 ASSERT((cached_registers.Count() * 2) == kNumCachedRegisters); 373 DCHECK((cached_registers.Count() * 2) == kNumCachedRegisters);
374 __ PushCPURegList(cached_registers); 374 __ PushCPURegList(cached_registers);
375 375
376 // Put arguments into arguments registers. 376 // Put arguments into arguments registers.
377 // Parameters are 377 // Parameters are
378 // x0: Address byte_offset1 - Address captured substring's start. 378 // x0: Address byte_offset1 - Address captured substring's start.
379 // x1: Address byte_offset2 - Address of current character position. 379 // x1: Address byte_offset2 - Address of current character position.
380 // w2: size_t byte_length - length of capture in bytes(!) 380 // w2: size_t byte_length - length of capture in bytes(!)
381 // x3: Isolate* isolate 381 // x3: Isolate* isolate
382 382
383 // Address of start of capture. 383 // Address of start of capture.
(...skipping 30 matching lines...) Expand all
414 int start_reg, 414 int start_reg,
415 Label* on_no_match) { 415 Label* on_no_match) {
416 Label fallthrough; 416 Label fallthrough;
417 417
418 Register capture_start_address = x12; 418 Register capture_start_address = x12;
419 Register capture_end_address = x13; 419 Register capture_end_address = x13;
420 Register current_position_address = x14; 420 Register current_position_address = x14;
421 Register capture_length = w15; 421 Register capture_length = w15;
422 422
423 // Find length of back-referenced capture. 423 // Find length of back-referenced capture.
424 ASSERT((start_reg % 2) == 0); 424 DCHECK((start_reg % 2) == 0);
425 if (start_reg < kNumCachedRegisters) { 425 if (start_reg < kNumCachedRegisters) {
426 __ Mov(x10, GetCachedRegister(start_reg)); 426 __ Mov(x10, GetCachedRegister(start_reg));
427 __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits); 427 __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits);
428 } else { 428 } else {
429 __ Ldp(w11, w10, capture_location(start_reg, x10)); 429 __ Ldp(w11, w10, capture_location(start_reg, x10));
430 } 430 }
431 __ Sub(capture_length, w11, w10); // Length to check. 431 __ Sub(capture_length, w11, w10); // Length to check.
432 // Succeed on empty capture (including no capture). 432 // Succeed on empty capture (including no capture).
433 __ Cbz(capture_length, &fallthrough); 433 __ Cbz(capture_length, &fallthrough);
434 434
435 // Check that there are enough characters left in the input. 435 // Check that there are enough characters left in the input.
436 __ Cmn(capture_length, current_input_offset()); 436 __ Cmn(capture_length, current_input_offset());
437 BranchOrBacktrack(gt, on_no_match); 437 BranchOrBacktrack(gt, on_no_match);
438 438
439 // Compute pointers to match string and capture string 439 // Compute pointers to match string and capture string
440 __ Add(capture_start_address, input_end(), Operand(w10, SXTW)); 440 __ Add(capture_start_address, input_end(), Operand(w10, SXTW));
441 __ Add(capture_end_address, 441 __ Add(capture_end_address,
442 capture_start_address, 442 capture_start_address,
443 Operand(capture_length, SXTW)); 443 Operand(capture_length, SXTW));
444 __ Add(current_position_address, 444 __ Add(current_position_address,
445 input_end(), 445 input_end(),
446 Operand(current_input_offset(), SXTW)); 446 Operand(current_input_offset(), SXTW));
447 447
448 Label loop; 448 Label loop;
449 __ Bind(&loop); 449 __ Bind(&loop);
450 if (mode_ == ASCII) { 450 if (mode_ == ASCII) {
451 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex)); 451 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex));
452 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex)); 452 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex));
453 } else { 453 } else {
454 ASSERT(mode_ == UC16); 454 DCHECK(mode_ == UC16);
455 __ Ldrh(w10, MemOperand(capture_start_address, 2, PostIndex)); 455 __ Ldrh(w10, MemOperand(capture_start_address, 2, PostIndex));
456 __ Ldrh(w11, MemOperand(current_position_address, 2, PostIndex)); 456 __ Ldrh(w11, MemOperand(current_position_address, 2, PostIndex));
457 } 457 }
458 __ Cmp(w10, w11); 458 __ Cmp(w10, w11);
459 BranchOrBacktrack(ne, on_no_match); 459 BranchOrBacktrack(ne, on_no_match);
460 __ Cmp(capture_start_address, capture_end_address); 460 __ Cmp(capture_start_address, capture_end_address);
461 __ B(lt, &loop); 461 __ B(lt, &loop);
462 462
463 // Move current character position to position after match. 463 // Move current character position to position after match.
464 __ Sub(current_input_offset().X(), current_position_address, input_end()); 464 __ Sub(current_input_offset().X(), current_position_address, input_end());
(...skipping 27 matching lines...) Expand all
492 __ And(w10, current_character(), mask); 492 __ And(w10, current_character(), mask);
493 CompareAndBranchOrBacktrack(w10, c, ne, on_not_equal); 493 CompareAndBranchOrBacktrack(w10, c, ne, on_not_equal);
494 } 494 }
495 495
496 496
497 void RegExpMacroAssemblerARM64::CheckNotCharacterAfterMinusAnd( 497 void RegExpMacroAssemblerARM64::CheckNotCharacterAfterMinusAnd(
498 uc16 c, 498 uc16 c,
499 uc16 minus, 499 uc16 minus,
500 uc16 mask, 500 uc16 mask,
501 Label* on_not_equal) { 501 Label* on_not_equal) {
502 ASSERT(minus < String::kMaxUtf16CodeUnit); 502 DCHECK(minus < String::kMaxUtf16CodeUnit);
503 __ Sub(w10, current_character(), minus); 503 __ Sub(w10, current_character(), minus);
504 __ And(w10, w10, mask); 504 __ And(w10, w10, mask);
505 CompareAndBranchOrBacktrack(w10, c, ne, on_not_equal); 505 CompareAndBranchOrBacktrack(w10, c, ne, on_not_equal);
506 } 506 }
507 507
508 508
509 void RegExpMacroAssemblerARM64::CheckCharacterInRange( 509 void RegExpMacroAssemblerARM64::CheckCharacterInRange(
510 uc16 from, 510 uc16 from,
511 uc16 to, 511 uc16 to,
512 Label* on_in_range) { 512 Label* on_in_range) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 // csp[0]: secondary link/return address used by native call 674 // csp[0]: secondary link/return address used by native call
675 675
676 // Tell the system that we have a stack frame. Because the type is MANUAL, no 676 // Tell the system that we have a stack frame. Because the type is MANUAL, no
677 // code is generated. 677 // code is generated.
678 FrameScope scope(masm_, StackFrame::MANUAL); 678 FrameScope scope(masm_, StackFrame::MANUAL);
679 679
680 // Push registers on the stack, only push the argument registers that we need. 680 // Push registers on the stack, only push the argument registers that we need.
681 CPURegList argument_registers(x0, x5, x6, x7); 681 CPURegList argument_registers(x0, x5, x6, x7);
682 682
683 CPURegList registers_to_retain = kCalleeSaved; 683 CPURegList registers_to_retain = kCalleeSaved;
684 ASSERT(kCalleeSaved.Count() == 11); 684 DCHECK(kCalleeSaved.Count() == 11);
685 registers_to_retain.Combine(lr); 685 registers_to_retain.Combine(lr);
686 686
687 ASSERT(csp.Is(__ StackPointer())); 687 DCHECK(csp.Is(__ StackPointer()));
688 __ PushCPURegList(registers_to_retain); 688 __ PushCPURegList(registers_to_retain);
689 __ PushCPURegList(argument_registers); 689 __ PushCPURegList(argument_registers);
690 690
691 // Set frame pointer in place. 691 // Set frame pointer in place.
692 __ Add(frame_pointer(), csp, argument_registers.Count() * kPointerSize); 692 __ Add(frame_pointer(), csp, argument_registers.Count() * kPointerSize);
693 693
694 // Initialize callee-saved registers. 694 // Initialize callee-saved registers.
695 __ Mov(start_offset(), w1); 695 __ Mov(start_offset(), w1);
696 __ Mov(input_start(), x2); 696 __ Mov(input_start(), x2);
697 __ Mov(input_end(), x3); 697 __ Mov(input_end(), x3);
698 __ Mov(output_array(), x4); 698 __ Mov(output_array(), x4);
699 699
700 // Set the number of registers we will need to allocate, that is: 700 // Set the number of registers we will need to allocate, that is:
701 // - success_counter (X register) 701 // - success_counter (X register)
702 // - (num_registers_ - kNumCachedRegisters) (W registers) 702 // - (num_registers_ - kNumCachedRegisters) (W registers)
703 int num_wreg_to_allocate = num_registers_ - kNumCachedRegisters; 703 int num_wreg_to_allocate = num_registers_ - kNumCachedRegisters;
704 // Do not allocate registers on the stack if they can all be cached. 704 // Do not allocate registers on the stack if they can all be cached.
705 if (num_wreg_to_allocate < 0) { num_wreg_to_allocate = 0; } 705 if (num_wreg_to_allocate < 0) { num_wreg_to_allocate = 0; }
706 // Make room for the success_counter. 706 // Make room for the success_counter.
707 num_wreg_to_allocate += 2; 707 num_wreg_to_allocate += 2;
708 708
709 // Make sure the stack alignment will be respected. 709 // Make sure the stack alignment will be respected.
710 int alignment = masm_->ActivationFrameAlignment(); 710 int alignment = masm_->ActivationFrameAlignment();
711 ASSERT_EQ(alignment % 16, 0); 711 DCHECK_EQ(alignment % 16, 0);
712 int align_mask = (alignment / kWRegSize) - 1; 712 int align_mask = (alignment / kWRegSize) - 1;
713 num_wreg_to_allocate = (num_wreg_to_allocate + align_mask) & ~align_mask; 713 num_wreg_to_allocate = (num_wreg_to_allocate + align_mask) & ~align_mask;
714 714
715 // Check if we have space on the stack. 715 // Check if we have space on the stack.
716 Label stack_limit_hit; 716 Label stack_limit_hit;
717 Label stack_ok; 717 Label stack_ok;
718 718
719 ExternalReference stack_limit = 719 ExternalReference stack_limit =
720 ExternalReference::address_of_stack_limit(isolate()); 720 ExternalReference::address_of_stack_limit(isolate());
721 __ Mov(x10, stack_limit); 721 __ Mov(x10, stack_limit);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 } 854 }
855 855
856 // Only carry on if there are more than kNumCachedRegisters capture 856 // Only carry on if there are more than kNumCachedRegisters capture
857 // registers. 857 // registers.
858 int num_registers_left_on_stack = 858 int num_registers_left_on_stack =
859 num_saved_registers_ - kNumCachedRegisters; 859 num_saved_registers_ - kNumCachedRegisters;
860 if (num_registers_left_on_stack > 0) { 860 if (num_registers_left_on_stack > 0) {
861 Register base = x10; 861 Register base = x10;
862 // There are always an even number of capture registers. A couple of 862 // There are always an even number of capture registers. A couple of
863 // registers determine one match with two offsets. 863 // registers determine one match with two offsets.
864 ASSERT_EQ(0, num_registers_left_on_stack % 2); 864 DCHECK_EQ(0, num_registers_left_on_stack % 2);
865 __ Add(base, frame_pointer(), kFirstCaptureOnStack); 865 __ Add(base, frame_pointer(), kFirstCaptureOnStack);
866 866
867 // We can unroll the loop here, we should not unroll for less than 2 867 // We can unroll the loop here, we should not unroll for less than 2
868 // registers. 868 // registers.
869 STATIC_ASSERT(kNumRegistersToUnroll > 2); 869 STATIC_ASSERT(kNumRegistersToUnroll > 2);
870 if (num_registers_left_on_stack <= kNumRegistersToUnroll) { 870 if (num_registers_left_on_stack <= kNumRegistersToUnroll) {
871 for (int i = 0; i < num_registers_left_on_stack / 2; i++) { 871 for (int i = 0; i < num_registers_left_on_stack / 2; i++) {
872 __ Ldp(capture_end, 872 __ Ldp(capture_end,
873 capture_start, 873 capture_start,
874 MemOperand(base, -kPointerSize, PostIndex)); 874 MemOperand(base, -kPointerSize, PostIndex));
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 // Exit and return w0 971 // Exit and return w0
972 __ Bind(&exit_label_); 972 __ Bind(&exit_label_);
973 if (global()) { 973 if (global()) {
974 __ Ldr(w0, MemOperand(frame_pointer(), kSuccessCounter)); 974 __ Ldr(w0, MemOperand(frame_pointer(), kSuccessCounter));
975 } 975 }
976 } 976 }
977 977
978 __ Bind(&return_w0); 978 __ Bind(&return_w0);
979 979
980 // Set stack pointer back to first register to retain 980 // Set stack pointer back to first register to retain
981 ASSERT(csp.Is(__ StackPointer())); 981 DCHECK(csp.Is(__ StackPointer()));
982 __ Mov(csp, fp); 982 __ Mov(csp, fp);
983 __ AssertStackConsistency(); 983 __ AssertStackConsistency();
984 984
985 // Restore registers. 985 // Restore registers.
986 __ PopCPURegList(registers_to_retain); 986 __ PopCPURegList(registers_to_retain);
987 987
988 __ Ret(); 988 __ Ret();
989 989
990 Label exit_with_exception; 990 Label exit_with_exception;
991 // Registers x0 to x7 are used to store the first captures, they need to be 991 // Registers x0 to x7 are used to store the first captures, they need to be
992 // retained over calls to C++ code. 992 // retained over calls to C++ code.
993 CPURegList cached_registers(CPURegister::kRegister, kXRegSizeInBits, 0, 7); 993 CPURegList cached_registers(CPURegister::kRegister, kXRegSizeInBits, 0, 7);
994 ASSERT((cached_registers.Count() * 2) == kNumCachedRegisters); 994 DCHECK((cached_registers.Count() * 2) == kNumCachedRegisters);
995 995
996 if (check_preempt_label_.is_linked()) { 996 if (check_preempt_label_.is_linked()) {
997 __ Bind(&check_preempt_label_); 997 __ Bind(&check_preempt_label_);
998 SaveLinkRegister(); 998 SaveLinkRegister();
999 // The cached registers need to be retained. 999 // The cached registers need to be retained.
1000 __ PushCPURegList(cached_registers); 1000 __ PushCPURegList(cached_registers);
1001 CallCheckStackGuardState(x10); 1001 CallCheckStackGuardState(x10);
1002 // Returning from the regexp code restores the stack (csp <- fp) 1002 // Returning from the regexp code restores the stack (csp <- fp)
1003 // so we don't need to drop the link register from it before exiting. 1003 // so we don't need to drop the link register from it before exiting.
1004 __ Cbnz(w0, &return_w0); 1004 __ Cbnz(w0, &return_w0);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 return kARM64Implementation; 1077 return kARM64Implementation;
1078 } 1078 }
1079 1079
1080 1080
1081 void RegExpMacroAssemblerARM64::LoadCurrentCharacter(int cp_offset, 1081 void RegExpMacroAssemblerARM64::LoadCurrentCharacter(int cp_offset,
1082 Label* on_end_of_input, 1082 Label* on_end_of_input,
1083 bool check_bounds, 1083 bool check_bounds,
1084 int characters) { 1084 int characters) {
1085 // TODO(pielan): Make sure long strings are caught before this, and not 1085 // TODO(pielan): Make sure long strings are caught before this, and not
1086 // just asserted in debug mode. 1086 // just asserted in debug mode.
1087 ASSERT(cp_offset >= -1); // ^ and \b can look behind one character. 1087 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character.
1088 // Be sane! (And ensure that an int32_t can be used to index the string) 1088 // Be sane! (And ensure that an int32_t can be used to index the string)
1089 ASSERT(cp_offset < (1<<30)); 1089 DCHECK(cp_offset < (1<<30));
1090 if (check_bounds) { 1090 if (check_bounds) {
1091 CheckPosition(cp_offset + characters - 1, on_end_of_input); 1091 CheckPosition(cp_offset + characters - 1, on_end_of_input);
1092 } 1092 }
1093 LoadCurrentCharacterUnchecked(cp_offset, characters); 1093 LoadCurrentCharacterUnchecked(cp_offset, characters);
1094 } 1094 }
1095 1095
1096 1096
1097 void RegExpMacroAssemblerARM64::PopCurrentPosition() { 1097 void RegExpMacroAssemblerARM64::PopCurrentPosition() {
1098 Pop(current_input_offset()); 1098 Pop(current_input_offset());
1099 } 1099 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 __ Mov(current_input_offset(), -by * char_size()); 1172 __ Mov(current_input_offset(), -by * char_size());
1173 // On RegExp code entry (where this operation is used), the character before 1173 // On RegExp code entry (where this operation is used), the character before
1174 // the current position is expected to be already loaded. 1174 // the current position is expected to be already loaded.
1175 // We have advanced the position, so it's safe to read backwards. 1175 // We have advanced the position, so it's safe to read backwards.
1176 LoadCurrentCharacterUnchecked(-1, 1); 1176 LoadCurrentCharacterUnchecked(-1, 1);
1177 __ Bind(&after_position); 1177 __ Bind(&after_position);
1178 } 1178 }
1179 1179
1180 1180
1181 void RegExpMacroAssemblerARM64::SetRegister(int register_index, int to) { 1181 void RegExpMacroAssemblerARM64::SetRegister(int register_index, int to) {
1182 ASSERT(register_index >= num_saved_registers_); // Reserved for positions! 1182 DCHECK(register_index >= num_saved_registers_); // Reserved for positions!
1183 Register set_to = wzr; 1183 Register set_to = wzr;
1184 if (to != 0) { 1184 if (to != 0) {
1185 set_to = w10; 1185 set_to = w10;
1186 __ Mov(set_to, to); 1186 __ Mov(set_to, to);
1187 } 1187 }
1188 StoreRegister(register_index, set_to); 1188 StoreRegister(register_index, set_to);
1189 } 1189 }
1190 1190
1191 1191
1192 bool RegExpMacroAssemblerARM64::Succeed() { 1192 bool RegExpMacroAssemblerARM64::Succeed() {
1193 __ B(&success_label_); 1193 __ B(&success_label_);
1194 return global(); 1194 return global();
1195 } 1195 }
1196 1196
1197 1197
1198 void RegExpMacroAssemblerARM64::WriteCurrentPositionToRegister(int reg, 1198 void RegExpMacroAssemblerARM64::WriteCurrentPositionToRegister(int reg,
1199 int cp_offset) { 1199 int cp_offset) {
1200 Register position = current_input_offset(); 1200 Register position = current_input_offset();
1201 if (cp_offset != 0) { 1201 if (cp_offset != 0) {
1202 position = w10; 1202 position = w10;
1203 __ Add(position, current_input_offset(), cp_offset * char_size()); 1203 __ Add(position, current_input_offset(), cp_offset * char_size());
1204 } 1204 }
1205 StoreRegister(reg, position); 1205 StoreRegister(reg, position);
1206 } 1206 }
1207 1207
1208 1208
1209 void RegExpMacroAssemblerARM64::ClearRegisters(int reg_from, int reg_to) { 1209 void RegExpMacroAssemblerARM64::ClearRegisters(int reg_from, int reg_to) {
1210 ASSERT(reg_from <= reg_to); 1210 DCHECK(reg_from <= reg_to);
1211 int num_registers = reg_to - reg_from + 1; 1211 int num_registers = reg_to - reg_from + 1;
1212 1212
1213 // If the first capture register is cached in a hardware register but not 1213 // If the first capture register is cached in a hardware register but not
1214 // aligned on a 64-bit one, we need to clear the first one specifically. 1214 // aligned on a 64-bit one, we need to clear the first one specifically.
1215 if ((reg_from < kNumCachedRegisters) && ((reg_from % 2) != 0)) { 1215 if ((reg_from < kNumCachedRegisters) && ((reg_from % 2) != 0)) {
1216 StoreRegister(reg_from, non_position_value()); 1216 StoreRegister(reg_from, non_position_value());
1217 num_registers--; 1217 num_registers--;
1218 reg_from++; 1218 reg_from++;
1219 } 1219 }
1220 1220
1221 // Clear cached registers in pairs as far as possible. 1221 // Clear cached registers in pairs as far as possible.
1222 while ((num_registers >= 2) && (reg_from < kNumCachedRegisters)) { 1222 while ((num_registers >= 2) && (reg_from < kNumCachedRegisters)) {
1223 ASSERT(GetRegisterState(reg_from) == CACHED_LSW); 1223 DCHECK(GetRegisterState(reg_from) == CACHED_LSW);
1224 __ Mov(GetCachedRegister(reg_from), twice_non_position_value()); 1224 __ Mov(GetCachedRegister(reg_from), twice_non_position_value());
1225 reg_from += 2; 1225 reg_from += 2;
1226 num_registers -= 2; 1226 num_registers -= 2;
1227 } 1227 }
1228 1228
1229 if ((num_registers % 2) == 1) { 1229 if ((num_registers % 2) == 1) {
1230 StoreRegister(reg_from, non_position_value()); 1230 StoreRegister(reg_from, non_position_value());
1231 num_registers--; 1231 num_registers--;
1232 reg_from++; 1232 reg_from++;
1233 } 1233 }
1234 1234
1235 if (num_registers > 0) { 1235 if (num_registers > 0) {
1236 // If there are some remaining registers, they are stored on the stack. 1236 // If there are some remaining registers, they are stored on the stack.
1237 ASSERT(reg_from >= kNumCachedRegisters); 1237 DCHECK(reg_from >= kNumCachedRegisters);
1238 1238
1239 // Move down the indexes of the registers on stack to get the correct offset 1239 // Move down the indexes of the registers on stack to get the correct offset
1240 // in memory. 1240 // in memory.
1241 reg_from -= kNumCachedRegisters; 1241 reg_from -= kNumCachedRegisters;
1242 reg_to -= kNumCachedRegisters; 1242 reg_to -= kNumCachedRegisters;
1243 // We should not unroll the loop for less than 2 registers. 1243 // We should not unroll the loop for less than 2 registers.
1244 STATIC_ASSERT(kNumRegistersToUnroll > 2); 1244 STATIC_ASSERT(kNumRegistersToUnroll > 2);
1245 // We position the base pointer to (reg_from + 1). 1245 // We position the base pointer to (reg_from + 1).
1246 int base_offset = kFirstRegisterOnStack - 1246 int base_offset = kFirstRegisterOnStack -
1247 kWRegSize - (kWRegSize * reg_from); 1247 kWRegSize - (kWRegSize * reg_from);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 1310
1311 // Prepare for possible GC. 1311 // Prepare for possible GC.
1312 HandleScope handles(isolate); 1312 HandleScope handles(isolate);
1313 Handle<Code> code_handle(re_code); 1313 Handle<Code> code_handle(re_code);
1314 1314
1315 Handle<String> subject(frame_entry<String*>(re_frame, kInput)); 1315 Handle<String> subject(frame_entry<String*>(re_frame, kInput));
1316 1316
1317 // Current string. 1317 // Current string.
1318 bool is_ascii = subject->IsOneByteRepresentationUnderneath(); 1318 bool is_ascii = subject->IsOneByteRepresentationUnderneath();
1319 1319
1320 ASSERT(re_code->instruction_start() <= *return_address); 1320 DCHECK(re_code->instruction_start() <= *return_address);
1321 ASSERT(*return_address <= 1321 DCHECK(*return_address <=
1322 re_code->instruction_start() + re_code->instruction_size()); 1322 re_code->instruction_start() + re_code->instruction_size());
1323 1323
1324 Object* result = isolate->stack_guard()->HandleInterrupts(); 1324 Object* result = isolate->stack_guard()->HandleInterrupts();
1325 1325
1326 if (*code_handle != re_code) { // Return address no longer valid 1326 if (*code_handle != re_code) { // Return address no longer valid
1327 int delta = code_handle->address() - re_code->address(); 1327 int delta = code_handle->address() - re_code->address();
1328 // Overwrite the return address on the stack. 1328 // Overwrite the return address on the stack.
1329 *return_address += delta; 1329 *return_address += delta;
1330 } 1330 }
1331 1331
(...skipping 18 matching lines...) Expand all
1350 // If we changed between an ASCII and an UC16 string, the specialized 1350 // If we changed between an ASCII and an UC16 string, the specialized
1351 // code cannot be used, and we need to restart regexp matching from 1351 // code cannot be used, and we need to restart regexp matching from
1352 // scratch (including, potentially, compiling a new version of the code). 1352 // scratch (including, potentially, compiling a new version of the code).
1353 return RETRY; 1353 return RETRY;
1354 } 1354 }
1355 1355
1356 // Otherwise, the content of the string might have moved. It must still 1356 // Otherwise, the content of the string might have moved. It must still
1357 // be a sequential or external string with the same content. 1357 // be a sequential or external string with the same content.
1358 // Update the start and end pointers in the stack frame to the current 1358 // Update the start and end pointers in the stack frame to the current
1359 // location (whether it has actually moved or not). 1359 // location (whether it has actually moved or not).
1360 ASSERT(StringShape(*subject_tmp).IsSequential() || 1360 DCHECK(StringShape(*subject_tmp).IsSequential() ||
1361 StringShape(*subject_tmp).IsExternal()); 1361 StringShape(*subject_tmp).IsExternal());
1362 1362
1363 // The original start address of the characters to match. 1363 // The original start address of the characters to match.
1364 const byte* start_address = *input_start; 1364 const byte* start_address = *input_start;
1365 1365
1366 // Find the current start address of the same character at the current string 1366 // Find the current start address of the same character at the current string
1367 // position. 1367 // position.
1368 const byte* new_address = StringCharacterPosition(*subject_tmp, 1368 const byte* new_address = StringCharacterPosition(*subject_tmp,
1369 start_offset + slice_offset); 1369 start_offset + slice_offset);
1370 1370
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1403 1403
1404 1404
1405 // Private methods: 1405 // Private methods:
1406 1406
1407 void RegExpMacroAssemblerARM64::CallCheckStackGuardState(Register scratch) { 1407 void RegExpMacroAssemblerARM64::CallCheckStackGuardState(Register scratch) {
1408 // Allocate space on the stack to store the return address. The 1408 // Allocate space on the stack to store the return address. The
1409 // CheckStackGuardState C++ function will override it if the code 1409 // CheckStackGuardState C++ function will override it if the code
1410 // moved. Allocate extra space for 2 arguments passed by pointers. 1410 // moved. Allocate extra space for 2 arguments passed by pointers.
1411 // AAPCS64 requires the stack to be 16 byte aligned. 1411 // AAPCS64 requires the stack to be 16 byte aligned.
1412 int alignment = masm_->ActivationFrameAlignment(); 1412 int alignment = masm_->ActivationFrameAlignment();
1413 ASSERT_EQ(alignment % 16, 0); 1413 DCHECK_EQ(alignment % 16, 0);
1414 int align_mask = (alignment / kXRegSize) - 1; 1414 int align_mask = (alignment / kXRegSize) - 1;
1415 int xreg_to_claim = (3 + align_mask) & ~align_mask; 1415 int xreg_to_claim = (3 + align_mask) & ~align_mask;
1416 1416
1417 ASSERT(csp.Is(__ StackPointer())); 1417 DCHECK(csp.Is(__ StackPointer()));
1418 __ Claim(xreg_to_claim); 1418 __ Claim(xreg_to_claim);
1419 1419
1420 // CheckStackGuardState needs the end and start addresses of the input string. 1420 // CheckStackGuardState needs the end and start addresses of the input string.
1421 __ Poke(input_end(), 2 * kPointerSize); 1421 __ Poke(input_end(), 2 * kPointerSize);
1422 __ Add(x5, csp, 2 * kPointerSize); 1422 __ Add(x5, csp, 2 * kPointerSize);
1423 __ Poke(input_start(), kPointerSize); 1423 __ Poke(input_start(), kPointerSize);
1424 __ Add(x4, csp, kPointerSize); 1424 __ Add(x4, csp, kPointerSize);
1425 1425
1426 __ Mov(w3, start_offset()); 1426 __ Mov(w3, start_offset());
1427 // RegExp code frame pointer. 1427 // RegExp code frame pointer.
1428 __ Mov(x2, frame_pointer()); 1428 __ Mov(x2, frame_pointer());
1429 // Code* of self. 1429 // Code* of self.
1430 __ Mov(x1, Operand(masm_->CodeObject())); 1430 __ Mov(x1, Operand(masm_->CodeObject()));
1431 1431
1432 // We need to pass a pointer to the return address as first argument. 1432 // We need to pass a pointer to the return address as first argument.
1433 // The DirectCEntry stub will place the return address on the stack before 1433 // The DirectCEntry stub will place the return address on the stack before
1434 // calling so the stack pointer will point to it. 1434 // calling so the stack pointer will point to it.
1435 __ Mov(x0, csp); 1435 __ Mov(x0, csp);
1436 1436
1437 ExternalReference check_stack_guard_state = 1437 ExternalReference check_stack_guard_state =
1438 ExternalReference::re_check_stack_guard_state(isolate()); 1438 ExternalReference::re_check_stack_guard_state(isolate());
1439 __ Mov(scratch, check_stack_guard_state); 1439 __ Mov(scratch, check_stack_guard_state);
1440 DirectCEntryStub stub(isolate()); 1440 DirectCEntryStub stub(isolate());
1441 stub.GenerateCall(masm_, scratch); 1441 stub.GenerateCall(masm_, scratch);
1442 1442
1443 // The input string may have been moved in memory, we need to reload it. 1443 // The input string may have been moved in memory, we need to reload it.
1444 __ Peek(input_start(), kPointerSize); 1444 __ Peek(input_start(), kPointerSize);
1445 __ Peek(input_end(), 2 * kPointerSize); 1445 __ Peek(input_end(), 2 * kPointerSize);
1446 1446
1447 ASSERT(csp.Is(__ StackPointer())); 1447 DCHECK(csp.Is(__ StackPointer()));
1448 __ Drop(xreg_to_claim); 1448 __ Drop(xreg_to_claim);
1449 1449
1450 // Reload the Code pointer. 1450 // Reload the Code pointer.
1451 __ Mov(code_pointer(), Operand(masm_->CodeObject())); 1451 __ Mov(code_pointer(), Operand(masm_->CodeObject()));
1452 } 1452 }
1453 1453
1454 void RegExpMacroAssemblerARM64::BranchOrBacktrack(Condition condition, 1454 void RegExpMacroAssemblerARM64::BranchOrBacktrack(Condition condition,
1455 Label* to) { 1455 Label* to) {
1456 if (condition == al) { // Unconditional. 1456 if (condition == al) { // Unconditional.
1457 if (to == NULL) { 1457 if (to == NULL) {
(...skipping 28 matching lines...) Expand all
1486 } 1486 }
1487 } 1487 }
1488 1488
1489 1489
1490 void RegExpMacroAssemblerARM64::CheckPreemption() { 1490 void RegExpMacroAssemblerARM64::CheckPreemption() {
1491 // Check for preemption. 1491 // Check for preemption.
1492 ExternalReference stack_limit = 1492 ExternalReference stack_limit =
1493 ExternalReference::address_of_stack_limit(isolate()); 1493 ExternalReference::address_of_stack_limit(isolate());
1494 __ Mov(x10, stack_limit); 1494 __ Mov(x10, stack_limit);
1495 __ Ldr(x10, MemOperand(x10)); 1495 __ Ldr(x10, MemOperand(x10));
1496 ASSERT(csp.Is(__ StackPointer())); 1496 DCHECK(csp.Is(__ StackPointer()));
1497 __ Cmp(csp, x10); 1497 __ Cmp(csp, x10);
1498 CallIf(&check_preempt_label_, ls); 1498 CallIf(&check_preempt_label_, ls);
1499 } 1499 }
1500 1500
1501 1501
1502 void RegExpMacroAssemblerARM64::CheckStackLimit() { 1502 void RegExpMacroAssemblerARM64::CheckStackLimit() {
1503 ExternalReference stack_limit = 1503 ExternalReference stack_limit =
1504 ExternalReference::address_of_regexp_stack_limit(isolate()); 1504 ExternalReference::address_of_regexp_stack_limit(isolate());
1505 __ Mov(x10, stack_limit); 1505 __ Mov(x10, stack_limit);
1506 __ Ldr(x10, MemOperand(x10)); 1506 __ Ldr(x10, MemOperand(x10));
1507 __ Cmp(backtrack_stackpointer(), x10); 1507 __ Cmp(backtrack_stackpointer(), x10);
1508 CallIf(&stack_overflow_label_, ls); 1508 CallIf(&stack_overflow_label_, ls);
1509 } 1509 }
1510 1510
1511 1511
1512 void RegExpMacroAssemblerARM64::Push(Register source) { 1512 void RegExpMacroAssemblerARM64::Push(Register source) {
1513 ASSERT(source.Is32Bits()); 1513 DCHECK(source.Is32Bits());
1514 ASSERT(!source.is(backtrack_stackpointer())); 1514 DCHECK(!source.is(backtrack_stackpointer()));
1515 __ Str(source, 1515 __ Str(source,
1516 MemOperand(backtrack_stackpointer(), 1516 MemOperand(backtrack_stackpointer(),
1517 -static_cast<int>(kWRegSize), 1517 -static_cast<int>(kWRegSize),
1518 PreIndex)); 1518 PreIndex));
1519 } 1519 }
1520 1520
1521 1521
1522 void RegExpMacroAssemblerARM64::Pop(Register target) { 1522 void RegExpMacroAssemblerARM64::Pop(Register target) {
1523 ASSERT(target.Is32Bits()); 1523 DCHECK(target.Is32Bits());
1524 ASSERT(!target.is(backtrack_stackpointer())); 1524 DCHECK(!target.is(backtrack_stackpointer()));
1525 __ Ldr(target, 1525 __ Ldr(target,
1526 MemOperand(backtrack_stackpointer(), kWRegSize, PostIndex)); 1526 MemOperand(backtrack_stackpointer(), kWRegSize, PostIndex));
1527 } 1527 }
1528 1528
1529 1529
1530 Register RegExpMacroAssemblerARM64::GetCachedRegister(int register_index) { 1530 Register RegExpMacroAssemblerARM64::GetCachedRegister(int register_index) {
1531 ASSERT(register_index < kNumCachedRegisters); 1531 DCHECK(register_index < kNumCachedRegisters);
1532 return Register::Create(register_index / 2, kXRegSizeInBits); 1532 return Register::Create(register_index / 2, kXRegSizeInBits);
1533 } 1533 }
1534 1534
1535 1535
1536 Register RegExpMacroAssemblerARM64::GetRegister(int register_index, 1536 Register RegExpMacroAssemblerARM64::GetRegister(int register_index,
1537 Register maybe_result) { 1537 Register maybe_result) {
1538 ASSERT(maybe_result.Is32Bits()); 1538 DCHECK(maybe_result.Is32Bits());
1539 ASSERT(register_index >= 0); 1539 DCHECK(register_index >= 0);
1540 if (num_registers_ <= register_index) { 1540 if (num_registers_ <= register_index) {
1541 num_registers_ = register_index + 1; 1541 num_registers_ = register_index + 1;
1542 } 1542 }
1543 Register result; 1543 Register result;
1544 RegisterState register_state = GetRegisterState(register_index); 1544 RegisterState register_state = GetRegisterState(register_index);
1545 switch (register_state) { 1545 switch (register_state) {
1546 case STACKED: 1546 case STACKED:
1547 __ Ldr(maybe_result, register_location(register_index)); 1547 __ Ldr(maybe_result, register_location(register_index));
1548 result = maybe_result; 1548 result = maybe_result;
1549 break; 1549 break;
1550 case CACHED_LSW: 1550 case CACHED_LSW:
1551 result = GetCachedRegister(register_index).W(); 1551 result = GetCachedRegister(register_index).W();
1552 break; 1552 break;
1553 case CACHED_MSW: 1553 case CACHED_MSW:
1554 __ Lsr(maybe_result.X(), GetCachedRegister(register_index), 1554 __ Lsr(maybe_result.X(), GetCachedRegister(register_index),
1555 kWRegSizeInBits); 1555 kWRegSizeInBits);
1556 result = maybe_result; 1556 result = maybe_result;
1557 break; 1557 break;
1558 default: 1558 default:
1559 UNREACHABLE(); 1559 UNREACHABLE();
1560 break; 1560 break;
1561 } 1561 }
1562 ASSERT(result.Is32Bits()); 1562 DCHECK(result.Is32Bits());
1563 return result; 1563 return result;
1564 } 1564 }
1565 1565
1566 1566
1567 void RegExpMacroAssemblerARM64::StoreRegister(int register_index, 1567 void RegExpMacroAssemblerARM64::StoreRegister(int register_index,
1568 Register source) { 1568 Register source) {
1569 ASSERT(source.Is32Bits()); 1569 DCHECK(source.Is32Bits());
1570 ASSERT(register_index >= 0); 1570 DCHECK(register_index >= 0);
1571 if (num_registers_ <= register_index) { 1571 if (num_registers_ <= register_index) {
1572 num_registers_ = register_index + 1; 1572 num_registers_ = register_index + 1;
1573 } 1573 }
1574 1574
1575 Register cached_register; 1575 Register cached_register;
1576 RegisterState register_state = GetRegisterState(register_index); 1576 RegisterState register_state = GetRegisterState(register_index);
1577 switch (register_state) { 1577 switch (register_state) {
1578 case STACKED: 1578 case STACKED:
1579 __ Str(source, register_location(register_index)); 1579 __ Str(source, register_location(register_index));
1580 break; 1580 break;
(...skipping 16 matching lines...) Expand all
1597 1597
1598 void RegExpMacroAssemblerARM64::CallIf(Label* to, Condition condition) { 1598 void RegExpMacroAssemblerARM64::CallIf(Label* to, Condition condition) {
1599 Label skip_call; 1599 Label skip_call;
1600 if (condition != al) __ B(&skip_call, NegateCondition(condition)); 1600 if (condition != al) __ B(&skip_call, NegateCondition(condition));
1601 __ Bl(to); 1601 __ Bl(to);
1602 __ Bind(&skip_call); 1602 __ Bind(&skip_call);
1603 } 1603 }
1604 1604
1605 1605
1606 void RegExpMacroAssemblerARM64::RestoreLinkRegister() { 1606 void RegExpMacroAssemblerARM64::RestoreLinkRegister() {
1607 ASSERT(csp.Is(__ StackPointer())); 1607 DCHECK(csp.Is(__ StackPointer()));
1608 __ Pop(lr, xzr); 1608 __ Pop(lr, xzr);
1609 __ Add(lr, lr, Operand(masm_->CodeObject())); 1609 __ Add(lr, lr, Operand(masm_->CodeObject()));
1610 } 1610 }
1611 1611
1612 1612
1613 void RegExpMacroAssemblerARM64::SaveLinkRegister() { 1613 void RegExpMacroAssemblerARM64::SaveLinkRegister() {
1614 ASSERT(csp.Is(__ StackPointer())); 1614 DCHECK(csp.Is(__ StackPointer()));
1615 __ Sub(lr, lr, Operand(masm_->CodeObject())); 1615 __ Sub(lr, lr, Operand(masm_->CodeObject()));
1616 __ Push(xzr, lr); 1616 __ Push(xzr, lr);
1617 } 1617 }
1618 1618
1619 1619
1620 MemOperand RegExpMacroAssemblerARM64::register_location(int register_index) { 1620 MemOperand RegExpMacroAssemblerARM64::register_location(int register_index) {
1621 ASSERT(register_index < (1<<30)); 1621 DCHECK(register_index < (1<<30));
1622 ASSERT(register_index >= kNumCachedRegisters); 1622 DCHECK(register_index >= kNumCachedRegisters);
1623 if (num_registers_ <= register_index) { 1623 if (num_registers_ <= register_index) {
1624 num_registers_ = register_index + 1; 1624 num_registers_ = register_index + 1;
1625 } 1625 }
1626 register_index -= kNumCachedRegisters; 1626 register_index -= kNumCachedRegisters;
1627 int offset = kFirstRegisterOnStack - register_index * kWRegSize; 1627 int offset = kFirstRegisterOnStack - register_index * kWRegSize;
1628 return MemOperand(frame_pointer(), offset); 1628 return MemOperand(frame_pointer(), offset);
1629 } 1629 }
1630 1630
1631 MemOperand RegExpMacroAssemblerARM64::capture_location(int register_index, 1631 MemOperand RegExpMacroAssemblerARM64::capture_location(int register_index,
1632 Register scratch) { 1632 Register scratch) {
1633 ASSERT(register_index < (1<<30)); 1633 DCHECK(register_index < (1<<30));
1634 ASSERT(register_index < num_saved_registers_); 1634 DCHECK(register_index < num_saved_registers_);
1635 ASSERT(register_index >= kNumCachedRegisters); 1635 DCHECK(register_index >= kNumCachedRegisters);
1636 ASSERT_EQ(register_index % 2, 0); 1636 DCHECK_EQ(register_index % 2, 0);
1637 register_index -= kNumCachedRegisters; 1637 register_index -= kNumCachedRegisters;
1638 int offset = kFirstCaptureOnStack - register_index * kWRegSize; 1638 int offset = kFirstCaptureOnStack - register_index * kWRegSize;
1639 // capture_location is used with Stp instructions to load/store 2 registers. 1639 // capture_location is used with Stp instructions to load/store 2 registers.
1640 // The immediate field in the encoding is limited to 7 bits (signed). 1640 // The immediate field in the encoding is limited to 7 bits (signed).
1641 if (is_int7(offset)) { 1641 if (is_int7(offset)) {
1642 return MemOperand(frame_pointer(), offset); 1642 return MemOperand(frame_pointer(), offset);
1643 } else { 1643 } else {
1644 __ Add(scratch, frame_pointer(), offset); 1644 __ Add(scratch, frame_pointer(), offset);
1645 return MemOperand(scratch); 1645 return MemOperand(scratch);
1646 } 1646 }
1647 } 1647 }
1648 1648
1649 void RegExpMacroAssemblerARM64::LoadCurrentCharacterUnchecked(int cp_offset, 1649 void RegExpMacroAssemblerARM64::LoadCurrentCharacterUnchecked(int cp_offset,
1650 int characters) { 1650 int characters) {
1651 Register offset = current_input_offset(); 1651 Register offset = current_input_offset();
1652 1652
1653 // The ldr, str, ldrh, strh instructions can do unaligned accesses, if the CPU 1653 // The ldr, str, ldrh, strh instructions can do unaligned accesses, if the CPU
1654 // and the operating system running on the target allow it. 1654 // and the operating system running on the target allow it.
1655 // If unaligned load/stores are not supported then this function must only 1655 // If unaligned load/stores are not supported then this function must only
1656 // be used to load a single character at a time. 1656 // be used to load a single character at a time.
1657 1657
1658 // ARMv8 supports unaligned accesses but V8 or the kernel can decide to 1658 // ARMv8 supports unaligned accesses but V8 or the kernel can decide to
1659 // disable it. 1659 // disable it.
1660 // TODO(pielan): See whether or not we should disable unaligned accesses. 1660 // TODO(pielan): See whether or not we should disable unaligned accesses.
1661 if (!CanReadUnaligned()) { 1661 if (!CanReadUnaligned()) {
1662 ASSERT(characters == 1); 1662 DCHECK(characters == 1);
1663 } 1663 }
1664 1664
1665 if (cp_offset != 0) { 1665 if (cp_offset != 0) {
1666 if (masm_->emit_debug_code()) { 1666 if (masm_->emit_debug_code()) {
1667 __ Mov(x10, cp_offset * char_size()); 1667 __ Mov(x10, cp_offset * char_size());
1668 __ Add(x10, x10, Operand(current_input_offset(), SXTW)); 1668 __ Add(x10, x10, Operand(current_input_offset(), SXTW));
1669 __ Cmp(x10, Operand(w10, SXTW)); 1669 __ Cmp(x10, Operand(w10, SXTW));
1670 // The offset needs to fit in a W register. 1670 // The offset needs to fit in a W register.
1671 __ Check(eq, kOffsetOutOfRange); 1671 __ Check(eq, kOffsetOutOfRange);
1672 } else { 1672 } else {
1673 __ Add(w10, current_input_offset(), cp_offset * char_size()); 1673 __ Add(w10, current_input_offset(), cp_offset * char_size());
1674 } 1674 }
1675 offset = w10; 1675 offset = w10;
1676 } 1676 }
1677 1677
1678 if (mode_ == ASCII) { 1678 if (mode_ == ASCII) {
1679 if (characters == 4) { 1679 if (characters == 4) {
1680 __ Ldr(current_character(), MemOperand(input_end(), offset, SXTW)); 1680 __ Ldr(current_character(), MemOperand(input_end(), offset, SXTW));
1681 } else if (characters == 2) { 1681 } else if (characters == 2) {
1682 __ Ldrh(current_character(), MemOperand(input_end(), offset, SXTW)); 1682 __ Ldrh(current_character(), MemOperand(input_end(), offset, SXTW));
1683 } else { 1683 } else {
1684 ASSERT(characters == 1); 1684 DCHECK(characters == 1);
1685 __ Ldrb(current_character(), MemOperand(input_end(), offset, SXTW)); 1685 __ Ldrb(current_character(), MemOperand(input_end(), offset, SXTW));
1686 } 1686 }
1687 } else { 1687 } else {
1688 ASSERT(mode_ == UC16); 1688 DCHECK(mode_ == UC16);
1689 if (characters == 2) { 1689 if (characters == 2) {
1690 __ Ldr(current_character(), MemOperand(input_end(), offset, SXTW)); 1690 __ Ldr(current_character(), MemOperand(input_end(), offset, SXTW));
1691 } else { 1691 } else {
1692 ASSERT(characters == 1); 1692 DCHECK(characters == 1);
1693 __ Ldrh(current_character(), MemOperand(input_end(), offset, SXTW)); 1693 __ Ldrh(current_character(), MemOperand(input_end(), offset, SXTW));
1694 } 1694 }
1695 } 1695 }
1696 } 1696 }
1697 1697
1698 #endif // V8_INTERPRETED_REGEXP 1698 #endif // V8_INTERPRETED_REGEXP
1699 1699
1700 }} // namespace v8::internal 1700 }} // namespace v8::internal
1701 1701
1702 #endif // V8_TARGET_ARCH_ARM64 1702 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/arm64/regexp-macro-assembler-arm64.h ('k') | src/arm64/simulator-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698