OLD | NEW |
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 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/regexp/arm64/regexp-macro-assembler-arm64.h" | 7 #include "src/regexp/arm64/regexp-macro-assembler-arm64.h" |
8 | 8 |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/log.h" | 10 #include "src/log.h" |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 } | 203 } |
204 | 204 |
205 | 205 |
206 void RegExpMacroAssemblerARM64::CheckCharacterGT(uc16 limit, | 206 void RegExpMacroAssemblerARM64::CheckCharacterGT(uc16 limit, |
207 Label* on_greater) { | 207 Label* on_greater) { |
208 CompareAndBranchOrBacktrack(current_character(), limit, hi, on_greater); | 208 CompareAndBranchOrBacktrack(current_character(), limit, hi, on_greater); |
209 } | 209 } |
210 | 210 |
211 | 211 |
212 void RegExpMacroAssemblerARM64::CheckAtStart(Label* on_at_start) { | 212 void RegExpMacroAssemblerARM64::CheckAtStart(Label* on_at_start) { |
213 Label not_at_start; | |
214 // Did we start the match at the start of the input string? | |
215 CompareAndBranchOrBacktrack(start_offset(), 0, ne, ¬_at_start); | |
216 // If we did, are we still at the start of the input string? | |
217 __ Add(x10, input_end(), Operand(current_input_offset(), SXTW)); | 213 __ Add(x10, input_end(), Operand(current_input_offset(), SXTW)); |
| 214 for (int i = 0; i < char_size(); i++) { |
| 215 __ Add(x10, x10, Operand(start_offset(), SXTW)); |
| 216 } |
218 __ Cmp(x10, input_start()); | 217 __ Cmp(x10, input_start()); |
219 BranchOrBacktrack(eq, on_at_start); | 218 BranchOrBacktrack(eq, on_at_start); |
220 __ Bind(¬_at_start); | |
221 } | 219 } |
222 | 220 |
223 | 221 |
224 void RegExpMacroAssemblerARM64::CheckNotAtStart(Label* on_not_at_start) { | 222 void RegExpMacroAssemblerARM64::CheckNotAtStart(int cp_offset, |
225 // Did we start the match at the start of the input string? | 223 Label* on_not_at_start) { |
226 CompareAndBranchOrBacktrack(start_offset(), 0, ne, on_not_at_start); | |
227 // If we did, are we still at the start of the input string? | |
228 __ Add(x10, input_end(), Operand(current_input_offset(), SXTW)); | 224 __ Add(x10, input_end(), Operand(current_input_offset(), SXTW)); |
| 225 __ Add(x10, x10, cp_offset * char_size()); |
| 226 for (int i = 0; i < char_size(); i++) { |
| 227 __ Add(x10, x10, Operand(start_offset(), SXTW)); |
| 228 } |
229 __ Cmp(x10, input_start()); | 229 __ Cmp(x10, input_start()); |
230 BranchOrBacktrack(ne, on_not_at_start); | 230 BranchOrBacktrack(ne, on_not_at_start); |
231 } | 231 } |
232 | 232 |
233 | 233 |
234 void RegExpMacroAssemblerARM64::CheckCharacterLT(uc16 limit, Label* on_less) { | 234 void RegExpMacroAssemblerARM64::CheckCharacterLT(uc16 limit, Label* on_less) { |
235 CompareAndBranchOrBacktrack(current_character(), limit, lo, on_less); | 235 CompareAndBranchOrBacktrack(current_character(), limit, lo, on_less); |
236 } | 236 } |
237 | 237 |
238 | 238 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 | 270 |
271 void RegExpMacroAssemblerARM64::CheckGreedyLoop(Label* on_equal) { | 271 void RegExpMacroAssemblerARM64::CheckGreedyLoop(Label* on_equal) { |
272 __ Ldr(w10, MemOperand(backtrack_stackpointer())); | 272 __ Ldr(w10, MemOperand(backtrack_stackpointer())); |
273 __ Cmp(current_input_offset(), w10); | 273 __ Cmp(current_input_offset(), w10); |
274 __ Cset(x11, eq); | 274 __ Cset(x11, eq); |
275 __ Add(backtrack_stackpointer(), | 275 __ Add(backtrack_stackpointer(), |
276 backtrack_stackpointer(), Operand(x11, LSL, kWRegSizeLog2)); | 276 backtrack_stackpointer(), Operand(x11, LSL, kWRegSizeLog2)); |
277 BranchOrBacktrack(eq, on_equal); | 277 BranchOrBacktrack(eq, on_equal); |
278 } | 278 } |
279 | 279 |
| 280 |
280 void RegExpMacroAssemblerARM64::CheckNotBackReferenceIgnoreCase( | 281 void RegExpMacroAssemblerARM64::CheckNotBackReferenceIgnoreCase( |
281 int start_reg, | 282 int start_reg, bool read_backward, Label* on_no_match) { |
282 Label* on_no_match) { | |
283 Label fallthrough; | 283 Label fallthrough; |
284 | 284 |
285 Register capture_start_offset = w10; | 285 Register capture_start_offset = w10; |
286 // Save the capture length in a callee-saved register so it will | 286 // Save the capture length in a callee-saved register so it will |
287 // be preserved if we call a C helper. | 287 // be preserved if we call a C helper. |
288 Register capture_length = w19; | 288 Register capture_length = w19; |
289 DCHECK(kCalleeSaved.IncludesAliasOf(capture_length)); | 289 DCHECK(kCalleeSaved.IncludesAliasOf(capture_length)); |
290 | 290 |
291 // Find length of back-referenced capture. | 291 // Find length of back-referenced capture. |
292 DCHECK((start_reg % 2) == 0); | 292 DCHECK((start_reg % 2) == 0); |
293 if (start_reg < kNumCachedRegisters) { | 293 if (start_reg < kNumCachedRegisters) { |
294 __ Mov(capture_start_offset.X(), GetCachedRegister(start_reg)); | 294 __ Mov(capture_start_offset.X(), GetCachedRegister(start_reg)); |
295 __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits); | 295 __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits); |
296 } else { | 296 } else { |
297 __ Ldp(w11, capture_start_offset, capture_location(start_reg, x10)); | 297 __ Ldp(w11, capture_start_offset, capture_location(start_reg, x10)); |
298 } | 298 } |
299 __ Sub(capture_length, w11, capture_start_offset); // Length to check. | 299 __ Sub(capture_length, w11, capture_start_offset); // Length to check. |
300 // Succeed on empty capture (including no capture). | 300 |
301 __ Cbz(capture_length, &fallthrough); | 301 // The length of the capture can only be negative if the end of the |
| 302 // capture is not yet recorded. If the length is zero, the capture is |
| 303 // either empty or uncaptured. In either of those cases, succeed. |
| 304 __ CompareAndBranch(capture_length, Operand(0), le, &fallthrough); |
302 | 305 |
303 // Check that there are enough characters left in the input. | 306 // Check that there are enough characters left in the input. |
304 __ Cmn(capture_length, current_input_offset()); | 307 if (read_backward) { |
305 BranchOrBacktrack(gt, on_no_match); | 308 __ Add(x12, input_end(), Operand(current_input_offset(), SXTW)); |
| 309 for (int i = 0; i < char_size(); i++) { |
| 310 __ Add(x12, x12, Operand(start_offset(), SXTW)); |
| 311 } |
| 312 __ Cmp(x12, input_start()); |
| 313 BranchOrBacktrack(lt, on_no_match); |
| 314 } else { |
| 315 __ Cmn(capture_length, current_input_offset()); |
| 316 BranchOrBacktrack(gt, on_no_match); |
| 317 } |
306 | 318 |
307 if (mode_ == LATIN1) { | 319 if (mode_ == LATIN1) { |
308 Label success; | 320 Label success; |
309 Label fail; | 321 Label fail; |
310 Label loop_check; | 322 Label loop_check; |
311 | 323 |
312 Register capture_start_address = x12; | 324 Register capture_start_address = x12; |
313 Register capture_end_addresss = x13; | 325 Register capture_end_addresss = x13; |
314 Register current_position_address = x14; | 326 Register current_position_address = x14; |
315 | 327 |
316 __ Add(capture_start_address, | 328 __ Add(capture_start_address, |
317 input_end(), | 329 input_end(), |
318 Operand(capture_start_offset, SXTW)); | 330 Operand(capture_start_offset, SXTW)); |
319 __ Add(capture_end_addresss, | 331 __ Add(capture_end_addresss, |
320 capture_start_address, | 332 capture_start_address, |
321 Operand(capture_length, SXTW)); | 333 Operand(capture_length, SXTW)); |
322 __ Add(current_position_address, | 334 __ Add(current_position_address, |
323 input_end(), | 335 input_end(), |
324 Operand(current_input_offset(), SXTW)); | 336 Operand(current_input_offset(), SXTW)); |
| 337 if (read_backward) { |
| 338 // Offset by length when matching backwards. |
| 339 __ Sub(current_position_address, current_position_address, |
| 340 Operand(capture_length, SXTW)); |
| 341 } |
325 | 342 |
326 Label loop; | 343 Label loop; |
327 __ Bind(&loop); | 344 __ Bind(&loop); |
328 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex)); | 345 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex)); |
329 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex)); | 346 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex)); |
330 __ Cmp(w10, w11); | 347 __ Cmp(w10, w11); |
331 __ B(eq, &loop_check); | 348 __ B(eq, &loop_check); |
332 | 349 |
333 // Mismatch, try case-insensitive match (converting letters to lower-case). | 350 // Mismatch, try case-insensitive match (converting letters to lower-case). |
334 __ Orr(w10, w10, 0x20); // Convert capture character to lower-case. | 351 __ Orr(w10, w10, 0x20); // Convert capture character to lower-case. |
(...skipping 19 matching lines...) Expand all Loading... |
354 | 371 |
355 __ Bind(&success); | 372 __ Bind(&success); |
356 // Compute new value of character position after the matched part. | 373 // Compute new value of character position after the matched part. |
357 __ Sub(current_input_offset().X(), current_position_address, input_end()); | 374 __ Sub(current_input_offset().X(), current_position_address, input_end()); |
358 if (masm_->emit_debug_code()) { | 375 if (masm_->emit_debug_code()) { |
359 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW)); | 376 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW)); |
360 __ Ccmp(current_input_offset(), 0, NoFlag, eq); | 377 __ Ccmp(current_input_offset(), 0, NoFlag, eq); |
361 // The current input offset should be <= 0, and fit in a W register. | 378 // The current input offset should be <= 0, and fit in a W register. |
362 __ Check(le, kOffsetOutOfRange); | 379 __ Check(le, kOffsetOutOfRange); |
363 } | 380 } |
| 381 if (read_backward) { |
| 382 __ Sub(current_input_offset(), current_input_offset(), |
| 383 Operand(capture_length, SXTW)); |
| 384 } |
364 } else { | 385 } else { |
365 DCHECK(mode_ == UC16); | 386 DCHECK(mode_ == UC16); |
366 int argument_count = 4; | 387 int argument_count = 4; |
367 | 388 |
368 // The cached registers need to be retained. | 389 // The cached registers need to be retained. |
369 CPURegList cached_registers(CPURegister::kRegister, kXRegSizeInBits, 0, 7); | 390 CPURegList cached_registers(CPURegister::kRegister, kXRegSizeInBits, 0, 7); |
370 DCHECK((cached_registers.Count() * 2) == kNumCachedRegisters); | 391 DCHECK((cached_registers.Count() * 2) == kNumCachedRegisters); |
371 __ PushCPURegList(cached_registers); | 392 __ PushCPURegList(cached_registers); |
372 | 393 |
373 // Put arguments into arguments registers. | 394 // Put arguments into arguments registers. |
374 // Parameters are | 395 // Parameters are |
375 // x0: Address byte_offset1 - Address captured substring's start. | 396 // x0: Address byte_offset1 - Address captured substring's start. |
376 // x1: Address byte_offset2 - Address of current character position. | 397 // x1: Address byte_offset2 - Address of current character position. |
377 // w2: size_t byte_length - length of capture in bytes(!) | 398 // w2: size_t byte_length - length of capture in bytes(!) |
378 // x3: Isolate* isolate | 399 // x3: Isolate* isolate |
379 | 400 |
380 // Address of start of capture. | 401 // Address of start of capture. |
381 __ Add(x0, input_end(), Operand(capture_start_offset, SXTW)); | 402 __ Add(x0, input_end(), Operand(capture_start_offset, SXTW)); |
382 // Length of capture. | 403 // Length of capture. |
383 __ Mov(w2, capture_length); | 404 __ Mov(w2, capture_length); |
384 // Address of current input position. | 405 // Address of current input position. |
385 __ Add(x1, input_end(), Operand(current_input_offset(), SXTW)); | 406 __ Add(x1, input_end(), Operand(current_input_offset(), SXTW)); |
| 407 if (read_backward) { |
| 408 __ Sub(x1, x1, Operand(capture_length, SXTW)); |
| 409 } |
386 // Isolate. | 410 // Isolate. |
387 __ Mov(x3, ExternalReference::isolate_address(isolate())); | 411 __ Mov(x3, ExternalReference::isolate_address(isolate())); |
388 | 412 |
389 { | 413 { |
390 AllowExternalCallThatCantCauseGC scope(masm_); | 414 AllowExternalCallThatCantCauseGC scope(masm_); |
391 ExternalReference function = | 415 ExternalReference function = |
392 ExternalReference::re_case_insensitive_compare_uc16(isolate()); | 416 ExternalReference::re_case_insensitive_compare_uc16(isolate()); |
393 __ CallCFunction(function, argument_count); | 417 __ CallCFunction(function, argument_count); |
394 } | 418 } |
395 | 419 |
396 // Check if function returned non-zero for success or zero for failure. | 420 // Check if function returned non-zero for success or zero for failure. |
397 // x0 is one of the registers used as a cache so it must be tested before | 421 // x0 is one of the registers used as a cache so it must be tested before |
398 // the cache is restored. | 422 // the cache is restored. |
399 __ Cmp(x0, 0); | 423 __ Cmp(x0, 0); |
400 __ PopCPURegList(cached_registers); | 424 __ PopCPURegList(cached_registers); |
401 BranchOrBacktrack(eq, on_no_match); | 425 BranchOrBacktrack(eq, on_no_match); |
402 | 426 |
403 // On success, increment position by length of capture. | 427 // On success, advance position by length of capture. |
404 __ Add(current_input_offset(), current_input_offset(), capture_length); | 428 if (read_backward) { |
| 429 __ Sub(current_input_offset(), current_input_offset(), capture_length); |
| 430 } else { |
| 431 __ Add(current_input_offset(), current_input_offset(), capture_length); |
| 432 } |
405 } | 433 } |
406 | 434 |
407 __ Bind(&fallthrough); | 435 __ Bind(&fallthrough); |
408 } | 436 } |
409 | 437 |
410 void RegExpMacroAssemblerARM64::CheckNotBackReference( | 438 void RegExpMacroAssemblerARM64::CheckNotBackReference(int start_reg, |
411 int start_reg, | 439 bool read_backward, |
412 Label* on_no_match) { | 440 Label* on_no_match) { |
413 Label fallthrough; | 441 Label fallthrough; |
414 | 442 |
415 Register capture_start_address = x12; | 443 Register capture_start_address = x12; |
416 Register capture_end_address = x13; | 444 Register capture_end_address = x13; |
417 Register current_position_address = x14; | 445 Register current_position_address = x14; |
418 Register capture_length = w15; | 446 Register capture_length = w15; |
419 | 447 |
420 // Find length of back-referenced capture. | 448 // Find length of back-referenced capture. |
421 DCHECK((start_reg % 2) == 0); | 449 DCHECK((start_reg % 2) == 0); |
422 if (start_reg < kNumCachedRegisters) { | 450 if (start_reg < kNumCachedRegisters) { |
423 __ Mov(x10, GetCachedRegister(start_reg)); | 451 __ Mov(x10, GetCachedRegister(start_reg)); |
424 __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits); | 452 __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits); |
425 } else { | 453 } else { |
426 __ Ldp(w11, w10, capture_location(start_reg, x10)); | 454 __ Ldp(w11, w10, capture_location(start_reg, x10)); |
427 } | 455 } |
428 __ Sub(capture_length, w11, w10); // Length to check. | 456 __ Sub(capture_length, w11, w10); // Length to check. |
429 // Succeed on empty capture (including no capture). | 457 // The length of the capture can only be negative if the end of the |
430 __ Cbz(capture_length, &fallthrough); | 458 // capture is not yet recorded. If the length is zero, the capture is |
| 459 // either empty or uncaptured. In either of those cases, succeed. |
| 460 __ CompareAndBranch(capture_length, Operand(0), le, &fallthrough); |
431 | 461 |
432 // Check that there are enough characters left in the input. | 462 // Check that there are enough characters left in the input. |
433 __ Cmn(capture_length, current_input_offset()); | 463 if (read_backward) { |
434 BranchOrBacktrack(gt, on_no_match); | 464 __ Add(x12, input_end(), Operand(current_input_offset(), SXTW)); |
| 465 for (int i = 0; i < char_size(); i++) { |
| 466 __ Add(x12, x12, Operand(start_offset(), SXTW)); |
| 467 } |
| 468 __ Cmp(x12, input_start()); |
| 469 BranchOrBacktrack(lt, on_no_match); |
| 470 } else { |
| 471 __ Cmn(capture_length, current_input_offset()); |
| 472 BranchOrBacktrack(gt, on_no_match); |
| 473 } |
435 | 474 |
436 // Compute pointers to match string and capture string | 475 // Compute pointers to match string and capture string |
437 __ Add(capture_start_address, input_end(), Operand(w10, SXTW)); | 476 __ Add(capture_start_address, input_end(), Operand(w10, SXTW)); |
438 __ Add(capture_end_address, | 477 __ Add(capture_end_address, |
439 capture_start_address, | 478 capture_start_address, |
440 Operand(capture_length, SXTW)); | 479 Operand(capture_length, SXTW)); |
441 __ Add(current_position_address, | 480 __ Add(current_position_address, |
442 input_end(), | 481 input_end(), |
443 Operand(current_input_offset(), SXTW)); | 482 Operand(current_input_offset(), SXTW)); |
| 483 if (read_backward) { |
| 484 // Offset by length when matching backwards. |
| 485 __ Sub(current_position_address, current_position_address, |
| 486 Operand(capture_length, SXTW)); |
| 487 } |
444 | 488 |
445 Label loop; | 489 Label loop; |
446 __ Bind(&loop); | 490 __ Bind(&loop); |
447 if (mode_ == LATIN1) { | 491 if (mode_ == LATIN1) { |
448 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex)); | 492 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex)); |
449 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex)); | 493 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex)); |
450 } else { | 494 } else { |
451 DCHECK(mode_ == UC16); | 495 DCHECK(mode_ == UC16); |
452 __ Ldrh(w10, MemOperand(capture_start_address, 2, PostIndex)); | 496 __ Ldrh(w10, MemOperand(capture_start_address, 2, PostIndex)); |
453 __ Ldrh(w11, MemOperand(current_position_address, 2, PostIndex)); | 497 __ Ldrh(w11, MemOperand(current_position_address, 2, PostIndex)); |
454 } | 498 } |
455 __ Cmp(w10, w11); | 499 __ Cmp(w10, w11); |
456 BranchOrBacktrack(ne, on_no_match); | 500 BranchOrBacktrack(ne, on_no_match); |
457 __ Cmp(capture_start_address, capture_end_address); | 501 __ Cmp(capture_start_address, capture_end_address); |
458 __ B(lt, &loop); | 502 __ B(lt, &loop); |
459 | 503 |
460 // Move current character position to position after match. | 504 // Move current character position to position after match. |
461 __ Sub(current_input_offset().X(), current_position_address, input_end()); | 505 __ Sub(current_input_offset().X(), current_position_address, input_end()); |
| 506 if (read_backward) { |
| 507 __ Sub(current_input_offset(), current_input_offset(), |
| 508 Operand(capture_length, SXTW)); |
| 509 } |
| 510 |
462 if (masm_->emit_debug_code()) { | 511 if (masm_->emit_debug_code()) { |
463 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW)); | 512 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW)); |
464 __ Ccmp(current_input_offset(), 0, NoFlag, eq); | 513 __ Ccmp(current_input_offset(), 0, NoFlag, eq); |
465 // The current input offset should be <= 0, and fit in a W register. | 514 // The current input offset should be <= 0, and fit in a W register. |
466 __ Check(le, kOffsetOutOfRange); | 515 __ Check(le, kOffsetOutOfRange); |
467 } | 516 } |
468 __ Bind(&fallthrough); | 517 __ Bind(&fallthrough); |
469 } | 518 } |
470 | 519 |
471 | 520 |
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 return kARM64Implementation; | 1123 return kARM64Implementation; |
1075 } | 1124 } |
1076 | 1125 |
1077 | 1126 |
1078 void RegExpMacroAssemblerARM64::LoadCurrentCharacter(int cp_offset, | 1127 void RegExpMacroAssemblerARM64::LoadCurrentCharacter(int cp_offset, |
1079 Label* on_end_of_input, | 1128 Label* on_end_of_input, |
1080 bool check_bounds, | 1129 bool check_bounds, |
1081 int characters) { | 1130 int characters) { |
1082 // TODO(pielan): Make sure long strings are caught before this, and not | 1131 // TODO(pielan): Make sure long strings are caught before this, and not |
1083 // just asserted in debug mode. | 1132 // just asserted in debug mode. |
1084 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character. | |
1085 // Be sane! (And ensure that an int32_t can be used to index the string) | 1133 // Be sane! (And ensure that an int32_t can be used to index the string) |
1086 DCHECK(cp_offset < (1<<30)); | 1134 DCHECK(cp_offset < (1<<30)); |
1087 if (check_bounds) { | 1135 if (check_bounds) { |
1088 CheckPosition(cp_offset + characters - 1, on_end_of_input); | 1136 if (cp_offset >= 0) { |
| 1137 CheckPosition(cp_offset + characters - 1, on_end_of_input); |
| 1138 } else { |
| 1139 CheckPosition(cp_offset, on_end_of_input); |
| 1140 } |
1089 } | 1141 } |
1090 LoadCurrentCharacterUnchecked(cp_offset, characters); | 1142 LoadCurrentCharacterUnchecked(cp_offset, characters); |
1091 } | 1143 } |
1092 | 1144 |
1093 | 1145 |
1094 void RegExpMacroAssemblerARM64::PopCurrentPosition() { | 1146 void RegExpMacroAssemblerARM64::PopCurrentPosition() { |
1095 Pop(current_input_offset()); | 1147 Pop(current_input_offset()); |
1096 } | 1148 } |
1097 | 1149 |
1098 | 1150 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 const byte** input_start, const byte** input_end) { | 1346 const byte** input_start, const byte** input_end) { |
1295 return NativeRegExpMacroAssembler::CheckStackGuardState( | 1347 return NativeRegExpMacroAssembler::CheckStackGuardState( |
1296 frame_entry<Isolate*>(re_frame, kIsolate), start_index, | 1348 frame_entry<Isolate*>(re_frame, kIsolate), start_index, |
1297 frame_entry<int>(re_frame, kDirectCall) == 1, return_address, re_code, | 1349 frame_entry<int>(re_frame, kDirectCall) == 1, return_address, re_code, |
1298 frame_entry_address<String*>(re_frame, kInput), input_start, input_end); | 1350 frame_entry_address<String*>(re_frame, kInput), input_start, input_end); |
1299 } | 1351 } |
1300 | 1352 |
1301 | 1353 |
1302 void RegExpMacroAssemblerARM64::CheckPosition(int cp_offset, | 1354 void RegExpMacroAssemblerARM64::CheckPosition(int cp_offset, |
1303 Label* on_outside_input) { | 1355 Label* on_outside_input) { |
1304 CompareAndBranchOrBacktrack(current_input_offset(), | 1356 if (cp_offset >= 0) { |
1305 -cp_offset * char_size(), | 1357 CompareAndBranchOrBacktrack(current_input_offset(), |
1306 ge, | 1358 -cp_offset * char_size(), ge, on_outside_input); |
1307 on_outside_input); | 1359 } else { |
| 1360 __ Add(x12, input_end(), Operand(current_input_offset(), SXTW)); |
| 1361 __ Add(x12, x12, cp_offset * char_size()); |
| 1362 for (int i = 0; i < char_size(); i++) { |
| 1363 __ Add(x12, x12, Operand(start_offset(), SXTW)); |
| 1364 } |
| 1365 __ Cmp(x12, input_start()); |
| 1366 BranchOrBacktrack(lt, on_outside_input); |
| 1367 } |
1308 } | 1368 } |
1309 | 1369 |
1310 | 1370 |
1311 bool RegExpMacroAssemblerARM64::CanReadUnaligned() { | 1371 bool RegExpMacroAssemblerARM64::CanReadUnaligned() { |
1312 // TODO(pielan): See whether or not we should disable unaligned accesses. | 1372 // TODO(pielan): See whether or not we should disable unaligned accesses. |
1313 return !slow_safe(); | 1373 return !slow_safe(); |
1314 } | 1374 } |
1315 | 1375 |
1316 | 1376 |
1317 // Private methods: | 1377 // Private methods: |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1606 } | 1666 } |
1607 } | 1667 } |
1608 } | 1668 } |
1609 | 1669 |
1610 #endif // V8_INTERPRETED_REGEXP | 1670 #endif // V8_INTERPRETED_REGEXP |
1611 | 1671 |
1612 } // namespace internal | 1672 } // namespace internal |
1613 } // namespace v8 | 1673 } // namespace v8 |
1614 | 1674 |
1615 #endif // V8_TARGET_ARCH_ARM64 | 1675 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |