7 #include "src/regexp/ppc/regexp-macro-assembler-ppc.h" 9 #include "src/assembler-inl.h" 10 #include "src/base/bits.h" 11 #include "src/code-stubs.h" 13 #include "src/macro-assembler.h" 14 #include "src/regexp/regexp-macro-assembler.h" 15 #include "src/regexp/regexp-stack.h" 21 #ifndef V8_INTERPRETED_REGEXP 92 #define __ ACCESS_MASM(masm_) 94 RegExpMacroAssemblerPPC::RegExpMacroAssemblerPPC(Isolate* isolate, Zone* zone,
96 int registers_to_save)
97 : NativeRegExpMacroAssembler(isolate, zone),
98 masm_(new MacroAssembler(isolate, nullptr, kRegExpCodeSize,
99 CodeObjectRequired::kYes)),
101 num_registers_(registers_to_save),
102 num_saved_registers_(registers_to_save),
108 internal_failure_label_() {
109 DCHECK_EQ(0, registers_to_save % 2);
112 __ function_descriptor();
117 __ bind(&internal_failure_label_);
118 __ li(r3, Operand(FAILURE));
120 __ bind(&start_label_);
124 RegExpMacroAssemblerPPC::~RegExpMacroAssemblerPPC() {
127 entry_label_.Unuse();
128 start_label_.Unuse();
129 success_label_.Unuse();
130 backtrack_label_.Unuse();
132 check_preempt_label_.Unuse();
133 stack_overflow_label_.Unuse();
134 internal_failure_label_.Unuse();
138 int RegExpMacroAssemblerPPC::stack_limit_slack() {
139 return RegExpStack::kStackLimitSlack;
143 void RegExpMacroAssemblerPPC::AdvanceCurrentPosition(
int by) {
145 __ addi(current_input_offset(), current_input_offset(),
146 Operand(by * char_size()));
151 void RegExpMacroAssemblerPPC::AdvanceRegister(
int reg,
int by) {
153 DCHECK_GT(num_registers_, reg);
155 __ LoadP(r3, register_location(reg), r0);
156 __ mov(r0, Operand(by));
158 __ StoreP(r3, register_location(reg), r0);
163 void RegExpMacroAssemblerPPC::Backtrack() {
167 __ add(r3, r3, code_pointer());
172 void RegExpMacroAssemblerPPC::Bind(Label* label) { __ bind(label); }
175 void RegExpMacroAssemblerPPC::CheckCharacter(
uint32_t c, Label* on_equal) {
176 __ Cmpli(current_character(), Operand(c), r0);
177 BranchOrBacktrack(eq, on_equal);
181 void RegExpMacroAssemblerPPC::CheckCharacterGT(uc16 limit, Label* on_greater) {
182 __ Cmpli(current_character(), Operand(limit), r0);
183 BranchOrBacktrack(gt, on_greater);
187 void RegExpMacroAssemblerPPC::CheckAtStart(Label* on_at_start) {
188 __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne));
189 __ addi(r3, current_input_offset(), Operand(-char_size()));
191 BranchOrBacktrack(eq, on_at_start);
195 void RegExpMacroAssemblerPPC::CheckNotAtStart(
int cp_offset,
196 Label* on_not_at_start) {
197 __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne));
198 __ addi(r3, current_input_offset(),
199 Operand(-char_size() + cp_offset * char_size()));
201 BranchOrBacktrack(ne, on_not_at_start);
205 void RegExpMacroAssemblerPPC::CheckCharacterLT(uc16 limit, Label* on_less) {
206 __ Cmpli(current_character(), Operand(limit), r0);
207 BranchOrBacktrack(lt, on_less);
211 void RegExpMacroAssemblerPPC::CheckGreedyLoop(Label* on_equal) {
212 Label backtrack_non_equal;
213 __ LoadP(r3, MemOperand(backtrack_stackpointer(), 0));
214 __ cmp(current_input_offset(), r3);
215 __ bne(&backtrack_non_equal);
216 __ addi(backtrack_stackpointer(), backtrack_stackpointer(),
217 Operand(kPointerSize));
219 __ bind(&backtrack_non_equal);
220 BranchOrBacktrack(eq, on_equal);
223 void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase(
224 int start_reg,
bool read_backward,
bool unicode, Label* on_no_match) {
226 __ LoadP(r3, register_location(start_reg), r0);
227 __ LoadP(r4, register_location(start_reg + 1), r0);
228 __ sub(r4, r4, r3, LeaveOE, SetRC);
233 __ beq(&fallthrough, cr0);
237 __ LoadP(r6, MemOperand(frame_pointer(), kStringStartMinusOne));
239 __ cmp(current_input_offset(), r6);
240 BranchOrBacktrack(le, on_no_match);
242 __ add(r0, r4, current_input_offset(), LeaveOE, SetRC);
243 BranchOrBacktrack(gt, on_no_match, cr0);
246 if (mode_ == LATIN1) {
253 __ add(r3, r3, end_of_input_address());
254 __ add(r5, end_of_input_address(), current_input_offset());
266 __ lbz(r6, MemOperand(r3));
267 __ addi(r3, r3, Operand(char_size()));
268 __ lbz(r25, MemOperand(r5));
269 __ addi(r5, r5, Operand(char_size()));
274 __ ori(r6, r6, Operand(0x20));
275 __ ori(r25, r25, Operand(0x20));
278 __ subi(r6, r6, Operand(
'a'));
279 __ cmpli(r6, Operand(
'z' -
'a'));
282 __ subi(r6, r6, Operand(224 -
'a'));
283 __ cmpli(r6, Operand(254 - 224));
285 __ cmpi(r6, Operand(247 - 224));
288 __ bind(&loop_check);
294 BranchOrBacktrack(al, on_no_match);
298 __ sub(current_input_offset(), r5, end_of_input_address());
300 __ LoadP(r3, register_location(start_reg));
302 register_location(start_reg + 1));
303 __ add(current_input_offset(), current_input_offset(), r3);
304 __ sub(current_input_offset(), current_input_offset(), r4);
307 DCHECK(mode_ == UC16);
308 int argument_count = 4;
309 __ PrepareCallCFunction(argument_count, r5);
322 __ add(r3, r3, end_of_input_address());
328 __ add(r4, current_input_offset(), end_of_input_address());
333 #ifdef V8_INTL_SUPPORT 335 __ li(r6, Operand::Zero());
337 #endif // V8_INTL_SUPPORT 339 __ mov(r6, Operand(ExternalReference::isolate_address(isolate())));
343 AllowExternalCallThatCantCauseGC scope(masm_);
344 ExternalReference
function =
345 ExternalReference::re_case_insensitive_compare_uc16(isolate());
346 __ CallCFunction(
function, argument_count);
350 __ cmpi(r3, Operand::Zero());
351 BranchOrBacktrack(eq, on_no_match);
355 __ sub(current_input_offset(), current_input_offset(), r25);
357 __ add(current_input_offset(), current_input_offset(), r25);
361 __ bind(&fallthrough);
365 void RegExpMacroAssemblerPPC::CheckNotBackReference(
int start_reg,
367 Label* on_no_match) {
372 __ LoadP(r3, register_location(start_reg), r0);
373 __ LoadP(r4, register_location(start_reg + 1), r0);
374 __ sub(r4, r4, r3, LeaveOE, SetRC);
379 __ beq(&fallthrough, cr0);
383 __ LoadP(r6, MemOperand(frame_pointer(), kStringStartMinusOne));
385 __ cmp(current_input_offset(), r6);
386 BranchOrBacktrack(le, on_no_match);
388 __ add(r0, r4, current_input_offset(), LeaveOE, SetRC);
389 BranchOrBacktrack(gt, on_no_match, cr0);
394 __ add(r3, r3, end_of_input_address());
395 __ add(r5, end_of_input_address(), current_input_offset());
403 if (mode_ == LATIN1) {
404 __ lbz(r6, MemOperand(r3));
405 __ addi(r3, r3, Operand(char_size()));
406 __ lbz(r25, MemOperand(r5));
407 __ addi(r5, r5, Operand(char_size()));
409 DCHECK(mode_ == UC16);
410 __ lhz(r6, MemOperand(r3));
411 __ addi(r3, r3, Operand(char_size()));
412 __ lhz(r25, MemOperand(r5));
413 __ addi(r5, r5, Operand(char_size()));
416 BranchOrBacktrack(ne, on_no_match);
421 __ sub(current_input_offset(), r5, end_of_input_address());
423 __ LoadP(r3, register_location(start_reg));
424 __ LoadP(r4, register_location(start_reg + 1));
425 __ add(current_input_offset(), current_input_offset(), r3);
426 __ sub(current_input_offset(), current_input_offset(), r4);
429 __ bind(&fallthrough);
433 void RegExpMacroAssemblerPPC::CheckNotCharacter(
unsigned c,
434 Label* on_not_equal) {
435 __ Cmpli(current_character(), Operand(c), r0);
436 BranchOrBacktrack(ne, on_not_equal);
440 void RegExpMacroAssemblerPPC::CheckCharacterAfterAnd(
uint32_t c,
uint32_t mask,
442 __ mov(r0, Operand(mask));
444 __ and_(r3, current_character(), r0, SetRC);
446 __ and_(r3, current_character(), r0);
447 __ Cmpli(r3, Operand(c), r0, cr0);
449 BranchOrBacktrack(eq, on_equal, cr0);
453 void RegExpMacroAssemblerPPC::CheckNotCharacterAfterAnd(
unsigned c,
455 Label* on_not_equal) {
456 __ mov(r0, Operand(mask));
458 __ and_(r3, current_character(), r0, SetRC);
460 __ and_(r3, current_character(), r0);
461 __ Cmpli(r3, Operand(c), r0, cr0);
463 BranchOrBacktrack(ne, on_not_equal, cr0);
467 void RegExpMacroAssemblerPPC::CheckNotCharacterAfterMinusAnd(
468 uc16 c, uc16 minus, uc16 mask, Label* on_not_equal) {
469 DCHECK_GT(String::kMaxUtf16CodeUnit, minus);
470 __ subi(r3, current_character(), Operand(minus));
471 __ mov(r0, Operand(mask));
473 __ Cmpli(r3, Operand(c), r0);
474 BranchOrBacktrack(ne, on_not_equal);
478 void RegExpMacroAssemblerPPC::CheckCharacterInRange(uc16 from, uc16 to,
479 Label* on_in_range) {
480 __ mov(r0, Operand(from));
481 __ sub(r3, current_character(), r0);
482 __ Cmpli(r3, Operand(to - from), r0);
483 BranchOrBacktrack(le, on_in_range);
487 void RegExpMacroAssemblerPPC::CheckCharacterNotInRange(uc16 from, uc16 to,
488 Label* on_not_in_range) {
489 __ mov(r0, Operand(from));
490 __ sub(r3, current_character(), r0);
491 __ Cmpli(r3, Operand(to - from), r0);
492 BranchOrBacktrack(gt, on_not_in_range);
496 void RegExpMacroAssemblerPPC::CheckBitInTable(Handle<ByteArray> table,
498 __ mov(r3, Operand(table));
499 if (mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) {
500 __ andi(r4, current_character(), Operand(kTableSize - 1));
501 __ addi(r4, r4, Operand(ByteArray::kHeaderSize - kHeapObjectTag));
503 __ addi(r4, current_character(),
504 Operand(ByteArray::kHeaderSize - kHeapObjectTag));
506 __ lbzx(r3, MemOperand(r3, r4));
507 __ cmpi(r3, Operand::Zero());
508 BranchOrBacktrack(ne, on_bit_set);
512 bool RegExpMacroAssemblerPPC::CheckSpecialCharacterClass(uc16 type,
513 Label* on_no_match) {
519 if (mode_ == LATIN1) {
522 __ cmpi(current_character(), Operand(
' '));
525 __ subi(r3, current_character(), Operand(
'\t'));
526 __ cmpli(r3, Operand(
'\r' -
'\t'));
529 __ cmpi(r3, Operand(0x00A0 -
'\t'));
530 BranchOrBacktrack(ne, on_no_match);
540 __ subi(r3, current_character(), Operand(
'0'));
541 __ cmpli(r3, Operand(
'9' -
'0'));
542 BranchOrBacktrack(gt, on_no_match);
546 __ subi(r3, current_character(), Operand(
'0'));
547 __ cmpli(r3, Operand(
'9' -
'0'));
548 BranchOrBacktrack(le, on_no_match);
552 __ xori(r3, current_character(), Operand(0x01));
554 __ subi(r3, r3, Operand(0x0B));
555 __ cmpli(r3, Operand(0x0C - 0x0B));
556 BranchOrBacktrack(le, on_no_match);
561 __ subi(r3, r3, Operand(0x2028 - 0x0B));
562 __ cmpli(r3, Operand(1));
563 BranchOrBacktrack(le, on_no_match);
569 __ xori(r3, current_character(), Operand(0x01));
571 __ subi(r3, r3, Operand(0x0B));
572 __ cmpli(r3, Operand(0x0C - 0x0B));
573 if (mode_ == LATIN1) {
574 BranchOrBacktrack(gt, on_no_match);
581 __ subi(r3, r3, Operand(0x2028 - 0x0B));
582 __ cmpli(r3, Operand(1));
583 BranchOrBacktrack(gt, on_no_match);
589 if (mode_ != LATIN1) {
591 __ cmpi(current_character(), Operand(
'z'));
592 BranchOrBacktrack(gt, on_no_match);
594 ExternalReference map =
595 ExternalReference::re_word_character_map(isolate());
596 __ mov(r3, Operand(map));
597 __ lbzx(r3, MemOperand(r3, current_character()));
598 __ cmpli(r3, Operand::Zero());
599 BranchOrBacktrack(eq, on_no_match);
604 if (mode_ != LATIN1) {
606 __ cmpli(current_character(), Operand(
'z'));
609 ExternalReference map =
610 ExternalReference::re_word_character_map(isolate());
611 __ mov(r3, Operand(map));
612 __ lbzx(r3, MemOperand(r3, current_character()));
613 __ cmpli(r3, Operand::Zero());
614 BranchOrBacktrack(ne, on_no_match);
615 if (mode_ != LATIN1) {
630 void RegExpMacroAssemblerPPC::Fail() {
631 __ li(r3, Operand(FAILURE));
636 Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
639 if (masm_->has_exception()) {
643 __ bind_to(&entry_label_, internal_failure_label_.pos());
649 __ bind(&entry_label_);
653 FrameScope scope(masm_, StackFrame::MANUAL);
656 DCHECK(r25.bit() & kRegExpCalleeSaved);
657 DCHECK(code_pointer().bit() & kRegExpCalleeSaved);
658 DCHECK(current_input_offset().bit() & kRegExpCalleeSaved);
659 DCHECK(current_character().bit() & kRegExpCalleeSaved);
660 DCHECK(backtrack_stackpointer().bit() & kRegExpCalleeSaved);
661 DCHECK(end_of_input_address().bit() & kRegExpCalleeSaved);
662 DCHECK(frame_pointer().bit() & kRegExpCalleeSaved);
670 RegList registers_to_retain = kRegExpCalleeSaved;
671 RegList argument_registers = r3.bit() | r4.bit() | r5.bit() | r6.bit() |
672 r7.bit() | r8.bit() | r9.bit() | r10.bit();
675 __ MultiPush(argument_registers | registers_to_retain);
678 __ addi(frame_pointer(), sp, Operand(8 * kPointerSize));
679 __ li(r3, Operand::Zero());
683 Label stack_limit_hit;
686 ExternalReference stack_limit =
687 ExternalReference::address_of_stack_limit(isolate());
688 __ mov(r3, Operand(stack_limit));
689 __ LoadP(r3, MemOperand(r3));
690 __ sub(r3, sp, r3, LeaveOE, SetRC);
692 __ ble(&stack_limit_hit, cr0);
695 __ Cmpli(r3, Operand(num_registers_ * kPointerSize), r0);
699 __ li(r3, Operand(EXCEPTION));
702 __ bind(&stack_limit_hit);
703 CallCheckStackGuardState(r3);
704 __ cmpi(r3, Operand::Zero());
711 __ Add(sp, sp, -num_registers_ * kPointerSize, r0);
713 __ LoadP(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
715 __ LoadP(r3, MemOperand(frame_pointer(), kInputStart));
717 __ sub(current_input_offset(), r3, end_of_input_address());
720 __ LoadP(r4, MemOperand(frame_pointer(), kStartIndex));
721 __ subi(r3, current_input_offset(), Operand(char_size()));
723 __ ShiftLeftImm(r0, r4, Operand(1));
730 __ StoreP(r3, MemOperand(frame_pointer(), kStringStartMinusOne));
733 __ mov(code_pointer(), Operand(masm_->CodeObject()));
735 Label load_char_start_regexp, start_regexp;
737 __ cmpi(r4, Operand::Zero());
738 __ bne(&load_char_start_regexp);
739 __ li(current_character(), Operand(
'\n'));
743 __ bind(&load_char_start_regexp);
745 LoadCurrentCharacterUnchecked(-1, 1);
746 __ bind(&start_regexp);
749 if (num_saved_registers_ > 0) {
751 if (num_saved_registers_ > 8) {
753 __ addi(r4, frame_pointer(), Operand(kRegisterZero + kPointerSize));
754 __ li(r5, Operand(num_saved_registers_));
758 __ StorePU(r3, MemOperand(r4, -kPointerSize));
761 for (
int i = 0;
i < num_saved_registers_;
i++) {
762 __ StoreP(r3, register_location(
i), r0);
768 __ LoadP(backtrack_stackpointer(),
769 MemOperand(frame_pointer(), kStackHighEnd));
774 if (success_label_.is_linked()) {
776 __ bind(&success_label_);
777 if (num_saved_registers_ > 0) {
779 __ LoadP(r4, MemOperand(frame_pointer(), kInputStart));
780 __ LoadP(r3, MemOperand(frame_pointer(), kRegisterOutput));
781 __ LoadP(r5, MemOperand(frame_pointer(), kStartIndex));
782 __ sub(r4, end_of_input_address(), r4);
785 __ ShiftRightImm(r4, r4, Operand(1));
791 DCHECK_EQ(0, num_saved_registers_ % 2);
795 for (
int i = 0;
i < num_saved_registers_;
i += 2) {
796 __ LoadP(r5, register_location(
i), r0);
797 __ LoadP(r6, register_location(
i + 1), r0);
798 if (
i == 0 && global_with_zero_length_check()) {
803 __ ShiftRightArithImm(r5, r5, 1);
805 __ ShiftRightArithImm(r6, r6, 1);
811 __ stw(r5, MemOperand(r3));
812 __ addi(r3, r3, Operand(kIntSize));
813 __ stw(r6, MemOperand(r3));
814 __ addi(r3, r3, Operand(kIntSize));
820 __ LoadP(r3, MemOperand(frame_pointer(), kSuccessfulCaptures));
821 __ LoadP(r4, MemOperand(frame_pointer(), kNumOutputRegisters));
822 __ LoadP(r5, MemOperand(frame_pointer(), kRegisterOutput));
824 __ addi(r3, r3, Operand(1));
825 __ StoreP(r3, MemOperand(frame_pointer(), kSuccessfulCaptures));
828 __ subi(r4, r4, Operand(num_saved_registers_));
830 __ cmpi(r4, Operand(num_saved_registers_));
833 __ StoreP(r4, MemOperand(frame_pointer(), kNumOutputRegisters));
835 __ addi(r5, r5, Operand(num_saved_registers_ * kIntSize));
836 __ StoreP(r5, MemOperand(frame_pointer(), kRegisterOutput));
839 __ LoadP(r3, MemOperand(frame_pointer(), kStringStartMinusOne));
841 if (global_with_zero_length_check()) {
844 __ cmp(current_input_offset(), r25);
846 __ bne(&load_char_start_regexp);
848 __ cmpi(current_input_offset(), Operand::Zero());
849 __ beq(&exit_label_);
853 __ addi(current_input_offset(), current_input_offset(),
854 Operand((mode_ == UC16) ? 2 : 1));
855 if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
858 __ b(&load_char_start_regexp);
860 __ li(r3, Operand(SUCCESS));
865 __ bind(&exit_label_);
867 __ LoadP(r3, MemOperand(frame_pointer(), kSuccessfulCaptures));
872 __ mr(sp, frame_pointer());
874 __ MultiPop(registers_to_retain);
880 if (backtrack_label_.is_linked()) {
881 __ bind(&backtrack_label_);
885 Label exit_with_exception;
888 if (check_preempt_label_.is_linked()) {
889 SafeCallTarget(&check_preempt_label_);
891 CallCheckStackGuardState(r3);
892 __ cmpi(r3, Operand::Zero());
898 __ LoadP(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
903 if (stack_overflow_label_.is_linked()) {
904 SafeCallTarget(&stack_overflow_label_);
909 static const int num_arguments = 3;
910 __ PrepareCallCFunction(num_arguments, r3);
911 __ mr(r3, backtrack_stackpointer());
912 __ addi(r4, frame_pointer(), Operand(kStackHighEnd));
913 __ mov(r5, Operand(ExternalReference::isolate_address(isolate())));
914 ExternalReference grow_stack =
915 ExternalReference::re_grow_stack(isolate());
916 __ CallCFunction(grow_stack, num_arguments);
919 __ cmpi(r3, Operand::Zero());
920 __ beq(&exit_with_exception);
922 __ mr(backtrack_stackpointer(), r3);
927 if (exit_with_exception.is_linked()) {
929 __ bind(&exit_with_exception);
931 __ li(r3, Operand(EXCEPTION));
937 masm_->GetCode(isolate(), &code_desc);
938 Handle<Code> code = isolate()->factory()->NewCode(code_desc, Code::REGEXP,
939 masm_->CodeObject());
940 PROFILE(masm_->isolate(),
941 RegExpCodeCreateEvent(AbstractCode::cast(*code), *source));
942 return Handle<HeapObject>::cast(code);
946 void RegExpMacroAssemblerPPC::GoTo(Label* to) { BranchOrBacktrack(al, to); }
949 void RegExpMacroAssemblerPPC::IfRegisterGE(
int reg,
int comparand,
951 __ LoadP(r3, register_location(reg), r0);
952 __ Cmpi(r3, Operand(comparand), r0);
953 BranchOrBacktrack(ge, if_ge);
957 void RegExpMacroAssemblerPPC::IfRegisterLT(
int reg,
int comparand,
959 __ LoadP(r3, register_location(reg), r0);
960 __ Cmpi(r3, Operand(comparand), r0);
961 BranchOrBacktrack(lt, if_lt);
965 void RegExpMacroAssemblerPPC::IfRegisterEqPos(
int reg, Label* if_eq) {
966 __ LoadP(r3, register_location(reg), r0);
967 __ cmp(r3, current_input_offset());
968 BranchOrBacktrack(eq, if_eq);
972 RegExpMacroAssembler::IrregexpImplementation
973 RegExpMacroAssemblerPPC::Implementation() {
974 return kPPCImplementation;
978 void RegExpMacroAssemblerPPC::LoadCurrentCharacter(
int cp_offset,
979 Label* on_end_of_input,
982 DCHECK(cp_offset < (1 << 30));
984 if (cp_offset >= 0) {
985 CheckPosition(cp_offset + characters - 1, on_end_of_input);
987 CheckPosition(cp_offset, on_end_of_input);
990 LoadCurrentCharacterUnchecked(cp_offset, characters);
994 void RegExpMacroAssemblerPPC::PopCurrentPosition() {
995 Pop(current_input_offset());
999 void RegExpMacroAssemblerPPC::PopRegister(
int register_index) {
1001 __ StoreP(r3, register_location(register_index), r0);
1005 void RegExpMacroAssemblerPPC::PushBacktrack(Label* label) {
1006 __ mov_label_offset(r3, label);
1012 void RegExpMacroAssemblerPPC::PushCurrentPosition() {
1013 Push(current_input_offset());
1017 void RegExpMacroAssemblerPPC::PushRegister(
int register_index,
1018 StackCheckFlag check_stack_limit) {
1019 __ LoadP(r3, register_location(register_index), r0);
1021 if (check_stack_limit) CheckStackLimit();
1025 void RegExpMacroAssemblerPPC::ReadCurrentPositionFromRegister(
int reg) {
1026 __ LoadP(current_input_offset(), register_location(reg), r0);
1030 void RegExpMacroAssemblerPPC::ReadStackPointerFromRegister(
int reg) {
1031 __ LoadP(backtrack_stackpointer(), register_location(reg), r0);
1032 __ LoadP(r3, MemOperand(frame_pointer(), kStackHighEnd));
1033 __ add(backtrack_stackpointer(), backtrack_stackpointer(), r3);
1037 void RegExpMacroAssemblerPPC::SetCurrentPositionFromEnd(
int by) {
1038 Label after_position;
1039 __ Cmpi(current_input_offset(), Operand(-by * char_size()), r0);
1040 __ bge(&after_position);
1041 __ mov(current_input_offset(), Operand(-by * char_size()));
1045 LoadCurrentCharacterUnchecked(-1, 1);
1046 __ bind(&after_position);
1050 void RegExpMacroAssemblerPPC::SetRegister(
int register_index,
int to) {
1051 DCHECK(register_index >= num_saved_registers_);
1052 __ mov(r3, Operand(to));
1053 __ StoreP(r3, register_location(register_index), r0);
1057 bool RegExpMacroAssemblerPPC::Succeed() {
1058 __ b(&success_label_);
1063 void RegExpMacroAssemblerPPC::WriteCurrentPositionToRegister(
int reg,
1065 if (cp_offset == 0) {
1066 __ StoreP(current_input_offset(), register_location(reg), r0);
1068 __ mov(r0, Operand(cp_offset * char_size()));
1069 __ add(r3, current_input_offset(), r0);
1070 __ StoreP(r3, register_location(reg), r0);
1075 void RegExpMacroAssemblerPPC::ClearRegisters(
int reg_from,
int reg_to) {
1076 DCHECK(reg_from <= reg_to);
1077 __ LoadP(r3, MemOperand(frame_pointer(), kStringStartMinusOne));
1078 for (
int reg = reg_from; reg <= reg_to; reg++) {
1079 __ StoreP(r3, register_location(reg), r0);
1084 void RegExpMacroAssemblerPPC::WriteStackPointerToRegister(
int reg) {
1085 __ LoadP(r4, MemOperand(frame_pointer(), kStackHighEnd));
1086 __ sub(r3, backtrack_stackpointer(), r4);
1087 __ StoreP(r3, register_location(reg), r0);
1093 void RegExpMacroAssemblerPPC::CallCheckStackGuardState(Register scratch) {
1094 int frame_alignment = masm_->ActivationFrameAlignment();
1095 int stack_space = kNumRequiredStackFrameSlots;
1096 int stack_passed_arguments = 1;
1101 if (frame_alignment > kPointerSize) {
1105 __ addi(sp, sp, Operand(-(stack_passed_arguments + 1) * kPointerSize));
1106 DCHECK(base::bits::IsPowerOfTwo(frame_alignment));
1107 __ ClearRightImm(sp, sp, Operand(WhichPowerOf2(frame_alignment)));
1108 __ StoreP(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize));
1111 stack_space += stack_passed_arguments;
1115 __ li(r0, Operand::Zero());
1116 __ StorePU(r0, MemOperand(sp, -stack_space * kPointerSize));
1119 __ mr(r5, frame_pointer());
1121 __ mov(r4, Operand(masm_->CodeObject()));
1123 __ addi(r3, sp, Operand(kStackFrameExtraParamSlot * kPointerSize));
1125 ExternalReference stack_guard_check =
1126 ExternalReference::re_check_stack_guard_state(isolate());
1127 __ mov(ip, Operand(stack_guard_check));
1128 DirectCEntryStub stub(isolate());
1129 stub.GenerateCall(masm_, ip);
1132 stack_space = kNumRequiredStackFrameSlots + stack_passed_arguments;
1133 if (frame_alignment > kPointerSize) {
1134 __ LoadP(sp, MemOperand(sp, stack_space * kPointerSize));
1136 __ addi(sp, sp, Operand(stack_space * kPointerSize));
1139 __ mov(code_pointer(), Operand(masm_->CodeObject()));
1144 template <
typename T>
1145 static T& frame_entry(Address re_frame,
int frame_offset) {
1146 return reinterpret_cast<T&
>(Memory<int32_t>(re_frame + frame_offset));
1150 template <
typename T>
1151 static T* frame_entry_address(Address re_frame,
int frame_offset) {
1152 return reinterpret_cast<T*
>(re_frame + frame_offset);
1155 int RegExpMacroAssemblerPPC::CheckStackGuardState(Address* return_address,
1158 Code re_code = Code::cast(ObjectPtr(raw_code));
1159 return NativeRegExpMacroAssembler::CheckStackGuardState(
1160 frame_entry<Isolate*>(re_frame, kIsolate),
1161 frame_entry<intptr_t>(re_frame, kStartIndex),
1162 frame_entry<intptr_t>(re_frame, kDirectCall) == 1, return_address,
1163 re_code, frame_entry_address<Address>(re_frame, kInputString),
1164 frame_entry_address<const byte*>(re_frame, kInputStart),
1165 frame_entry_address<const byte*>(re_frame, kInputEnd));
1169 MemOperand RegExpMacroAssemblerPPC::register_location(
int register_index) {
1170 DCHECK(register_index < (1 << 30));
1171 if (num_registers_ <= register_index) {
1172 num_registers_ = register_index + 1;
1174 return MemOperand(frame_pointer(),
1175 kRegisterZero - register_index * kPointerSize);
1179 void RegExpMacroAssemblerPPC::CheckPosition(
int cp_offset,
1180 Label* on_outside_input) {
1181 if (cp_offset >= 0) {
1182 __ Cmpi(current_input_offset(), Operand(-cp_offset * char_size()), r0);
1183 BranchOrBacktrack(ge, on_outside_input);
1185 __ LoadP(r4, MemOperand(frame_pointer(), kStringStartMinusOne));
1186 __ addi(r3, current_input_offset(), Operand(cp_offset * char_size()));
1188 BranchOrBacktrack(le, on_outside_input);
1193 void RegExpMacroAssemblerPPC::BranchOrBacktrack(Condition condition, Label* to,
1195 if (condition == al) {
1196 if (to ==
nullptr) {
1203 if (to ==
nullptr) {
1204 __ b(condition, &backtrack_label_, cr);
1207 __ b(condition, to, cr);
1211 void RegExpMacroAssemblerPPC::SafeCall(Label* to, Condition cond,
1213 __ b(cond, to, cr, SetLK);
1217 void RegExpMacroAssemblerPPC::SafeReturn() {
1219 __ mov(ip, Operand(masm_->CodeObject()));
1226 void RegExpMacroAssemblerPPC::SafeCallTarget(Label* name) {
1229 __ mov(ip, Operand(masm_->CodeObject()));
1235 void RegExpMacroAssemblerPPC::Push(Register source) {
1236 DCHECK(source != backtrack_stackpointer());
1237 __ StorePU(source, MemOperand(backtrack_stackpointer(), -kPointerSize));
1241 void RegExpMacroAssemblerPPC::Pop(Register target) {
1242 DCHECK(target != backtrack_stackpointer());
1243 __ LoadP(target, MemOperand(backtrack_stackpointer()));
1244 __ addi(backtrack_stackpointer(), backtrack_stackpointer(),
1245 Operand(kPointerSize));
1249 void RegExpMacroAssemblerPPC::CheckPreemption() {
1251 ExternalReference stack_limit =
1252 ExternalReference::address_of_stack_limit(isolate());
1253 __ mov(r3, Operand(stack_limit));
1254 __ LoadP(r3, MemOperand(r3));
1256 SafeCall(&check_preempt_label_, le);
1260 void RegExpMacroAssemblerPPC::CheckStackLimit() {
1261 ExternalReference stack_limit =
1262 ExternalReference::address_of_regexp_stack_limit(isolate());
1263 __ mov(r3, Operand(stack_limit));
1264 __ LoadP(r3, MemOperand(r3));
1265 __ cmpl(backtrack_stackpointer(), r3);
1266 SafeCall(&stack_overflow_label_, le);
1270 void RegExpMacroAssemblerPPC::LoadCurrentCharacterUnchecked(
int cp_offset,
1272 Register offset = current_input_offset();
1273 if (cp_offset != 0) {
1275 __ addi(r25, current_input_offset(), Operand(cp_offset * char_size()));
1283 __ add(current_character(), end_of_input_address(), offset);
1284 #if V8_TARGET_LITTLE_ENDIAN 1285 if (mode_ == LATIN1) {
1286 if (characters == 4) {
1287 __ lwz(current_character(), MemOperand(current_character()));
1288 }
else if (characters == 2) {
1289 __ lhz(current_character(), MemOperand(current_character()));
1291 DCHECK_EQ(1, characters);
1292 __ lbz(current_character(), MemOperand(current_character()));
1295 DCHECK(mode_ == UC16);
1296 if (characters == 2) {
1297 __ lwz(current_character(), MemOperand(current_character()));
1299 DCHECK_EQ(1, characters);
1300 __ lhz(current_character(), MemOperand(current_character()));
1304 if (mode_ == LATIN1) {
1305 if (characters == 4) {
1306 __ lwbrx(current_character(), MemOperand(r0, current_character()));
1307 }
else if (characters == 2) {
1308 __ lhbrx(current_character(), MemOperand(r0, current_character()));
1310 DCHECK_EQ(1, characters);
1311 __ lbz(current_character(), MemOperand(current_character()));
1314 DCHECK(mode_ == UC16);
1315 if (characters == 2) {
1316 __ lwz(current_character(), MemOperand(current_character()));
1317 __ rlwinm(current_character(), current_character(), 16, 0, 31);
1319 DCHECK_EQ(1, characters);
1320 __ lhz(current_character(), MemOperand(current_character()));
1329 #endif // V8_INTERPRETED_REGEXP 1333 #endif // V8_TARGET_ARCH_PPC