| 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 |