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