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_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/regexp/arm/regexp-macro-assembler-arm.h" | 7 #include "src/regexp/arm/regexp-macro-assembler-arm.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 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
169 } | 169 } |
170 | 170 |
171 | 171 |
172 void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) { | 172 void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) { |
173 __ cmp(current_character(), Operand(limit)); | 173 __ cmp(current_character(), Operand(limit)); |
174 BranchOrBacktrack(gt, on_greater); | 174 BranchOrBacktrack(gt, on_greater); |
175 } | 175 } |
176 | 176 |
177 | 177 |
178 void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) { | 178 void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) { |
179 Label not_at_start; | 179 __ add(r0, end_of_input_address(), current_input_offset()); |
180 // Did we start the match at the start of the string at all? | 180 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); |
181 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); | 181 for (int i = 0; i < char_size(); i++) { |
182 __ cmp(r0, Operand::Zero()); | 182 __ add(r0, r0, r1); |
183 BranchOrBacktrack(ne, ¬_at_start); | 183 } |
184 | |
185 // If we did, are we still at the start of the input? | |
186 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); | 184 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); |
187 __ add(r0, end_of_input_address(), Operand(current_input_offset())); | |
188 __ cmp(r0, r1); | 185 __ cmp(r0, r1); |
189 BranchOrBacktrack(eq, on_at_start); | 186 BranchOrBacktrack(eq, on_at_start); |
190 __ bind(¬_at_start); | |
191 } | 187 } |
192 | 188 |
193 | 189 |
194 void RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) { | 190 void RegExpMacroAssemblerARM::CheckNotAtStart(int cp_offset, |
195 // Did we start the match at the start of the string at all? | 191 Label* on_not_at_start) { |
196 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); | 192 __ add(r0, end_of_input_address(), current_input_offset()); |
197 __ cmp(r0, Operand::Zero()); | 193 __ add(r0, r0, Operand(cp_offset * char_size())); |
198 BranchOrBacktrack(ne, on_not_at_start); | 194 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); |
199 // If we did, are we still at the start of the input? | 195 for (int i = 0; i < char_size(); i++) { |
196 __ add(r0, r0, r1); | |
197 } | |
200 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); | 198 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); |
201 __ add(r0, end_of_input_address(), Operand(current_input_offset())); | |
202 __ cmp(r0, r1); | 199 __ cmp(r0, r1); |
203 BranchOrBacktrack(ne, on_not_at_start); | 200 BranchOrBacktrack(ne, on_not_at_start); |
204 } | 201 } |
205 | 202 |
206 | 203 |
207 void RegExpMacroAssemblerARM::CheckCharacterLT(uc16 limit, Label* on_less) { | 204 void RegExpMacroAssemblerARM::CheckCharacterLT(uc16 limit, Label* on_less) { |
208 __ cmp(current_character(), Operand(limit)); | 205 __ cmp(current_character(), Operand(limit)); |
209 BranchOrBacktrack(lt, on_less); | 206 BranchOrBacktrack(lt, on_less); |
210 } | 207 } |
211 | 208 |
212 | 209 |
213 void RegExpMacroAssemblerARM::CheckGreedyLoop(Label* on_equal) { | 210 void RegExpMacroAssemblerARM::CheckGreedyLoop(Label* on_equal) { |
214 __ ldr(r0, MemOperand(backtrack_stackpointer(), 0)); | 211 __ ldr(r0, MemOperand(backtrack_stackpointer(), 0)); |
215 __ cmp(current_input_offset(), r0); | 212 __ cmp(current_input_offset(), r0); |
216 __ add(backtrack_stackpointer(), | 213 __ add(backtrack_stackpointer(), |
217 backtrack_stackpointer(), Operand(kPointerSize), LeaveCC, eq); | 214 backtrack_stackpointer(), Operand(kPointerSize), LeaveCC, eq); |
218 BranchOrBacktrack(eq, on_equal); | 215 BranchOrBacktrack(eq, on_equal); |
219 } | 216 } |
220 | 217 |
221 | 218 |
222 void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase( | 219 void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase( |
223 int start_reg, | 220 int start_reg, bool read_backward, Label* on_no_match) { |
224 Label* on_no_match) { | |
225 Label fallthrough; | 221 Label fallthrough; |
226 __ ldr(r0, register_location(start_reg)); // Index of start of capture | 222 __ ldr(r0, register_location(start_reg)); // Index of start of capture |
227 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture | 223 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture |
228 __ sub(r1, r1, r0, SetCC); // Length of capture. | 224 __ sub(r1, r1, r0, SetCC); // Length of capture. |
229 | 225 |
230 // If length is zero, either the capture is empty or it is not participating. | 226 // The length of the capture can only be negative if the end of the |
231 // In either case succeed immediately. | 227 // capture is not yet recorded. If the length is zero, the capture is |
232 __ b(eq, &fallthrough); | 228 // either empty or uncaptured. In either of those cases, succeed. |
229 __ b(le, &fallthrough); | |
233 | 230 |
234 // Check that there are enough characters left in the input. | 231 // Check that there are enough characters left in the input. |
235 __ cmn(r1, Operand(current_input_offset())); | 232 if (read_backward) { |
236 BranchOrBacktrack(gt, on_no_match); | 233 __ add(r2, end_of_input_address(), current_input_offset()); |
234 __ ldr(r3, MemOperand(frame_pointer(), kStartIndex)); | |
235 for (int i = 0; i < char_size(); i++) { | |
236 __ add(r2, r2, r3); | |
237 } | |
238 __ ldr(r3, MemOperand(frame_pointer(), kInputStart)); | |
239 __ cmp(r2, r3); | |
240 BranchOrBacktrack(lt, on_no_match); | |
241 } else { | |
242 __ cmn(r1, Operand(current_input_offset())); | |
243 BranchOrBacktrack(gt, on_no_match); | |
244 } | |
237 | 245 |
238 if (mode_ == LATIN1) { | 246 if (mode_ == LATIN1) { |
239 Label success; | 247 Label success; |
240 Label fail; | 248 Label fail; |
241 Label loop_check; | 249 Label loop_check; |
242 | 250 |
243 // r0 - offset of start of capture | 251 // r0 - offset of start of capture |
244 // r1 - length of capture | 252 // r1 - length of capture |
245 __ add(r0, r0, Operand(end_of_input_address())); | 253 __ add(r0, r0, end_of_input_address()); |
246 __ add(r2, end_of_input_address(), Operand(current_input_offset())); | 254 __ add(r2, end_of_input_address(), current_input_offset()); |
247 __ add(r1, r0, Operand(r1)); | 255 if (read_backward) { |
256 __ sub(r2, r2, r1); // Offset by length when matching backwards. | |
257 } | |
258 __ add(r1, r0, r1); | |
248 | 259 |
249 // r0 - Address of start of capture. | 260 // r0 - Address of start of capture. |
250 // r1 - Address of end of capture | 261 // r1 - Address of end of capture |
251 // r2 - Address of current input position. | 262 // r2 - Address of current input position. |
252 | 263 |
253 Label loop; | 264 Label loop; |
254 __ bind(&loop); | 265 __ bind(&loop); |
255 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); | 266 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); |
256 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); | 267 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); |
257 __ cmp(r4, r3); | 268 __ cmp(r4, r3); |
(...skipping 18 matching lines...) Expand all Loading... | |
276 __ cmp(r0, r1); | 287 __ cmp(r0, r1); |
277 __ b(lt, &loop); | 288 __ b(lt, &loop); |
278 __ jmp(&success); | 289 __ jmp(&success); |
279 | 290 |
280 __ bind(&fail); | 291 __ bind(&fail); |
281 BranchOrBacktrack(al, on_no_match); | 292 BranchOrBacktrack(al, on_no_match); |
282 | 293 |
283 __ bind(&success); | 294 __ bind(&success); |
284 // Compute new value of character position after the matched part. | 295 // Compute new value of character position after the matched part. |
285 __ sub(current_input_offset(), r2, end_of_input_address()); | 296 __ sub(current_input_offset(), r2, end_of_input_address()); |
297 if (read_backward) { | |
298 __ ldr(r0, register_location(start_reg)); // Index of start of capture | |
299 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture | |
300 __ add(current_input_offset(), current_input_offset(), r0); | |
301 __ sub(current_input_offset(), current_input_offset(), r1); | |
302 } | |
286 } else { | 303 } else { |
287 DCHECK(mode_ == UC16); | 304 DCHECK(mode_ == UC16); |
288 int argument_count = 4; | 305 int argument_count = 4; |
289 __ PrepareCallCFunction(argument_count, r2); | 306 __ PrepareCallCFunction(argument_count, r2); |
290 | 307 |
291 // r0 - offset of start of capture | 308 // r0 - offset of start of capture |
292 // r1 - length of capture | 309 // r1 - length of capture |
293 | 310 |
294 // Put arguments into arguments registers. | 311 // Put arguments into arguments registers. |
295 // Parameters are | 312 // Parameters are |
296 // r0: Address byte_offset1 - Address captured substring's start. | 313 // r0: Address byte_offset1 - Address captured substring's start. |
297 // r1: Address byte_offset2 - Address of current character position. | 314 // r1: Address byte_offset2 - Address of current character position. |
298 // r2: size_t byte_length - length of capture in bytes(!) | 315 // r2: size_t byte_length - length of capture in bytes(!) |
299 // r3: Isolate* isolate | 316 // r3: Isolate* isolate |
300 | 317 |
301 // Address of start of capture. | 318 // Address of start of capture. |
302 __ add(r0, r0, Operand(end_of_input_address())); | 319 __ add(r0, r0, Operand(end_of_input_address())); |
303 // Length of capture. | 320 // Length of capture. |
304 __ mov(r2, Operand(r1)); | 321 __ mov(r2, Operand(r1)); |
305 // Save length in callee-save register for use on return. | 322 // Save length in callee-save register for use on return. |
306 __ mov(r4, Operand(r1)); | 323 __ mov(r4, Operand(r1)); |
307 // Address of current input position. | 324 // Address of current input position. |
308 __ add(r1, current_input_offset(), Operand(end_of_input_address())); | 325 __ add(r1, current_input_offset(), end_of_input_address()); |
326 if (read_backward) { | |
327 __ sub(r1, r1, r4); | |
328 } | |
309 // Isolate. | 329 // Isolate. |
310 __ mov(r3, Operand(ExternalReference::isolate_address(isolate()))); | 330 __ mov(r3, Operand(ExternalReference::isolate_address(isolate()))); |
311 | 331 |
312 { | 332 { |
313 AllowExternalCallThatCantCauseGC scope(masm_); | 333 AllowExternalCallThatCantCauseGC scope(masm_); |
314 ExternalReference function = | 334 ExternalReference function = |
315 ExternalReference::re_case_insensitive_compare_uc16(isolate()); | 335 ExternalReference::re_case_insensitive_compare_uc16(isolate()); |
316 __ CallCFunction(function, argument_count); | 336 __ CallCFunction(function, argument_count); |
317 } | 337 } |
318 | 338 |
319 // Check if function returned non-zero for success or zero for failure. | 339 // Check if function returned non-zero for success or zero for failure. |
320 __ cmp(r0, Operand::Zero()); | 340 __ cmp(r0, Operand::Zero()); |
321 BranchOrBacktrack(eq, on_no_match); | 341 BranchOrBacktrack(eq, on_no_match); |
322 // On success, increment position by length of capture. | 342 |
323 __ add(current_input_offset(), current_input_offset(), Operand(r4)); | 343 // On success, advance position by length of capture. |
344 if (read_backward) { | |
345 __ sub(current_input_offset(), current_input_offset(), r4); | |
346 } else { | |
347 __ add(current_input_offset(), current_input_offset(), r4); | |
348 } | |
324 } | 349 } |
325 | 350 |
326 __ bind(&fallthrough); | 351 __ bind(&fallthrough); |
327 } | 352 } |
328 | 353 |
329 | 354 |
330 void RegExpMacroAssemblerARM::CheckNotBackReference( | 355 void RegExpMacroAssemblerARM::CheckNotBackReference(int start_reg, |
331 int start_reg, | 356 bool read_backward, |
332 Label* on_no_match) { | 357 Label* on_no_match) { |
333 Label fallthrough; | 358 Label fallthrough; |
334 Label success; | 359 Label success; |
335 | 360 |
336 // Find length of back-referenced capture. | 361 // Find length of back-referenced capture. |
337 __ ldr(r0, register_location(start_reg)); | 362 __ ldr(r0, register_location(start_reg)); |
338 __ ldr(r1, register_location(start_reg + 1)); | 363 __ ldr(r1, register_location(start_reg + 1)); |
339 __ sub(r1, r1, r0, SetCC); // Length to check. | 364 __ sub(r1, r1, r0, SetCC); // Length to check. |
340 // Succeed on empty capture (including no capture). | 365 |
341 __ b(eq, &fallthrough); | 366 // The length of the capture can only be negative if the end of the |
367 // capture is not yet recorded. If the length is zero, the capture is | |
368 // either empty or uncaptured. In either of those cases, succeed. | |
369 __ b(le, &fallthrough); | |
342 | 370 |
343 // Check that there are enough characters left in the input. | 371 // Check that there are enough characters left in the input. |
344 __ cmn(r1, Operand(current_input_offset())); | 372 if (read_backward) { |
345 BranchOrBacktrack(gt, on_no_match); | 373 __ add(r2, end_of_input_address(), current_input_offset()); |
374 __ ldr(r3, MemOperand(frame_pointer(), kStartIndex)); | |
375 for (int i = 0; i < char_size(); i++) { | |
376 __ add(r2, r2, r3); | |
377 } | |
378 __ ldr(r3, MemOperand(frame_pointer(), kInputStart)); | |
379 __ cmp(r2, r3); | |
380 BranchOrBacktrack(lt, on_no_match); | |
381 } else { | |
382 __ cmn(r1, Operand(current_input_offset())); | |
383 BranchOrBacktrack(gt, on_no_match); | |
384 } | |
346 | 385 |
347 // Compute pointers to match string and capture string | 386 // r0 - offset of start of capture |
348 __ add(r0, r0, Operand(end_of_input_address())); | 387 // r1 - length of capture |
349 __ add(r2, end_of_input_address(), Operand(current_input_offset())); | 388 __ add(r0, r0, end_of_input_address()); |
350 __ add(r1, r1, Operand(r0)); | 389 __ add(r2, end_of_input_address(), current_input_offset()); |
390 if (read_backward) { | |
391 __ sub(r2, r2, r1); // Offset by length when matching backwards. | |
392 } | |
393 __ add(r1, r0, r1); | |
351 | 394 |
352 Label loop; | 395 Label loop; |
353 __ bind(&loop); | 396 __ bind(&loop); |
354 if (mode_ == LATIN1) { | 397 if (mode_ == LATIN1) { |
355 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); | 398 __ ldrb(r3, MemOperand(r0, char_size(), PostIndex)); |
356 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); | 399 __ ldrb(r4, MemOperand(r2, char_size(), PostIndex)); |
357 } else { | 400 } else { |
358 DCHECK(mode_ == UC16); | 401 DCHECK(mode_ == UC16); |
359 __ ldrh(r3, MemOperand(r0, char_size(), PostIndex)); | 402 __ ldrh(r3, MemOperand(r0, char_size(), PostIndex)); |
360 __ ldrh(r4, MemOperand(r2, char_size(), PostIndex)); | 403 __ ldrh(r4, MemOperand(r2, char_size(), PostIndex)); |
361 } | 404 } |
362 __ cmp(r3, r4); | 405 __ cmp(r3, r4); |
363 BranchOrBacktrack(ne, on_no_match); | 406 BranchOrBacktrack(ne, on_no_match); |
364 __ cmp(r0, r1); | 407 __ cmp(r0, r1); |
365 __ b(lt, &loop); | 408 __ b(lt, &loop); |
366 | 409 |
367 // Move current character position to position after match. | 410 // Move current character position to position after match. |
368 __ sub(current_input_offset(), r2, end_of_input_address()); | 411 __ sub(current_input_offset(), r2, end_of_input_address()); |
412 if (read_backward) { | |
413 __ ldr(r0, register_location(start_reg)); // Index of start of capture | |
414 __ ldr(r1, register_location(start_reg + 1)); // Index of end of capture | |
415 __ add(current_input_offset(), current_input_offset(), r0); | |
416 __ sub(current_input_offset(), current_input_offset(), r1); | |
417 } | |
418 | |
369 __ bind(&fallthrough); | 419 __ bind(&fallthrough); |
370 } | 420 } |
371 | 421 |
372 | 422 |
373 void RegExpMacroAssemblerARM::CheckNotCharacter(unsigned c, | 423 void RegExpMacroAssemblerARM::CheckNotCharacter(unsigned c, |
374 Label* on_not_equal) { | 424 Label* on_not_equal) { |
375 __ cmp(current_character(), Operand(c)); | 425 __ cmp(current_character(), Operand(c)); |
376 BranchOrBacktrack(ne, on_not_equal); | 426 BranchOrBacktrack(ne, on_not_equal); |
377 } | 427 } |
378 | 428 |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
637 // Load string end. | 687 // Load string end. |
638 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); | 688 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); |
639 // Load input start. | 689 // Load input start. |
640 __ ldr(r0, MemOperand(frame_pointer(), kInputStart)); | 690 __ ldr(r0, MemOperand(frame_pointer(), kInputStart)); |
641 // Find negative length (offset of start relative to end). | 691 // Find negative length (offset of start relative to end). |
642 __ sub(current_input_offset(), r0, end_of_input_address()); | 692 __ sub(current_input_offset(), r0, end_of_input_address()); |
643 // Set r0 to address of char before start of the input string | 693 // Set r0 to address of char before start of the input string |
644 // (effectively string position -1). | 694 // (effectively string position -1). |
645 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); | 695 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); |
646 __ sub(r0, current_input_offset(), Operand(char_size())); | 696 __ sub(r0, current_input_offset(), Operand(char_size())); |
647 __ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0)); | 697 __ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0)); |
erikcorry
2015/11/13 14:30:13
This instruction is better than the short for loop
| |
648 // Store this value in a local variable, for use when clearing | 698 // Store this value in a local variable, for use when clearing |
649 // position registers. | 699 // position registers. |
650 __ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); | 700 __ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); |
erikcorry
2015/11/13 14:30:13
This looks useful. It's the actual position 1 les
| |
651 | 701 |
652 // Initialize code pointer register | 702 // Initialize code pointer register |
653 __ mov(code_pointer(), Operand(masm_->CodeObject())); | 703 __ mov(code_pointer(), Operand(masm_->CodeObject())); |
654 | 704 |
655 Label load_char_start_regexp, start_regexp; | 705 Label load_char_start_regexp, start_regexp; |
656 // Load newline if index is at start, previous character otherwise. | 706 // Load newline if index is at start, previous character otherwise. |
657 __ cmp(r1, Operand::Zero()); | 707 __ cmp(r1, Operand::Zero()); |
658 __ b(ne, &load_char_start_regexp); | 708 __ b(ne, &load_char_start_regexp); |
659 __ mov(current_character(), Operand('\n'), LeaveCC, eq); | 709 __ mov(current_character(), Operand('\n'), LeaveCC, eq); |
660 __ jmp(&start_regexp); | 710 __ jmp(&start_regexp); |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
885 RegExpMacroAssembler::IrregexpImplementation | 935 RegExpMacroAssembler::IrregexpImplementation |
886 RegExpMacroAssemblerARM::Implementation() { | 936 RegExpMacroAssemblerARM::Implementation() { |
887 return kARMImplementation; | 937 return kARMImplementation; |
888 } | 938 } |
889 | 939 |
890 | 940 |
891 void RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset, | 941 void RegExpMacroAssemblerARM::LoadCurrentCharacter(int cp_offset, |
892 Label* on_end_of_input, | 942 Label* on_end_of_input, |
893 bool check_bounds, | 943 bool check_bounds, |
894 int characters) { | 944 int characters) { |
895 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character. | |
896 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) | 945 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) |
897 if (check_bounds) { | 946 if (check_bounds) { |
898 CheckPosition(cp_offset + characters - 1, on_end_of_input); | 947 if (cp_offset >= 0) { |
948 CheckPosition(cp_offset + characters - 1, on_end_of_input); | |
949 } else { | |
950 CheckPosition(cp_offset, on_end_of_input); | |
951 } | |
899 } | 952 } |
900 LoadCurrentCharacterUnchecked(cp_offset, characters); | 953 LoadCurrentCharacterUnchecked(cp_offset, characters); |
901 } | 954 } |
902 | 955 |
903 | 956 |
904 void RegExpMacroAssemblerARM::PopCurrentPosition() { | 957 void RegExpMacroAssemblerARM::PopCurrentPosition() { |
905 Pop(current_input_offset()); | 958 Pop(current_input_offset()); |
906 } | 959 } |
907 | 960 |
908 | 961 |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1062 if (num_registers_ <= register_index) { | 1115 if (num_registers_ <= register_index) { |
1063 num_registers_ = register_index + 1; | 1116 num_registers_ = register_index + 1; |
1064 } | 1117 } |
1065 return MemOperand(frame_pointer(), | 1118 return MemOperand(frame_pointer(), |
1066 kRegisterZero - register_index * kPointerSize); | 1119 kRegisterZero - register_index * kPointerSize); |
1067 } | 1120 } |
1068 | 1121 |
1069 | 1122 |
1070 void RegExpMacroAssemblerARM::CheckPosition(int cp_offset, | 1123 void RegExpMacroAssemblerARM::CheckPosition(int cp_offset, |
1071 Label* on_outside_input) { | 1124 Label* on_outside_input) { |
1072 __ cmp(current_input_offset(), Operand(-cp_offset * char_size())); | 1125 if (cp_offset >= 0) { |
1073 BranchOrBacktrack(ge, on_outside_input); | 1126 __ cmp(current_input_offset(), Operand(-cp_offset * char_size())); |
1127 BranchOrBacktrack(ge, on_outside_input); | |
1128 } else { | |
1129 __ add(r0, end_of_input_address(), current_input_offset()); | |
1130 __ add(r0, r0, Operand(cp_offset * char_size())); | |
1131 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); | |
1132 for (int i = 0; i < char_size(); i++) { | |
1133 __ add(r0, r0, r1); | |
1134 } | |
1135 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); | |
1136 __ cmp(r0, r1); | |
1137 BranchOrBacktrack(lt, on_outside_input); | |
1138 } | |
1074 } | 1139 } |
1075 | 1140 |
1076 | 1141 |
1077 void RegExpMacroAssemblerARM::BranchOrBacktrack(Condition condition, | 1142 void RegExpMacroAssemblerARM::BranchOrBacktrack(Condition condition, |
1078 Label* to) { | 1143 Label* to) { |
1079 if (condition == al) { // Unconditional. | 1144 if (condition == al) { // Unconditional. |
1080 if (to == NULL) { | 1145 if (to == NULL) { |
1081 Backtrack(); | 1146 Backtrack(); |
1082 return; | 1147 return; |
1083 } | 1148 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1188 | 1253 |
1189 | 1254 |
1190 #undef __ | 1255 #undef __ |
1191 | 1256 |
1192 #endif // V8_INTERPRETED_REGEXP | 1257 #endif // V8_INTERPRETED_REGEXP |
1193 | 1258 |
1194 } // namespace internal | 1259 } // namespace internal |
1195 } // namespace v8 | 1260 } // namespace v8 |
1196 | 1261 |
1197 #endif // V8_TARGET_ARCH_ARM | 1262 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |