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

Side by Side Diff: src/regexp/mips/regexp-macro-assembler-mips.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_MIPS 5 #if V8_TARGET_ARCH_MIPS
6 6
7 #include "src/regexp/mips/regexp-macro-assembler-mips.h" 7 #include "src/regexp/mips/regexp-macro-assembler-mips.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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 BranchOrBacktrack(on_equal, eq, current_character(), Operand(c)); 174 BranchOrBacktrack(on_equal, eq, current_character(), Operand(c));
175 } 175 }
176 176
177 177
178 void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) { 178 void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) {
179 BranchOrBacktrack(on_greater, gt, current_character(), Operand(limit)); 179 BranchOrBacktrack(on_greater, gt, current_character(), Operand(limit));
180 } 180 }
181 181
182 182
183 void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) { 183 void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
184 Label not_at_start; 184 __ lw(a1, MemOperand(frame_pointer(), kStringStartMinusOne));
185 // Did we start the match at the start of the string at all? 185 __ Addu(a0, current_input_offset(), Operand(-char_size()));
186 __ lw(a0, MemOperand(frame_pointer(), kStartIndex));
187 BranchOrBacktrack(&not_at_start, ne, a0, Operand(zero_reg));
188
189 // If we did, are we still at the start of the input?
190 __ lw(a1, MemOperand(frame_pointer(), kInputStart));
191 __ Addu(a0, end_of_input_address(), Operand(current_input_offset()));
192 BranchOrBacktrack(on_at_start, eq, a0, Operand(a1)); 186 BranchOrBacktrack(on_at_start, eq, a0, Operand(a1));
193 __ bind(&not_at_start);
194 } 187 }
195 188
196 189
197 void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) { 190 void RegExpMacroAssemblerMIPS::CheckNotAtStart(int cp_offset,
198 // Did we start the match at the start of the string at all? 191 Label* on_not_at_start) {
199 __ lw(a0, MemOperand(frame_pointer(), kStartIndex)); 192 __ lw(a1, MemOperand(frame_pointer(), kStringStartMinusOne));
200 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(zero_reg)); 193 __ Addu(a0, current_input_offset(),
201 // If we did, are we still at the start of the input? 194 Operand(-char_size() + cp_offset * char_size()));
202 __ lw(a1, MemOperand(frame_pointer(), kInputStart));
203 __ Addu(a0, end_of_input_address(), Operand(current_input_offset()));
204 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(a1)); 195 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(a1));
205 } 196 }
206 197
207 198
208 void RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) { 199 void RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) {
209 BranchOrBacktrack(on_less, lt, current_character(), Operand(limit)); 200 BranchOrBacktrack(on_less, lt, current_character(), Operand(limit));
210 } 201 }
211 202
212 203
213 void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) { 204 void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) {
214 Label backtrack_non_equal; 205 Label backtrack_non_equal;
215 __ lw(a0, MemOperand(backtrack_stackpointer(), 0)); 206 __ lw(a0, MemOperand(backtrack_stackpointer(), 0));
216 __ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0)); 207 __ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0));
217 __ Addu(backtrack_stackpointer(), 208 __ Addu(backtrack_stackpointer(),
218 backtrack_stackpointer(), 209 backtrack_stackpointer(),
219 Operand(kPointerSize)); 210 Operand(kPointerSize));
220 __ bind(&backtrack_non_equal); 211 __ bind(&backtrack_non_equal);
221 BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0)); 212 BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0));
222 } 213 }
223 214
224 215
225 void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( 216 void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
226 int start_reg, 217 int start_reg, bool read_backward, Label* on_no_match) {
227 Label* on_no_match) {
228 Label fallthrough; 218 Label fallthrough;
229 __ lw(a0, register_location(start_reg)); // Index of start of capture. 219 __ lw(a0, register_location(start_reg)); // Index of start of capture.
230 __ lw(a1, register_location(start_reg + 1)); // Index of end of capture. 220 __ lw(a1, register_location(start_reg + 1)); // Index of end of capture.
231 __ Subu(a1, a1, a0); // Length of capture. 221 __ Subu(a1, a1, a0); // Length of capture.
232 222
233 // If length is zero, either the capture is empty or it is not participating. 223 // At this point, the capture registers are either both set or both cleared.
234 // In either case succeed immediately. 224 // If the capture length is zero, then the capture is either empty or cleared.
225 // Fall through in both cases.
235 __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); 226 __ Branch(&fallthrough, eq, a1, Operand(zero_reg));
236 227
237 __ Addu(t5, a1, current_input_offset()); 228 if (read_backward) {
238 // Check that there are enough characters left in the input. 229 __ lw(t0, MemOperand(frame_pointer(), kStringStartMinusOne));
239 BranchOrBacktrack(on_no_match, gt, t5, Operand(zero_reg)); 230 __ Addu(t0, t0, a1);
231 BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t0));
232 } else {
233 __ Addu(t5, a1, current_input_offset());
234 // Check that there are enough characters left in the input.
235 BranchOrBacktrack(on_no_match, gt, t5, Operand(zero_reg));
236 }
240 237
241 if (mode_ == LATIN1) { 238 if (mode_ == LATIN1) {
242 Label success; 239 Label success;
243 Label fail; 240 Label fail;
244 Label loop_check; 241 Label loop_check;
245 242
246 // a0 - offset of start of capture. 243 // a0 - offset of start of capture.
247 // a1 - length of capture. 244 // a1 - length of capture.
248 __ Addu(a0, a0, Operand(end_of_input_address())); 245 __ Addu(a0, a0, Operand(end_of_input_address()));
249 __ Addu(a2, end_of_input_address(), Operand(current_input_offset())); 246 __ Addu(a2, end_of_input_address(), Operand(current_input_offset()));
247 if (read_backward) {
248 __ Subu(a2, a2, Operand(a1));
249 }
250 __ Addu(a1, a0, Operand(a1)); 250 __ Addu(a1, a0, Operand(a1));
251 251
252 // a0 - Address of start of capture. 252 // a0 - Address of start of capture.
253 // a1 - Address of end of capture. 253 // a1 - Address of end of capture.
254 // a2 - Address of current input position. 254 // a2 - Address of current input position.
255 255
256 Label loop; 256 Label loop;
257 __ bind(&loop); 257 __ bind(&loop);
258 __ lbu(a3, MemOperand(a0, 0)); 258 __ lbu(a3, MemOperand(a0, 0));
259 __ addiu(a0, a0, char_size()); 259 __ addiu(a0, a0, char_size());
(...skipping 18 matching lines...) Expand all
278 __ bind(&loop_check); 278 __ bind(&loop_check);
279 __ Branch(&loop, lt, a0, Operand(a1)); 279 __ Branch(&loop, lt, a0, Operand(a1));
280 __ jmp(&success); 280 __ jmp(&success);
281 281
282 __ bind(&fail); 282 __ bind(&fail);
283 GoTo(on_no_match); 283 GoTo(on_no_match);
284 284
285 __ bind(&success); 285 __ bind(&success);
286 // Compute new value of character position after the matched part. 286 // Compute new value of character position after the matched part.
287 __ Subu(current_input_offset(), a2, end_of_input_address()); 287 __ Subu(current_input_offset(), a2, end_of_input_address());
288 if (read_backward) {
289 __ lw(t0, register_location(start_reg)); // Index of start of capture.
290 __ lw(t5, register_location(start_reg + 1)); // Index of end of capture.
291 __ Addu(current_input_offset(), current_input_offset(), Operand(t0));
292 __ Subu(current_input_offset(), current_input_offset(), Operand(t5));
293 }
288 } else { 294 } else {
289 DCHECK(mode_ == UC16); 295 DCHECK(mode_ == UC16);
290 // Put regexp engine registers on stack. 296 // Put regexp engine registers on stack.
291 RegList regexp_registers_to_retain = current_input_offset().bit() | 297 RegList regexp_registers_to_retain = current_input_offset().bit() |
292 current_character().bit() | backtrack_stackpointer().bit(); 298 current_character().bit() | backtrack_stackpointer().bit();
293 __ MultiPush(regexp_registers_to_retain); 299 __ MultiPush(regexp_registers_to_retain);
294 300
295 int argument_count = 4; 301 int argument_count = 4;
296 __ PrepareCallCFunction(argument_count, a2); 302 __ PrepareCallCFunction(argument_count, a2);
297 303
298 // a0 - offset of start of capture. 304 // a0 - offset of start of capture.
299 // a1 - length of capture. 305 // a1 - length of capture.
300 306
301 // Put arguments into arguments registers. 307 // Put arguments into arguments registers.
302 // Parameters are 308 // Parameters are
303 // a0: Address byte_offset1 - Address captured substring's start. 309 // a0: Address byte_offset1 - Address captured substring's start.
304 // a1: Address byte_offset2 - Address of current character position. 310 // a1: Address byte_offset2 - Address of current character position.
305 // a2: size_t byte_length - length of capture in bytes(!). 311 // a2: size_t byte_length - length of capture in bytes(!).
306 // a3: Isolate* isolate. 312 // a3: Isolate* isolate.
307 313
308 // Address of start of capture. 314 // Address of start of capture.
309 __ Addu(a0, a0, Operand(end_of_input_address())); 315 __ Addu(a0, a0, Operand(end_of_input_address()));
310 // Length of capture. 316 // Length of capture.
311 __ mov(a2, a1); 317 __ mov(a2, a1);
312 // Save length in callee-save register for use on return. 318 // Save length in callee-save register for use on return.
313 __ mov(s3, a1); 319 __ mov(s3, a1);
314 // Address of current input position. 320 // Address of current input position.
315 __ Addu(a1, current_input_offset(), Operand(end_of_input_address())); 321 __ Addu(a1, current_input_offset(), Operand(end_of_input_address()));
322 if (read_backward) {
323 __ Subu(a1, a1, Operand(s3));
324 }
316 // Isolate. 325 // Isolate.
317 __ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate()))); 326 __ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate())));
318 327
319 { 328 {
320 AllowExternalCallThatCantCauseGC scope(masm_); 329 AllowExternalCallThatCantCauseGC scope(masm_);
321 ExternalReference function = 330 ExternalReference function =
322 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate()); 331 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate());
323 __ CallCFunction(function, argument_count); 332 __ CallCFunction(function, argument_count);
324 } 333 }
325 334
326 // Restore regexp engine registers. 335 // Restore regexp engine registers.
327 __ MultiPop(regexp_registers_to_retain); 336 __ MultiPop(regexp_registers_to_retain);
328 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 337 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
329 __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 338 __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
330 339
331 // Check if function returned non-zero for success or zero for failure. 340 // Check if function returned non-zero for success or zero for failure.
332 BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg)); 341 BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg));
333 // On success, increment position by length of capture. 342 // On success, advance position by length of capture.
334 __ Addu(current_input_offset(), current_input_offset(), Operand(s3)); 343 if (read_backward) {
344 __ Subu(current_input_offset(), current_input_offset(), Operand(s3));
345 } else {
346 __ Addu(current_input_offset(), current_input_offset(), Operand(s3));
347 }
335 } 348 }
336 349
337 __ bind(&fallthrough); 350 __ bind(&fallthrough);
338 } 351 }
339 352
340 353
341 void RegExpMacroAssemblerMIPS::CheckNotBackReference( 354 void RegExpMacroAssemblerMIPS::CheckNotBackReference(int start_reg,
342 int start_reg, 355 bool read_backward,
343 Label* on_no_match) { 356 Label* on_no_match) {
344 Label fallthrough; 357 Label fallthrough;
345 Label success; 358 Label success;
346 359
347 // Find length of back-referenced capture. 360 // Find length of back-referenced capture.
348 __ lw(a0, register_location(start_reg)); 361 __ lw(a0, register_location(start_reg));
349 __ lw(a1, register_location(start_reg + 1)); 362 __ lw(a1, register_location(start_reg + 1));
350 __ Subu(a1, a1, a0); // Length to check. 363 __ Subu(a1, a1, a0); // Length to check.
351 // Succeed on empty capture (including no capture).
352 __ Branch(&fallthrough, eq, a1, Operand(zero_reg));
353 364
354 __ Addu(t5, a1, current_input_offset()); 365 // At this point, the capture registers are either both set or both cleared.
355 // Check that there are enough characters left in the input. 366 // If the capture length is zero, then the capture is either empty or cleared.
356 BranchOrBacktrack(on_no_match, gt, t5, Operand(zero_reg)); 367 // Fall through in both cases.
368 __ Branch(&fallthrough, le, a1, Operand(zero_reg));
357 369
358 // Compute pointers to match string and capture string. 370 if (read_backward) {
371 __ lw(t0, MemOperand(frame_pointer(), kStringStartMinusOne));
372 __ Addu(t0, t0, a1);
373 BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t0));
374 } else {
375 __ Addu(t5, a1, current_input_offset());
376 // Check that there are enough characters left in the input.
377 BranchOrBacktrack(on_no_match, gt, t5, Operand(zero_reg));
378 }
379
380 // a0 - offset of start of capture.
381 // a1 - length of capture.
359 __ Addu(a0, a0, Operand(end_of_input_address())); 382 __ Addu(a0, a0, Operand(end_of_input_address()));
360 __ Addu(a2, end_of_input_address(), Operand(current_input_offset())); 383 __ Addu(a2, end_of_input_address(), Operand(current_input_offset()));
361 __ Addu(a1, a1, Operand(a0)); 384 if (read_backward) {
385 __ Subu(a2, a2, Operand(a1));
386 }
387 __ Addu(a1, a0, Operand(a1));
388
389 // a0 - Address of start of capture.
390 // a1 - Address of end of capture.
391 // a2 - Address of current input position.
392
362 393
363 Label loop; 394 Label loop;
364 __ bind(&loop); 395 __ bind(&loop);
365 if (mode_ == LATIN1) { 396 if (mode_ == LATIN1) {
366 __ lbu(a3, MemOperand(a0, 0)); 397 __ lbu(a3, MemOperand(a0, 0));
367 __ addiu(a0, a0, char_size()); 398 __ addiu(a0, a0, char_size());
368 __ lbu(t0, MemOperand(a2, 0)); 399 __ lbu(t0, MemOperand(a2, 0));
369 __ addiu(a2, a2, char_size()); 400 __ addiu(a2, a2, char_size());
370 } else { 401 } else {
371 DCHECK(mode_ == UC16); 402 DCHECK(mode_ == UC16);
372 __ lhu(a3, MemOperand(a0, 0)); 403 __ lhu(a3, MemOperand(a0, 0));
373 __ addiu(a0, a0, char_size()); 404 __ addiu(a0, a0, char_size());
374 __ lhu(t0, MemOperand(a2, 0)); 405 __ lhu(t0, MemOperand(a2, 0));
375 __ addiu(a2, a2, char_size()); 406 __ addiu(a2, a2, char_size());
376 } 407 }
377 BranchOrBacktrack(on_no_match, ne, a3, Operand(t0)); 408 BranchOrBacktrack(on_no_match, ne, a3, Operand(t0));
378 __ Branch(&loop, lt, a0, Operand(a1)); 409 __ Branch(&loop, lt, a0, Operand(a1));
379 410
380 // Move current character position to position after match. 411 // Move current character position to position after match.
381 __ Subu(current_input_offset(), a2, end_of_input_address()); 412 __ Subu(current_input_offset(), a2, end_of_input_address());
413 if (read_backward) {
414 __ lw(t0, register_location(start_reg)); // Index of start of capture.
415 __ lw(t5, register_location(start_reg + 1)); // Index of end of capture.
416 __ Addu(current_input_offset(), current_input_offset(), Operand(t0));
417 __ Subu(current_input_offset(), current_input_offset(), Operand(t5));
418 }
382 __ bind(&fallthrough); 419 __ bind(&fallthrough);
383 } 420 }
384 421
385 422
386 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c, 423 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c,
387 Label* on_not_equal) { 424 Label* on_not_equal) {
388 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c)); 425 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c));
389 } 426 }
390 427
391 428
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 // Order here should correspond to order of offset constants in header file. 629 // Order here should correspond to order of offset constants in header file.
593 RegList registers_to_retain = s0.bit() | s1.bit() | s2.bit() | 630 RegList registers_to_retain = s0.bit() | s1.bit() | s2.bit() |
594 s3.bit() | s4.bit() | s5.bit() | s6.bit() | s7.bit() | fp.bit(); 631 s3.bit() | s4.bit() | s5.bit() | s6.bit() | s7.bit() | fp.bit();
595 RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit(); 632 RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit();
596 __ MultiPush(argument_registers | registers_to_retain | ra.bit()); 633 __ MultiPush(argument_registers | registers_to_retain | ra.bit());
597 // Set frame pointer in space for it if this is not a direct call 634 // Set frame pointer in space for it if this is not a direct call
598 // from generated code. 635 // from generated code.
599 __ Addu(frame_pointer(), sp, Operand(4 * kPointerSize)); 636 __ Addu(frame_pointer(), sp, Operand(4 * kPointerSize));
600 __ mov(a0, zero_reg); 637 __ mov(a0, zero_reg);
601 __ push(a0); // Make room for success counter and initialize it to 0. 638 __ push(a0); // Make room for success counter and initialize it to 0.
602 __ push(a0); // Make room for "position - 1" constant (value irrelevant). 639 __ push(a0); // Make room for "string start - 1" constant.
603 640
604 // Check if we have space on the stack for registers. 641 // Check if we have space on the stack for registers.
605 Label stack_limit_hit; 642 Label stack_limit_hit;
606 Label stack_ok; 643 Label stack_ok;
607 644
608 ExternalReference stack_limit = 645 ExternalReference stack_limit =
609 ExternalReference::address_of_stack_limit(masm_->isolate()); 646 ExternalReference::address_of_stack_limit(masm_->isolate());
610 __ li(a0, Operand(stack_limit)); 647 __ li(a0, Operand(stack_limit));
611 __ lw(a0, MemOperand(a0)); 648 __ lw(a0, MemOperand(a0));
612 __ Subu(a0, sp, a0); 649 __ Subu(a0, sp, a0);
(...skipping 22 matching lines...) Expand all
635 // Find negative length (offset of start relative to end). 672 // Find negative length (offset of start relative to end).
636 __ Subu(current_input_offset(), a0, end_of_input_address()); 673 __ Subu(current_input_offset(), a0, end_of_input_address());
637 // Set a0 to address of char before start of the input string 674 // Set a0 to address of char before start of the input string
638 // (effectively string position -1). 675 // (effectively string position -1).
639 __ lw(a1, MemOperand(frame_pointer(), kStartIndex)); 676 __ lw(a1, MemOperand(frame_pointer(), kStartIndex));
640 __ Subu(a0, current_input_offset(), Operand(char_size())); 677 __ Subu(a0, current_input_offset(), Operand(char_size()));
641 __ sll(t5, a1, (mode_ == UC16) ? 1 : 0); 678 __ sll(t5, a1, (mode_ == UC16) ? 1 : 0);
642 __ Subu(a0, a0, t5); 679 __ Subu(a0, a0, t5);
643 // Store this value in a local variable, for use when clearing 680 // Store this value in a local variable, for use when clearing
644 // position registers. 681 // position registers.
645 __ sw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 682 __ sw(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
646 683
647 // Initialize code pointer register 684 // Initialize code pointer register
648 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 685 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
649 686
650 Label load_char_start_regexp, start_regexp; 687 Label load_char_start_regexp, start_regexp;
651 // Load newline if index is at start, previous character otherwise. 688 // Load newline if index is at start, previous character otherwise.
652 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg)); 689 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
653 __ li(current_character(), Operand('\n')); 690 __ li(current_character(), Operand('\n'));
654 __ jmp(&start_regexp); 691 __ jmp(&start_regexp);
655 692
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 // Check whether we have enough room for another set of capture results. 781 // Check whether we have enough room for another set of capture results.
745 __ mov(v0, a0); 782 __ mov(v0, a0);
746 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_)); 783 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_));
747 784
748 __ sw(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); 785 __ sw(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
749 // Advance the location for output. 786 // Advance the location for output.
750 __ Addu(a2, a2, num_saved_registers_ * kPointerSize); 787 __ Addu(a2, a2, num_saved_registers_ * kPointerSize);
751 __ sw(a2, MemOperand(frame_pointer(), kRegisterOutput)); 788 __ sw(a2, MemOperand(frame_pointer(), kRegisterOutput));
752 789
753 // Prepare a0 to initialize registers with its value in the next run. 790 // Prepare a0 to initialize registers with its value in the next run.
754 __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 791 __ lw(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
755 792
756 if (global_with_zero_length_check()) { 793 if (global_with_zero_length_check()) {
757 // Special case for zero-length matches. 794 // Special case for zero-length matches.
758 // t7: capture start index 795 // t7: capture start index
759 // Not a zero-length match, restart. 796 // Not a zero-length match, restart.
760 __ Branch( 797 __ Branch(
761 &load_char_start_regexp, ne, current_input_offset(), Operand(t7)); 798 &load_char_start_regexp, ne, current_input_offset(), Operand(t7));
762 // Offset from the end is zero if we already reached the end. 799 // Offset from the end is zero if we already reached the end.
763 __ Branch(&exit_label_, eq, current_input_offset(), 800 __ Branch(&exit_label_, eq, current_input_offset(),
764 Operand(zero_reg)); 801 Operand(zero_reg));
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 RegExpMacroAssembler::IrregexpImplementation 935 RegExpMacroAssembler::IrregexpImplementation
899 RegExpMacroAssemblerMIPS::Implementation() { 936 RegExpMacroAssemblerMIPS::Implementation() {
900 return kMIPSImplementation; 937 return kMIPSImplementation;
901 } 938 }
902 939
903 940
904 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset, 941 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset,
905 Label* on_end_of_input, 942 Label* on_end_of_input,
906 bool check_bounds, 943 bool check_bounds,
907 int characters) { 944 int characters) {
908 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character.
909 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works). 945 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works).
910 if (check_bounds) { 946 if (check_bounds) {
911 CheckPosition(cp_offset + characters - 1, on_end_of_input); 947 if (cp_offset >= 0) {
948 CheckPosition(cp_offset + characters - 1, on_end_of_input);
949 } else {
950 CheckPosition(cp_offset, on_end_of_input);
951 }
912 } 952 }
913 LoadCurrentCharacterUnchecked(cp_offset, characters); 953 LoadCurrentCharacterUnchecked(cp_offset, characters);
914 } 954 }
915 955
916 956
917 void RegExpMacroAssemblerMIPS::PopCurrentPosition() { 957 void RegExpMacroAssemblerMIPS::PopCurrentPosition() {
918 Pop(current_input_offset()); 958 Pop(current_input_offset());
919 } 959 }
920 960
921 961
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 __ sw(current_input_offset(), register_location(reg)); 1049 __ sw(current_input_offset(), register_location(reg));
1010 } else { 1050 } else {
1011 __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size())); 1051 __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1012 __ sw(a0, register_location(reg)); 1052 __ sw(a0, register_location(reg));
1013 } 1053 }
1014 } 1054 }
1015 1055
1016 1056
1017 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { 1057 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) {
1018 DCHECK(reg_from <= reg_to); 1058 DCHECK(reg_from <= reg_to);
1019 __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 1059 __ lw(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
1020 for (int reg = reg_from; reg <= reg_to; reg++) { 1060 for (int reg = reg_from; reg <= reg_to; reg++) {
1021 __ sw(a0, register_location(reg)); 1061 __ sw(a0, register_location(reg));
1022 } 1062 }
1023 } 1063 }
1024 1064
1025 1065
1026 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) { 1066 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) {
1027 __ lw(a1, MemOperand(frame_pointer(), kStackHighEnd)); 1067 __ lw(a1, MemOperand(frame_pointer(), kStackHighEnd));
1028 __ Subu(a0, backtrack_stackpointer(), a1); 1068 __ Subu(a0, backtrack_stackpointer(), a1);
1029 __ sw(a0, register_location(reg)); 1069 __ sw(a0, register_location(reg));
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 if (num_registers_ <= register_index) { 1162 if (num_registers_ <= register_index) {
1123 num_registers_ = register_index + 1; 1163 num_registers_ = register_index + 1;
1124 } 1164 }
1125 return MemOperand(frame_pointer(), 1165 return MemOperand(frame_pointer(),
1126 kRegisterZero - register_index * kPointerSize); 1166 kRegisterZero - register_index * kPointerSize);
1127 } 1167 }
1128 1168
1129 1169
1130 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset, 1170 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset,
1131 Label* on_outside_input) { 1171 Label* on_outside_input) {
1132 BranchOrBacktrack(on_outside_input, 1172 if (cp_offset >= 0) {
1133 ge, 1173 BranchOrBacktrack(on_outside_input, ge, current_input_offset(),
1134 current_input_offset(), 1174 Operand(-cp_offset * char_size()));
1135 Operand(-cp_offset * char_size())); 1175 } else {
1176 __ lw(a1, MemOperand(frame_pointer(), kStringStartMinusOne));
1177 __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1178 BranchOrBacktrack(on_outside_input, le, a0, Operand(a1));
1179 }
1136 } 1180 }
1137 1181
1138 1182
1139 void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to, 1183 void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to,
1140 Condition condition, 1184 Condition condition,
1141 Register rs, 1185 Register rs,
1142 const Operand& rt) { 1186 const Operand& rt) {
1143 if (condition == al) { // Unconditional. 1187 if (condition == al) { // Unconditional.
1144 if (to == NULL) { 1188 if (to == NULL) {
1145 Backtrack(); 1189 Backtrack();
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 1280
1237 1281
1238 #undef __ 1282 #undef __
1239 1283
1240 #endif // V8_INTERPRETED_REGEXP 1284 #endif // V8_INTERPRETED_REGEXP
1241 1285
1242 } // namespace internal 1286 } // namespace internal
1243 } // namespace v8 1287 } // namespace v8
1244 1288
1245 #endif // V8_TARGET_ARCH_MIPS 1289 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/regexp/mips/regexp-macro-assembler-mips.h ('k') | src/regexp/mips64/regexp-macro-assembler-mips64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698