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

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: 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_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 // The length of the capture can only be negative if the end of the
234 // In either case succeed immediately. 224 // capture is not yet recorded. If the length is zero, the capture is
235 __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); 225 // either empty or uncaptured. In either of those cases, succeed.
226 __ Branch(&fallthrough, le, 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 __ Subu(t5, current_input_offset(), a1);
231 BranchOrBacktrack(on_no_match, le, t5, 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). 364 // The length of the capture can only be negative if the end of the
352 __ Branch(&fallthrough, eq, a1, Operand(zero_reg)); 365 // capture is not yet recorded. If the length is zero, the capture is
366 // either empty or uncaptured. In either of those cases, succeed.
367 __ Branch(&fallthrough, le, a1, Operand(zero_reg));
353 368
354 __ Addu(t5, a1, current_input_offset()); 369 if (read_backward) {
355 // Check that there are enough characters left in the input. 370 __ lw(t0, MemOperand(frame_pointer(), kStringStartMinusOne));
356 BranchOrBacktrack(on_no_match, gt, t5, Operand(zero_reg)); 371 __ Subu(t5, current_input_offset(), a1);
372 BranchOrBacktrack(on_no_match, le, t5, Operand(t0));
373 } else {
374 __ Addu(t5, a1, current_input_offset());
375 // Check that there are enough characters left in the input.
376 BranchOrBacktrack(on_no_match, gt, t5, Operand(zero_reg));
377 }
357 378
358 // Compute pointers to match string and capture string. 379 // a0 - offset of start of capture.
380 // a1 - length of capture.
359 __ Addu(a0, a0, Operand(end_of_input_address())); 381 __ Addu(a0, a0, Operand(end_of_input_address()));
360 __ Addu(a2, end_of_input_address(), Operand(current_input_offset())); 382 __ Addu(a2, end_of_input_address(), Operand(current_input_offset()));
361 __ Addu(a1, a1, Operand(a0)); 383 if (read_backward) {
384 __ Subu(a2, a2, Operand(a1));
385 }
386 __ Addu(a1, a0, Operand(a1));
387
388 // a0 - Address of start of capture.
389 // a1 - Address of end of capture.
390 // a2 - Address of current input position.
391
362 392
363 Label loop; 393 Label loop;
364 __ bind(&loop); 394 __ bind(&loop);
365 if (mode_ == LATIN1) { 395 if (mode_ == LATIN1) {
366 __ lbu(a3, MemOperand(a0, 0)); 396 __ lbu(a3, MemOperand(a0, 0));
367 __ addiu(a0, a0, char_size()); 397 __ addiu(a0, a0, char_size());
368 __ lbu(t0, MemOperand(a2, 0)); 398 __ lbu(t0, MemOperand(a2, 0));
369 __ addiu(a2, a2, char_size()); 399 __ addiu(a2, a2, char_size());
370 } else { 400 } else {
371 DCHECK(mode_ == UC16); 401 DCHECK(mode_ == UC16);
372 __ lhu(a3, MemOperand(a0, 0)); 402 __ lhu(a3, MemOperand(a0, 0));
373 __ addiu(a0, a0, char_size()); 403 __ addiu(a0, a0, char_size());
374 __ lhu(t0, MemOperand(a2, 0)); 404 __ lhu(t0, MemOperand(a2, 0));
375 __ addiu(a2, a2, char_size()); 405 __ addiu(a2, a2, char_size());
376 } 406 }
377 BranchOrBacktrack(on_no_match, ne, a3, Operand(t0)); 407 BranchOrBacktrack(on_no_match, ne, a3, Operand(t0));
378 __ Branch(&loop, lt, a0, Operand(a1)); 408 __ Branch(&loop, lt, a0, Operand(a1));
379 409
380 // Move current character position to position after match. 410 // Move current character position to position after match.
381 __ Subu(current_input_offset(), a2, end_of_input_address()); 411 __ Subu(current_input_offset(), a2, end_of_input_address());
412 if (read_backward) {
413 __ lw(t0, register_location(start_reg)); // Index of start of capture.
414 __ lw(t5, register_location(start_reg + 1)); // Index of end of capture.
415 __ Addu(current_input_offset(), current_input_offset(), Operand(t0));
416 __ Subu(current_input_offset(), current_input_offset(), Operand(t5));
417 }
382 __ bind(&fallthrough); 418 __ bind(&fallthrough);
383 } 419 }
384 420
385 421
386 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c, 422 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c,
387 Label* on_not_equal) { 423 Label* on_not_equal) {
388 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c)); 424 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c));
389 } 425 }
390 426
391 427
(...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. 628 // Order here should correspond to order of offset constants in header file.
593 RegList registers_to_retain = s0.bit() | s1.bit() | s2.bit() | 629 RegList registers_to_retain = s0.bit() | s1.bit() | s2.bit() |
594 s3.bit() | s4.bit() | s5.bit() | s6.bit() | s7.bit() | fp.bit(); 630 s3.bit() | s4.bit() | s5.bit() | s6.bit() | s7.bit() | fp.bit();
595 RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit(); 631 RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit();
596 __ MultiPush(argument_registers | registers_to_retain | ra.bit()); 632 __ MultiPush(argument_registers | registers_to_retain | ra.bit());
597 // Set frame pointer in space for it if this is not a direct call 633 // Set frame pointer in space for it if this is not a direct call
598 // from generated code. 634 // from generated code.
599 __ Addu(frame_pointer(), sp, Operand(4 * kPointerSize)); 635 __ Addu(frame_pointer(), sp, Operand(4 * kPointerSize));
600 __ mov(a0, zero_reg); 636 __ mov(a0, zero_reg);
601 __ push(a0); // Make room for success counter and initialize it to 0. 637 __ push(a0); // Make room for success counter and initialize it to 0.
602 __ push(a0); // Make room for "position - 1" constant (value irrelevant). 638 __ push(a0); // Make room for "string start - 1" constant.
603 639
604 // Check if we have space on the stack for registers. 640 // Check if we have space on the stack for registers.
605 Label stack_limit_hit; 641 Label stack_limit_hit;
606 Label stack_ok; 642 Label stack_ok;
607 643
608 ExternalReference stack_limit = 644 ExternalReference stack_limit =
609 ExternalReference::address_of_stack_limit(masm_->isolate()); 645 ExternalReference::address_of_stack_limit(masm_->isolate());
610 __ li(a0, Operand(stack_limit)); 646 __ li(a0, Operand(stack_limit));
611 __ lw(a0, MemOperand(a0)); 647 __ lw(a0, MemOperand(a0));
612 __ Subu(a0, sp, a0); 648 __ Subu(a0, sp, a0);
(...skipping 22 matching lines...) Expand all
635 // Find negative length (offset of start relative to end). 671 // Find negative length (offset of start relative to end).
636 __ Subu(current_input_offset(), a0, end_of_input_address()); 672 __ Subu(current_input_offset(), a0, end_of_input_address());
637 // Set a0 to address of char before start of the input string 673 // Set a0 to address of char before start of the input string
638 // (effectively string position -1). 674 // (effectively string position -1).
639 __ lw(a1, MemOperand(frame_pointer(), kStartIndex)); 675 __ lw(a1, MemOperand(frame_pointer(), kStartIndex));
640 __ Subu(a0, current_input_offset(), Operand(char_size())); 676 __ Subu(a0, current_input_offset(), Operand(char_size()));
641 __ sll(t5, a1, (mode_ == UC16) ? 1 : 0); 677 __ sll(t5, a1, (mode_ == UC16) ? 1 : 0);
642 __ Subu(a0, a0, t5); 678 __ Subu(a0, a0, t5);
643 // Store this value in a local variable, for use when clearing 679 // Store this value in a local variable, for use when clearing
644 // position registers. 680 // position registers.
645 __ sw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 681 __ sw(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
646 682
647 // Initialize code pointer register 683 // Initialize code pointer register
648 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); 684 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
649 685
650 Label load_char_start_regexp, start_regexp; 686 Label load_char_start_regexp, start_regexp;
651 // Load newline if index is at start, previous character otherwise. 687 // Load newline if index is at start, previous character otherwise.
652 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg)); 688 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
653 __ li(current_character(), Operand('\n')); 689 __ li(current_character(), Operand('\n'));
654 __ jmp(&start_regexp); 690 __ jmp(&start_regexp);
655 691
(...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. 780 // Check whether we have enough room for another set of capture results.
745 __ mov(v0, a0); 781 __ mov(v0, a0);
746 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_)); 782 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_));
747 783
748 __ sw(a1, MemOperand(frame_pointer(), kNumOutputRegisters)); 784 __ sw(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
749 // Advance the location for output. 785 // Advance the location for output.
750 __ Addu(a2, a2, num_saved_registers_ * kPointerSize); 786 __ Addu(a2, a2, num_saved_registers_ * kPointerSize);
751 __ sw(a2, MemOperand(frame_pointer(), kRegisterOutput)); 787 __ sw(a2, MemOperand(frame_pointer(), kRegisterOutput));
752 788
753 // Prepare a0 to initialize registers with its value in the next run. 789 // Prepare a0 to initialize registers with its value in the next run.
754 __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 790 __ lw(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
755 791
756 if (global_with_zero_length_check()) { 792 if (global_with_zero_length_check()) {
757 // Special case for zero-length matches. 793 // Special case for zero-length matches.
758 // t7: capture start index 794 // t7: capture start index
759 // Not a zero-length match, restart. 795 // Not a zero-length match, restart.
760 __ Branch( 796 __ Branch(
761 &load_char_start_regexp, ne, current_input_offset(), Operand(t7)); 797 &load_char_start_regexp, ne, current_input_offset(), Operand(t7));
762 // Offset from the end is zero if we already reached the end. 798 // Offset from the end is zero if we already reached the end.
763 __ Branch(&exit_label_, eq, current_input_offset(), 799 __ Branch(&exit_label_, eq, current_input_offset(),
764 Operand(zero_reg)); 800 Operand(zero_reg));
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 RegExpMacroAssembler::IrregexpImplementation 934 RegExpMacroAssembler::IrregexpImplementation
899 RegExpMacroAssemblerMIPS::Implementation() { 935 RegExpMacroAssemblerMIPS::Implementation() {
900 return kMIPSImplementation; 936 return kMIPSImplementation;
901 } 937 }
902 938
903 939
904 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset, 940 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset,
905 Label* on_end_of_input, 941 Label* on_end_of_input,
906 bool check_bounds, 942 bool check_bounds,
907 int characters) { 943 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). 944 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works).
910 if (check_bounds) { 945 if (check_bounds) {
911 CheckPosition(cp_offset + characters - 1, on_end_of_input); 946 if (cp_offset >= 0) {
947 CheckPosition(cp_offset + characters - 1, on_end_of_input);
948 } else {
949 CheckPosition(cp_offset, on_end_of_input);
950 }
912 } 951 }
913 LoadCurrentCharacterUnchecked(cp_offset, characters); 952 LoadCurrentCharacterUnchecked(cp_offset, characters);
914 } 953 }
915 954
916 955
917 void RegExpMacroAssemblerMIPS::PopCurrentPosition() { 956 void RegExpMacroAssemblerMIPS::PopCurrentPosition() {
918 Pop(current_input_offset()); 957 Pop(current_input_offset());
919 } 958 }
920 959
921 960
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 __ sw(current_input_offset(), register_location(reg)); 1048 __ sw(current_input_offset(), register_location(reg));
1010 } else { 1049 } else {
1011 __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size())); 1050 __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1012 __ sw(a0, register_location(reg)); 1051 __ sw(a0, register_location(reg));
1013 } 1052 }
1014 } 1053 }
1015 1054
1016 1055
1017 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { 1056 void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) {
1018 DCHECK(reg_from <= reg_to); 1057 DCHECK(reg_from <= reg_to);
1019 __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne)); 1058 __ lw(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
1020 for (int reg = reg_from; reg <= reg_to; reg++) { 1059 for (int reg = reg_from; reg <= reg_to; reg++) {
1021 __ sw(a0, register_location(reg)); 1060 __ sw(a0, register_location(reg));
1022 } 1061 }
1023 } 1062 }
1024 1063
1025 1064
1026 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) { 1065 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) {
1027 __ lw(a1, MemOperand(frame_pointer(), kStackHighEnd)); 1066 __ lw(a1, MemOperand(frame_pointer(), kStackHighEnd));
1028 __ Subu(a0, backtrack_stackpointer(), a1); 1067 __ Subu(a0, backtrack_stackpointer(), a1);
1029 __ sw(a0, register_location(reg)); 1068 __ sw(a0, register_location(reg));
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 if (num_registers_ <= register_index) { 1161 if (num_registers_ <= register_index) {
1123 num_registers_ = register_index + 1; 1162 num_registers_ = register_index + 1;
1124 } 1163 }
1125 return MemOperand(frame_pointer(), 1164 return MemOperand(frame_pointer(),
1126 kRegisterZero - register_index * kPointerSize); 1165 kRegisterZero - register_index * kPointerSize);
1127 } 1166 }
1128 1167
1129 1168
1130 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset, 1169 void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset,
1131 Label* on_outside_input) { 1170 Label* on_outside_input) {
1132 BranchOrBacktrack(on_outside_input, 1171 if (cp_offset >= 0) {
1133 ge, 1172 BranchOrBacktrack(on_outside_input, ge, current_input_offset(),
1134 current_input_offset(), 1173 Operand(-cp_offset * char_size()));
1135 Operand(-cp_offset * char_size())); 1174 } else {
1175 __ lw(a1, MemOperand(frame_pointer(), kStringStartMinusOne));
1176 __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1177 BranchOrBacktrack(on_outside_input, le, a0, Operand(a1));
1178 }
1136 } 1179 }
1137 1180
1138 1181
1139 void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to, 1182 void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to,
1140 Condition condition, 1183 Condition condition,
1141 Register rs, 1184 Register rs,
1142 const Operand& rt) { 1185 const Operand& rt) {
1143 if (condition == al) { // Unconditional. 1186 if (condition == al) { // Unconditional.
1144 if (to == NULL) { 1187 if (to == NULL) {
1145 Backtrack(); 1188 Backtrack();
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 1279
1237 1280
1238 #undef __ 1281 #undef __
1239 1282
1240 #endif // V8_INTERPRETED_REGEXP 1283 #endif // V8_INTERPRETED_REGEXP
1241 1284
1242 } // namespace internal 1285 } // namespace internal
1243 } // namespace v8 1286 } // namespace v8
1244 1287
1245 #endif // V8_TARGET_ARCH_MIPS 1288 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698