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

Side by Side Diff: src/regexp/mips64/regexp-macro-assembler-mips64.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
« no previous file with comments | « src/regexp/mips64/regexp-macro-assembler-mips64.h ('k') | src/regexp/regexp-macro-assembler.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 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_MIPS64 5 #if V8_TARGET_ARCH_MIPS64
6 6
7 #include "src/regexp/mips64/regexp-macro-assembler-mips64.h" 7 #include "src/regexp/mips64/regexp-macro-assembler-mips64.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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 * - fp[36] return address (lr). 54 * - fp[36] return address (lr).
55 * - fp[32] old frame pointer (r11). 55 * - fp[32] old frame pointer (r11).
56 * - fp[0..31] backup of registers s0..s7. 56 * - fp[0..31] backup of registers s0..s7.
57 * --- frame pointer ---- 57 * --- frame pointer ----
58 * - fp[-4] end of input (address of end of string). 58 * - fp[-4] end of input (address of end of string).
59 * - fp[-8] start of input (address of first character in string). 59 * - fp[-8] start of input (address of first character in string).
60 * - fp[-12] start index (character index of start). 60 * - fp[-12] start index (character index of start).
61 * - fp[-16] void* input_string (location of a handle containing the string). 61 * - fp[-16] void* input_string (location of a handle containing the string).
62 * - fp[-20] success counter (only for global regexps to count matches). 62 * - fp[-20] success counter (only for global regexps to count matches).
63 * - fp[-24] Offset of location before start of input (effectively character 63 * - fp[-24] Offset of location before start of input (effectively character
64 * position -1). Used to initialize capture registers to a 64 * string start - 1). Used to initialize capture registers to a
65 * non-position. 65 * non-position.
66 * - fp[-28] At start (if 1, we are starting at the start of the 66 * - fp[-28] At start (if 1, we are starting at the start of the
67 * string, otherwise 0) 67 * string, otherwise 0)
68 * - fp[-32] register 0 (Only positions must be stored in the first 68 * - fp[-32] register 0 (Only positions must be stored in the first
69 * - register 1 num_saved_registers_ registers) 69 * - register 1 num_saved_registers_ registers)
70 * - ... 70 * - ...
71 * - register num_registers-1 71 * - register num_registers-1
72 * --- sp --- 72 * --- sp ---
73 * 73 *
74 * 74 *
75 * The N64 stack will have the following structure: 75 * The N64 stack will have the following structure:
76 * 76 *
77 * - fp[88] Isolate* isolate (address of the current isolate) kIsolate 77 * - fp[88] Isolate* isolate (address of the current isolate) kIsolate
78 * - fp[80] secondary link/return address used by exit frame on native call. kSecondaryReturnAddress 78 * - fp[80] secondary link/return address used by exit frame on native call. kSecondaryReturnAddress
79 kStackFrameHeader 79 kStackFrameHeader
80 * --- sp when called --- 80 * --- sp when called ---
81 * - fp[72] ra Return from RegExp code (ra). kReturnAddress 81 * - fp[72] ra Return from RegExp code (ra). kReturnAddress
82 * - fp[64] s9, old-fp Old fp, callee saved(s9). 82 * - fp[64] s9, old-fp Old fp, callee saved(s9).
83 * - fp[0..63] s0..s7 Callee-saved registers s0..s7. 83 * - fp[0..63] s0..s7 Callee-saved registers s0..s7.
84 * --- frame pointer ---- 84 * --- frame pointer ----
85 * - fp[-8] direct_call (1 = direct call from JS, 0 = from runtime) kDirectCall 85 * - fp[-8] direct_call (1 = direct call from JS, 0 = from runtime) kDirectCall
86 * - fp[-16] stack_base (Top of backtracking stack). kStackHighEnd 86 * - fp[-16] stack_base (Top of backtracking stack). kStackHighEnd
87 * - fp[-24] capture array size (may fit multiple sets of matches) kNumOutputRegisters 87 * - fp[-24] capture array size (may fit multiple sets of matches) kNumOutputRegisters
88 * - fp[-32] int* capture_array (int[num_saved_registers_], for output). kRegisterOutput 88 * - fp[-32] int* capture_array (int[num_saved_registers_], for output). kRegisterOutput
89 * - fp[-40] end of input (address of end of string). kInputEnd 89 * - fp[-40] end of input (address of end of string). kInputEnd
90 * - fp[-48] start of input (address of first character in string). kInputStart 90 * - fp[-48] start of input (address of first character in string). kInputStart
91 * - fp[-56] start index (character index of start). kStartIndex 91 * - fp[-56] start index (character index of start). kStartIndex
92 * - fp[-64] void* input_string (location of a handle containing the string). kInputString 92 * - fp[-64] void* input_string (location of a handle containing the string). kInputString
93 * - fp[-72] success counter (only for global regexps to count matches). kSuccessfulCaptures 93 * - fp[-72] success counter (only for global regexps to count matches). kSuccessfulCaptures
94 * - fp[-80] Offset of location before start of input (effectively character kInputStartMinusOne 94 * - fp[-80] Offset of location before start of input (effectively character kStringStartMinusOne
95 * position -1). Used to initialize capture registers to a 95 * position -1). Used to initialize capture registers to a
96 * non-position. 96 * non-position.
97 * --------- The following output registers are 32-bit values. --------- 97 * --------- The following output registers are 32-bit values. ---------
98 * - fp[-88] register 0 (Only positions must be stored in the first kRegisterZero 98 * - fp[-88] register 0 (Only positions must be stored in the first kRegisterZero
99 * - register 1 num_saved_registers_ registers) 99 * - register 1 num_saved_registers_ registers)
100 * - ... 100 * - ...
101 * - register num_registers-1 101 * - register num_registers-1
102 * --- sp --- 102 * --- sp ---
103 * 103 *
104 * The first num_saved_registers_ registers are initialized to point to 104 * The first num_saved_registers_ registers are initialized to point to
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 BranchOrBacktrack(on_equal, eq, current_character(), Operand(c)); 210 BranchOrBacktrack(on_equal, eq, current_character(), Operand(c));
211 } 211 }
212 212
213 213
214 void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) { 214 void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) {
215 BranchOrBacktrack(on_greater, gt, current_character(), Operand(limit)); 215 BranchOrBacktrack(on_greater, gt, current_character(), Operand(limit));
216 } 216 }
217 217
218 218
219 void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) { 219 void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
220 Label not_at_start; 220 __ ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne));
221 // Did we start the match at the start of the string at all? 221 __ Daddu(a0, current_input_offset(), Operand(-char_size()));
222 __ ld(a0, MemOperand(frame_pointer(), kStartIndex));
223 BranchOrBacktrack(&not_at_start, ne, a0, Operand(zero_reg));
224
225 // If we did, are we still at the start of the input?
226 __ ld(a1, MemOperand(frame_pointer(), kInputStart));
227 __ Daddu(a0, end_of_input_address(), Operand(current_input_offset()));
228 BranchOrBacktrack(on_at_start, eq, a0, Operand(a1)); 222 BranchOrBacktrack(on_at_start, eq, a0, Operand(a1));
229 __ bind(&not_at_start);
230 } 223 }
231 224
232 225
233 void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) { 226 void RegExpMacroAssemblerMIPS::CheckNotAtStart(int cp_offset,
234 // Did we start the match at the start of the string at all? 227 Label* on_not_at_start) {
235 __ ld(a0, MemOperand(frame_pointer(), kStartIndex)); 228 __ ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne));
236 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(zero_reg)); 229 __ Daddu(a0, current_input_offset(),
237 // If we did, are we still at the start of the input? 230 Operand(-char_size() + cp_offset * char_size()));
238 __ ld(a1, MemOperand(frame_pointer(), kInputStart));
239 __ Daddu(a0, end_of_input_address(), Operand(current_input_offset()));
240 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(a1)); 231 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(a1));
241 } 232 }
242 233
243 234
244 void RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) { 235 void RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) {
245 BranchOrBacktrack(on_less, lt, current_character(), Operand(limit)); 236 BranchOrBacktrack(on_less, lt, current_character(), Operand(limit));
246 } 237 }
247 238
248 239
249 void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) { 240 void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) {
250 Label backtrack_non_equal; 241 Label backtrack_non_equal;
251 __ lw(a0, MemOperand(backtrack_stackpointer(), 0)); 242 __ lw(a0, MemOperand(backtrack_stackpointer(), 0));
252 __ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0)); 243 __ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0));
253 __ Daddu(backtrack_stackpointer(), 244 __ Daddu(backtrack_stackpointer(),
254 backtrack_stackpointer(), 245 backtrack_stackpointer(),
255 Operand(kIntSize)); 246 Operand(kIntSize));
256 __ bind(&backtrack_non_equal); 247 __ bind(&backtrack_non_equal);
257 BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0)); 248 BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0));
258 } 249 }
259 250
260 251
261 void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( 252 void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
262 int start_reg, 253 int start_reg, bool read_backward, Label* on_no_match) {
263 Label* on_no_match) {
264 Label fallthrough; 254 Label fallthrough;
265 __ ld(a0, register_location(start_reg)); // Index of start of capture. 255 __ ld(a0, register_location(start_reg)); // Index of start of capture.
266 __ ld(a1, register_location(start_reg + 1)); // Index of end of capture. 256 __ ld(a1, register_location(start_reg + 1)); // Index of end of capture.
267 __ Dsubu(a1, a1, a0); // Length of capture. 257 __ Dsubu(a1, a1, a0); // Length of capture.
268 258
269 // If length is zero, either the capture is empty or it is not participating. 259 // At this point, the capture registers are either both set or both cleared.
270 // In either case succeed immediately. 260 // If the capture length is zero, then the capture is either empty or cleared.
261 // Fall through in both cases.
271 __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); 262 __ Branch(&fallthrough, eq, a1, Operand(zero_reg));
272 263
273 __ Daddu(t1, a1, current_input_offset()); 264 if (read_backward) {
274 // Check that there are enough characters left in the input. 265 __ ld(t1, MemOperand(frame_pointer(), kStringStartMinusOne));
275 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg)); 266 __ Daddu(t1, t1, a1);
267 BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t1));
268 } else {
269 __ Daddu(t1, a1, current_input_offset());
270 // Check that there are enough characters left in the input.
271 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg));
272 }
276 273
277 if (mode_ == LATIN1) { 274 if (mode_ == LATIN1) {
278 Label success; 275 Label success;
279 Label fail; 276 Label fail;
280 Label loop_check; 277 Label loop_check;
281 278
282 // a0 - offset of start of capture. 279 // a0 - offset of start of capture.
283 // a1 - length of capture. 280 // a1 - length of capture.
284 __ Daddu(a0, a0, Operand(end_of_input_address())); 281 __ Daddu(a0, a0, Operand(end_of_input_address()));
285 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset())); 282 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset()));
283 if (read_backward) {
284 __ Dsubu(a2, a2, Operand(a1));
285 }
286 __ Daddu(a1, a0, Operand(a1)); 286 __ Daddu(a1, a0, Operand(a1));
287 287
288 // a0 - Address of start of capture. 288 // a0 - Address of start of capture.
289 // a1 - Address of end of capture. 289 // a1 - Address of end of capture.
290 // a2 - Address of current input position. 290 // a2 - Address of current input position.
291 291
292 Label loop; 292 Label loop;
293 __ bind(&loop); 293 __ bind(&loop);
294 __ lbu(a3, MemOperand(a0, 0)); 294 __ lbu(a3, MemOperand(a0, 0));
295 __ daddiu(a0, a0, char_size()); 295 __ daddiu(a0, a0, char_size());
(...skipping 18 matching lines...) Expand all
314 __ bind(&loop_check); 314 __ bind(&loop_check);
315 __ Branch(&loop, lt, a0, Operand(a1)); 315 __ Branch(&loop, lt, a0, Operand(a1));
316 __ jmp(&success); 316 __ jmp(&success);
317 317
318 __ bind(&fail); 318 __ bind(&fail);
319 GoTo(on_no_match); 319 GoTo(on_no_match);
320 320
321 __ bind(&success); 321 __ bind(&success);
322 // Compute new value of character position after the matched part. 322 // Compute new value of character position after the matched part.
323 __ Dsubu(current_input_offset(), a2, end_of_input_address()); 323 __ Dsubu(current_input_offset(), a2, end_of_input_address());
324 if (read_backward) {
325 __ ld(t1, register_location(start_reg)); // Index of start of capture.
326 __ ld(a2, register_location(start_reg + 1)); // Index of end of capture.
327 __ Daddu(current_input_offset(), current_input_offset(), Operand(t1));
328 __ Dsubu(current_input_offset(), current_input_offset(), Operand(a2));
329 }
324 } else { 330 } else {
325 DCHECK(mode_ == UC16); 331 DCHECK(mode_ == UC16);
326 // Put regexp engine registers on stack. 332 // Put regexp engine registers on stack.
327 RegList regexp_registers_to_retain = current_input_offset().bit() | 333 RegList regexp_registers_to_retain = current_input_offset().bit() |
328 current_character().bit() | backtrack_stackpointer().bit(); 334 current_character().bit() | backtrack_stackpointer().bit();
329 __ MultiPush(regexp_registers_to_retain); 335 __ MultiPush(regexp_registers_to_retain);
330 336
331 int argument_count = 4; 337 int argument_count = 4;
332 __ PrepareCallCFunction(argument_count, a2); 338 __ PrepareCallCFunction(argument_count, a2);
333 339
334 // a0 - offset of start of capture. 340 // a0 - offset of start of capture.
335 // a1 - length of capture. 341 // a1 - length of capture.
336 342
337 // Put arguments into arguments registers. 343 // Put arguments into arguments registers.
338 // Parameters are 344 // Parameters are
339 // a0: Address byte_offset1 - Address captured substring's start. 345 // a0: Address byte_offset1 - Address captured substring's start.
340 // a1: Address byte_offset2 - Address of current character position. 346 // a1: Address byte_offset2 - Address of current character position.
341 // a2: size_t byte_length - length of capture in bytes(!). 347 // a2: size_t byte_length - length of capture in bytes(!).
342 // a3: Isolate* isolate. 348 // a3: Isolate* isolate.
343 349
344 // Address of start of capture. 350 // Address of start of capture.
345 __ Daddu(a0, a0, Operand(end_of_input_address())); 351 __ Daddu(a0, a0, Operand(end_of_input_address()));
346 // Length of capture. 352 // Length of capture.
347 __ mov(a2, a1); 353 __ mov(a2, a1);
348 // Save length in callee-save register for use on return. 354 // Save length in callee-save register for use on return.
349 __ mov(s3, a1); 355 __ mov(s3, a1);
350 // Address of current input position. 356 // Address of current input position.
351 __ Daddu(a1, current_input_offset(), Operand(end_of_input_address())); 357 __ Daddu(a1, current_input_offset(), Operand(end_of_input_address()));
358 if (read_backward) {
359 __ Dsubu(a1, a1, Operand(s3));
360 }
352 // Isolate. 361 // Isolate.
353 __ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate()))); 362 __ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate())));
354 363
355 { 364 {
356 AllowExternalCallThatCantCauseGC scope(masm_); 365 AllowExternalCallThatCantCauseGC scope(masm_);
357 ExternalReference function = 366 ExternalReference function =
358 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate()); 367 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate());
359 __ CallCFunction(function, argument_count); 368 __ CallCFunction(function, argument_count);
360 } 369 }
361 370
362 // Restore regexp engine registers. 371 // Restore regexp engine registers.
363 __ MultiPop(regexp_registers_to_retain); 372 __ MultiPop(regexp_registers_to_retain);
364 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 373 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
365 __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 374 __ ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
366 375
367 // Check if function returned non-zero for success or zero for failure. 376 // Check if function returned non-zero for success or zero for failure.
368 BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg)); 377 BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg));
369 // On success, increment position by length of capture. 378 // On success, increment position by length of capture.
370 __ Daddu(current_input_offset(), current_input_offset(), Operand(s3)); 379 if (read_backward) {
380 __ Dsubu(current_input_offset(), current_input_offset(), Operand(s3));
381 } else {
382 __ Daddu(current_input_offset(), current_input_offset(), Operand(s3));
383 }
371 } 384 }
372 385
373 __ bind(&fallthrough); 386 __ bind(&fallthrough);
374 } 387 }
375 388
376 389
377 void RegExpMacroAssemblerMIPS::CheckNotBackReference( 390 void RegExpMacroAssemblerMIPS::CheckNotBackReference(int start_reg,
378 int start_reg, 391 bool read_backward,
379 Label* on_no_match) { 392 Label* on_no_match) {
380 Label fallthrough; 393 Label fallthrough;
381 Label success; 394 Label success;
382 395
383 // Find length of back-referenced capture. 396 // Find length of back-referenced capture.
384 __ ld(a0, register_location(start_reg)); 397 __ ld(a0, register_location(start_reg));
385 __ ld(a1, register_location(start_reg + 1)); 398 __ ld(a1, register_location(start_reg + 1));
386 __ Dsubu(a1, a1, a0); // Length to check. 399 __ Dsubu(a1, a1, a0); // Length to check.
387 // Succeed on empty capture (including no capture). 400
401 // At this point, the capture registers are either both set or both cleared.
402 // If the capture length is zero, then the capture is either empty or cleared.
403 // Fall through in both cases.
388 __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); 404 __ Branch(&fallthrough, eq, a1, Operand(zero_reg));
389 405
390 __ Daddu(t1, a1, current_input_offset()); 406 if (read_backward) {
391 // Check that there are enough characters left in the input. 407 __ ld(t1, MemOperand(frame_pointer(), kStringStartMinusOne));
392 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg)); 408 __ Daddu(t1, t1, a1);
409 BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t1));
410 } else {
411 __ Daddu(t1, a1, current_input_offset());
412 // Check that there are enough characters left in the input.
413 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg));
414 }
393 415
394 // Compute pointers to match string and capture string. 416 // Compute pointers to match string and capture string.
395 __ Daddu(a0, a0, Operand(end_of_input_address())); 417 __ Daddu(a0, a0, Operand(end_of_input_address()));
396 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset())); 418 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset()));
419 if (read_backward) {
420 __ Dsubu(a2, a2, Operand(a1));
421 }
397 __ Daddu(a1, a1, Operand(a0)); 422 __ Daddu(a1, a1, Operand(a0));
398 423
399 Label loop; 424 Label loop;
400 __ bind(&loop); 425 __ bind(&loop);
401 if (mode_ == LATIN1) { 426 if (mode_ == LATIN1) {
402 __ lbu(a3, MemOperand(a0, 0)); 427 __ lbu(a3, MemOperand(a0, 0));
403 __ daddiu(a0, a0, char_size()); 428 __ daddiu(a0, a0, char_size());
404 __ lbu(a4, MemOperand(a2, 0)); 429 __ lbu(a4, MemOperand(a2, 0));
405 __ daddiu(a2, a2, char_size()); 430 __ daddiu(a2, a2, char_size());
406 } else { 431 } else {
407 DCHECK(mode_ == UC16); 432 DCHECK(mode_ == UC16);
408 __ lhu(a3, MemOperand(a0, 0)); 433 __ lhu(a3, MemOperand(a0, 0));
409 __ daddiu(a0, a0, char_size()); 434 __ daddiu(a0, a0, char_size());
410 __ lhu(a4, MemOperand(a2, 0)); 435 __ lhu(a4, MemOperand(a2, 0));
411 __ daddiu(a2, a2, char_size()); 436 __ daddiu(a2, a2, char_size());
412 } 437 }
413 BranchOrBacktrack(on_no_match, ne, a3, Operand(a4)); 438 BranchOrBacktrack(on_no_match, ne, a3, Operand(a4));
414 __ Branch(&loop, lt, a0, Operand(a1)); 439 __ Branch(&loop, lt, a0, Operand(a1));
415 440
416 // Move current character position to position after match. 441 // Move current character position to position after match.
417 __ Dsubu(current_input_offset(), a2, end_of_input_address()); 442 __ Dsubu(current_input_offset(), a2, end_of_input_address());
443 if (read_backward) {
444 __ ld(t1, register_location(start_reg)); // Index of start of capture.
445 __ ld(a2, register_location(start_reg + 1)); // Index of end of capture.
446 __ Daddu(current_input_offset(), current_input_offset(), Operand(t1));
447 __ Dsubu(current_input_offset(), current_input_offset(), Operand(a2));
448 }
418 __ bind(&fallthrough); 449 __ bind(&fallthrough);
419 } 450 }
420 451
421 452
422 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c, 453 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c,
423 Label* on_not_equal) { 454 Label* on_not_equal) {
424 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c)); 455 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c));
425 } 456 }
426 457
427 458
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 argument_registers |= a4.bit() | a5.bit() | a6.bit() | a7.bit(); 668 argument_registers |= a4.bit() | a5.bit() | a6.bit() | a7.bit();
638 } 669 }
639 670
640 __ MultiPush(argument_registers | registers_to_retain | ra.bit()); 671 __ MultiPush(argument_registers | registers_to_retain | ra.bit());
641 // Set frame pointer in space for it if this is not a direct call 672 // Set frame pointer in space for it if this is not a direct call
642 // from generated code. 673 // from generated code.
643 // TODO(plind): this 8 is the # of argument regs, should have definition. 674 // TODO(plind): this 8 is the # of argument regs, should have definition.
644 __ Daddu(frame_pointer(), sp, Operand(8 * kPointerSize)); 675 __ Daddu(frame_pointer(), sp, Operand(8 * kPointerSize));
645 __ mov(a0, zero_reg); 676 __ mov(a0, zero_reg);
646 __ push(a0); // Make room for success counter and initialize it to 0. 677 __ push(a0); // Make room for success counter and initialize it to 0.
647 __ push(a0); // Make room for "position - 1" constant (value irrelevant). 678 __ push(a0); // Make room for "string start - 1" constant.
648 679
649 // Check if we have space on the stack for registers. 680 // Check if we have space on the stack for registers.
650 Label stack_limit_hit; 681 Label stack_limit_hit;
651 Label stack_ok; 682 Label stack_ok;
652 683
653 ExternalReference stack_limit = 684 ExternalReference stack_limit =
654 ExternalReference::address_of_stack_limit(masm_->isolate()); 685 ExternalReference::address_of_stack_limit(masm_->isolate());
655 __ li(a0, Operand(stack_limit)); 686 __ li(a0, Operand(stack_limit));
656 __ ld(a0, MemOperand(a0)); 687 __ ld(a0, MemOperand(a0));
657 __ Dsubu(a0, sp, a0); 688 __ Dsubu(a0, sp, a0);
(...skipping 22 matching lines...) Expand all
680 // Find negative length (offset of start relative to end). 711 // Find negative length (offset of start relative to end).
681 __ Dsubu(current_input_offset(), a0, end_of_input_address()); 712 __ Dsubu(current_input_offset(), a0, end_of_input_address());
682 // Set a0 to address of char before start of the input string 713 // Set a0 to address of char before start of the input string
683 // (effectively string position -1). 714 // (effectively string position -1).
684 __ ld(a1, MemOperand(frame_pointer(), kStartIndex)); 715 __ ld(a1, MemOperand(frame_pointer(), kStartIndex));
685 __ Dsubu(a0, current_input_offset(), Operand(char_size())); 716 __ Dsubu(a0, current_input_offset(), Operand(char_size()));
686 __ dsll(t1, a1, (mode_ == UC16) ? 1 : 0); 717 __ dsll(t1, a1, (mode_ == UC16) ? 1 : 0);
687 __ Dsubu(a0, a0, t1); 718 __ Dsubu(a0, a0, t1);
688 // Store this value in a local variable, for use when clearing 719 // Store this value in a local variable, for use when clearing
689 // position registers. 720 // position registers.
690 __ sd(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 721 __ sd(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
691 722
692 // Initialize code pointer register 723 // Initialize code pointer register
693 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 724 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
694 725
695 Label load_char_start_regexp, start_regexp; 726 Label load_char_start_regexp, start_regexp;
696 // Load newline if index is at start, previous character otherwise. 727 // Load newline if index is at start, previous character otherwise.
697 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg)); 728 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
698 __ li(current_character(), Operand('\n')); 729 __ li(current_character(), Operand('\n'));
699 __ jmp(&start_regexp); 730 __ jmp(&start_regexp);
700 731
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 // Check whether we have enough room for another set of capture results. 821 // Check whether we have enough room for another set of capture results.
791 __ mov(v0, a0); 822 __ mov(v0, a0);
792 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_)); 823 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_));
793 824
794 __ sd(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); 825 __ sd(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
795 // Advance the location for output. 826 // Advance the location for output.
796 __ Daddu(a2, a2, num_saved_registers_ * kIntSize); 827 __ Daddu(a2, a2, num_saved_registers_ * kIntSize);
797 __ sd(a2, MemOperand(frame_pointer(), kRegisterOutput)); 828 __ sd(a2, MemOperand(frame_pointer(), kRegisterOutput));
798 829
799 // Prepare a0 to initialize registers with its value in the next run. 830 // Prepare a0 to initialize registers with its value in the next run.
800 __ ld(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 831 __ ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
801 832
802 if (global_with_zero_length_check()) { 833 if (global_with_zero_length_check()) {
803 // Special case for zero-length matches. 834 // Special case for zero-length matches.
804 // t3: capture start index 835 // t3: capture start index
805 // Not a zero-length match, restart. 836 // Not a zero-length match, restart.
806 __ Branch( 837 __ Branch(
807 &load_char_start_regexp, ne, current_input_offset(), Operand(t3)); 838 &load_char_start_regexp, ne, current_input_offset(), Operand(t3));
808 // Offset from the end is zero if we already reached the end. 839 // Offset from the end is zero if we already reached the end.
809 __ Branch(&exit_label_, eq, current_input_offset(), 840 __ Branch(&exit_label_, eq, current_input_offset(),
810 Operand(zero_reg)); 841 Operand(zero_reg));
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 RegExpMacroAssembler::IrregexpImplementation 975 RegExpMacroAssembler::IrregexpImplementation
945 RegExpMacroAssemblerMIPS::Implementation() { 976 RegExpMacroAssemblerMIPS::Implementation() {
946 return kMIPSImplementation; 977 return kMIPSImplementation;
947 } 978 }
948 979
949 980
950 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset, 981 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset,
951 Label* on_end_of_input, 982 Label* on_end_of_input,
952 bool check_bounds, 983 bool check_bounds,
953 int characters) { 984 int characters) {
954 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character.
955 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works). 985 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works).
956 if (check_bounds) { 986 if (check_bounds) {
957 CheckPosition(cp_offset + characters - 1, on_end_of_input); 987 if (cp_offset >= 0) {
988 CheckPosition(cp_offset + characters - 1, on_end_of_input);
989 } else {
990 CheckPosition(cp_offset, on_end_of_input);
991 }
958 } 992 }
959 LoadCurrentCharacterUnchecked(cp_offset, characters); 993 LoadCurrentCharacterUnchecked(cp_offset, characters);
960 } 994 }
961 995
962 996
963 void RegExpMacroAssemblerMIPS::PopCurrentPosition() { 997 void RegExpMacroAssemblerMIPS::PopCurrentPosition() {
964 Pop(current_input_offset()); 998 Pop(current_input_offset());
965 } 999 }
966 1000
967 1001
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 __ sd(current_input_offset(), register_location(reg)); 1089 __ sd(current_input_offset(), register_location(reg));
1056 } else { 1090 } else {
1057 __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size())); 1091 __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1058 __ sd(a0, register_location(reg)); 1092 __ sd(a0, register_location(reg));
1059 } 1093 }
1060 } 1094 }
1061 1095
1062 1096
1063 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { 1097 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) {
1064 DCHECK(reg_from <= reg_to); 1098 DCHECK(reg_from <= reg_to);
1065 __ ld(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 1099 __ ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
1066 for (int reg = reg_from; reg <= reg_to; reg++) { 1100 for (int reg = reg_from; reg <= reg_to; reg++) {
1067 __ sd(a0, register_location(reg)); 1101 __ sd(a0, register_location(reg));
1068 } 1102 }
1069 } 1103 }
1070 1104
1071 1105
1072 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) { 1106 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) {
1073 __ ld(a1, MemOperand(frame_pointer(), kStackHighEnd)); 1107 __ ld(a1, MemOperand(frame_pointer(), kStackHighEnd));
1074 __ Dsubu(a0, backtrack_stackpointer(), a1); 1108 __ Dsubu(a0, backtrack_stackpointer(), a1);
1075 __ sd(a0, register_location(reg)); 1109 __ sd(a0, register_location(reg));
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 if (num_registers_ <= register_index) { 1202 if (num_registers_ <= register_index) {
1169 num_registers_ = register_index + 1; 1203 num_registers_ = register_index + 1;
1170 } 1204 }
1171 return MemOperand(frame_pointer(), 1205 return MemOperand(frame_pointer(),
1172 kRegisterZero - register_index * kPointerSize); 1206 kRegisterZero - register_index * kPointerSize);
1173 } 1207 }
1174 1208
1175 1209
1176 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset, 1210 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset,
1177 Label* on_outside_input) { 1211 Label* on_outside_input) {
1178 BranchOrBacktrack(on_outside_input, 1212 if (cp_offset >= 0) {
1179 ge, 1213 BranchOrBacktrack(on_outside_input, ge, current_input_offset(),
1180 current_input_offset(), 1214 Operand(-cp_offset * char_size()));
1181 Operand(-cp_offset * char_size())); 1215 } else {
1216 __ ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne));
1217 __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1218 BranchOrBacktrack(on_outside_input, le, a0, Operand(a1));
1219 }
1182 } 1220 }
1183 1221
1184 1222
1185 void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to, 1223 void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to,
1186 Condition condition, 1224 Condition condition,
1187 Register rs, 1225 Register rs,
1188 const Operand& rt) { 1226 const Operand& rt) {
1189 if (condition == al) { // Unconditional. 1227 if (condition == al) { // Unconditional.
1190 if (to == NULL) { 1228 if (to == NULL) {
1191 Backtrack(); 1229 Backtrack();
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 } 1319 }
1282 1320
1283 #undef __ 1321 #undef __
1284 1322
1285 #endif // V8_INTERPRETED_REGEXP 1323 #endif // V8_INTERPRETED_REGEXP
1286 1324
1287 } // namespace internal 1325 } // namespace internal
1288 } // namespace v8 1326 } // namespace v8
1289 1327
1290 #endif // V8_TARGET_ARCH_MIPS64 1328 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/regexp/mips64/regexp-macro-assembler-mips64.h ('k') | src/regexp/regexp-macro-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698