| Index: src/regexp/ppc/regexp-macro-assembler-ppc.cc
|
| diff --git a/src/regexp/ppc/regexp-macro-assembler-ppc.cc b/src/regexp/ppc/regexp-macro-assembler-ppc.cc
|
| index 03f9741147e81cc7d323ce0f01157b55475fd825..d11b20d81f246b8e71dabfdb10560dc85b86ce1d 100644
|
| --- a/src/regexp/ppc/regexp-macro-assembler-ppc.cc
|
| +++ b/src/regexp/ppc/regexp-macro-assembler-ppc.cc
|
| @@ -60,7 +60,7 @@ namespace internal {
|
| * - fp[-32] void* input_string (location of a handle containing the string).
|
| * - fp[-36] success counter (only for global regexps to count matches).
|
| * - fp[-40] Offset of location before start of input (effectively character
|
| - * position -1). Used to initialize capture registers to a
|
| + * string start - 1). Used to initialize capture registers to a
|
| * non-position.
|
| * - fp[-44] At start (if 1, we are starting at the start of the
|
| * string, otherwise 0)
|
| @@ -189,30 +189,18 @@ void RegExpMacroAssemblerPPC::CheckCharacterGT(uc16 limit, Label* on_greater) {
|
|
|
|
|
| void RegExpMacroAssemblerPPC::CheckAtStart(Label* on_at_start) {
|
| - Label not_at_start;
|
| - // Did we start the match at the start of the string at all?
|
| - __ LoadP(r3, MemOperand(frame_pointer(), kStartIndex));
|
| - __ cmpi(r3, Operand::Zero());
|
| - BranchOrBacktrack(ne, ¬_at_start);
|
| -
|
| - // If we did, are we still at the start of the input?
|
| - __ LoadP(r4, MemOperand(frame_pointer(), kInputStart));
|
| - __ mr(r0, current_input_offset());
|
| - __ add(r3, end_of_input_address(), r0);
|
| - __ cmp(r4, r3);
|
| + __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne));
|
| + __ addi(r3, current_input_offset(), Operand(-char_size()));
|
| + __ cmp(r3, r4);
|
| BranchOrBacktrack(eq, on_at_start);
|
| - __ bind(¬_at_start);
|
| }
|
|
|
|
|
| -void RegExpMacroAssemblerPPC::CheckNotAtStart(Label* on_not_at_start) {
|
| - // Did we start the match at the start of the string at all?
|
| - __ LoadP(r3, MemOperand(frame_pointer(), kStartIndex));
|
| - __ cmpi(r3, Operand::Zero());
|
| - BranchOrBacktrack(ne, on_not_at_start);
|
| - // If we did, are we still at the start of the input?
|
| - __ LoadP(r4, MemOperand(frame_pointer(), kInputStart));
|
| - __ add(r3, end_of_input_address(), current_input_offset());
|
| +void RegExpMacroAssemblerPPC::CheckNotAtStart(int cp_offset,
|
| + Label* on_not_at_start) {
|
| + __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne));
|
| + __ addi(r3, current_input_offset(),
|
| + Operand(-char_size() + cp_offset * char_size()));
|
| __ cmp(r3, r4);
|
| BranchOrBacktrack(ne, on_not_at_start);
|
| }
|
| @@ -238,20 +226,27 @@ void RegExpMacroAssemblerPPC::CheckGreedyLoop(Label* on_equal) {
|
|
|
|
|
| void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase(
|
| - int start_reg, Label* on_no_match) {
|
| + int start_reg, bool read_backward, Label* on_no_match) {
|
| Label fallthrough;
|
| __ LoadP(r3, register_location(start_reg), r0); // Index of start of capture
|
| __ LoadP(r4, register_location(start_reg + 1), r0); // Index of end
|
| __ sub(r4, r4, r3, LeaveOE, SetRC); // Length of capture.
|
|
|
| - // If length is zero, either the capture is empty or it is not participating.
|
| - // In either case succeed immediately.
|
| + // At this point, the capture registers are either both set or both cleared.
|
| + // If the capture length is zero, then the capture is either empty or cleared.
|
| + // Fall through in both cases.
|
| __ beq(&fallthrough, cr0);
|
|
|
| // Check that there are enough characters left in the input.
|
| - __ add(r0, r4, current_input_offset(), LeaveOE, SetRC);
|
| - // __ cmn(r1, Operand(current_input_offset()));
|
| - BranchOrBacktrack(gt, on_no_match, cr0);
|
| + if (read_backward) {
|
| + __ LoadP(r6, MemOperand(frame_pointer(), kStringStartMinusOne));
|
| + __ add(r6, r6, r4);
|
| + __ cmp(current_input_offset(), r6);
|
| + BranchOrBacktrack(le, on_no_match);
|
| + } else {
|
| + __ add(r0, r4, current_input_offset(), LeaveOE, SetRC);
|
| + BranchOrBacktrack(gt, on_no_match, cr0);
|
| + }
|
|
|
| if (mode_ == LATIN1) {
|
| Label success;
|
| @@ -262,6 +257,9 @@ void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase(
|
| // r4 - length of capture
|
| __ add(r3, r3, end_of_input_address());
|
| __ add(r5, end_of_input_address(), current_input_offset());
|
| + if (read_backward) {
|
| + __ sub(r5, r5, r4); // Offset by length when matching backwards.
|
| + }
|
| __ add(r4, r3, r4);
|
|
|
| // r3 - Address of start of capture.
|
| @@ -303,6 +301,13 @@ void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase(
|
| __ bind(&success);
|
| // Compute new value of character position after the matched part.
|
| __ sub(current_input_offset(), r5, end_of_input_address());
|
| + if (read_backward) {
|
| + __ LoadP(r3, register_location(start_reg)); // Index of start of capture
|
| + __ LoadP(r4,
|
| + register_location(start_reg + 1)); // Index of end of capture
|
| + __ add(current_input_offset(), current_input_offset(), r3);
|
| + __ sub(current_input_offset(), current_input_offset(), r4);
|
| + }
|
| } else {
|
| DCHECK(mode_ == UC16);
|
| int argument_count = 4;
|
| @@ -326,6 +331,9 @@ void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase(
|
| __ mr(r25, r4);
|
| // Address of current input position.
|
| __ add(r4, current_input_offset(), end_of_input_address());
|
| + if (read_backward) {
|
| + __ sub(r4, r4, r25);
|
| + }
|
| // Isolate.
|
| __ mov(r6, Operand(ExternalReference::isolate_address(isolate())));
|
|
|
| @@ -339,8 +347,13 @@ void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase(
|
| // Check if function returned non-zero for success or zero for failure.
|
| __ cmpi(r3, Operand::Zero());
|
| BranchOrBacktrack(eq, on_no_match);
|
| - // On success, increment position by length of capture.
|
| - __ add(current_input_offset(), current_input_offset(), r25);
|
| +
|
| + // On success, advance position by length of capture.
|
| + if (read_backward) {
|
| + __ sub(current_input_offset(), current_input_offset(), r25);
|
| + } else {
|
| + __ add(current_input_offset(), current_input_offset(), r25);
|
| + }
|
| }
|
|
|
| __ bind(&fallthrough);
|
| @@ -348,6 +361,7 @@ void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase(
|
|
|
|
|
| void RegExpMacroAssemblerPPC::CheckNotBackReference(int start_reg,
|
| + bool read_backward,
|
| Label* on_no_match) {
|
| Label fallthrough;
|
| Label success;
|
| @@ -356,16 +370,30 @@ void RegExpMacroAssemblerPPC::CheckNotBackReference(int start_reg,
|
| __ LoadP(r3, register_location(start_reg), r0);
|
| __ LoadP(r4, register_location(start_reg + 1), r0);
|
| __ sub(r4, r4, r3, LeaveOE, SetRC); // Length to check.
|
| - // Succeed on empty capture (including no capture).
|
| +
|
| + // At this point, the capture registers are either both set or both cleared.
|
| + // If the capture length is zero, then the capture is either empty or cleared.
|
| + // Fall through in both cases.
|
| __ beq(&fallthrough, cr0);
|
|
|
| // Check that there are enough characters left in the input.
|
| - __ add(r0, r4, current_input_offset(), LeaveOE, SetRC);
|
| - BranchOrBacktrack(gt, on_no_match, cr0);
|
| + if (read_backward) {
|
| + __ LoadP(r6, MemOperand(frame_pointer(), kStringStartMinusOne));
|
| + __ add(r6, r6, r4);
|
| + __ cmp(current_input_offset(), r6);
|
| + BranchOrBacktrack(lt, on_no_match);
|
| + } else {
|
| + __ add(r0, r4, current_input_offset(), LeaveOE, SetRC);
|
| + BranchOrBacktrack(gt, on_no_match, cr0);
|
| + }
|
|
|
| - // Compute pointers to match string and capture string
|
| + // r3 - offset of start of capture
|
| + // r4 - length of capture
|
| __ add(r3, r3, end_of_input_address());
|
| __ add(r5, end_of_input_address(), current_input_offset());
|
| + if (read_backward) {
|
| + __ sub(r5, r5, r4); // Offset by length when matching backwards.
|
| + }
|
| __ add(r4, r4, r3);
|
|
|
| Label loop;
|
| @@ -389,6 +417,13 @@ void RegExpMacroAssemblerPPC::CheckNotBackReference(int start_reg,
|
|
|
| // Move current character position to position after match.
|
| __ sub(current_input_offset(), r5, end_of_input_address());
|
| + if (read_backward) {
|
| + __ LoadP(r3, register_location(start_reg)); // Index of start of capture
|
| + __ LoadP(r4, register_location(start_reg + 1)); // Index of end of capture
|
| + __ add(current_input_offset(), current_input_offset(), r3);
|
| + __ sub(current_input_offset(), current_input_offset(), r4);
|
| + }
|
| +
|
| __ bind(&fallthrough);
|
| }
|
|
|
| @@ -639,7 +674,7 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
|
| __ addi(frame_pointer(), sp, Operand(8 * kPointerSize));
|
| __ li(r3, Operand::Zero());
|
| __ push(r3); // Make room for success counter and initialize it to 0.
|
| - __ push(r3); // Make room for "position - 1" constant (value is irrelevant)
|
| + __ push(r3); // Make room for "string start - 1" constant.
|
| // Check if we have space on the stack for registers.
|
| Label stack_limit_hit;
|
| Label stack_ok;
|
| @@ -688,7 +723,7 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
|
| }
|
| // Store this value in a local variable, for use when clearing
|
| // position registers.
|
| - __ StoreP(r3, MemOperand(frame_pointer(), kInputStartMinusOne));
|
| + __ StoreP(r3, MemOperand(frame_pointer(), kStringStartMinusOne));
|
|
|
| // Initialize code pointer register
|
| __ mov(code_pointer(), Operand(masm_->CodeObject()));
|
| @@ -797,7 +832,7 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
|
| __ StoreP(r5, MemOperand(frame_pointer(), kRegisterOutput));
|
|
|
| // Prepare r3 to initialize registers with its value in the next run.
|
| - __ LoadP(r3, MemOperand(frame_pointer(), kInputStartMinusOne));
|
| + __ LoadP(r3, MemOperand(frame_pointer(), kStringStartMinusOne));
|
|
|
| if (global_with_zero_length_check()) {
|
| // Special case for zero-length matches.
|
| @@ -936,10 +971,13 @@ void RegExpMacroAssemblerPPC::LoadCurrentCharacter(int cp_offset,
|
| Label* on_end_of_input,
|
| bool check_bounds,
|
| int characters) {
|
| - DCHECK(cp_offset >= -1); // ^ and \b can look behind one character.
|
| DCHECK(cp_offset < (1 << 30)); // Be sane! (And ensure negation works)
|
| if (check_bounds) {
|
| - CheckPosition(cp_offset + characters - 1, on_end_of_input);
|
| + if (cp_offset >= 0) {
|
| + CheckPosition(cp_offset + characters - 1, on_end_of_input);
|
| + } else {
|
| + CheckPosition(cp_offset, on_end_of_input);
|
| + }
|
| }
|
| LoadCurrentCharacterUnchecked(cp_offset, characters);
|
| }
|
| @@ -1028,7 +1066,7 @@ void RegExpMacroAssemblerPPC::WriteCurrentPositionToRegister(int reg,
|
|
|
| void RegExpMacroAssemblerPPC::ClearRegisters(int reg_from, int reg_to) {
|
| DCHECK(reg_from <= reg_to);
|
| - __ LoadP(r3, MemOperand(frame_pointer(), kInputStartMinusOne));
|
| + __ LoadP(r3, MemOperand(frame_pointer(), kStringStartMinusOne));
|
| for (int reg = reg_from; reg <= reg_to; reg++) {
|
| __ StoreP(r3, register_location(reg), r0);
|
| }
|
| @@ -1132,8 +1170,15 @@ MemOperand RegExpMacroAssemblerPPC::register_location(int register_index) {
|
|
|
| void RegExpMacroAssemblerPPC::CheckPosition(int cp_offset,
|
| Label* on_outside_input) {
|
| - __ Cmpi(current_input_offset(), Operand(-cp_offset * char_size()), r0);
|
| - BranchOrBacktrack(ge, on_outside_input);
|
| + if (cp_offset >= 0) {
|
| + __ Cmpi(current_input_offset(), Operand(-cp_offset * char_size()), r0);
|
| + BranchOrBacktrack(ge, on_outside_input);
|
| + } else {
|
| + __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne));
|
| + __ addi(r3, current_input_offset(), Operand(cp_offset * char_size()));
|
| + __ cmp(r3, r4);
|
| + BranchOrBacktrack(le, on_outside_input);
|
| + }
|
| }
|
|
|
|
|
|
|