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 3 // found in the LICENSE file. 4 5 #if V8_TARGET_ARCH_PPC 6 7 #include "src/regexp/ppc/regexp-macro-assembler-ppc.h" 8 9 #include "src/base/bits.h" 10 #include "src/code-stubs.h" 11 #include "src/log.h" 12 #include "src/macro-assembler.h" 13 #include "src/profiler/cpu-profiler.h" 14 #include "src/regexp/regexp-macro-assembler.h" 15 #include "src/regexp/regexp-stack.h" 16 #include "src/unicode.h" 17 18 namespace v8 { 19 namespace internal { 20 21 #ifndef V8_INTERPRETED_REGEXP 22 /* 23 * This assembler uses the following register assignment convention 24 * - r25: Temporarily stores the index of capture start after a matching pass 25 * for a global regexp. 26 * - r26: Pointer to current code object (Code*) including heap object tag. 27 * - r27: Current position in input, as negative offset from end of string. 28 * Please notice that this is the byte offset, not the character offset! 29 * - r28: Currently loaded character. Must be loaded using 30 * LoadCurrentCharacter before using any of the dispatch methods. 31 * - r29: Points to tip of backtrack stack 32 * - r30: End of input (points to byte after last character in input). 33 * - r31: Frame pointer. Used to access arguments, local variables and 34 * RegExp registers. 35 * - r12: IP register, used by assembler. Very volatile. 36 * - r1/sp : Points to tip of C stack. 37 * 38 * The remaining registers are free for computations. 39 * Each call to a public method should retain this convention. 40 * 41 * The stack will have the following structure: 42 * - fp[44] Isolate* isolate (address of the current isolate) 43 * - fp[40] secondary link/return address used by native call. 44 * - fp[36] lr save area (currently unused) 45 * - fp[32] backchain (currently unused) 46 * --- sp when called --- 47 * - fp[28] return address (lr). 48 * - fp[24] old frame pointer (r31). 49 * - fp[0..20] backup of registers r25..r30 50 * --- frame pointer ---- 51 * - fp[-4] direct_call (if 1, direct call from JavaScript code, 52 * if 0, call through the runtime system). 53 * - fp[-8] stack_area_base (high end of the memory area to use as 54 * backtracking stack). 55 * - fp[-12] capture array size (may fit multiple sets of matches) 56 * - fp[-16] int* capture_array (int[num_saved_registers_], for output). 57 * - fp[-20] end of input (address of end of string). 58 * - fp[-24] start of input (address of first character in string). 59 * - fp[-28] start index (character index of start). 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). 62 * - fp[-40] Offset of location before start of input (effectively character 63 * string start - 1). Used to initialize capture registers to a 64 * non-position. 65 * - fp[-44] At start (if 1, we are starting at the start of the 66 * string, otherwise 0) 67 * - fp[-48] register 0 (Only positions must be stored in the first 68 * - register 1 num_saved_registers_ registers) 69 * - ... 70 * - register num_registers-1 71 * --- sp --- 72 * 73 * The first num_saved_registers_ registers are initialized to point to 74 * "character -1" in the string (i.e., char_size() bytes before the first 75 * character of the string). The remaining registers start out as garbage. 76 * 77 * The data up to the return address must be placed there by the calling 78 * code and the remaining arguments are passed in registers, e.g. by calling the 79 * code entry as cast to a function with the signature: 80 * int (*match)(String* input_string, 81 * int start_index, 82 * Address start, 83 * Address end, 84 * int* capture_output_array, 85 * byte* stack_area_base, 86 * Address secondary_return_address, // Only used by native call. 87 * bool direct_call = false) 88 * The call is performed by NativeRegExpMacroAssembler::Execute() 89 * (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro 90 * in ppc/simulator-ppc.h. 91 * When calling as a non-direct call (i.e., from C++ code), the return address 92 * area is overwritten with the LR register by the RegExp code. When doing a 93 * direct call from generated code, the return address is placed there by 94 * the calling code, as in a normal exit frame. 95 */ 96 97 #define __ ACCESS_MASM(masm_) 98 99 RegExpMacroAssemblerPPC::RegExpMacroAssemblerPPC(Isolate* isolate, Zone* zone, 100 Mode mode, 101 int registers_to_save) 102 : NativeRegExpMacroAssembler(isolate, zone), 103 masm_(new MacroAssembler(isolate, NULL, kRegExpCodeSize, 104 CodeObjectRequired::kYes)), 105 mode_(mode), 106 num_registers_(registers_to_save), 107 num_saved_registers_(registers_to_save), 108 entry_label_(), 109 start_label_(), 110 success_label_(), 111 backtrack_label_(), 112 exit_label_(), 113 internal_failure_label_() { 114 DCHECK_EQ(0, registers_to_save % 2); 115 116 // Called from C 117 __ function_descriptor(); 118 119 __ b(&entry_label_); // We'll write the entry code later. 120 // If the code gets too big or corrupted, an internal exception will be 121 // raised, and we will exit right away. 122 __ bind(&internal_failure_label_); 123 __ li(r3, Operand(FAILURE)); 124 __ Ret(); 125 __ bind(&start_label_); // And then continue from here. 126 } 127 128 129 RegExpMacroAssemblerPPC::~RegExpMacroAssemblerPPC() { 130 delete masm_; 131 // Unuse labels in case we throw away the assembler without calling GetCode. 132 entry_label_.Unuse(); 133 start_label_.Unuse(); 134 success_label_.Unuse(); 135 backtrack_label_.Unuse(); 136 exit_label_.Unuse(); 137 check_preempt_label_.Unuse(); 138 stack_overflow_label_.Unuse(); 139 internal_failure_label_.Unuse(); 140 } 141 142 143 int RegExpMacroAssemblerPPC::stack_limit_slack() { 144 return RegExpStack::kStackLimitSlack; 145 } 146 147 148 void RegExpMacroAssemblerPPC::AdvanceCurrentPosition(int by) { 149 if (by != 0) { 150 __ addi(current_input_offset(), current_input_offset(), 151 Operand(by * char_size())); 152 } 153 } 154 155 156 void RegExpMacroAssemblerPPC::AdvanceRegister(int reg, int by) { 157 DCHECK(reg >= 0); 158 DCHECK(reg < num_registers_); 159 if (by != 0) { 160 __ LoadP(r3, register_location(reg), r0); 161 __ mov(r0, Operand(by)); 162 __ add(r3, r3, r0); 163 __ StoreP(r3, register_location(reg), r0); 164 } 165 } 166 167 168 void RegExpMacroAssemblerPPC::Backtrack() { 169 CheckPreemption(); 170 // Pop Code* offset from backtrack stack, add Code* and jump to location. 171 Pop(r3); 172 __ add(r3, r3, code_pointer()); 173 __ Jump(r3); 174 } 175 176 177 void RegExpMacroAssemblerPPC::Bind(Label* label) { __ bind(label); } 178 179 180 void RegExpMacroAssemblerPPC::CheckCharacter(uint32_t c, Label* on_equal) { 181 __ Cmpli(current_character(), Operand(c), r0); 182 BranchOrBacktrack(eq, on_equal); 183 } 184 185 186 void RegExpMacroAssemblerPPC::CheckCharacterGT(uc16 limit, Label* on_greater) { 187 __ Cmpli(current_character(), Operand(limit), r0); 188 BranchOrBacktrack(gt, on_greater); 189 } 190 191 192 void RegExpMacroAssemblerPPC::CheckAtStart(Label* on_at_start) { 193 __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne)); 194 __ addi(r3, current_input_offset(), Operand(-char_size())); 195 __ cmp(r3, r4); 196 BranchOrBacktrack(eq, on_at_start); 197 } 198 199 200 void RegExpMacroAssemblerPPC::CheckNotAtStart(int cp_offset, 201 Label* on_not_at_start) { 202 __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne)); 203 __ addi(r3, current_input_offset(), 204 Operand(-char_size() + cp_offset * char_size())); 205 __ cmp(r3, r4); 206 BranchOrBacktrack(ne, on_not_at_start); 207 } 208 209 210 void RegExpMacroAssemblerPPC::CheckCharacterLT(uc16 limit, Label* on_less) { 211 __ Cmpli(current_character(), Operand(limit), r0); 212 BranchOrBacktrack(lt, on_less); 213 } 214 215 216 void RegExpMacroAssemblerPPC::CheckGreedyLoop(Label* on_equal) { 217 Label backtrack_non_equal; 218 __ LoadP(r3, MemOperand(backtrack_stackpointer(), 0)); 219 __ cmp(current_input_offset(), r3); 220 __ bne(&backtrack_non_equal); 221 __ addi(backtrack_stackpointer(), backtrack_stackpointer(), 222 Operand(kPointerSize)); 223 224 __ bind(&backtrack_non_equal); 225 BranchOrBacktrack(eq, on_equal); 226 } 227 228 229 void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase( 230 int start_reg, bool read_backward, Label* on_no_match) { 231 Label fallthrough; 232 __ LoadP(r3, register_location(start_reg), r0); // Index of start of capture 233 __ LoadP(r4, register_location(start_reg + 1), r0); // Index of end 234 __ sub(r4, r4, r3, LeaveOE, SetRC); // Length of capture. 235 236 // At this point, the capture registers are either both set or both cleared. 237 // If the capture length is zero, then the capture is either empty or cleared. 238 // Fall through in both cases. 239 __ beq(&fallthrough, cr0); 240 241 // Check that there are enough characters left in the input. 242 if (read_backward) { 243 __ LoadP(r6, MemOperand(frame_pointer(), kStringStartMinusOne)); 244 __ add(r6, r6, r4); 245 __ cmp(current_input_offset(), r6); 246 BranchOrBacktrack(le, on_no_match); 247 } else { 248 __ add(r0, r4, current_input_offset(), LeaveOE, SetRC); 249 BranchOrBacktrack(gt, on_no_match, cr0); 250 } 251 252 if (mode_ == LATIN1) { 253 Label success; 254 Label fail; 255 Label loop_check; 256 257 // r3 - offset of start of capture 258 // r4 - length of capture 259 __ add(r3, r3, end_of_input_address()); 260 __ add(r5, end_of_input_address(), current_input_offset()); 261 if (read_backward) { 262 __ sub(r5, r5, r4); // Offset by length when matching backwards. 263 } 264 __ add(r4, r3, r4); 265 266 // r3 - Address of start of capture. 267 // r4 - Address of end of capture 268 // r5 - Address of current input position. 269 270 Label loop; 271 __ bind(&loop); 272 __ lbz(r6, MemOperand(r3)); 273 __ addi(r3, r3, Operand(char_size())); 274 __ lbz(r25, MemOperand(r5)); 275 __ addi(r5, r5, Operand(char_size())); 276 __ cmp(r25, r6); 277 __ beq(&loop_check); 278 279 // Mismatch, try case-insensitive match (converting letters to lower-case). 280 __ ori(r6, r6, Operand(0x20)); // Convert capture character to lower-case. 281 __ ori(r25, r25, Operand(0x20)); // Also convert input character. 282 __ cmp(r25, r6); 283 __ bne(&fail); 284 __ subi(r6, r6, Operand('a')); 285 __ cmpli(r6, Operand('z' - 'a')); // Is r6 a lowercase letter? 286 __ ble(&loop_check); // In range 'a'-'z'. 287 // Latin-1: Check for values in range [224,254] but not 247. 288 __ subi(r6, r6, Operand(224 - 'a')); 289 __ cmpli(r6, Operand(254 - 224)); 290 __ bgt(&fail); // Weren't Latin-1 letters. 291 __ cmpi(r6, Operand(247 - 224)); // Check for 247. 292 __ beq(&fail); 293 294 __ bind(&loop_check); 295 __ cmp(r3, r4); 296 __ blt(&loop); 297 __ b(&success); 298 299 __ bind(&fail); 300 BranchOrBacktrack(al, on_no_match); 301 302 __ bind(&success); 303 // Compute new value of character position after the matched part. 304 __ sub(current_input_offset(), r5, end_of_input_address()); 305 if (read_backward) { 306 __ LoadP(r3, register_location(start_reg)); // Index of start of capture 307 __ LoadP(r4, 308 register_location(start_reg + 1)); // Index of end of capture 309 __ add(current_input_offset(), current_input_offset(), r3); 310 __ sub(current_input_offset(), current_input_offset(), r4); 311 } 312 } else { 313 DCHECK(mode_ == UC16); 314 int argument_count = 4; 315 __ PrepareCallCFunction(argument_count, r5); 316 317 // r3 - offset of start of capture 318 // r4 - length of capture 319 320 // Put arguments into arguments registers. 321 // Parameters are 322 // r3: Address byte_offset1 - Address captured substring's start. 323 // r4: Address byte_offset2 - Address of current character position. 324 // r5: size_t byte_length - length of capture in bytes(!) 325 // r6: Isolate* isolate 326 327 // Address of start of capture. 328 __ add(r3, r3, end_of_input_address()); 329 // Length of capture. 330 __ mr(r5, r4); 331 // Save length in callee-save register for use on return. 332 __ mr(r25, r4); 333 // Address of current input position. 334 __ add(r4, current_input_offset(), end_of_input_address()); 335 if (read_backward) { 336 __ sub(r4, r4, r25); 337 } 338 // Isolate. 339 __ mov(r6, Operand(ExternalReference::isolate_address(isolate()))); 340 341 { 342 AllowExternalCallThatCantCauseGC scope(masm_); 343 ExternalReference function = 344 ExternalReference::re_case_insensitive_compare_uc16(isolate()); 345 __ CallCFunction(function, argument_count); 346 } 347 348 // Check if function returned non-zero for success or zero for failure. 349 __ cmpi(r3, Operand::Zero()); 350 BranchOrBacktrack(eq, on_no_match); 351 352 // On success, advance position by length of capture. 353 if (read_backward) { 354 __ sub(current_input_offset(), current_input_offset(), r25); 355 } else { 356 __ add(current_input_offset(), current_input_offset(), r25); 357 } 358 } 359 360 __ bind(&fallthrough); 361 } 362 363 364 void RegExpMacroAssemblerPPC::CheckNotBackReference(int start_reg, 365 bool read_backward, 366 Label* on_no_match) { 367 Label fallthrough; 368 Label success; 369 370 // Find length of back-referenced capture. 371 __ LoadP(r3, register_location(start_reg), r0); 372 __ LoadP(r4, register_location(start_reg + 1), r0); 373 __ sub(r4, r4, r3, LeaveOE, SetRC); // Length to check. 374 375 // At this point, the capture registers are either both set or both cleared. 376 // If the capture length is zero, then the capture is either empty or cleared. 377 // Fall through in both cases. 378 __ beq(&fallthrough, cr0); 379 380 // Check that there are enough characters left in the input. 381 if (read_backward) { 382 __ LoadP(r6, MemOperand(frame_pointer(), kStringStartMinusOne)); 383 __ add(r6, r6, r4); 384 __ cmp(current_input_offset(), r6); 385 BranchOrBacktrack(lt, on_no_match); 386 } else { 387 __ add(r0, r4, current_input_offset(), LeaveOE, SetRC); 388 BranchOrBacktrack(gt, on_no_match, cr0); 389 } 390 391 // r3 - offset of start of capture 392 // r4 - length of capture 393 __ add(r3, r3, end_of_input_address()); 394 __ add(r5, end_of_input_address(), current_input_offset()); 395 if (read_backward) { 396 __ sub(r5, r5, r4); // Offset by length when matching backwards. 397 } 398 __ add(r4, r4, r3); 399 400 Label loop; 401 __ bind(&loop); 402 if (mode_ == LATIN1) { 403 __ lbz(r6, MemOperand(r3)); 404 __ addi(r3, r3, Operand(char_size())); 405 __ lbz(r25, MemOperand(r5)); 406 __ addi(r5, r5, Operand(char_size())); 407 } else { 408 DCHECK(mode_ == UC16); 409 __ lhz(r6, MemOperand(r3)); 410 __ addi(r3, r3, Operand(char_size())); 411 __ lhz(r25, MemOperand(r5)); 412 __ addi(r5, r5, Operand(char_size())); 413 } 414 __ cmp(r6, r25); 415 BranchOrBacktrack(ne, on_no_match); 416 __ cmp(r3, r4); 417 __ blt(&loop); 418 419 // Move current character position to position after match. 420 __ sub(current_input_offset(), r5, end_of_input_address()); 421 if (read_backward) { 422 __ LoadP(r3, register_location(start_reg)); // Index of start of capture 423 __ LoadP(r4, register_location(start_reg + 1)); // Index of end of capture 424 __ add(current_input_offset(), current_input_offset(), r3); 425 __ sub(current_input_offset(), current_input_offset(), r4); 426 } 427 428 __ bind(&fallthrough); 429 } 430 431 432 void RegExpMacroAssemblerPPC::CheckNotCharacter(unsigned c, 433 Label* on_not_equal) { 434 __ Cmpli(current_character(), Operand(c), r0); 435 BranchOrBacktrack(ne, on_not_equal); 436 } 437 438 439 void RegExpMacroAssemblerPPC::CheckCharacterAfterAnd(uint32_t c, uint32_t mask, 440 Label* on_equal) { 441 __ mov(r0, Operand(mask)); 442 if (c == 0) { 443 __ and_(r3, current_character(), r0, SetRC); 444 } else { 445 __ and_(r3, current_character(), r0); 446 __ Cmpli(r3, Operand(c), r0, cr0); 447 } 448 BranchOrBacktrack(eq, on_equal, cr0); 449 } 450 451 452 void RegExpMacroAssemblerPPC::CheckNotCharacterAfterAnd(unsigned c, 453 unsigned mask, 454 Label* on_not_equal) { 455 __ mov(r0, Operand(mask)); 456 if (c == 0) { 457 __ and_(r3, current_character(), r0, SetRC); 458 } else { 459 __ and_(r3, current_character(), r0); 460 __ Cmpli(r3, Operand(c), r0, cr0); 461 } 462 BranchOrBacktrack(ne, on_not_equal, cr0); 463 } 464 465 466 void RegExpMacroAssemblerPPC::CheckNotCharacterAfterMinusAnd( 467 uc16 c, uc16 minus, uc16 mask, Label* on_not_equal) { 468 DCHECK(minus < String::kMaxUtf16CodeUnit); 469 __ subi(r3, current_character(), Operand(minus)); 470 __ mov(r0, Operand(mask)); 471 __ and_(r3, r3, r0); 472 __ Cmpli(r3, Operand(c), r0); 473 BranchOrBacktrack(ne, on_not_equal); 474 } 475 476 477 void RegExpMacroAssemblerPPC::CheckCharacterInRange(uc16 from, uc16 to, 478 Label* on_in_range) { 479 __ mov(r0, Operand(from)); 480 __ sub(r3, current_character(), r0); 481 __ Cmpli(r3, Operand(to - from), r0); 482 BranchOrBacktrack(le, on_in_range); // Unsigned lower-or-same condition. 483 } 484 485 486 void RegExpMacroAssemblerPPC::CheckCharacterNotInRange(uc16 from, uc16 to, 487 Label* on_not_in_range) { 488 __ mov(r0, Operand(from)); 489 __ sub(r3, current_character(), r0); 490 __ Cmpli(r3, Operand(to - from), r0); 491 BranchOrBacktrack(gt, on_not_in_range); // Unsigned higher condition. 492 } 493 494 495 void RegExpMacroAssemblerPPC::CheckBitInTable(Handle<ByteArray> table, 496 Label* on_bit_set) { 497 __ mov(r3, Operand(table)); 498 if (mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) { 499 __ andi(r4, current_character(), Operand(kTableSize - 1)); 500 __ addi(r4, r4, Operand(ByteArray::kHeaderSize - kHeapObjectTag)); 501 } else { 502 __ addi(r4, current_character(), 503 Operand(ByteArray::kHeaderSize - kHeapObjectTag)); 504 } 505 __ lbzx(r3, MemOperand(r3, r4)); 506 __ cmpi(r3, Operand::Zero()); 507 BranchOrBacktrack(ne, on_bit_set); 508 } 509 510 511 bool RegExpMacroAssemblerPPC::CheckSpecialCharacterClass(uc16 type, 512 Label* on_no_match) { 513 // Range checks (c in min..max) are generally implemented by an unsigned 514 // (c - min) <= (max - min) check 515 switch (type) { 516 case 's': 517 // Match space-characters 518 if (mode_ == LATIN1) { 519 // One byte space characters are '\t'..'\r', ' ' and \u00a0. 520 Label success; 521 __ cmpi(current_character(), Operand(' ')); 522 __ beq(&success); 523 // Check range 0x09..0x0d 524 __ subi(r3, current_character(), Operand('\t')); 525 __ cmpli(r3, Operand('\r' - '\t')); 526 __ ble(&success); 527 // \u00a0 (NBSP). 528 __ cmpi(r3, Operand(0x00a0 - '\t')); 529 BranchOrBacktrack(ne, on_no_match); 530 __ bind(&success); 531 return true; 532 } 533 return false; 534 case 'S': 535 // The emitted code for generic character classes is good enough. 536 return false; 537 case 'd': 538 // Match ASCII digits ('0'..'9') 539 __ subi(r3, current_character(), Operand('0')); 540 __ cmpli(r3, Operand('9' - '0')); 541 BranchOrBacktrack(gt, on_no_match); 542 return true; 543 case 'D': 544 // Match non ASCII-digits 545 __ subi(r3, current_character(), Operand('0')); 546 __ cmpli(r3, Operand('9' - '0')); 547 BranchOrBacktrack(le, on_no_match); 548 return true; 549 case '.': { 550 // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029) 551 __ xori(r3, current_character(), Operand(0x01)); 552 // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c 553 __ subi(r3, r3, Operand(0x0b)); 554 __ cmpli(r3, Operand(0x0c - 0x0b)); 555 BranchOrBacktrack(le, on_no_match); 556 if (mode_ == UC16) { 557 // Compare original value to 0x2028 and 0x2029, using the already 558 // computed (current_char ^ 0x01 - 0x0b). I.e., check for 559 // 0x201d (0x2028 - 0x0b) or 0x201e. 560 __ subi(r3, r3, Operand(0x2028 - 0x0b)); 561 __ cmpli(r3, Operand(1)); 562 BranchOrBacktrack(le, on_no_match); 563 } 564 return true; 565 } 566 case 'n': { 567 // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029) 568 __ xori(r3, current_character(), Operand(0x01)); 569 // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c 570 __ subi(r3, r3, Operand(0x0b)); 571 __ cmpli(r3, Operand(0x0c - 0x0b)); 572 if (mode_ == LATIN1) { 573 BranchOrBacktrack(gt, on_no_match); 574 } else { 575 Label done; 576 __ ble(&done); 577 // Compare original value to 0x2028 and 0x2029, using the already 578 // computed (current_char ^ 0x01 - 0x0b). I.e., check for 579 // 0x201d (0x2028 - 0x0b) or 0x201e. 580 __ subi(r3, r3, Operand(0x2028 - 0x0b)); 581 __ cmpli(r3, Operand(1)); 582 BranchOrBacktrack(gt, on_no_match); 583 __ bind(&done); 584 } 585 return true; 586 } 587 case 'w': { 588 if (mode_ != LATIN1) { 589 // Table is 256 entries, so all Latin1 characters can be tested. 590 __ cmpi(current_character(), Operand('z')); 591 BranchOrBacktrack(gt, on_no_match); 592 } 593 ExternalReference map = ExternalReference::re_word_character_map(); 594 __ mov(r3, Operand(map)); 595 __ lbzx(r3, MemOperand(r3, current_character())); 596 __ cmpli(r3, Operand::Zero()); 597 BranchOrBacktrack(eq, on_no_match); 598 return true; 599 } 600 case 'W': { 601 Label done; 602 if (mode_ != LATIN1) { 603 // Table is 256 entries, so all Latin1 characters can be tested. 604 __ cmpli(current_character(), Operand('z')); 605 __ bgt(&done); 606 } 607 ExternalReference map = ExternalReference::re_word_character_map(); 608 __ mov(r3, Operand(map)); 609 __ lbzx(r3, MemOperand(r3, current_character())); 610 __ cmpli(r3, Operand::Zero()); 611 BranchOrBacktrack(ne, on_no_match); 612 if (mode_ != LATIN1) { 613 __ bind(&done); 614 } 615 return true; 616 } 617 case '*': 618 // Match any character. 619 return true; 620 // No custom implementation (yet): s(UC16), S(UC16). 621 default: 622 return false; 623 } 624 } 625 626 627 void RegExpMacroAssemblerPPC::Fail() { 628 __ li(r3, Operand(FAILURE)); 629 __ b(&exit_label_); 630 } 631 632 633 Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) { 634 Label return_r3; 635 636 if (masm_->has_exception()) { 637 // If the code gets corrupted due to long regular expressions and lack of 638 // space on trampolines, an internal exception flag is set. If this case 639 // is detected, we will jump into exit sequence right away. 640 __ bind_to(&entry_label_, internal_failure_label_.pos()); 641 } else { 642 // Finalize code - write the entry point code now we know how many 643 // registers we need. 644 645 // Entry code: 646 __ bind(&entry_label_); 647 648 // Tell the system that we have a stack frame. Because the type 649 // is MANUAL, no is generated. 650 FrameScope scope(masm_, StackFrame::MANUAL); 651 652 // Ensure register assigments are consistent with callee save mask 653 DCHECK(r25.bit() & kRegExpCalleeSaved); 654 DCHECK(code_pointer().bit() & kRegExpCalleeSaved); 655 DCHECK(current_input_offset().bit() & kRegExpCalleeSaved); 656 DCHECK(current_character().bit() & kRegExpCalleeSaved); 657 DCHECK(backtrack_stackpointer().bit() & kRegExpCalleeSaved); 658 DCHECK(end_of_input_address().bit() & kRegExpCalleeSaved); 659 DCHECK(frame_pointer().bit() & kRegExpCalleeSaved); 660 661 // Actually emit code to start a new stack frame. 662 // Push arguments 663 // Save callee-save registers. 664 // Start new stack frame. 665 // Store link register in existing stack-cell. 666 // Order here should correspond to order of offset constants in header file. 667 RegList registers_to_retain = kRegExpCalleeSaved; 668 RegList argument_registers = r3.bit() | r4.bit() | r5.bit() | r6.bit() | 669 r7.bit() | r8.bit() | r9.bit() | r10.bit(); 670 __ mflr(r0); 671 __ push(r0); 672 __ MultiPush(argument_registers | registers_to_retain); 673 // Set frame pointer in space for it if this is not a direct call 674 // from generated code. 675 __ addi(frame_pointer(), sp, Operand(8 * kPointerSize)); 676 __ li(r3, Operand::Zero()); 677 __ push(r3); // Make room for success counter and initialize it to 0. 678 __ push(r3); // Make room for "string start - 1" constant. 679 // Check if we have space on the stack for registers. 680 Label stack_limit_hit; 681 Label stack_ok; 682 683 ExternalReference stack_limit = 684 ExternalReference::address_of_stack_limit(isolate()); 685 __ mov(r3, Operand(stack_limit)); 686 __ LoadP(r3, MemOperand(r3)); 687 __ sub(r3, sp, r3, LeaveOE, SetRC); 688 // Handle it if the stack pointer is already below the stack limit. 689 __ ble(&stack_limit_hit, cr0); 690 // Check if there is room for the variable number of registers above 691 // the stack limit. 692 __ Cmpli(r3, Operand(num_registers_ * kPointerSize), r0); 693 __ bge(&stack_ok); 694 // Exit with OutOfMemory exception. There is not enough space on the stack 695 // for our working registers. 696 __ li(r3, Operand(EXCEPTION)); 697 __ b(&return_r3); 698 699 __ bind(&stack_limit_hit); 700 CallCheckStackGuardState(r3); 701 __ cmpi(r3, Operand::Zero()); 702 // If returned value is non-zero, we exit with the returned value as result. 703 __ bne(&return_r3); 704 705 __ bind(&stack_ok); 706 707 // Allocate space on stack for registers. 708 __ Add(sp, sp, -num_registers_ * kPointerSize, r0); 709 // Load string end. 710 __ LoadP(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 711 // Load input start. 712 __ LoadP(r3, MemOperand(frame_pointer(), kInputStart)); 713 // Find negative length (offset of start relative to end). 714 __ sub(current_input_offset(), r3, end_of_input_address()); 715 // Set r3 to address of char before start of the input string 716 // (effectively string position -1). 717 __ LoadP(r4, MemOperand(frame_pointer(), kStartIndex)); 718 __ subi(r3, current_input_offset(), Operand(char_size())); 719 if (mode_ == UC16) { 720 __ ShiftLeftImm(r0, r4, Operand(1)); 721 __ sub(r3, r3, r0); 722 } else { 723 __ sub(r3, r3, r4); 724 } 725 // Store this value in a local variable, for use when clearing 726 // position registers. 727 __ StoreP(r3, MemOperand(frame_pointer(), kStringStartMinusOne)); 728 729 // Initialize code pointer register 730 __ mov(code_pointer(), Operand(masm_->CodeObject())); 731 732 Label load_char_start_regexp, start_regexp; 733 // Load newline if index is at start, previous character otherwise. 734 __ cmpi(r4, Operand::Zero()); 735 __ bne(&load_char_start_regexp); 736 __ li(current_character(), Operand('\n')); 737 __ b(&start_regexp); 738 739 // Global regexp restarts matching here. 740 __ bind(&load_char_start_regexp); 741 // Load previous char as initial value of current character register. 742 LoadCurrentCharacterUnchecked(-1, 1); 743 __ bind(&start_regexp); 744 745 // Initialize on-stack registers. 746 if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. 747 // Fill saved registers with initial value = start offset - 1 748 if (num_saved_registers_ > 8) { 749 // One slot beyond address of register 0. 750 __ addi(r4, frame_pointer(), Operand(kRegisterZero + kPointerSize)); 751 __ li(r5, Operand(num_saved_registers_)); 752 __ mtctr(r5); 753 Label init_loop; 754 __ bind(&init_loop); 755 __ StorePU(r3, MemOperand(r4, -kPointerSize)); 756 __ bdnz(&init_loop); 757 } else { 758 for (int i = 0; i < num_saved_registers_; i++) { 759 __ StoreP(r3, register_location(i), r0); 760 } 761 } 762 } 763 764 // Initialize backtrack stack pointer. 765 __ LoadP(backtrack_stackpointer(), 766 MemOperand(frame_pointer(), kStackHighEnd)); 767 768 __ b(&start_label_); 769 770 // Exit code: 771 if (success_label_.is_linked()) { 772 // Save captures when successful. 773 __ bind(&success_label_); 774 if (num_saved_registers_ > 0) { 775 // copy captures to output 776 __ LoadP(r4, MemOperand(frame_pointer(), kInputStart)); 777 __ LoadP(r3, MemOperand(frame_pointer(), kRegisterOutput)); 778 __ LoadP(r5, MemOperand(frame_pointer(), kStartIndex)); 779 __ sub(r4, end_of_input_address(), r4); 780 // r4 is length of input in bytes. 781 if (mode_ == UC16) { 782 __ ShiftRightImm(r4, r4, Operand(1)); 783 } 784 // r4 is length of input in characters. 785 __ add(r4, r4, r5); 786 // r4 is length of string in characters. 787 788 DCHECK_EQ(0, num_saved_registers_ % 2); 789 // Always an even number of capture registers. This allows us to 790 // unroll the loop once to add an operation between a load of a register 791 // and the following use of that register. 792 for (int i = 0; i < num_saved_registers_; i += 2) { 793 __ LoadP(r5, register_location(i), r0); 794 __ LoadP(r6, register_location(i + 1), r0); 795 if (i == 0 && global_with_zero_length_check()) { 796 // Keep capture start in r25 for the zero-length check later. 797 __ mr(r25, r5); 798 } 799 if (mode_ == UC16) { 800 __ ShiftRightArithImm(r5, r5, 1); 801 __ add(r5, r4, r5); 802 __ ShiftRightArithImm(r6, r6, 1); 803 __ add(r6, r4, r6); 804 } else { 805 __ add(r5, r4, r5); 806 __ add(r6, r4, r6); 807 } 808 __ stw(r5, MemOperand(r3)); 809 __ addi(r3, r3, Operand(kIntSize)); 810 __ stw(r6, MemOperand(r3)); 811 __ addi(r3, r3, Operand(kIntSize)); 812 } 813 } 814 815 if (global()) { 816 // Restart matching if the regular expression is flagged as global. 817 __ LoadP(r3, MemOperand(frame_pointer(), kSuccessfulCaptures)); 818 __ LoadP(r4, MemOperand(frame_pointer(), kNumOutputRegisters)); 819 __ LoadP(r5, MemOperand(frame_pointer(), kRegisterOutput)); 820 // Increment success counter. 821 __ addi(r3, r3, Operand(1)); 822 __ StoreP(r3, MemOperand(frame_pointer(), kSuccessfulCaptures)); 823 // Capture results have been stored, so the number of remaining global 824 // output registers is reduced by the number of stored captures. 825 __ subi(r4, r4, Operand(num_saved_registers_)); 826 // Check whether we have enough room for another set of capture results. 827 __ cmpi(r4, Operand(num_saved_registers_)); 828 __ blt(&return_r3); 829 830 __ StoreP(r4, MemOperand(frame_pointer(), kNumOutputRegisters)); 831 // Advance the location for output. 832 __ addi(r5, r5, Operand(num_saved_registers_ * kIntSize)); 833 __ StoreP(r5, MemOperand(frame_pointer(), kRegisterOutput)); 834 835 // Prepare r3 to initialize registers with its value in the next run. 836 __ LoadP(r3, MemOperand(frame_pointer(), kStringStartMinusOne)); 837 838 if (global_with_zero_length_check()) { 839 // Special case for zero-length matches. 840 // r25: capture start index 841 __ cmp(current_input_offset(), r25); 842 // Not a zero-length match, restart. 843 __ bne(&load_char_start_regexp); 844 // Offset from the end is zero if we already reached the end. 845 __ cmpi(current_input_offset(), Operand::Zero()); 846 __ beq(&exit_label_); 847 // Advance current position after a zero-length match. 848 __ addi(current_input_offset(), current_input_offset(), 849 Operand((mode_ == UC16) ? 2 : 1)); 850 } 851 852 __ b(&load_char_start_regexp); 853 } else { 854 __ li(r3, Operand(SUCCESS)); 855 } 856 } 857 858 // Exit and return r3 859 __ bind(&exit_label_); 860 if (global()) { 861 __ LoadP(r3, MemOperand(frame_pointer(), kSuccessfulCaptures)); 862 } 863 864 __ bind(&return_r3); 865 // Skip sp past regexp registers and local variables.. 866 __ mr(sp, frame_pointer()); 867 // Restore registers r25..r31 and return (restoring lr to pc). 868 __ MultiPop(registers_to_retain); 869 __ pop(r0); 870 __ mtlr(r0); 871 __ blr(); 872 873 // Backtrack code (branch target for conditional backtracks). 874 if (backtrack_label_.is_linked()) { 875 __ bind(&backtrack_label_); 876 Backtrack(); 877 } 878 879 Label exit_with_exception; 880 881 // Preempt-code 882 if (check_preempt_label_.is_linked()) { 883 SafeCallTarget(&check_preempt_label_); 884 885 CallCheckStackGuardState(r3); 886 __ cmpi(r3, Operand::Zero()); 887 // If returning non-zero, we should end execution with the given 888 // result as return value. 889 __ bne(&return_r3); 890 891 // String might have moved: Reload end of string from frame. 892 __ LoadP(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); 893 SafeReturn(); 894 } 895 896 // Backtrack stack overflow code. 897 if (stack_overflow_label_.is_linked()) { 898 SafeCallTarget(&stack_overflow_label_); 899 // Reached if the backtrack-stack limit has been hit. 900 Label grow_failed; 901 902 // Call GrowStack(backtrack_stackpointer(), &stack_base) 903 static const int num_arguments = 3; 904 __ PrepareCallCFunction(num_arguments, r3); 905 __ mr(r3, backtrack_stackpointer()); 906 __ addi(r4, frame_pointer(), Operand(kStackHighEnd)); 907 __ mov(r5, Operand(ExternalReference::isolate_address(isolate()))); 908 ExternalReference grow_stack = 909 ExternalReference::re_grow_stack(isolate()); 910 __ CallCFunction(grow_stack, num_arguments); 911 // If return NULL, we have failed to grow the stack, and 912 // must exit with a stack-overflow exception. 913 __ cmpi(r3, Operand::Zero()); 914 __ beq(&exit_with_exception); 915 // Otherwise use return value as new stack pointer. 916 __ mr(backtrack_stackpointer(), r3); 917 // Restore saved registers and continue. 918 SafeReturn(); 919 } 920 921 if (exit_with_exception.is_linked()) { 922 // If any of the code above needed to exit with an exception. 923 __ bind(&exit_with_exception); 924 // Exit with Result EXCEPTION(-1) to signal thrown exception. 925 __ li(r3, Operand(EXCEPTION)); 926 __ b(&return_r3); 927 } 928 } 929 930 CodeDesc code_desc; 931 masm_->GetCode(&code_desc); 932 Handle<Code> code = isolate()->factory()->NewCode( 933 code_desc, Code::ComputeFlags(Code::REGEXP), masm_->CodeObject()); 934 PROFILE(masm_->isolate(), RegExpCodeCreateEvent(*code, *source)); 935 return Handle<HeapObject>::cast(code); 936 } 937 938 939 void RegExpMacroAssemblerPPC::GoTo(Label* to) { BranchOrBacktrack(al, to); } 940 941 942 void RegExpMacroAssemblerPPC::IfRegisterGE(int reg, int comparand, 943 Label* if_ge) { 944 __ LoadP(r3, register_location(reg), r0); 945 __ Cmpi(r3, Operand(comparand), r0); 946 BranchOrBacktrack(ge, if_ge); 947 } 948 949 950 void RegExpMacroAssemblerPPC::IfRegisterLT(int reg, int comparand, 951 Label* if_lt) { 952 __ LoadP(r3, register_location(reg), r0); 953 __ Cmpi(r3, Operand(comparand), r0); 954 BranchOrBacktrack(lt, if_lt); 955 } 956 957 958 void RegExpMacroAssemblerPPC::IfRegisterEqPos(int reg, Label* if_eq) { 959 __ LoadP(r3, register_location(reg), r0); 960 __ cmp(r3, current_input_offset()); 961 BranchOrBacktrack(eq, if_eq); 962 } 963 964 965 RegExpMacroAssembler::IrregexpImplementation 966 RegExpMacroAssemblerPPC::Implementation() { 967 return kPPCImplementation; 968 } 969 970 971 void RegExpMacroAssemblerPPC::LoadCurrentCharacter(int cp_offset, 972 Label* on_end_of_input, 973 bool check_bounds, 974 int characters) { 975 DCHECK(cp_offset < (1 << 30)); // Be sane! (And ensure negation works) 976 if (check_bounds) { 977 if (cp_offset >= 0) { 978 CheckPosition(cp_offset + characters - 1, on_end_of_input); 979 } else { 980 CheckPosition(cp_offset, on_end_of_input); 981 } 982 } 983 LoadCurrentCharacterUnchecked(cp_offset, characters); 984 } 985 986 987 void RegExpMacroAssemblerPPC::PopCurrentPosition() { 988 Pop(current_input_offset()); 989 } 990 991 992 void RegExpMacroAssemblerPPC::PopRegister(int register_index) { 993 Pop(r3); 994 __ StoreP(r3, register_location(register_index), r0); 995 } 996 997 998 void RegExpMacroAssemblerPPC::PushBacktrack(Label* label) { 999 __ mov_label_offset(r3, label); 1000 Push(r3); 1001 CheckStackLimit(); 1002 } 1003 1004 1005 void RegExpMacroAssemblerPPC::PushCurrentPosition() { 1006 Push(current_input_offset()); 1007 } 1008 1009 1010 void RegExpMacroAssemblerPPC::PushRegister(int register_index, 1011 StackCheckFlag check_stack_limit) { 1012 __ LoadP(r3, register_location(register_index), r0); 1013 Push(r3); 1014 if (check_stack_limit) CheckStackLimit(); 1015 } 1016 1017 1018 void RegExpMacroAssemblerPPC::ReadCurrentPositionFromRegister(int reg) { 1019 __ LoadP(current_input_offset(), register_location(reg), r0); 1020 } 1021 1022 1023 void RegExpMacroAssemblerPPC::ReadStackPointerFromRegister(int reg) { 1024 __ LoadP(backtrack_stackpointer(), register_location(reg), r0); 1025 __ LoadP(r3, MemOperand(frame_pointer(), kStackHighEnd)); 1026 __ add(backtrack_stackpointer(), backtrack_stackpointer(), r3); 1027 } 1028 1029 1030 void RegExpMacroAssemblerPPC::SetCurrentPositionFromEnd(int by) { 1031 Label after_position; 1032 __ Cmpi(current_input_offset(), Operand(-by * char_size()), r0); 1033 __ bge(&after_position); 1034 __ mov(current_input_offset(), Operand(-by * char_size())); 1035 // On RegExp code entry (where this operation is used), the character before 1036 // the current position is expected to be already loaded. 1037 // We have advanced the position, so it's safe to read backwards. 1038 LoadCurrentCharacterUnchecked(-1, 1); 1039 __ bind(&after_position); 1040 } 1041 1042 1043 void RegExpMacroAssemblerPPC::SetRegister(int register_index, int to) { 1044 DCHECK(register_index >= num_saved_registers_); // Reserved for positions! 1045 __ mov(r3, Operand(to)); 1046 __ StoreP(r3, register_location(register_index), r0); 1047 } 1048 1049 1050 bool RegExpMacroAssemblerPPC::Succeed() { 1051 __ b(&success_label_); 1052 return global(); 1053 } 1054 1055 1056 void RegExpMacroAssemblerPPC::WriteCurrentPositionToRegister(int reg, 1057 int cp_offset) { 1058 if (cp_offset == 0) { 1059 __ StoreP(current_input_offset(), register_location(reg), r0); 1060 } else { 1061 __ mov(r0, Operand(cp_offset * char_size())); 1062 __ add(r3, current_input_offset(), r0); 1063 __ StoreP(r3, register_location(reg), r0); 1064 } 1065 } 1066 1067 1068 void RegExpMacroAssemblerPPC::ClearRegisters(int reg_from, int reg_to) { 1069 DCHECK(reg_from <= reg_to); 1070 __ LoadP(r3, MemOperand(frame_pointer(), kStringStartMinusOne)); 1071 for (int reg = reg_from; reg <= reg_to; reg++) { 1072 __ StoreP(r3, register_location(reg), r0); 1073 } 1074 } 1075 1076 1077 void RegExpMacroAssemblerPPC::WriteStackPointerToRegister(int reg) { 1078 __ LoadP(r4, MemOperand(frame_pointer(), kStackHighEnd)); 1079 __ sub(r3, backtrack_stackpointer(), r4); 1080 __ StoreP(r3, register_location(reg), r0); 1081 } 1082 1083 1084 // Private methods: 1085 1086 void RegExpMacroAssemblerPPC::CallCheckStackGuardState(Register scratch) { 1087 int frame_alignment = masm_->ActivationFrameAlignment(); 1088 int stack_space = kNumRequiredStackFrameSlots; 1089 int stack_passed_arguments = 1; // space for return address pointer 1090 1091 // The following stack manipulation logic is similar to 1092 // PrepareCallCFunction. However, we need an extra slot on the 1093 // stack to house the return address parameter. 1094 if (frame_alignment > kPointerSize) { 1095 // Make stack end at alignment and make room for stack arguments 1096 // -- preserving original value of sp. 1097 __ mr(scratch, sp); 1098 __ addi(sp, sp, Operand(-(stack_passed_arguments + 1) * kPointerSize)); 1099 DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); 1100 __ ClearRightImm(sp, sp, Operand(WhichPowerOf2(frame_alignment))); 1101 __ StoreP(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize)); 1102 } else { 1103 // Make room for stack arguments 1104 stack_space += stack_passed_arguments; 1105 } 1106 1107 // Allocate frame with required slots to make ABI work. 1108 __ li(r0, Operand::Zero()); 1109 __ StorePU(r0, MemOperand(sp, -stack_space * kPointerSize)); 1110 1111 // RegExp code frame pointer. 1112 __ mr(r5, frame_pointer()); 1113 // Code* of self. 1114 __ mov(r4, Operand(masm_->CodeObject())); 1115 // r3 will point to the return address, placed by DirectCEntry. 1116 __ addi(r3, sp, Operand(kStackFrameExtraParamSlot * kPointerSize)); 1117 1118 ExternalReference stack_guard_check = 1119 ExternalReference::re_check_stack_guard_state(isolate()); 1120 __ mov(ip, Operand(stack_guard_check)); 1121 DirectCEntryStub stub(isolate()); 1122 stub.GenerateCall(masm_, ip); 1123 1124 // Restore the stack pointer 1125 stack_space = kNumRequiredStackFrameSlots + stack_passed_arguments; 1126 if (frame_alignment > kPointerSize) { 1127 __ LoadP(sp, MemOperand(sp, stack_space * kPointerSize)); 1128 } else { 1129 __ addi(sp, sp, Operand(stack_space * kPointerSize)); 1130 } 1131 1132 __ mov(code_pointer(), Operand(masm_->CodeObject())); 1133 } 1134 1135 1136 // Helper function for reading a value out of a stack frame. 1137 template <typename T> 1138 static T& frame_entry(Address re_frame, int frame_offset) { 1139 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); 1140 } 1141 1142 1143 template <typename T> 1144 static T* frame_entry_address(Address re_frame, int frame_offset) { 1145 return reinterpret_cast<T*>(re_frame + frame_offset); 1146 } 1147 1148 1149 int RegExpMacroAssemblerPPC::CheckStackGuardState(Address* return_address, 1150 Code* re_code, 1151 Address re_frame) { 1152 return NativeRegExpMacroAssembler::CheckStackGuardState( 1153 frame_entry<Isolate*>(re_frame, kIsolate), 1154 frame_entry<intptr_t>(re_frame, kStartIndex), 1155 frame_entry<intptr_t>(re_frame, kDirectCall) == 1, return_address, 1156 re_code, frame_entry_address<String*>(re_frame, kInputString), 1157 frame_entry_address<const byte*>(re_frame, kInputStart), 1158 frame_entry_address<const byte*>(re_frame, kInputEnd)); 1159 } 1160 1161 1162 MemOperand RegExpMacroAssemblerPPC::register_location(int register_index) { 1163 DCHECK(register_index < (1 << 30)); 1164 if (num_registers_ <= register_index) { 1165 num_registers_ = register_index + 1; 1166 } 1167 return MemOperand(frame_pointer(), 1168 kRegisterZero - register_index * kPointerSize); 1169 } 1170 1171 1172 void RegExpMacroAssemblerPPC::CheckPosition(int cp_offset, 1173 Label* on_outside_input) { 1174 if (cp_offset >= 0) { 1175 __ Cmpi(current_input_offset(), Operand(-cp_offset * char_size()), r0); 1176 BranchOrBacktrack(ge, on_outside_input); 1177 } else { 1178 __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne)); 1179 __ addi(r3, current_input_offset(), Operand(cp_offset * char_size())); 1180 __ cmp(r3, r4); 1181 BranchOrBacktrack(le, on_outside_input); 1182 } 1183 } 1184 1185 1186 void RegExpMacroAssemblerPPC::BranchOrBacktrack(Condition condition, Label* to, 1187 CRegister cr) { 1188 if (condition == al) { // Unconditional. 1189 if (to == NULL) { 1190 Backtrack(); 1191 return; 1192 } 1193 __ b(to); 1194 return; 1195 } 1196 if (to == NULL) { 1197 __ b(condition, &backtrack_label_, cr); 1198 return; 1199 } 1200 __ b(condition, to, cr); 1201 } 1202 1203 1204 void RegExpMacroAssemblerPPC::SafeCall(Label* to, Condition cond, 1205 CRegister cr) { 1206 __ b(cond, to, cr, SetLK); 1207 } 1208 1209 1210 void RegExpMacroAssemblerPPC::SafeReturn() { 1211 __ pop(r0); 1212 __ mov(ip, Operand(masm_->CodeObject())); 1213 __ add(r0, r0, ip); 1214 __ mtlr(r0); 1215 __ blr(); 1216 } 1217 1218 1219 void RegExpMacroAssemblerPPC::SafeCallTarget(Label* name) { 1220 __ bind(name); 1221 __ mflr(r0); 1222 __ mov(ip, Operand(masm_->CodeObject())); 1223 __ sub(r0, r0, ip); 1224 __ push(r0); 1225 } 1226 1227 1228 void RegExpMacroAssemblerPPC::Push(Register source) { 1229 DCHECK(!source.is(backtrack_stackpointer())); 1230 __ StorePU(source, MemOperand(backtrack_stackpointer(), -kPointerSize)); 1231 } 1232 1233 1234 void RegExpMacroAssemblerPPC::Pop(Register target) { 1235 DCHECK(!target.is(backtrack_stackpointer())); 1236 __ LoadP(target, MemOperand(backtrack_stackpointer())); 1237 __ addi(backtrack_stackpointer(), backtrack_stackpointer(), 1238 Operand(kPointerSize)); 1239 } 1240 1241 1242 void RegExpMacroAssemblerPPC::CheckPreemption() { 1243 // Check for preemption. 1244 ExternalReference stack_limit = 1245 ExternalReference::address_of_stack_limit(isolate()); 1246 __ mov(r3, Operand(stack_limit)); 1247 __ LoadP(r3, MemOperand(r3)); 1248 __ cmpl(sp, r3); 1249 SafeCall(&check_preempt_label_, le); 1250 } 1251 1252 1253 void RegExpMacroAssemblerPPC::CheckStackLimit() { 1254 ExternalReference stack_limit = 1255 ExternalReference::address_of_regexp_stack_limit(isolate()); 1256 __ mov(r3, Operand(stack_limit)); 1257 __ LoadP(r3, MemOperand(r3)); 1258 __ cmpl(backtrack_stackpointer(), r3); 1259 SafeCall(&stack_overflow_label_, le); 1260 } 1261 1262 1263 bool RegExpMacroAssemblerPPC::CanReadUnaligned() { 1264 return CpuFeatures::IsSupported(UNALIGNED_ACCESSES) && !slow_safe(); 1265 } 1266 1267 1268 void RegExpMacroAssemblerPPC::LoadCurrentCharacterUnchecked(int cp_offset, 1269 int characters) { 1270 Register offset = current_input_offset(); 1271 if (cp_offset != 0) { 1272 // r25 is not being used to store the capture start index at this point. 1273 __ addi(r25, current_input_offset(), Operand(cp_offset * char_size())); 1274 offset = r25; 1275 } 1276 // The lwz, stw, lhz, sth instructions can do unaligned accesses, if the CPU 1277 // and the operating system running on the target allow it. 1278 // We assume we don't want to do unaligned loads on PPC, so this function 1279 // must only be used to load a single character at a time. 1280 1281 DCHECK(characters == 1); 1282 __ add(current_character(), end_of_input_address(), offset); 1283 if (mode_ == LATIN1) { 1284 __ lbz(current_character(), MemOperand(current_character())); 1285 } else { 1286 DCHECK(mode_ == UC16); 1287 __ lhz(current_character(), MemOperand(current_character())); 1288 } 1289 } 1290 1291 1292 #undef __ 1293 1294 #endif // V8_INTERPRETED_REGEXP 1295 } // namespace internal 1296 } // namespace v8 1297 1298 #endif // V8_TARGET_ARCH_PPC 1299