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

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: addressed comments 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_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 // The length of the capture can only be negative if the end of the
270 // In either case succeed immediately. 260 // capture is not yet recorded. If the length is zero, the capture is
271 __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); 261 // either empty or uncaptured. In either of those cases, succeed.
262 __ Branch(&fallthrough, le, 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 __ Dsubu(a2, current_input_offset(), a1);
267 BranchOrBacktrack(on_no_match, le, a2, 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 // The length of the capture can only be negative if the end of the
388 __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); 401 // capture is not yet recorded. If the length is zero, the capture is
402 // either empty or uncaptured. In either of those cases, succeed.
403 __ Branch(&fallthrough, le, a1, Operand(zero_reg));
389 404
390 __ Daddu(t1, a1, current_input_offset()); 405 if (read_backward) {
391 // Check that there are enough characters left in the input. 406 __ ld(t1, MemOperand(frame_pointer(), kStringStartMinusOne));
392 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg)); 407 __ Dsubu(a2, current_input_offset(), a1);
408 BranchOrBacktrack(on_no_match, le, a2, Operand(t1));
409 } else {
410 __ Daddu(t1, a1, current_input_offset());
411 // Check that there are enough characters left in the input.
412 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg));
413 }
393 414
394 // Compute pointers to match string and capture string. 415 // Compute pointers to match string and capture string.
395 __ Daddu(a0, a0, Operand(end_of_input_address())); 416 __ Daddu(a0, a0, Operand(end_of_input_address()));
396 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset())); 417 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset()));
418 if (read_backward) {
419 __ Dsubu(a2, a2, Operand(a1));
420 }
397 __ Daddu(a1, a1, Operand(a0)); 421 __ Daddu(a1, a1, Operand(a0));
398 422
399 Label loop; 423 Label loop;
400 __ bind(&loop); 424 __ bind(&loop);
401 if (mode_ == LATIN1) { 425 if (mode_ == LATIN1) {
402 __ lbu(a3, MemOperand(a0, 0)); 426 __ lbu(a3, MemOperand(a0, 0));
403 __ daddiu(a0, a0, char_size()); 427 __ daddiu(a0, a0, char_size());
404 __ lbu(a4, MemOperand(a2, 0)); 428 __ lbu(a4, MemOperand(a2, 0));
405 __ daddiu(a2, a2, char_size()); 429 __ daddiu(a2, a2, char_size());
406 } else { 430 } else {
407 DCHECK(mode_ == UC16); 431 DCHECK(mode_ == UC16);
408 __ lhu(a3, MemOperand(a0, 0)); 432 __ lhu(a3, MemOperand(a0, 0));
409 __ daddiu(a0, a0, char_size()); 433 __ daddiu(a0, a0, char_size());
410 __ lhu(a4, MemOperand(a2, 0)); 434 __ lhu(a4, MemOperand(a2, 0));
411 __ daddiu(a2, a2, char_size()); 435 __ daddiu(a2, a2, char_size());
412 } 436 }
413 BranchOrBacktrack(on_no_match, ne, a3, Operand(a4)); 437 BranchOrBacktrack(on_no_match, ne, a3, Operand(a4));
414 __ Branch(&loop, lt, a0, Operand(a1)); 438 __ Branch(&loop, lt, a0, Operand(a1));
415 439
416 // Move current character position to position after match. 440 // Move current character position to position after match.
417 __ Dsubu(current_input_offset(), a2, end_of_input_address()); 441 __ Dsubu(current_input_offset(), a2, end_of_input_address());
442 if (read_backward) {
443 __ ld(t1, register_location(start_reg)); // Index of start of capture.
444 __ ld(a2, register_location(start_reg + 1)); // Index of end of capture.
445 __ Daddu(current_input_offset(), current_input_offset(), Operand(t1));
446 __ Dsubu(current_input_offset(), current_input_offset(), Operand(a2));
447 }
418 __ bind(&fallthrough); 448 __ bind(&fallthrough);
419 } 449 }
420 450
421 451
422 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c, 452 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c,
423 Label* on_not_equal) { 453 Label* on_not_equal) {
424 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c)); 454 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c));
425 } 455 }
426 456
427 457
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 argument_registers |= a4.bit() | a5.bit() | a6.bit() | a7.bit(); 667 argument_registers |= a4.bit() | a5.bit() | a6.bit() | a7.bit();
638 } 668 }
639 669
640 __ MultiPush(argument_registers | registers_to_retain | ra.bit()); 670 __ MultiPush(argument_registers | registers_to_retain | ra.bit());
641 // Set frame pointer in space for it if this is not a direct call 671 // Set frame pointer in space for it if this is not a direct call
642 // from generated code. 672 // from generated code.
643 // TODO(plind): this 8 is the # of argument regs, should have definition. 673 // TODO(plind): this 8 is the # of argument regs, should have definition.
644 __ Daddu(frame_pointer(), sp, Operand(8 * kPointerSize)); 674 __ Daddu(frame_pointer(), sp, Operand(8 * kPointerSize));
645 __ mov(a0, zero_reg); 675 __ mov(a0, zero_reg);
646 __ push(a0); // Make room for success counter and initialize it to 0. 676 __ push(a0); // Make room for success counter and initialize it to 0.
647 __ push(a0); // Make room for "position - 1" constant (value irrelevant). 677 __ push(a0); // Make room for "string start - 1" constant.
648 678
649 // Check if we have space on the stack for registers. 679 // Check if we have space on the stack for registers.
650 Label stack_limit_hit; 680 Label stack_limit_hit;
651 Label stack_ok; 681 Label stack_ok;
652 682
653 ExternalReference stack_limit = 683 ExternalReference stack_limit =
654 ExternalReference::address_of_stack_limit(masm_->isolate()); 684 ExternalReference::address_of_stack_limit(masm_->isolate());
655 __ li(a0, Operand(stack_limit)); 685 __ li(a0, Operand(stack_limit));
656 __ ld(a0, MemOperand(a0)); 686 __ ld(a0, MemOperand(a0));
657 __ Dsubu(a0, sp, a0); 687 __ Dsubu(a0, sp, a0);
(...skipping 22 matching lines...) Expand all
680 // Find negative length (offset of start relative to end). 710 // Find negative length (offset of start relative to end).
681 __ Dsubu(current_input_offset(), a0, end_of_input_address()); 711 __ Dsubu(current_input_offset(), a0, end_of_input_address());
682 // Set a0 to address of char before start of the input string 712 // Set a0 to address of char before start of the input string
683 // (effectively string position -1). 713 // (effectively string position -1).
684 __ ld(a1, MemOperand(frame_pointer(), kStartIndex)); 714 __ ld(a1, MemOperand(frame_pointer(), kStartIndex));
685 __ Dsubu(a0, current_input_offset(), Operand(char_size())); 715 __ Dsubu(a0, current_input_offset(), Operand(char_size()));
686 __ dsll(t1, a1, (mode_ == UC16) ? 1 : 0); 716 __ dsll(t1, a1, (mode_ == UC16) ? 1 : 0);
687 __ Dsubu(a0, a0, t1); 717 __ Dsubu(a0, a0, t1);
688 // Store this value in a local variable, for use when clearing 718 // Store this value in a local variable, for use when clearing
689 // position registers. 719 // position registers.
690 __ sd(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 720 __ sd(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
691 721
692 // Initialize code pointer register 722 // Initialize code pointer register
693 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 723 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
694 724
695 Label load_char_start_regexp, start_regexp; 725 Label load_char_start_regexp, start_regexp;
696 // Load newline if index is at start, previous character otherwise. 726 // Load newline if index is at start, previous character otherwise.
697 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg)); 727 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
698 __ li(current_character(), Operand('\n')); 728 __ li(current_character(), Operand('\n'));
699 __ jmp(&start_regexp); 729 __ jmp(&start_regexp);
700 730
(...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. 820 // Check whether we have enough room for another set of capture results.
791 __ mov(v0, a0); 821 __ mov(v0, a0);
792 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_)); 822 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_));
793 823
794 __ sd(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); 824 __ sd(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
795 // Advance the location for output. 825 // Advance the location for output.
796 __ Daddu(a2, a2, num_saved_registers_ * kIntSize); 826 __ Daddu(a2, a2, num_saved_registers_ * kIntSize);
797 __ sd(a2, MemOperand(frame_pointer(), kRegisterOutput)); 827 __ sd(a2, MemOperand(frame_pointer(), kRegisterOutput));
798 828
799 // Prepare a0 to initialize registers with its value in the next run. 829 // Prepare a0 to initialize registers with its value in the next run.
800 __ ld(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 830 __ ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
801 831
802 if (global_with_zero_length_check()) { 832 if (global_with_zero_length_check()) {
803 // Special case for zero-length matches. 833 // Special case for zero-length matches.
804 // t3: capture start index 834 // t3: capture start index
805 // Not a zero-length match, restart. 835 // Not a zero-length match, restart.
806 __ Branch( 836 __ Branch(
807 &load_char_start_regexp, ne, current_input_offset(), Operand(t3)); 837 &load_char_start_regexp, ne, current_input_offset(), Operand(t3));
808 // Offset from the end is zero if we already reached the end. 838 // Offset from the end is zero if we already reached the end.
809 __ Branch(&exit_label_, eq, current_input_offset(), 839 __ Branch(&exit_label_, eq, current_input_offset(),
810 Operand(zero_reg)); 840 Operand(zero_reg));
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 RegExpMacroAssembler::IrregexpImplementation 974 RegExpMacroAssembler::IrregexpImplementation
945 RegExpMacroAssemblerMIPS::Implementation() { 975 RegExpMacroAssemblerMIPS::Implementation() {
946 return kMIPSImplementation; 976 return kMIPSImplementation;
947 } 977 }
948 978
949 979
950 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset, 980 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset,
951 Label* on_end_of_input, 981 Label* on_end_of_input,
952 bool check_bounds, 982 bool check_bounds,
953 int characters) { 983 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). 984 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works).
956 if (check_bounds) { 985 if (check_bounds) {
957 CheckPosition(cp_offset + characters - 1, on_end_of_input); 986 if (cp_offset >= 0) {
987 CheckPosition(cp_offset + characters - 1, on_end_of_input);
988 } else {
989 CheckPosition(cp_offset, on_end_of_input);
990 }
958 } 991 }
959 LoadCurrentCharacterUnchecked(cp_offset, characters); 992 LoadCurrentCharacterUnchecked(cp_offset, characters);
960 } 993 }
961 994
962 995
963 void RegExpMacroAssemblerMIPS::PopCurrentPosition() { 996 void RegExpMacroAssemblerMIPS::PopCurrentPosition() {
964 Pop(current_input_offset()); 997 Pop(current_input_offset());
965 } 998 }
966 999
967 1000
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 __ sd(current_input_offset(), register_location(reg)); 1088 __ sd(current_input_offset(), register_location(reg));
1056 } else { 1089 } else {
1057 __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size())); 1090 __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1058 __ sd(a0, register_location(reg)); 1091 __ sd(a0, register_location(reg));
1059 } 1092 }
1060 } 1093 }
1061 1094
1062 1095
1063 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { 1096 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) {
1064 DCHECK(reg_from <= reg_to); 1097 DCHECK(reg_from <= reg_to);
1065 __ ld(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 1098 __ ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
1066 for (int reg = reg_from; reg <= reg_to; reg++) { 1099 for (int reg = reg_from; reg <= reg_to; reg++) {
1067 __ sd(a0, register_location(reg)); 1100 __ sd(a0, register_location(reg));
1068 } 1101 }
1069 } 1102 }
1070 1103
1071 1104
1072 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) { 1105 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) {
1073 __ ld(a1, MemOperand(frame_pointer(), kStackHighEnd)); 1106 __ ld(a1, MemOperand(frame_pointer(), kStackHighEnd));
1074 __ Dsubu(a0, backtrack_stackpointer(), a1); 1107 __ Dsubu(a0, backtrack_stackpointer(), a1);
1075 __ sd(a0, register_location(reg)); 1108 __ sd(a0, register_location(reg));
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 if (num_registers_ <= register_index) { 1201 if (num_registers_ <= register_index) {
1169 num_registers_ = register_index + 1; 1202 num_registers_ = register_index + 1;
1170 } 1203 }
1171 return MemOperand(frame_pointer(), 1204 return MemOperand(frame_pointer(),
1172 kRegisterZero - register_index * kPointerSize); 1205 kRegisterZero - register_index * kPointerSize);
1173 } 1206 }
1174 1207
1175 1208
1176 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset, 1209 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset,
1177 Label* on_outside_input) { 1210 Label* on_outside_input) {
1178 BranchOrBacktrack(on_outside_input, 1211 if (cp_offset >= 0) {
1179 ge, 1212 BranchOrBacktrack(on_outside_input, ge, current_input_offset(),
1180 current_input_offset(), 1213 Operand(-cp_offset * char_size()));
1181 Operand(-cp_offset * char_size())); 1214 } else {
1215 __ ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne));
1216 __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1217 BranchOrBacktrack(on_outside_input, le, a0, Operand(a1));
1218 }
1182 } 1219 }
1183 1220
1184 1221
1185 void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to, 1222 void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to,
1186 Condition condition, 1223 Condition condition,
1187 Register rs, 1224 Register rs,
1188 const Operand& rt) { 1225 const Operand& rt) {
1189 if (condition == al) { // Unconditional. 1226 if (condition == al) { // Unconditional.
1190 if (to == NULL) { 1227 if (to == NULL) {
1191 Backtrack(); 1228 Backtrack();
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 } 1318 }
1282 1319
1283 #undef __ 1320 #undef __
1284 1321
1285 #endif // V8_INTERPRETED_REGEXP 1322 #endif // V8_INTERPRETED_REGEXP
1286 1323
1287 } // namespace internal 1324 } // namespace internal
1288 } // namespace v8 1325 } // namespace v8
1289 1326
1290 #endif // V8_TARGET_ARCH_MIPS64 1327 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698