OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 5 #if V8_TARGET_ARCH_PPC |
6 | 6 |
7 #include "src/regexp/ppc/regexp-macro-assembler-ppc.h" | 7 #include "src/regexp/ppc/regexp-macro-assembler-ppc.h" |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 * - fp[-8] stack_area_base (high end of the memory area to use as | 53 * - fp[-8] stack_area_base (high end of the memory area to use as |
54 * backtracking stack). | 54 * backtracking stack). |
55 * - fp[-12] capture array size (may fit multiple sets of matches) | 55 * - fp[-12] capture array size (may fit multiple sets of matches) |
56 * - fp[-16] int* capture_array (int[num_saved_registers_], for output). | 56 * - fp[-16] int* capture_array (int[num_saved_registers_], for output). |
57 * - fp[-20] end of input (address of end of string). | 57 * - fp[-20] end of input (address of end of string). |
58 * - fp[-24] start of input (address of first character in string). | 58 * - fp[-24] start of input (address of first character in string). |
59 * - fp[-28] start index (character index of start). | 59 * - fp[-28] start index (character index of start). |
60 * - fp[-32] void* input_string (location of a handle containing the string). | 60 * - fp[-32] void* input_string (location of a handle containing the string). |
61 * - fp[-36] success counter (only for global regexps to count matches). | 61 * - fp[-36] success counter (only for global regexps to count matches). |
62 * - fp[-40] Offset of location before start of input (effectively character | 62 * - fp[-40] Offset of location before start of input (effectively character |
63 * position -1). Used to initialize capture registers to a | 63 * string start - 1). Used to initialize capture registers to a |
64 * non-position. | 64 * non-position. |
65 * - fp[-44] At start (if 1, we are starting at the start of the | 65 * - fp[-44] At start (if 1, we are starting at the start of the |
66 * string, otherwise 0) | 66 * string, otherwise 0) |
67 * - fp[-48] register 0 (Only positions must be stored in the first | 67 * - fp[-48] register 0 (Only positions must be stored in the first |
68 * - register 1 num_saved_registers_ registers) | 68 * - register 1 num_saved_registers_ registers) |
69 * - ... | 69 * - ... |
70 * - register num_registers-1 | 70 * - register num_registers-1 |
71 * --- sp --- | 71 * --- sp --- |
72 * | 72 * |
73 * The first num_saved_registers_ registers are initialized to point to | 73 * The first num_saved_registers_ registers are initialized to point to |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 } | 182 } |
183 | 183 |
184 | 184 |
185 void RegExpMacroAssemblerPPC::CheckCharacterGT(uc16 limit, Label* on_greater) { | 185 void RegExpMacroAssemblerPPC::CheckCharacterGT(uc16 limit, Label* on_greater) { |
186 __ Cmpli(current_character(), Operand(limit), r0); | 186 __ Cmpli(current_character(), Operand(limit), r0); |
187 BranchOrBacktrack(gt, on_greater); | 187 BranchOrBacktrack(gt, on_greater); |
188 } | 188 } |
189 | 189 |
190 | 190 |
191 void RegExpMacroAssemblerPPC::CheckAtStart(Label* on_at_start) { | 191 void RegExpMacroAssemblerPPC::CheckAtStart(Label* on_at_start) { |
192 Label not_at_start; | 192 __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne)); |
193 // Did we start the match at the start of the string at all? | 193 __ addi(r3, current_input_offset(), Operand(-char_size())); |
194 __ LoadP(r3, MemOperand(frame_pointer(), kStartIndex)); | 194 __ cmp(r3, r4); |
195 __ cmpi(r3, Operand::Zero()); | |
196 BranchOrBacktrack(ne, ¬_at_start); | |
197 | |
198 // If we did, are we still at the start of the input? | |
199 __ LoadP(r4, MemOperand(frame_pointer(), kInputStart)); | |
200 __ mr(r0, current_input_offset()); | |
201 __ add(r3, end_of_input_address(), r0); | |
202 __ cmp(r4, r3); | |
203 BranchOrBacktrack(eq, on_at_start); | 195 BranchOrBacktrack(eq, on_at_start); |
204 __ bind(¬_at_start); | |
205 } | 196 } |
206 | 197 |
207 | 198 |
208 void RegExpMacroAssemblerPPC::CheckNotAtStart(Label* on_not_at_start) { | 199 void RegExpMacroAssemblerPPC::CheckNotAtStart(int cp_offset, |
209 // Did we start the match at the start of the string at all? | 200 Label* on_not_at_start) { |
210 __ LoadP(r3, MemOperand(frame_pointer(), kStartIndex)); | 201 __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne)); |
211 __ cmpi(r3, Operand::Zero()); | 202 __ addi(r3, current_input_offset(), |
212 BranchOrBacktrack(ne, on_not_at_start); | 203 Operand(-char_size() + cp_offset * char_size())); |
213 // If we did, are we still at the start of the input? | |
214 __ LoadP(r4, MemOperand(frame_pointer(), kInputStart)); | |
215 __ add(r3, end_of_input_address(), current_input_offset()); | |
216 __ cmp(r3, r4); | 204 __ cmp(r3, r4); |
217 BranchOrBacktrack(ne, on_not_at_start); | 205 BranchOrBacktrack(ne, on_not_at_start); |
218 } | 206 } |
219 | 207 |
220 | 208 |
221 void RegExpMacroAssemblerPPC::CheckCharacterLT(uc16 limit, Label* on_less) { | 209 void RegExpMacroAssemblerPPC::CheckCharacterLT(uc16 limit, Label* on_less) { |
222 __ Cmpli(current_character(), Operand(limit), r0); | 210 __ Cmpli(current_character(), Operand(limit), r0); |
223 BranchOrBacktrack(lt, on_less); | 211 BranchOrBacktrack(lt, on_less); |
224 } | 212 } |
225 | 213 |
226 | 214 |
227 void RegExpMacroAssemblerPPC::CheckGreedyLoop(Label* on_equal) { | 215 void RegExpMacroAssemblerPPC::CheckGreedyLoop(Label* on_equal) { |
228 Label backtrack_non_equal; | 216 Label backtrack_non_equal; |
229 __ LoadP(r3, MemOperand(backtrack_stackpointer(), 0)); | 217 __ LoadP(r3, MemOperand(backtrack_stackpointer(), 0)); |
230 __ cmp(current_input_offset(), r3); | 218 __ cmp(current_input_offset(), r3); |
231 __ bne(&backtrack_non_equal); | 219 __ bne(&backtrack_non_equal); |
232 __ addi(backtrack_stackpointer(), backtrack_stackpointer(), | 220 __ addi(backtrack_stackpointer(), backtrack_stackpointer(), |
233 Operand(kPointerSize)); | 221 Operand(kPointerSize)); |
234 | 222 |
235 __ bind(&backtrack_non_equal); | 223 __ bind(&backtrack_non_equal); |
236 BranchOrBacktrack(eq, on_equal); | 224 BranchOrBacktrack(eq, on_equal); |
237 } | 225 } |
238 | 226 |
239 | 227 |
240 void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase( | 228 void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase( |
241 int start_reg, Label* on_no_match) { | 229 int start_reg, bool read_backward, Label* on_no_match) { |
242 Label fallthrough; | 230 Label fallthrough; |
243 __ LoadP(r3, register_location(start_reg), r0); // Index of start of capture | 231 __ LoadP(r3, register_location(start_reg), r0); // Index of start of capture |
244 __ LoadP(r4, register_location(start_reg + 1), r0); // Index of end | 232 __ LoadP(r4, register_location(start_reg + 1), r0); // Index of end |
245 __ sub(r4, r4, r3, LeaveOE, SetRC); // Length of capture. | 233 __ sub(r4, r4, r3, LeaveOE, SetRC); // Length of capture. |
246 | 234 |
247 // If length is zero, either the capture is empty or it is not participating. | 235 // At this point, the capture registers are either both set or both cleared. |
248 // In either case succeed immediately. | 236 // If the capture length is zero, then the capture is either empty or cleared. |
| 237 // Fall through in both cases. |
249 __ beq(&fallthrough, cr0); | 238 __ beq(&fallthrough, cr0); |
250 | 239 |
251 // Check that there are enough characters left in the input. | 240 // Check that there are enough characters left in the input. |
252 __ add(r0, r4, current_input_offset(), LeaveOE, SetRC); | 241 if (read_backward) { |
253 // __ cmn(r1, Operand(current_input_offset())); | 242 __ LoadP(r6, MemOperand(frame_pointer(), kStringStartMinusOne)); |
254 BranchOrBacktrack(gt, on_no_match, cr0); | 243 __ add(r6, r6, r4); |
| 244 __ cmp(current_input_offset(), r6); |
| 245 BranchOrBacktrack(le, on_no_match); |
| 246 } else { |
| 247 __ add(r0, r4, current_input_offset(), LeaveOE, SetRC); |
| 248 BranchOrBacktrack(gt, on_no_match, cr0); |
| 249 } |
255 | 250 |
256 if (mode_ == LATIN1) { | 251 if (mode_ == LATIN1) { |
257 Label success; | 252 Label success; |
258 Label fail; | 253 Label fail; |
259 Label loop_check; | 254 Label loop_check; |
260 | 255 |
261 // r3 - offset of start of capture | 256 // r3 - offset of start of capture |
262 // r4 - length of capture | 257 // r4 - length of capture |
263 __ add(r3, r3, end_of_input_address()); | 258 __ add(r3, r3, end_of_input_address()); |
264 __ add(r5, end_of_input_address(), current_input_offset()); | 259 __ add(r5, end_of_input_address(), current_input_offset()); |
| 260 if (read_backward) { |
| 261 __ sub(r5, r5, r4); // Offset by length when matching backwards. |
| 262 } |
265 __ add(r4, r3, r4); | 263 __ add(r4, r3, r4); |
266 | 264 |
267 // r3 - Address of start of capture. | 265 // r3 - Address of start of capture. |
268 // r4 - Address of end of capture | 266 // r4 - Address of end of capture |
269 // r5 - Address of current input position. | 267 // r5 - Address of current input position. |
270 | 268 |
271 Label loop; | 269 Label loop; |
272 __ bind(&loop); | 270 __ bind(&loop); |
273 __ lbz(r6, MemOperand(r3)); | 271 __ lbz(r6, MemOperand(r3)); |
274 __ addi(r3, r3, Operand(char_size())); | 272 __ addi(r3, r3, Operand(char_size())); |
(...skipping 21 matching lines...) Expand all Loading... |
296 __ cmp(r3, r4); | 294 __ cmp(r3, r4); |
297 __ blt(&loop); | 295 __ blt(&loop); |
298 __ b(&success); | 296 __ b(&success); |
299 | 297 |
300 __ bind(&fail); | 298 __ bind(&fail); |
301 BranchOrBacktrack(al, on_no_match); | 299 BranchOrBacktrack(al, on_no_match); |
302 | 300 |
303 __ bind(&success); | 301 __ bind(&success); |
304 // Compute new value of character position after the matched part. | 302 // Compute new value of character position after the matched part. |
305 __ sub(current_input_offset(), r5, end_of_input_address()); | 303 __ sub(current_input_offset(), r5, end_of_input_address()); |
| 304 if (read_backward) { |
| 305 __ LoadP(r3, register_location(start_reg)); // Index of start of capture |
| 306 __ LoadP(r4, |
| 307 register_location(start_reg + 1)); // Index of end of capture |
| 308 __ add(current_input_offset(), current_input_offset(), r3); |
| 309 __ sub(current_input_offset(), current_input_offset(), r4); |
| 310 } |
306 } else { | 311 } else { |
307 DCHECK(mode_ == UC16); | 312 DCHECK(mode_ == UC16); |
308 int argument_count = 4; | 313 int argument_count = 4; |
309 __ PrepareCallCFunction(argument_count, r5); | 314 __ PrepareCallCFunction(argument_count, r5); |
310 | 315 |
311 // r3 - offset of start of capture | 316 // r3 - offset of start of capture |
312 // r4 - length of capture | 317 // r4 - length of capture |
313 | 318 |
314 // Put arguments into arguments registers. | 319 // Put arguments into arguments registers. |
315 // Parameters are | 320 // Parameters are |
316 // r3: Address byte_offset1 - Address captured substring's start. | 321 // r3: Address byte_offset1 - Address captured substring's start. |
317 // r4: Address byte_offset2 - Address of current character position. | 322 // r4: Address byte_offset2 - Address of current character position. |
318 // r5: size_t byte_length - length of capture in bytes(!) | 323 // r5: size_t byte_length - length of capture in bytes(!) |
319 // r6: Isolate* isolate | 324 // r6: Isolate* isolate |
320 | 325 |
321 // Address of start of capture. | 326 // Address of start of capture. |
322 __ add(r3, r3, end_of_input_address()); | 327 __ add(r3, r3, end_of_input_address()); |
323 // Length of capture. | 328 // Length of capture. |
324 __ mr(r5, r4); | 329 __ mr(r5, r4); |
325 // Save length in callee-save register for use on return. | 330 // Save length in callee-save register for use on return. |
326 __ mr(r25, r4); | 331 __ mr(r25, r4); |
327 // Address of current input position. | 332 // Address of current input position. |
328 __ add(r4, current_input_offset(), end_of_input_address()); | 333 __ add(r4, current_input_offset(), end_of_input_address()); |
| 334 if (read_backward) { |
| 335 __ sub(r4, r4, r25); |
| 336 } |
329 // Isolate. | 337 // Isolate. |
330 __ mov(r6, Operand(ExternalReference::isolate_address(isolate()))); | 338 __ mov(r6, Operand(ExternalReference::isolate_address(isolate()))); |
331 | 339 |
332 { | 340 { |
333 AllowExternalCallThatCantCauseGC scope(masm_); | 341 AllowExternalCallThatCantCauseGC scope(masm_); |
334 ExternalReference function = | 342 ExternalReference function = |
335 ExternalReference::re_case_insensitive_compare_uc16(isolate()); | 343 ExternalReference::re_case_insensitive_compare_uc16(isolate()); |
336 __ CallCFunction(function, argument_count); | 344 __ CallCFunction(function, argument_count); |
337 } | 345 } |
338 | 346 |
339 // Check if function returned non-zero for success or zero for failure. | 347 // Check if function returned non-zero for success or zero for failure. |
340 __ cmpi(r3, Operand::Zero()); | 348 __ cmpi(r3, Operand::Zero()); |
341 BranchOrBacktrack(eq, on_no_match); | 349 BranchOrBacktrack(eq, on_no_match); |
342 // On success, increment position by length of capture. | 350 |
343 __ add(current_input_offset(), current_input_offset(), r25); | 351 // On success, advance position by length of capture. |
| 352 if (read_backward) { |
| 353 __ sub(current_input_offset(), current_input_offset(), r25); |
| 354 } else { |
| 355 __ add(current_input_offset(), current_input_offset(), r25); |
| 356 } |
344 } | 357 } |
345 | 358 |
346 __ bind(&fallthrough); | 359 __ bind(&fallthrough); |
347 } | 360 } |
348 | 361 |
349 | 362 |
350 void RegExpMacroAssemblerPPC::CheckNotBackReference(int start_reg, | 363 void RegExpMacroAssemblerPPC::CheckNotBackReference(int start_reg, |
| 364 bool read_backward, |
351 Label* on_no_match) { | 365 Label* on_no_match) { |
352 Label fallthrough; | 366 Label fallthrough; |
353 Label success; | 367 Label success; |
354 | 368 |
355 // Find length of back-referenced capture. | 369 // Find length of back-referenced capture. |
356 __ LoadP(r3, register_location(start_reg), r0); | 370 __ LoadP(r3, register_location(start_reg), r0); |
357 __ LoadP(r4, register_location(start_reg + 1), r0); | 371 __ LoadP(r4, register_location(start_reg + 1), r0); |
358 __ sub(r4, r4, r3, LeaveOE, SetRC); // Length to check. | 372 __ sub(r4, r4, r3, LeaveOE, SetRC); // Length to check. |
359 // Succeed on empty capture (including no capture). | 373 |
| 374 // At this point, the capture registers are either both set or both cleared. |
| 375 // If the capture length is zero, then the capture is either empty or cleared. |
| 376 // Fall through in both cases. |
360 __ beq(&fallthrough, cr0); | 377 __ beq(&fallthrough, cr0); |
361 | 378 |
362 // Check that there are enough characters left in the input. | 379 // Check that there are enough characters left in the input. |
363 __ add(r0, r4, current_input_offset(), LeaveOE, SetRC); | 380 if (read_backward) { |
364 BranchOrBacktrack(gt, on_no_match, cr0); | 381 __ LoadP(r6, MemOperand(frame_pointer(), kStringStartMinusOne)); |
| 382 __ add(r6, r6, r4); |
| 383 __ cmp(current_input_offset(), r6); |
| 384 BranchOrBacktrack(lt, on_no_match); |
| 385 } else { |
| 386 __ add(r0, r4, current_input_offset(), LeaveOE, SetRC); |
| 387 BranchOrBacktrack(gt, on_no_match, cr0); |
| 388 } |
365 | 389 |
366 // Compute pointers to match string and capture string | 390 // r3 - offset of start of capture |
| 391 // r4 - length of capture |
367 __ add(r3, r3, end_of_input_address()); | 392 __ add(r3, r3, end_of_input_address()); |
368 __ add(r5, end_of_input_address(), current_input_offset()); | 393 __ add(r5, end_of_input_address(), current_input_offset()); |
| 394 if (read_backward) { |
| 395 __ sub(r5, r5, r4); // Offset by length when matching backwards. |
| 396 } |
369 __ add(r4, r4, r3); | 397 __ add(r4, r4, r3); |
370 | 398 |
371 Label loop; | 399 Label loop; |
372 __ bind(&loop); | 400 __ bind(&loop); |
373 if (mode_ == LATIN1) { | 401 if (mode_ == LATIN1) { |
374 __ lbz(r6, MemOperand(r3)); | 402 __ lbz(r6, MemOperand(r3)); |
375 __ addi(r3, r3, Operand(char_size())); | 403 __ addi(r3, r3, Operand(char_size())); |
376 __ lbz(r25, MemOperand(r5)); | 404 __ lbz(r25, MemOperand(r5)); |
377 __ addi(r5, r5, Operand(char_size())); | 405 __ addi(r5, r5, Operand(char_size())); |
378 } else { | 406 } else { |
379 DCHECK(mode_ == UC16); | 407 DCHECK(mode_ == UC16); |
380 __ lhz(r6, MemOperand(r3)); | 408 __ lhz(r6, MemOperand(r3)); |
381 __ addi(r3, r3, Operand(char_size())); | 409 __ addi(r3, r3, Operand(char_size())); |
382 __ lhz(r25, MemOperand(r5)); | 410 __ lhz(r25, MemOperand(r5)); |
383 __ addi(r5, r5, Operand(char_size())); | 411 __ addi(r5, r5, Operand(char_size())); |
384 } | 412 } |
385 __ cmp(r6, r25); | 413 __ cmp(r6, r25); |
386 BranchOrBacktrack(ne, on_no_match); | 414 BranchOrBacktrack(ne, on_no_match); |
387 __ cmp(r3, r4); | 415 __ cmp(r3, r4); |
388 __ blt(&loop); | 416 __ blt(&loop); |
389 | 417 |
390 // Move current character position to position after match. | 418 // Move current character position to position after match. |
391 __ sub(current_input_offset(), r5, end_of_input_address()); | 419 __ sub(current_input_offset(), r5, end_of_input_address()); |
| 420 if (read_backward) { |
| 421 __ LoadP(r3, register_location(start_reg)); // Index of start of capture |
| 422 __ LoadP(r4, register_location(start_reg + 1)); // Index of end of capture |
| 423 __ add(current_input_offset(), current_input_offset(), r3); |
| 424 __ sub(current_input_offset(), current_input_offset(), r4); |
| 425 } |
| 426 |
392 __ bind(&fallthrough); | 427 __ bind(&fallthrough); |
393 } | 428 } |
394 | 429 |
395 | 430 |
396 void RegExpMacroAssemblerPPC::CheckNotCharacter(unsigned c, | 431 void RegExpMacroAssemblerPPC::CheckNotCharacter(unsigned c, |
397 Label* on_not_equal) { | 432 Label* on_not_equal) { |
398 __ Cmpli(current_character(), Operand(c), r0); | 433 __ Cmpli(current_character(), Operand(c), r0); |
399 BranchOrBacktrack(ne, on_not_equal); | 434 BranchOrBacktrack(ne, on_not_equal); |
400 } | 435 } |
401 | 436 |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 RegList argument_registers = r3.bit() | r4.bit() | r5.bit() | r6.bit() | | 667 RegList argument_registers = r3.bit() | r4.bit() | r5.bit() | r6.bit() | |
633 r7.bit() | r8.bit() | r9.bit() | r10.bit(); | 668 r7.bit() | r8.bit() | r9.bit() | r10.bit(); |
634 __ mflr(r0); | 669 __ mflr(r0); |
635 __ push(r0); | 670 __ push(r0); |
636 __ MultiPush(argument_registers | registers_to_retain); | 671 __ MultiPush(argument_registers | registers_to_retain); |
637 // Set frame pointer in space for it if this is not a direct call | 672 // Set frame pointer in space for it if this is not a direct call |
638 // from generated code. | 673 // from generated code. |
639 __ addi(frame_pointer(), sp, Operand(8 * kPointerSize)); | 674 __ addi(frame_pointer(), sp, Operand(8 * kPointerSize)); |
640 __ li(r3, Operand::Zero()); | 675 __ li(r3, Operand::Zero()); |
641 __ push(r3); // Make room for success counter and initialize it to 0. | 676 __ push(r3); // Make room for success counter and initialize it to 0. |
642 __ push(r3); // Make room for "position - 1" constant (value is irrelevant) | 677 __ push(r3); // Make room for "string start - 1" constant. |
643 // Check if we have space on the stack for registers. | 678 // Check if we have space on the stack for registers. |
644 Label stack_limit_hit; | 679 Label stack_limit_hit; |
645 Label stack_ok; | 680 Label stack_ok; |
646 | 681 |
647 ExternalReference stack_limit = | 682 ExternalReference stack_limit = |
648 ExternalReference::address_of_stack_limit(isolate()); | 683 ExternalReference::address_of_stack_limit(isolate()); |
649 __ mov(r3, Operand(stack_limit)); | 684 __ mov(r3, Operand(stack_limit)); |
650 __ LoadP(r3, MemOperand(r3)); | 685 __ LoadP(r3, MemOperand(r3)); |
651 __ sub(r3, sp, r3, LeaveOE, SetRC); | 686 __ sub(r3, sp, r3, LeaveOE, SetRC); |
652 // Handle it if the stack pointer is already below the stack limit. | 687 // Handle it if the stack pointer is already below the stack limit. |
(...skipping 28 matching lines...) Expand all Loading... |
681 __ LoadP(r4, MemOperand(frame_pointer(), kStartIndex)); | 716 __ LoadP(r4, MemOperand(frame_pointer(), kStartIndex)); |
682 __ subi(r3, current_input_offset(), Operand(char_size())); | 717 __ subi(r3, current_input_offset(), Operand(char_size())); |
683 if (mode_ == UC16) { | 718 if (mode_ == UC16) { |
684 __ ShiftLeftImm(r0, r4, Operand(1)); | 719 __ ShiftLeftImm(r0, r4, Operand(1)); |
685 __ sub(r3, r3, r0); | 720 __ sub(r3, r3, r0); |
686 } else { | 721 } else { |
687 __ sub(r3, r3, r4); | 722 __ sub(r3, r3, r4); |
688 } | 723 } |
689 // Store this value in a local variable, for use when clearing | 724 // Store this value in a local variable, for use when clearing |
690 // position registers. | 725 // position registers. |
691 __ StoreP(r3, MemOperand(frame_pointer(), kInputStartMinusOne)); | 726 __ StoreP(r3, MemOperand(frame_pointer(), kStringStartMinusOne)); |
692 | 727 |
693 // Initialize code pointer register | 728 // Initialize code pointer register |
694 __ mov(code_pointer(), Operand(masm_->CodeObject())); | 729 __ mov(code_pointer(), Operand(masm_->CodeObject())); |
695 | 730 |
696 Label load_char_start_regexp, start_regexp; | 731 Label load_char_start_regexp, start_regexp; |
697 // Load newline if index is at start, previous character otherwise. | 732 // Load newline if index is at start, previous character otherwise. |
698 __ cmpi(r4, Operand::Zero()); | 733 __ cmpi(r4, Operand::Zero()); |
699 __ bne(&load_char_start_regexp); | 734 __ bne(&load_char_start_regexp); |
700 __ li(current_character(), Operand('\n')); | 735 __ li(current_character(), Operand('\n')); |
701 __ b(&start_regexp); | 736 __ b(&start_regexp); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 // Check whether we have enough room for another set of capture results. | 825 // Check whether we have enough room for another set of capture results. |
791 __ cmpi(r4, Operand(num_saved_registers_)); | 826 __ cmpi(r4, Operand(num_saved_registers_)); |
792 __ blt(&return_r3); | 827 __ blt(&return_r3); |
793 | 828 |
794 __ StoreP(r4, MemOperand(frame_pointer(), kNumOutputRegisters)); | 829 __ StoreP(r4, MemOperand(frame_pointer(), kNumOutputRegisters)); |
795 // Advance the location for output. | 830 // Advance the location for output. |
796 __ addi(r5, r5, Operand(num_saved_registers_ * kIntSize)); | 831 __ addi(r5, r5, Operand(num_saved_registers_ * kIntSize)); |
797 __ StoreP(r5, MemOperand(frame_pointer(), kRegisterOutput)); | 832 __ StoreP(r5, MemOperand(frame_pointer(), kRegisterOutput)); |
798 | 833 |
799 // Prepare r3 to initialize registers with its value in the next run. | 834 // Prepare r3 to initialize registers with its value in the next run. |
800 __ LoadP(r3, MemOperand(frame_pointer(), kInputStartMinusOne)); | 835 __ LoadP(r3, MemOperand(frame_pointer(), kStringStartMinusOne)); |
801 | 836 |
802 if (global_with_zero_length_check()) { | 837 if (global_with_zero_length_check()) { |
803 // Special case for zero-length matches. | 838 // Special case for zero-length matches. |
804 // r25: capture start index | 839 // r25: capture start index |
805 __ cmp(current_input_offset(), r25); | 840 __ cmp(current_input_offset(), r25); |
806 // Not a zero-length match, restart. | 841 // Not a zero-length match, restart. |
807 __ bne(&load_char_start_regexp); | 842 __ bne(&load_char_start_regexp); |
808 // Offset from the end is zero if we already reached the end. | 843 // Offset from the end is zero if we already reached the end. |
809 __ cmpi(current_input_offset(), Operand::Zero()); | 844 __ cmpi(current_input_offset(), Operand::Zero()); |
810 __ beq(&exit_label_); | 845 __ beq(&exit_label_); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 RegExpMacroAssembler::IrregexpImplementation | 964 RegExpMacroAssembler::IrregexpImplementation |
930 RegExpMacroAssemblerPPC::Implementation() { | 965 RegExpMacroAssemblerPPC::Implementation() { |
931 return kPPCImplementation; | 966 return kPPCImplementation; |
932 } | 967 } |
933 | 968 |
934 | 969 |
935 void RegExpMacroAssemblerPPC::LoadCurrentCharacter(int cp_offset, | 970 void RegExpMacroAssemblerPPC::LoadCurrentCharacter(int cp_offset, |
936 Label* on_end_of_input, | 971 Label* on_end_of_input, |
937 bool check_bounds, | 972 bool check_bounds, |
938 int characters) { | 973 int characters) { |
939 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character. | |
940 DCHECK(cp_offset < (1 << 30)); // Be sane! (And ensure negation works) | 974 DCHECK(cp_offset < (1 << 30)); // Be sane! (And ensure negation works) |
941 if (check_bounds) { | 975 if (check_bounds) { |
942 CheckPosition(cp_offset + characters - 1, on_end_of_input); | 976 if (cp_offset >= 0) { |
| 977 CheckPosition(cp_offset + characters - 1, on_end_of_input); |
| 978 } else { |
| 979 CheckPosition(cp_offset, on_end_of_input); |
| 980 } |
943 } | 981 } |
944 LoadCurrentCharacterUnchecked(cp_offset, characters); | 982 LoadCurrentCharacterUnchecked(cp_offset, characters); |
945 } | 983 } |
946 | 984 |
947 | 985 |
948 void RegExpMacroAssemblerPPC::PopCurrentPosition() { | 986 void RegExpMacroAssemblerPPC::PopCurrentPosition() { |
949 Pop(current_input_offset()); | 987 Pop(current_input_offset()); |
950 } | 988 } |
951 | 989 |
952 | 990 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1021 } else { | 1059 } else { |
1022 __ mov(r0, Operand(cp_offset * char_size())); | 1060 __ mov(r0, Operand(cp_offset * char_size())); |
1023 __ add(r3, current_input_offset(), r0); | 1061 __ add(r3, current_input_offset(), r0); |
1024 __ StoreP(r3, register_location(reg), r0); | 1062 __ StoreP(r3, register_location(reg), r0); |
1025 } | 1063 } |
1026 } | 1064 } |
1027 | 1065 |
1028 | 1066 |
1029 void RegExpMacroAssemblerPPC::ClearRegisters(int reg_from, int reg_to) { | 1067 void RegExpMacroAssemblerPPC::ClearRegisters(int reg_from, int reg_to) { |
1030 DCHECK(reg_from <= reg_to); | 1068 DCHECK(reg_from <= reg_to); |
1031 __ LoadP(r3, MemOperand(frame_pointer(), kInputStartMinusOne)); | 1069 __ LoadP(r3, MemOperand(frame_pointer(), kStringStartMinusOne)); |
1032 for (int reg = reg_from; reg <= reg_to; reg++) { | 1070 for (int reg = reg_from; reg <= reg_to; reg++) { |
1033 __ StoreP(r3, register_location(reg), r0); | 1071 __ StoreP(r3, register_location(reg), r0); |
1034 } | 1072 } |
1035 } | 1073 } |
1036 | 1074 |
1037 | 1075 |
1038 void RegExpMacroAssemblerPPC::WriteStackPointerToRegister(int reg) { | 1076 void RegExpMacroAssemblerPPC::WriteStackPointerToRegister(int reg) { |
1039 __ LoadP(r4, MemOperand(frame_pointer(), kStackHighEnd)); | 1077 __ LoadP(r4, MemOperand(frame_pointer(), kStackHighEnd)); |
1040 __ sub(r3, backtrack_stackpointer(), r4); | 1078 __ sub(r3, backtrack_stackpointer(), r4); |
1041 __ StoreP(r3, register_location(reg), r0); | 1079 __ StoreP(r3, register_location(reg), r0); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1125 if (num_registers_ <= register_index) { | 1163 if (num_registers_ <= register_index) { |
1126 num_registers_ = register_index + 1; | 1164 num_registers_ = register_index + 1; |
1127 } | 1165 } |
1128 return MemOperand(frame_pointer(), | 1166 return MemOperand(frame_pointer(), |
1129 kRegisterZero - register_index * kPointerSize); | 1167 kRegisterZero - register_index * kPointerSize); |
1130 } | 1168 } |
1131 | 1169 |
1132 | 1170 |
1133 void RegExpMacroAssemblerPPC::CheckPosition(int cp_offset, | 1171 void RegExpMacroAssemblerPPC::CheckPosition(int cp_offset, |
1134 Label* on_outside_input) { | 1172 Label* on_outside_input) { |
1135 __ Cmpi(current_input_offset(), Operand(-cp_offset * char_size()), r0); | 1173 if (cp_offset >= 0) { |
1136 BranchOrBacktrack(ge, on_outside_input); | 1174 __ Cmpi(current_input_offset(), Operand(-cp_offset * char_size()), r0); |
| 1175 BranchOrBacktrack(ge, on_outside_input); |
| 1176 } else { |
| 1177 __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne)); |
| 1178 __ addi(r3, current_input_offset(), Operand(cp_offset * char_size())); |
| 1179 __ cmp(r3, r4); |
| 1180 BranchOrBacktrack(le, on_outside_input); |
| 1181 } |
1137 } | 1182 } |
1138 | 1183 |
1139 | 1184 |
1140 void RegExpMacroAssemblerPPC::BranchOrBacktrack(Condition condition, Label* to, | 1185 void RegExpMacroAssemblerPPC::BranchOrBacktrack(Condition condition, Label* to, |
1141 CRegister cr) { | 1186 CRegister cr) { |
1142 if (condition == al) { // Unconditional. | 1187 if (condition == al) { // Unconditional. |
1143 if (to == NULL) { | 1188 if (to == NULL) { |
1144 Backtrack(); | 1189 Backtrack(); |
1145 return; | 1190 return; |
1146 } | 1191 } |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1243 } | 1288 } |
1244 | 1289 |
1245 | 1290 |
1246 #undef __ | 1291 #undef __ |
1247 | 1292 |
1248 #endif // V8_INTERPRETED_REGEXP | 1293 #endif // V8_INTERPRETED_REGEXP |
1249 } // namespace internal | 1294 } // namespace internal |
1250 } // namespace v8 | 1295 } // namespace v8 |
1251 | 1296 |
1252 #endif // V8_TARGET_ARCH_PPC | 1297 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |