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

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

Issue 1418963009: Experimental support for RegExp lookbehind. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix arm64 debug code assertion Created 5 years, 1 month 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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_ARM 5 #if V8_TARGET_ARCH_ARM
6 6
7 #include "src/regexp/arm/regexp-macro-assembler-arm.h" 7 #include "src/regexp/arm/regexp-macro-assembler-arm.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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 * - fp[32] return address (lr). 51 * - fp[32] return address (lr).
52 * - fp[28] old frame pointer (r11). 52 * - fp[28] old frame pointer (r11).
53 * - fp[0..24] backup of registers r4..r10. 53 * - fp[0..24] backup of registers r4..r10.
54 * --- frame pointer ---- 54 * --- frame pointer ----
55 * - fp[-4] end of input (address of end of string). 55 * - fp[-4] end of input (address of end of string).
56 * - fp[-8] start of input (address of first character in string). 56 * - fp[-8] start of input (address of first character in string).
57 * - fp[-12] start index (character index of start). 57 * - fp[-12] start index (character index of start).
58 * - fp[-16] void* input_string (location of a handle containing the string). 58 * - fp[-16] void* input_string (location of a handle containing the string).
59 * - fp[-20] success counter (only for global regexps to count matches). 59 * - fp[-20] success counter (only for global regexps to count matches).
60 * - fp[-24] Offset of location before start of input (effectively character 60 * - fp[-24] Offset of location before start of input (effectively character
61 * position -1). Used to initialize capture registers to a 61 * string start - 1). Used to initialize capture registers to a
62 * non-position. 62 * non-position.
63 * - fp[-28] At start (if 1, we are starting at the start of the 63 * - fp[-28] At start (if 1, we are starting at the start of the
64 * string, otherwise 0) 64 * string, otherwise 0)
65 * - fp[-32] register 0 (Only positions must be stored in the first 65 * - fp[-32] register 0 (Only positions must be stored in the first
66 * - register 1 num_saved_registers_ registers) 66 * - register 1 num_saved_registers_ registers)
67 * - ... 67 * - ...
68 * - register num_registers-1 68 * - register num_registers-1
69 * --- sp --- 69 * --- sp ---
70 * 70 *
71 * The first num_saved_registers_ registers are initialized to point to 71 * The first num_saved_registers_ registers are initialized to point to
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 } 169 }
170 170
171 171
172 void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) { 172 void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) {
173 __ cmp(current_character(), Operand(limit)); 173 __ cmp(current_character(), Operand(limit));
174 BranchOrBacktrack(gt, on_greater); 174 BranchOrBacktrack(gt, on_greater);
175 } 175 }
176 176
177 177
178 void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) { 178 void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) {
179 Label not_at_start; 179 __ ldr(r1, MemOperand(frame_pointer(), kStringStartMinusOne));
180 // Did we start the match at the start of the string at all? 180 __ add(r0, current_input_offset(), Operand(-char_size()));
181 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex));
182 __ cmp(r0, Operand::Zero());
183 BranchOrBacktrack(ne, &not_at_start);
184
185 // If we did, are we still at the start of the input?
186 __ ldr(r1, MemOperand(frame_pointer(), kInputStart));
187 __ add(r0, end_of_input_address(), Operand(current_input_offset()));
188 __ cmp(r0, r1); 181 __ cmp(r0, r1);
189 BranchOrBacktrack(eq, on_at_start); 182 BranchOrBacktrack(eq, on_at_start);
190 __ bind(&not_at_start);
191 } 183 }
192 184
193 185
194 void RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) { 186 void RegExpMacroAssemblerARM::CheckNotAtStart(int cp_offset,
195 // Did we start the match at the start of the string at all? 187 Label* on_not_at_start) {
196 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); 188 __ ldr(r1, MemOperand(frame_pointer(), kStringStartMinusOne));
197 __ cmp(r0, Operand::Zero()); 189 __ add(r0, current_input_offset(),
198 BranchOrBacktrack(ne, on_not_at_start); 190 Operand(-char_size() + cp_offset * char_size()));
199 // If we did, are we still at the start of the input?
200 __ ldr(r1, MemOperand(frame_pointer(), kInputStart));
201 __ add(r0, end_of_input_address(), Operand(current_input_offset()));
202 __ cmp(r0, r1); 191 __ cmp(r0, r1);
203 BranchOrBacktrack(ne, on_not_at_start); 192 BranchOrBacktrack(ne, on_not_at_start);
204 } 193 }
205 194
206 195
207 void RegExpMacroAssemblerARM::CheckCharacterLT(uc16 limit, Label* on_less) { 196 void RegExpMacroAssemblerARM::CheckCharacterLT(uc16 limit, Label* on_less) {
208 __ cmp(current_character(), Operand(limit)); 197 __ cmp(current_character(), Operand(limit));
209 BranchOrBacktrack(lt, on_less); 198 BranchOrBacktrack(lt, on_less);
210 } 199 }
211 200
212 201
213 void RegExpMacroAssemblerARM::CheckGreedyLoop(Label* on_equal) { 202 void RegExpMacroAssemblerARM::CheckGreedyLoop(Label* on_equal) {
214 __ ldr(r0, MemOperand(backtrack_stackpointer(), 0)); 203 __ ldr(r0, MemOperand(backtrack_stackpointer(), 0));
215 __ cmp(current_input_offset(), r0); 204 __ cmp(current_input_offset(), r0);
216 __ add(backtrack_stackpointer(), 205 __ add(backtrack_stackpointer(),
217 backtrack_stackpointer(), Operand(kPointerSize), LeaveCC, eq); 206 backtrack_stackpointer(), Operand(kPointerSize), LeaveCC, eq);
218 BranchOrBacktrack(eq, on_equal); 207 BranchOrBacktrack(eq, on_equal);
219 } 208 }
220 209
221 210
222 void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase( 211 void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase(
223 int start_reg, 212 int start_reg, bool read_backward, Label* on_no_match) {
224 Label* on_no_match) {
225 Label fallthrough; 213 Label fallthrough;
226 __ ldr(r0, register_location(start_reg)); // Index of start of capture 214 __ ldr(r0, register_location(start_reg)); // Index of start of capture
227 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture 215 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture
228 __ sub(r1, r1, r0, SetCC); // Length of capture. 216 __ sub(r1, r1, r0, SetCC); // Length of capture.
229 217
230 // If length is zero, either the capture is empty or it is not participating. 218 // At this point, the capture registers are either both set or both cleared.
231 // In either case succeed immediately. 219 // If the capture length is zero, then the capture is either empty or cleared.
220 // Fall through in both cases.
232 __ b(eq, &fallthrough); 221 __ b(eq, &fallthrough);
233 222
234 // Check that there are enough characters left in the input. 223 // Check that there are enough characters left in the input.
235 __ cmn(r1, Operand(current_input_offset())); 224 if (read_backward) {
236 BranchOrBacktrack(gt, on_no_match); 225 __ ldr(r3, MemOperand(frame_pointer(), kStringStartMinusOne));
226 __ add(r3, r3, r1);
227 __ cmp(current_input_offset(), r3);
228 BranchOrBacktrack(le, on_no_match);
229 } else {
230 __ cmn(r1, Operand(current_input_offset()));
231 BranchOrBacktrack(gt, on_no_match);
232 }
237 233
238 if (mode_ == LATIN1) { 234 if (mode_ == LATIN1) {
239 Label success; 235 Label success;
240 Label fail; 236 Label fail;
241 Label loop_check; 237 Label loop_check;
242 238
243 // r0 - offset of start of capture 239 // r0 - offset of start of capture
244 // r1 - length of capture 240 // r1 - length of capture
245 __ add(r0, r0, Operand(end_of_input_address())); 241 __ add(r0, r0, end_of_input_address());
246 __ add(r2, end_of_input_address(), Operand(current_input_offset())); 242 __ add(r2, end_of_input_address(), current_input_offset());
247 __ add(r1, r0, Operand(r1)); 243 if (read_backward) {
244 __ sub(r2, r2, r1); // Offset by length when matching backwards.
245 }
246 __ add(r1, r0, r1);
248 247
249 // r0 - Address of start of capture. 248 // r0 - Address of start of capture.
250 // r1 - Address of end of capture 249 // r1 - Address of end of capture
251 // r2 - Address of current input position. 250 // r2 - Address of current input position.
252 251
253 Label loop; 252 Label loop;
254 __ bind(&loop); 253 __ bind(&loop);
255 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); 254 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex));
256 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); 255 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex));
257 __ cmp(r4, r3); 256 __ cmp(r4, r3);
(...skipping 18 matching lines...) Expand all
276 __ cmp(r0, r1); 275 __ cmp(r0, r1);
277 __ b(lt, &loop); 276 __ b(lt, &loop);
278 __ jmp(&success); 277 __ jmp(&success);
279 278
280 __ bind(&fail); 279 __ bind(&fail);
281 BranchOrBacktrack(al, on_no_match); 280 BranchOrBacktrack(al, on_no_match);
282 281
283 __ bind(&success); 282 __ bind(&success);
284 // Compute new value of character position after the matched part. 283 // Compute new value of character position after the matched part.
285 __ sub(current_input_offset(), r2, end_of_input_address()); 284 __ sub(current_input_offset(), r2, end_of_input_address());
285 if (read_backward) {
286 __ ldr(r0, register_location(start_reg)); // Index of start of capture
287 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture
288 __ add(current_input_offset(), current_input_offset(), r0);
289 __ sub(current_input_offset(), current_input_offset(), r1);
290 }
286 } else { 291 } else {
287 DCHECK(mode_ == UC16); 292 DCHECK(mode_ == UC16);
288 int argument_count = 4; 293 int argument_count = 4;
289 __ PrepareCallCFunction(argument_count, r2); 294 __ PrepareCallCFunction(argument_count, r2);
290 295
291 // r0 - offset of start of capture 296 // r0 - offset of start of capture
292 // r1 - length of capture 297 // r1 - length of capture
293 298
294 // Put arguments into arguments registers. 299 // Put arguments into arguments registers.
295 // Parameters are 300 // Parameters are
296 // r0: Address byte_offset1 - Address captured substring's start. 301 // r0: Address byte_offset1 - Address captured substring's start.
297 // r1: Address byte_offset2 - Address of current character position. 302 // r1: Address byte_offset2 - Address of current character position.
298 // r2: size_t byte_length - length of capture in bytes(!) 303 // r2: size_t byte_length - length of capture in bytes(!)
299 // r3: Isolate* isolate 304 // r3: Isolate* isolate
300 305
301 // Address of start of capture. 306 // Address of start of capture.
302 __ add(r0, r0, Operand(end_of_input_address())); 307 __ add(r0, r0, Operand(end_of_input_address()));
303 // Length of capture. 308 // Length of capture.
304 __ mov(r2, Operand(r1)); 309 __ mov(r2, Operand(r1));
305 // Save length in callee-save register for use on return. 310 // Save length in callee-save register for use on return.
306 __ mov(r4, Operand(r1)); 311 __ mov(r4, Operand(r1));
307 // Address of current input position. 312 // Address of current input position.
308 __ add(r1, current_input_offset(), Operand(end_of_input_address())); 313 __ add(r1, current_input_offset(), end_of_input_address());
314 if (read_backward) {
315 __ sub(r1, r1, r4);
316 }
309 // Isolate. 317 // Isolate.
310 __ mov(r3, Operand(ExternalReference::isolate_address(isolate()))); 318 __ mov(r3, Operand(ExternalReference::isolate_address(isolate())));
311 319
312 { 320 {
313 AllowExternalCallThatCantCauseGC scope(masm_); 321 AllowExternalCallThatCantCauseGC scope(masm_);
314 ExternalReference function = 322 ExternalReference function =
315 ExternalReference::re_case_insensitive_compare_uc16(isolate()); 323 ExternalReference::re_case_insensitive_compare_uc16(isolate());
316 __ CallCFunction(function, argument_count); 324 __ CallCFunction(function, argument_count);
317 } 325 }
318 326
319 // Check if function returned non-zero for success or zero for failure. 327 // Check if function returned non-zero for success or zero for failure.
320 __ cmp(r0, Operand::Zero()); 328 __ cmp(r0, Operand::Zero());
321 BranchOrBacktrack(eq, on_no_match); 329 BranchOrBacktrack(eq, on_no_match);
322 // On success, increment position by length of capture. 330
323 __ add(current_input_offset(), current_input_offset(), Operand(r4)); 331 // On success, advance position by length of capture.
332 if (read_backward) {
333 __ sub(current_input_offset(), current_input_offset(), r4);
334 } else {
335 __ add(current_input_offset(), current_input_offset(), r4);
336 }
324 } 337 }
325 338
326 __ bind(&fallthrough); 339 __ bind(&fallthrough);
327 } 340 }
328 341
329 342
330 void RegExpMacroAssemblerARM::CheckNotBackReference( 343 void RegExpMacroAssemblerARM::CheckNotBackReference(int start_reg,
331 int start_reg, 344 bool read_backward,
332 Label* on_no_match) { 345 Label* on_no_match) {
333 Label fallthrough; 346 Label fallthrough;
334 Label success; 347 Label success;
335 348
336 // Find length of back-referenced capture. 349 // Find length of back-referenced capture.
337 __ ldr(r0, register_location(start_reg)); 350 __ ldr(r0, register_location(start_reg));
338 __ ldr(r1, register_location(start_reg + 1)); 351 __ ldr(r1, register_location(start_reg + 1));
339 __ sub(r1, r1, r0, SetCC); // Length to check. 352 __ sub(r1, r1, r0, SetCC); // Length to check.
340 // Succeed on empty capture (including no capture). 353
354 // At this point, the capture registers are either both set or both cleared.
355 // If the capture length is zero, then the capture is either empty or cleared.
356 // Fall through in both cases.
341 __ b(eq, &fallthrough); 357 __ b(eq, &fallthrough);
342 358
343 // Check that there are enough characters left in the input. 359 // Check that there are enough characters left in the input.
344 __ cmn(r1, Operand(current_input_offset())); 360 if (read_backward) {
345 BranchOrBacktrack(gt, on_no_match); 361 __ ldr(r3, MemOperand(frame_pointer(), kStringStartMinusOne));
362 __ add(r3, r3, r1);
363 __ cmp(current_input_offset(), r3);
364 BranchOrBacktrack(lt, on_no_match);
365 } else {
366 __ cmn(r1, Operand(current_input_offset()));
367 BranchOrBacktrack(gt, on_no_match);
368 }
346 369
347 // Compute pointers to match string and capture string 370 // r0 - offset of start of capture
348 __ add(r0, r0, Operand(end_of_input_address())); 371 // r1 - length of capture
349 __ add(r2, end_of_input_address(), Operand(current_input_offset())); 372 __ add(r0, r0, end_of_input_address());
350 __ add(r1, r1, Operand(r0)); 373 __ add(r2, end_of_input_address(), current_input_offset());
374 if (read_backward) {
375 __ sub(r2, r2, r1); // Offset by length when matching backwards.
376 }
377 __ add(r1, r0, r1);
351 378
352 Label loop; 379 Label loop;
353 __ bind(&loop); 380 __ bind(&loop);
354 if (mode_ == LATIN1) { 381 if (mode_ == LATIN1) {
355 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); 382 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex));
356 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); 383 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex));
357 } else { 384 } else {
358 DCHECK(mode_ == UC16); 385 DCHECK(mode_ == UC16);
359 __ ldrh(r3, MemOperand(r0, char_size(), PostIndex)); 386 __ ldrh(r3, MemOperand(r0, char_size(), PostIndex));
360 __ ldrh(r4, MemOperand(r2, char_size(), PostIndex)); 387 __ ldrh(r4, MemOperand(r2, char_size(), PostIndex));
361 } 388 }
362 __ cmp(r3, r4); 389 __ cmp(r3, r4);
363 BranchOrBacktrack(ne, on_no_match); 390 BranchOrBacktrack(ne, on_no_match);
364 __ cmp(r0, r1); 391 __ cmp(r0, r1);
365 __ b(lt, &loop); 392 __ b(lt, &loop);
366 393
367 // Move current character position to position after match. 394 // Move current character position to position after match.
368 __ sub(current_input_offset(), r2, end_of_input_address()); 395 __ sub(current_input_offset(), r2, end_of_input_address());
396 if (read_backward) {
397 __ ldr(r0, register_location(start_reg)); // Index of start of capture
398 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture
399 __ add(current_input_offset(), current_input_offset(), r0);
400 __ sub(current_input_offset(), current_input_offset(), r1);
401 }
402
369 __ bind(&fallthrough); 403 __ bind(&fallthrough);
370 } 404 }
371 405
372 406
373 void RegExpMacroAssemblerARM::CheckNotCharacter(unsigned c, 407 void RegExpMacroAssemblerARM::CheckNotCharacter(unsigned c,
374 Label* on_not_equal) { 408 Label* on_not_equal) {
375 __ cmp(current_character(), Operand(c)); 409 __ cmp(current_character(), Operand(c));
376 BranchOrBacktrack(ne, on_not_equal); 410 BranchOrBacktrack(ne, on_not_equal);
377 } 411 }
378 412
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 // Order here should correspond to order of offset constants in header file. 630 // Order here should correspond to order of offset constants in header file.
597 RegList registers_to_retain = r4.bit() | r5.bit() | r6.bit() | 631 RegList registers_to_retain = r4.bit() | r5.bit() | r6.bit() |
598 r7.bit() | r8.bit() | r9.bit() | r10.bit() | fp.bit(); 632 r7.bit() | r8.bit() | r9.bit() | r10.bit() | fp.bit();
599 RegList argument_registers = r0.bit() | r1.bit() | r2.bit() | r3.bit(); 633 RegList argument_registers = r0.bit() | r1.bit() | r2.bit() | r3.bit();
600 __ stm(db_w, sp, argument_registers | registers_to_retain | lr.bit()); 634 __ stm(db_w, sp, argument_registers | registers_to_retain | lr.bit());
601 // Set frame pointer in space for it if this is not a direct call 635 // Set frame pointer in space for it if this is not a direct call
602 // from generated code. 636 // from generated code.
603 __ add(frame_pointer(), sp, Operand(4 * kPointerSize)); 637 __ add(frame_pointer(), sp, Operand(4 * kPointerSize));
604 __ mov(r0, Operand::Zero()); 638 __ mov(r0, Operand::Zero());
605 __ push(r0); // Make room for success counter and initialize it to 0. 639 __ push(r0); // Make room for success counter and initialize it to 0.
606 __ push(r0); // Make room for "position - 1" constant (value is irrelevant). 640 __ push(r0); // Make room for "string start - 1" constant.
607 // Check if we have space on the stack for registers. 641 // Check if we have space on the stack for registers.
608 Label stack_limit_hit; 642 Label stack_limit_hit;
609 Label stack_ok; 643 Label stack_ok;
610 644
611 ExternalReference stack_limit = 645 ExternalReference stack_limit =
612 ExternalReference::address_of_stack_limit(isolate()); 646 ExternalReference::address_of_stack_limit(isolate());
613 __ mov(r0, Operand(stack_limit)); 647 __ mov(r0, Operand(stack_limit));
614 __ ldr(r0, MemOperand(r0)); 648 __ ldr(r0, MemOperand(r0));
615 __ sub(r0, sp, r0, SetCC); 649 __ sub(r0, sp, r0, SetCC);
616 // Handle it if the stack pointer is already below the stack limit. 650 // Handle it if the stack pointer is already below the stack limit.
(...skipping 23 matching lines...) Expand all
640 __ ldr(r0, MemOperand(frame_pointer(), kInputStart)); 674 __ ldr(r0, MemOperand(frame_pointer(), kInputStart));
641 // Find negative length (offset of start relative to end). 675 // Find negative length (offset of start relative to end).
642 __ sub(current_input_offset(), r0, end_of_input_address()); 676 __ sub(current_input_offset(), r0, end_of_input_address());
643 // Set r0 to address of char before start of the input string 677 // Set r0 to address of char before start of the input string
644 // (effectively string position -1). 678 // (effectively string position -1).
645 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); 679 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex));
646 __ sub(r0, current_input_offset(), Operand(char_size())); 680 __ sub(r0, current_input_offset(), Operand(char_size()));
647 __ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0)); 681 __ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0));
648 // Store this value in a local variable, for use when clearing 682 // Store this value in a local variable, for use when clearing
649 // position registers. 683 // position registers.
650 __ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); 684 __ str(r0, MemOperand(frame_pointer(), kStringStartMinusOne));
651 685
652 // Initialize code pointer register 686 // Initialize code pointer register
653 __ mov(code_pointer(), Operand(masm_->CodeObject())); 687 __ mov(code_pointer(), Operand(masm_->CodeObject()));
654 688
655 Label load_char_start_regexp, start_regexp; 689 Label load_char_start_regexp, start_regexp;
656 // Load newline if index is at start, previous character otherwise. 690 // Load newline if index is at start, previous character otherwise.
657 __ cmp(r1, Operand::Zero()); 691 __ cmp(r1, Operand::Zero());
658 __ b(ne, &load_char_start_regexp); 692 __ b(ne, &load_char_start_regexp);
659 __ mov(current_character(), Operand('\n'), LeaveCC, eq); 693 __ mov(current_character(), Operand('\n'), LeaveCC, eq);
660 __ jmp(&start_regexp); 694 __ jmp(&start_regexp);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 // Check whether we have enough room for another set of capture results. 778 // Check whether we have enough room for another set of capture results.
745 __ cmp(r1, Operand(num_saved_registers_)); 779 __ cmp(r1, Operand(num_saved_registers_));
746 __ b(lt, &return_r0); 780 __ b(lt, &return_r0);
747 781
748 __ str(r1, MemOperand(frame_pointer(), kNumOutputRegisters)); 782 __ str(r1, MemOperand(frame_pointer(), kNumOutputRegisters));
749 // Advance the location for output. 783 // Advance the location for output.
750 __ add(r2, r2, Operand(num_saved_registers_ * kPointerSize)); 784 __ add(r2, r2, Operand(num_saved_registers_ * kPointerSize));
751 __ str(r2, MemOperand(frame_pointer(), kRegisterOutput)); 785 __ str(r2, MemOperand(frame_pointer(), kRegisterOutput));
752 786
753 // Prepare r0 to initialize registers with its value in the next run. 787 // Prepare r0 to initialize registers with its value in the next run.
754 __ ldr(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); 788 __ ldr(r0, MemOperand(frame_pointer(), kStringStartMinusOne));
755 789
756 if (global_with_zero_length_check()) { 790 if (global_with_zero_length_check()) {
757 // Special case for zero-length matches. 791 // Special case for zero-length matches.
758 // r4: capture start index 792 // r4: capture start index
759 __ cmp(current_input_offset(), r4); 793 __ cmp(current_input_offset(), r4);
760 // Not a zero-length match, restart. 794 // Not a zero-length match, restart.
761 __ b(ne, &load_char_start_regexp); 795 __ b(ne, &load_char_start_regexp);
762 // Offset from the end is zero if we already reached the end. 796 // Offset from the end is zero if we already reached the end.
763 __ cmp(current_input_offset(), Operand::Zero()); 797 __ cmp(current_input_offset(), Operand::Zero());
764 __ b(eq, &exit_label_); 798 __ b(eq, &exit_label_);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 RegExpMacroAssembler::IrregexpImplementation 919 RegExpMacroAssembler::IrregexpImplementation
886 RegExpMacroAssemblerARM::Implementation() { 920 RegExpMacroAssemblerARM::Implementation() {
887 return kARMImplementation; 921 return kARMImplementation;
888 } 922 }
889 923
890 924
891 void RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset, 925 void RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset,
892 Label* on_end_of_input, 926 Label* on_end_of_input,
893 bool check_bounds, 927 bool check_bounds,
894 int characters) { 928 int characters) {
895 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character.
896 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) 929 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works)
897 if (check_bounds) { 930 if (check_bounds) {
898 CheckPosition(cp_offset + characters - 1, on_end_of_input); 931 if (cp_offset >= 0) {
932 CheckPosition(cp_offset + characters - 1, on_end_of_input);
933 } else {
934 CheckPosition(cp_offset, on_end_of_input);
935 }
899 } 936 }
900 LoadCurrentCharacterUnchecked(cp_offset, characters); 937 LoadCurrentCharacterUnchecked(cp_offset, characters);
901 } 938 }
902 939
903 940
904 void RegExpMacroAssemblerARM::PopCurrentPosition() { 941 void RegExpMacroAssemblerARM::PopCurrentPosition() {
905 Pop(current_input_offset()); 942 Pop(current_input_offset());
906 } 943 }
907 944
908 945
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 __ str(current_input_offset(), register_location(reg)); 1013 __ str(current_input_offset(), register_location(reg));
977 } else { 1014 } else {
978 __ add(r0, current_input_offset(), Operand(cp_offset * char_size())); 1015 __ add(r0, current_input_offset(), Operand(cp_offset * char_size()));
979 __ str(r0, register_location(reg)); 1016 __ str(r0, register_location(reg));
980 } 1017 }
981 } 1018 }
982 1019
983 1020
984 void RegExpMacroAssemblerARM::ClearRegisters(int reg_from, int reg_to) { 1021 void RegExpMacroAssemblerARM::ClearRegisters(int reg_from, int reg_to) {
985 DCHECK(reg_from <= reg_to); 1022 DCHECK(reg_from <= reg_to);
986 __ ldr(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); 1023 __ ldr(r0, MemOperand(frame_pointer(), kStringStartMinusOne));
987 for (int reg = reg_from; reg <= reg_to; reg++) { 1024 for (int reg = reg_from; reg <= reg_to; reg++) {
988 __ str(r0, register_location(reg)); 1025 __ str(r0, register_location(reg));
989 } 1026 }
990 } 1027 }
991 1028
992 1029
993 void RegExpMacroAssemblerARM::WriteStackPointerToRegister(int reg) { 1030 void RegExpMacroAssemblerARM::WriteStackPointerToRegister(int reg) {
994 __ ldr(r1, MemOperand(frame_pointer(), kStackHighEnd)); 1031 __ ldr(r1, MemOperand(frame_pointer(), kStackHighEnd));
995 __ sub(r0, backtrack_stackpointer(), r1); 1032 __ sub(r0, backtrack_stackpointer(), r1);
996 __ str(r0, register_location(reg)); 1033 __ str(r0, register_location(reg));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 if (num_registers_ <= register_index) { 1099 if (num_registers_ <= register_index) {
1063 num_registers_ = register_index + 1; 1100 num_registers_ = register_index + 1;
1064 } 1101 }
1065 return MemOperand(frame_pointer(), 1102 return MemOperand(frame_pointer(),
1066 kRegisterZero - register_index * kPointerSize); 1103 kRegisterZero - register_index * kPointerSize);
1067 } 1104 }
1068 1105
1069 1106
1070 void RegExpMacroAssemblerARM::CheckPosition(int cp_offset, 1107 void RegExpMacroAssemblerARM::CheckPosition(int cp_offset,
1071 Label* on_outside_input) { 1108 Label* on_outside_input) {
1072 __ cmp(current_input_offset(), Operand(-cp_offset * char_size())); 1109 if (cp_offset >= 0) {
1073 BranchOrBacktrack(ge, on_outside_input); 1110 __ cmp(current_input_offset(), Operand(-cp_offset * char_size()));
1111 BranchOrBacktrack(ge, on_outside_input);
1112 } else {
1113 __ ldr(r1, MemOperand(frame_pointer(), kStringStartMinusOne));
1114 __ add(r0, current_input_offset(), Operand(cp_offset * char_size()));
1115 __ cmp(r0, r1);
1116 BranchOrBacktrack(le, on_outside_input);
1117 }
1074 } 1118 }
1075 1119
1076 1120
1077 void RegExpMacroAssemblerARM::BranchOrBacktrack(Condition condition, 1121 void RegExpMacroAssemblerARM::BranchOrBacktrack(Condition condition,
1078 Label* to) { 1122 Label* to) {
1079 if (condition == al) { // Unconditional. 1123 if (condition == al) { // Unconditional.
1080 if (to == NULL) { 1124 if (to == NULL) {
1081 Backtrack(); 1125 Backtrack();
1082 return; 1126 return;
1083 } 1127 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 1232
1189 1233
1190 #undef __ 1234 #undef __
1191 1235
1192 #endif // V8_INTERPRETED_REGEXP 1236 #endif // V8_INTERPRETED_REGEXP
1193 1237
1194 } // namespace internal 1238 } // namespace internal
1195 } // namespace v8 1239 } // namespace v8
1196 1240
1197 #endif // V8_TARGET_ARCH_ARM 1241 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/regexp/arm/regexp-macro-assembler-arm.h ('k') | src/regexp/arm64/regexp-macro-assembler-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698