5#if V8_TARGET_ARCH_PPC64
96#define __ ACCESS_MASM(masm_)
102 int registers_to_save)
103 : NativeRegExpMacroAssembler(isolate, zone),
104 masm_(
std::make_unique<MacroAssembler>(
107 no_root_array_scope_(
masm_.get()),
109 num_registers_(registers_to_save),
110 num_saved_registers_(registers_to_save),
116 internal_failure_label_() {
123 __ bind(&internal_failure_label_);
124 __ li(r3, Operand(FAILURE));
126 __ bind(&start_label_);
129RegExpMacroAssemblerPPC::~RegExpMacroAssemblerPPC() {
131 entry_label_.Unuse();
132 start_label_.Unuse();
133 success_label_.Unuse();
134 backtrack_label_.Unuse();
136 check_preempt_label_.Unuse();
137 stack_overflow_label_.Unuse();
138 internal_failure_label_.Unuse();
139 fallback_label_.Unuse();
142int RegExpMacroAssemblerPPC::stack_limit_slack_slot_count() {
143 return RegExpStack::kStackLimitSlackSlotCount;
146void RegExpMacroAssemblerPPC::AdvanceCurrentPosition(
int by) {
148 if (is_int16(by * char_size())) {
149 __ addi(current_input_offset(), current_input_offset(),
150 Operand(by * char_size()));
152 __ mov(r0, Operand(by * char_size()));
153 __ add(current_input_offset(), r0, current_input_offset());
159void RegExpMacroAssemblerPPC::AdvanceRegister(
int reg,
int by) {
163 __ LoadU64(r3, register_location(
reg), r0);
164 __ mov(r0, Operand(by));
166 __ StoreU64(r3, register_location(
reg), r0);
171void RegExpMacroAssemblerPPC::Backtrack() {
173 if (has_backtrack_limit()) {
175 __ LoadU64(r3,
MemOperand(frame_pointer(), kBacktrackCountOffset), r0);
176 __ addi(r3, r3, Operand(1));
177 __ StoreU64(r3,
MemOperand(frame_pointer(), kBacktrackCountOffset), r0);
178 __ mov(r0, Operand(backtrack_limit()));
183 if (can_fallback()) {
184 __ b(&fallback_label_);
195 __ add(r3, r3, code_pointer());
200void RegExpMacroAssemblerPPC::Bind(Label*
label) {
__ bind(
label); }
203void RegExpMacroAssemblerPPC::CheckCharacter(uint32_t c, Label* on_equal) {
204 __ CmpU64(current_character(), Operand(c), r0);
205 BranchOrBacktrack(eq, on_equal);
208void RegExpMacroAssemblerPPC::CheckCharacterGT(base::uc16 limit,
210 __ CmpU64(current_character(), Operand(limit), r0);
211 BranchOrBacktrack(gt, on_greater);
214void RegExpMacroAssemblerPPC::CheckAtStart(
int cp_offset, Label* on_at_start) {
215 __ LoadU64(r4,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
216 __ addi(r3, current_input_offset(),
217 Operand(-char_size() + cp_offset * char_size()));
219 BranchOrBacktrack(eq, on_at_start);
222void RegExpMacroAssemblerPPC::CheckNotAtStart(
int cp_offset,
223 Label* on_not_at_start) {
224 __ LoadU64(r4,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
225 __ addi(r3, current_input_offset(),
226 Operand(-char_size() + cp_offset * char_size()));
228 BranchOrBacktrack(ne, on_not_at_start);
231void RegExpMacroAssemblerPPC::CheckCharacterLT(base::uc16 limit,
233 __ CmpU64(current_character(), Operand(limit), r0);
234 BranchOrBacktrack(lt, on_less);
237void RegExpMacroAssemblerPPC::CheckGreedyLoop(Label* on_equal) {
238 Label backtrack_non_equal;
239 __ LoadU64(r3,
MemOperand(backtrack_stackpointer(), 0));
240 __ CmpS64(current_input_offset(), r3);
241 __ bne(&backtrack_non_equal);
242 __ addi(backtrack_stackpointer(), backtrack_stackpointer(),
243 Operand(kSystemPointerSize));
245 __ bind(&backtrack_non_equal);
246 BranchOrBacktrack(eq, on_equal);
249void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase(
250 int start_reg,
bool read_backward,
bool unicode, Label* on_no_match) {
252 __ LoadU64(r3, register_location(start_reg),
254 __ LoadU64(r4, register_location(start_reg + 1), r0);
255 __ sub(r4, r4, r3, LeaveOE, SetRC);
260 __ beq(&fallthrough, cr0);
264 __ LoadU64(r6,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
266 __ CmpS64(current_input_offset(), r6);
267 BranchOrBacktrack(le, on_no_match);
269 __ add(r0, r4, current_input_offset(), LeaveOE, SetRC);
270 BranchOrBacktrack(gt, on_no_match, cr0);
273 if (
mode_ == LATIN1) {
280 __ add(r3, r3, end_of_input_address());
281 __ add(r5, end_of_input_address(), current_input_offset());
294 __ addi(r3, r3, Operand(char_size()));
296 __ addi(r5, r5, Operand(char_size()));
301 __ ori(r6, r6, Operand(0x20));
302 __ ori(r25, r25, Operand(0x20));
305 __ subi(r6, r6, Operand(
'a'));
306 __ cmpli(r6, Operand(
'z' -
'a'));
309 __ subi(r6, r6, Operand(224 -
'a'));
310 __ cmpli(r6, Operand(254 - 224));
312 __ cmpi(r6, Operand(247 - 224));
315 __ bind(&loop_check);
321 BranchOrBacktrack(al, on_no_match);
325 __ sub(current_input_offset(), r5, end_of_input_address());
328 register_location(start_reg));
330 register_location(start_reg + 1));
331 __ add(current_input_offset(), current_input_offset(), r3);
332 __ sub(current_input_offset(), current_input_offset(), r4);
336 int argument_count = 4;
337 __ PrepareCallCFunction(argument_count, r5);
350 __ add(r3, r3, end_of_input_address());
356 __ add(r4, current_input_offset(), end_of_input_address());
361 __ mov(r6, Operand(ExternalReference::isolate_address(
isolate())));
364 AllowExternalCallThatCantCauseGC scope(
masm_.get());
365 ExternalReference function =
367 ? ExternalReference::re_case_insensitive_compare_unicode()
368 : ExternalReference::re_case_insensitive_compare_non_unicode();
369 CallCFunctionFromIrregexpCode(function, argument_count);
373 __ cmpi(r3, Operand::Zero());
374 BranchOrBacktrack(eq, on_no_match);
378 __ sub(current_input_offset(), current_input_offset(), r25);
380 __ add(current_input_offset(), current_input_offset(), r25);
384 __ bind(&fallthrough);
387void RegExpMacroAssemblerPPC::CheckNotBackReference(
int start_reg,
389 Label* on_no_match) {
393 __ LoadU64(r3, register_location(start_reg), r0);
394 __ LoadU64(r4, register_location(start_reg + 1), r0);
395 __ sub(r4, r4, r3, LeaveOE, SetRC);
400 __ beq(&fallthrough, cr0);
404 __ LoadU64(r6,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
406 __ CmpS64(current_input_offset(), r6);
407 BranchOrBacktrack(le, on_no_match);
409 __ add(r0, r4, current_input_offset(), LeaveOE, SetRC);
410 BranchOrBacktrack(gt, on_no_match, cr0);
415 __ add(r3, r3, end_of_input_address());
416 __ add(r5, end_of_input_address(), current_input_offset());
424 if (
mode_ == LATIN1) {
426 __ addi(r3, r3, Operand(char_size()));
428 __ addi(r5, r5, Operand(char_size()));
432 __ addi(r3, r3, Operand(char_size()));
434 __ addi(r5, r5, Operand(char_size()));
437 BranchOrBacktrack(ne, on_no_match);
442 __ sub(current_input_offset(), r5, end_of_input_address());
444 __ LoadU64(r3, register_location(start_reg));
446 register_location(start_reg + 1));
447 __ add(current_input_offset(), current_input_offset(), r3);
448 __ sub(current_input_offset(), current_input_offset(), r4);
451 __ bind(&fallthrough);
455void RegExpMacroAssemblerPPC::CheckNotCharacter(
unsigned c,
456 Label* on_not_equal) {
457 __ CmpU64(current_character(), Operand(c), r0);
458 BranchOrBacktrack(ne, on_not_equal);
462void RegExpMacroAssemblerPPC::CheckCharacterAfterAnd(uint32_t c, uint32_t
mask,
464 __ mov(r0, Operand(
mask));
466 __ and_(r3, current_character(), r0, SetRC);
468 __ and_(r3, current_character(), r0);
469 __ CmpU64(r3, Operand(c), r0, cr0);
471 BranchOrBacktrack(eq, on_equal, cr0);
475void RegExpMacroAssemblerPPC::CheckNotCharacterAfterAnd(
unsigned c,
477 Label* on_not_equal) {
478 __ mov(r0, Operand(
mask));
480 __ and_(r3, current_character(), r0, SetRC);
482 __ and_(r3, current_character(), r0);
483 __ CmpU64(r3, Operand(c), r0, cr0);
485 BranchOrBacktrack(ne, on_not_equal, cr0);
488void RegExpMacroAssemblerPPC::CheckNotCharacterAfterMinusAnd(
489 base::uc16 c, base::uc16 minus, base::uc16
mask, Label* on_not_equal) {
490 DCHECK_GT(String::kMaxUtf16CodeUnit, minus);
491 __ subi(r3, current_character(), Operand(minus));
492 __ mov(r0, Operand(
mask));
494 __ CmpU64(r3, Operand(c), r0);
495 BranchOrBacktrack(ne, on_not_equal);
498void RegExpMacroAssemblerPPC::CheckCharacterInRange(base::uc16 from,
500 Label* on_in_range) {
501 __ mov(r0, Operand(from));
502 __ sub(r3, current_character(), r0);
503 __ CmpU64(r3, Operand(to - from), r0);
504 BranchOrBacktrack(le, on_in_range);
507void RegExpMacroAssemblerPPC::CheckCharacterNotInRange(base::uc16 from,
509 Label* on_not_in_range) {
510 __ mov(r0, Operand(from));
511 __ sub(r3, current_character(), r0);
512 __ CmpU64(r3, Operand(to - from), r0);
513 BranchOrBacktrack(gt, on_not_in_range);
516void RegExpMacroAssemblerPPC::CallIsCharacterInRangeArray(
517 const ZoneList<CharacterRange>* ranges) {
518 static const int kNumArguments = 2;
519 __ PrepareCallCFunction(kNumArguments, r0);
521 __ mr(r3, current_character());
522 __ mov(r4, Operand(GetOrAddRangeArray(ranges)));
526 FrameScope scope(
masm_.get(), StackFrame::MANUAL);
527 CallCFunctionFromIrregexpCode(
528 ExternalReference::re_is_character_in_range_array(), kNumArguments);
531 __ mov(code_pointer(), Operand(
masm_->CodeObject()));
534bool RegExpMacroAssemblerPPC::CheckCharacterInRangeArray(
535 const ZoneList<CharacterRange>* ranges, Label* on_in_range) {
536 CallIsCharacterInRangeArray(ranges);
537 __ cmpi(r3, Operand::Zero());
538 BranchOrBacktrack(ne, on_in_range);
542bool RegExpMacroAssemblerPPC::CheckCharacterNotInRangeArray(
543 const ZoneList<CharacterRange>* ranges, Label* on_not_in_range) {
544 CallIsCharacterInRangeArray(ranges);
545 __ cmpi(r3, Operand::Zero());
546 BranchOrBacktrack(eq, on_not_in_range);
550void RegExpMacroAssemblerPPC::CheckBitInTable(Handle<ByteArray> table,
552 __ mov(r3, Operand(table));
553 if (
mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) {
554 __ andi(r4, current_character(), Operand(kTableSize - 1));
557 __ addi(r4, current_character(),
561 __ cmpi(r3, Operand::Zero());
562 BranchOrBacktrack(ne, on_bit_set);
565void RegExpMacroAssemblerPPC::SkipUntilBitInTable(
566 int cp_offset, Handle<ByteArray> table, Handle<ByteArray> nibble_table,
571 LoadCurrentCharacter(cp_offset, &cont,
true);
572 CheckBitInTable(table, &cont);
573 AdvanceCurrentPosition(advance_by);
578bool RegExpMacroAssemblerPPC::CheckSpecialClassRanges(StandardCharacterSet type,
579 Label* on_no_match) {
584 case StandardCharacterSet::kWhitespace:
586 if (
mode_ == LATIN1) {
589 __ cmpi(current_character(), Operand(
' '));
592 __ subi(r3, current_character(), Operand(
'\t'));
593 __ cmpli(r3, Operand(
'\r' -
'\t'));
596 __ cmpi(r3, Operand(0x00A0 -
'\t'));
597 BranchOrBacktrack(ne, on_no_match);
602 case StandardCharacterSet::kNotWhitespace:
605 case StandardCharacterSet::kDigit:
607 __ subi(r3, current_character(), Operand(
'0'));
608 __ cmpli(r3, Operand(
'9' -
'0'));
609 BranchOrBacktrack(gt, on_no_match);
611 case StandardCharacterSet::kNotDigit:
613 __ subi(r3, current_character(), Operand(
'0'));
614 __ cmpli(r3, Operand(
'9' -
'0'));
615 BranchOrBacktrack(le, on_no_match);
617 case StandardCharacterSet::kNotLineTerminator: {
619 __ xori(r3, current_character(), Operand(0x01));
621 __ subi(r3, r3, Operand(0x0B));
622 __ cmpli(r3, Operand(0x0C - 0x0B));
623 BranchOrBacktrack(le, on_no_match);
628 __ subi(r3, r3, Operand(0x2028 - 0x0B));
629 __ cmpli(r3, Operand(1));
630 BranchOrBacktrack(le, on_no_match);
634 case StandardCharacterSet::kLineTerminator: {
636 __ xori(r3, current_character(), Operand(0x01));
638 __ subi(r3, r3, Operand(0x0B));
639 __ cmpli(r3, Operand(0x0C - 0x0B));
640 if (
mode_ == LATIN1) {
641 BranchOrBacktrack(gt, on_no_match);
648 __ subi(r3, r3, Operand(0x2028 - 0x0B));
649 __ cmpli(r3, Operand(1));
650 BranchOrBacktrack(gt, on_no_match);
655 case StandardCharacterSet::kWord: {
656 if (
mode_ != LATIN1) {
658 __ cmpi(current_character(), Operand(
'z'));
659 BranchOrBacktrack(gt, on_no_match);
661 ExternalReference map = ExternalReference::re_word_character_map();
662 __ mov(r3, Operand(map));
664 __ cmpli(r3, Operand::Zero());
665 BranchOrBacktrack(eq, on_no_match);
668 case StandardCharacterSet::kNotWord: {
670 if (
mode_ != LATIN1) {
672 __ cmpli(current_character(), Operand(
'z'));
675 ExternalReference map = ExternalReference::re_word_character_map();
676 __ mov(r3, Operand(map));
678 __ cmpli(r3, Operand::Zero());
679 BranchOrBacktrack(ne, on_no_match);
680 if (
mode_ != LATIN1) {
685 case StandardCharacterSet::kEverything:
691void RegExpMacroAssemblerPPC::Fail() {
692 __ li(r3, Operand(FAILURE));
696void RegExpMacroAssemblerPPC::LoadRegExpStackPointerFromMemory(Register dst) {
697 ExternalReference ref =
698 ExternalReference::address_of_regexp_stack_stack_pointer(
isolate());
699 __ mov(dst, Operand(ref));
703void RegExpMacroAssemblerPPC::StoreRegExpStackPointerToMemory(
704 Register src, Register scratch) {
705 ExternalReference ref =
706 ExternalReference::address_of_regexp_stack_stack_pointer(
isolate());
707 __ mov(scratch, Operand(ref));
711void RegExpMacroAssemblerPPC::PushRegExpBasePointer(Register stack_pointer,
713 ExternalReference ref =
714 ExternalReference::address_of_regexp_stack_memory_top_address(
isolate());
715 __ mov(scratch, Operand(ref));
717 __ SubS64(scratch, stack_pointer, scratch);
719 MemOperand(frame_pointer(), kRegExpStackBasePointerOffset));
722void RegExpMacroAssemblerPPC::PopRegExpBasePointer(Register stack_pointer_out,
724 ExternalReference ref =
725 ExternalReference::address_of_regexp_stack_memory_top_address(
isolate());
726 __ LoadU64(stack_pointer_out,
727 MemOperand(frame_pointer(), kRegExpStackBasePointerOffset));
728 __ mov(scratch, Operand(ref));
730 __ AddS64(stack_pointer_out, stack_pointer_out, scratch);
731 StoreRegExpStackPointerToMemory(stack_pointer_out, scratch);
734DirectHandle<HeapObject> RegExpMacroAssemblerPPC::GetCode(
735 DirectHandle<String> source, RegExpFlags flags) {
738 if (
masm_->has_exception()) {
742 __ bind_to(&entry_label_, internal_failure_label_.pos());
748 __ bind(&entry_label_);
752 FrameScope scope(
masm_.get(), StackFrame::MANUAL);
769 __ MultiPush(registers_to_retain);
770 __ mr(frame_pointer(), sp);
772 RegList argument_registers = {r3, r4, r5, r6, r7, r8, r9, r10};
774 __ mov(r0, Operand(StackFrame::TypeToMarker(StackFrame::IRREGEXP)));
776 __ MultiPush(argument_registers);
778 static_assert(kSuccessfulCapturesOffset ==
780 __ li(r3, Operand::Zero());
782 static_assert(kStringStartMinusOneOffset ==
785 static_assert(kBacktrackCountOffset ==
788 static_assert(kRegExpStackBasePointerOffset ==
794 static_assert(backtrack_stackpointer() == r29);
795 LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
799 PushRegExpBasePointer(backtrack_stackpointer(), r4);
803 Label stack_limit_hit, stack_ok;
805 ExternalReference stack_limit =
806 ExternalReference::address_of_jslimit(
isolate());
807 __ mov(r3, Operand(stack_limit));
809 __ sub(r3, sp, r3, LeaveOE, SetRC);
810 Operand extra_space_for_variables(num_registers_ * kSystemPointerSize);
813 __ ble(&stack_limit_hit, cr0);
816 __ CmpU64(r3, extra_space_for_variables, r0);
820 __ li(r3, Operand(EXCEPTION));
823 __ bind(&stack_limit_hit);
824 CallCheckStackGuardState(r3, extra_space_for_variables);
825 __ cmpi(r3, Operand::Zero());
834 __ AddS64(sp, sp, Operand(-num_registers_ * kSystemPointerSize), r0);
836 __ LoadU64(end_of_input_address(),
837 MemOperand(frame_pointer(), kInputEndOffset));
839 __ LoadU64(r3,
MemOperand(frame_pointer(), kInputStartOffset));
841 __ sub(current_input_offset(), r3, end_of_input_address());
844 __ LoadU64(r4,
MemOperand(frame_pointer(), kStartIndexOffset));
845 __ subi(r3, current_input_offset(), Operand(char_size()));
847 __ ShiftLeftU64(r0, r4, Operand(1));
854 __ StoreU64(r3,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
857 __ mov(code_pointer(), Operand(
masm_->CodeObject()));
859 Label load_char_start_regexp;
863 __ cmpi(r4, Operand::Zero());
864 __ bne(&load_char_start_regexp);
865 __ li(current_character(), Operand(
'\n'));
869 __ bind(&load_char_start_regexp);
871 LoadCurrentCharacterUnchecked(-1, 1);
872 __ bind(&start_regexp);
876 if (num_saved_registers_ > 0) {
878 if (num_saved_registers_ > 8) {
880 __ addi(r4, frame_pointer(),
881 Operand(kRegisterZeroOffset + kSystemPointerSize));
882 __ mov(r5, Operand(num_saved_registers_));
886 __ StoreU64WithUpdate(r3,
MemOperand(r4, -kSystemPointerSize));
889 for (
int i = 0;
i < num_saved_registers_;
i++) {
890 __ StoreU64(r3, register_location(
i), r0);
898 if (success_label_.is_linked()) {
900 __ bind(&success_label_);
901 if (num_saved_registers_ > 0) {
903 __ LoadU64(r4,
MemOperand(frame_pointer(), kInputStartOffset));
904 __ LoadU64(r3,
MemOperand(frame_pointer(), kRegisterOutputOffset));
905 __ LoadU64(r5,
MemOperand(frame_pointer(), kStartIndexOffset));
906 __ sub(r4, end_of_input_address(), r4);
909 __ ShiftRightU64(r4, r4, Operand(1));
919 for (
int i = 0;
i < num_saved_registers_;
i += 2) {
920 __ LoadU64(r5, register_location(
i), r0);
921 __ LoadU64(r6, register_location(
i + 1), r0);
922 if (
i == 0 && global_with_zero_length_check()) {
927 __ ShiftRightS64(r5, r5, Operand(1));
929 __ ShiftRightS64(r6, r6, Operand(1));
936 __ addi(r3, r3, Operand(kIntSize));
938 __ addi(r3, r3, Operand(kIntSize));
944 __ LoadU64(r3,
MemOperand(frame_pointer(), kSuccessfulCapturesOffset));
945 __ LoadU64(r4,
MemOperand(frame_pointer(), kNumOutputRegistersOffset));
946 __ LoadU64(r5,
MemOperand(frame_pointer(), kRegisterOutputOffset));
948 __ addi(r3, r3, Operand(1));
949 __ StoreU64(r3,
MemOperand(frame_pointer(), kSuccessfulCapturesOffset));
952 __ subi(r4, r4, Operand(num_saved_registers_));
954 __ cmpi(r4, Operand(num_saved_registers_));
957 __ StoreU64(r4,
MemOperand(frame_pointer(), kNumOutputRegistersOffset));
959 __ addi(r5, r5, Operand(num_saved_registers_ * kIntSize));
960 __ StoreU64(r5,
MemOperand(frame_pointer(), kRegisterOutputOffset));
964 PopRegExpBasePointer(backtrack_stackpointer(), r5);
966 Label reload_string_start_minus_one;
968 if (global_with_zero_length_check()) {
971 __ CmpS64(current_input_offset(), r25);
973 __ bne(&reload_string_start_minus_one);
975 __ cmpi(current_input_offset(), Operand::Zero());
976 __ beq(&exit_label_);
980 __ addi(current_input_offset(), current_input_offset(),
981 Operand((
mode_ == UC16) ? 2 : 1));
982 if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
985 __ bind(&reload_string_start_minus_one);
988 __ LoadU64(r3,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
990 __ b(&load_char_start_regexp);
992 __ li(r3, Operand(SUCCESS));
997 __ bind(&exit_label_);
999 __ LoadU64(r3,
MemOperand(frame_pointer(), kSuccessfulCapturesOffset));
1002 __ bind(&return_r3);
1005 PopRegExpBasePointer(backtrack_stackpointer(), r5);
1008 __ mr(sp, frame_pointer());
1010 __ MultiPop(registers_to_retain);
1016 if (backtrack_label_.is_linked()) {
1017 __ bind(&backtrack_label_);
1021 Label exit_with_exception;
1024 if (check_preempt_label_.is_linked()) {
1025 SafeCallTarget(&check_preempt_label_);
1027 StoreRegExpStackPointerToMemory(backtrack_stackpointer(), r4);
1029 CallCheckStackGuardState(r3);
1030 __ cmpi(r3, Operand::Zero());
1035 LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
1038 __ LoadU64(end_of_input_address(),
1039 MemOperand(frame_pointer(), kInputEndOffset));
1044 if (stack_overflow_label_.is_linked()) {
1045 SafeCallTarget(&stack_overflow_label_);
1049 StoreRegExpStackPointerToMemory(backtrack_stackpointer(), r4);
1051 static constexpr int kNumArguments = 1;
1052 __ PrepareCallCFunction(kNumArguments, r3);
1053 __ mov(r3, Operand(ExternalReference::isolate_address(
isolate())));
1054 ExternalReference
grow_stack = ExternalReference::re_grow_stack();
1055 CallCFunctionFromIrregexpCode(grow_stack, kNumArguments);
1058 __ cmpi(r3, Operand::Zero());
1059 __ beq(&exit_with_exception);
1061 __ mr(backtrack_stackpointer(), r3);
1066 if (exit_with_exception.is_linked()) {
1068 __ bind(&exit_with_exception);
1070 __ li(r3, Operand(EXCEPTION));
1074 if (fallback_label_.is_linked()) {
1075 __ bind(&fallback_label_);
1076 __ li(r3, Operand(FALLBACK_TO_EXPERIMENTAL));
1085 .set_self_reference(
masm_->CodeObject())
1086 .set_empty_source_position_table()
1089 RegExpCodeCreateEvent(Cast<AbstractCode>(code), source, flags));
1090 return Cast<HeapObject>(code);
1093void RegExpMacroAssemblerPPC::GoTo(Label* to) { BranchOrBacktrack(al, to); }
1096void RegExpMacroAssemblerPPC::IfRegisterGE(
int reg,
int comparand,
1098 __ LoadU64(r3, register_location(
reg), r0);
1099 __ CmpS64(r3, Operand(comparand), r0);
1100 BranchOrBacktrack(ge, if_ge);
1104void RegExpMacroAssemblerPPC::IfRegisterLT(
int reg,
int comparand,
1106 __ LoadU64(r3, register_location(
reg), r0);
1107 __ CmpS64(r3, Operand(comparand), r0);
1108 BranchOrBacktrack(lt, if_lt);
1112void RegExpMacroAssemblerPPC::IfRegisterEqPos(
int reg, Label* if_eq) {
1113 __ LoadU64(r3, register_location(
reg), r0);
1114 __ CmpS64(r3, current_input_offset());
1115 BranchOrBacktrack(eq, if_eq);
1119RegExpMacroAssembler::IrregexpImplementation
1120RegExpMacroAssemblerPPC::Implementation() {
1121 return kPPCImplementation;
1125void RegExpMacroAssemblerPPC::PopCurrentPosition() {
1126 Pop(current_input_offset());
1130void RegExpMacroAssemblerPPC::PopRegister(
int register_index) {
1132 __ StoreU64(r3, register_location(register_index), r0);
1136void RegExpMacroAssemblerPPC::PushBacktrack(Label*
label) {
1137 __ mov_label_offset(r3,
label);
1143void RegExpMacroAssemblerPPC::PushCurrentPosition() {
1144 Push(current_input_offset());
1149void RegExpMacroAssemblerPPC::PushRegister(
int register_index,
1150 StackCheckFlag check_stack_limit) {
1151 __ LoadU64(r3, register_location(register_index), r0);
1153 if (check_stack_limit) {
1156 AssertAboveStackLimitMinusSlack();
1161void RegExpMacroAssemblerPPC::ReadCurrentPositionFromRegister(
int reg) {
1162 __ LoadU64(current_input_offset(), register_location(
reg), r0);
1165void RegExpMacroAssemblerPPC::WriteStackPointerToRegister(
int reg) {
1166 ExternalReference ref =
1167 ExternalReference::address_of_regexp_stack_memory_top_address(
isolate());
1168 __ mov(r4, Operand(ref));
1170 __ SubS64(r3, backtrack_stackpointer(), r4);
1171 __ StoreU64(r3, register_location(
reg), r0);
1174void RegExpMacroAssemblerPPC::ReadStackPointerFromRegister(
int reg) {
1175 ExternalReference ref =
1176 ExternalReference::address_of_regexp_stack_memory_top_address(
isolate());
1177 __ mov(r3, Operand(ref));
1179 __ LoadU64(backtrack_stackpointer(), register_location(
reg), r0);
1180 __ AddS64(backtrack_stackpointer(), backtrack_stackpointer(), r3);
1183void RegExpMacroAssemblerPPC::SetCurrentPositionFromEnd(
int by) {
1184 Label after_position;
1185 __ CmpS64(current_input_offset(), Operand(-by * char_size()), r0);
1186 __ bge(&after_position);
1187 __ mov(current_input_offset(), Operand(-by * char_size()));
1191 LoadCurrentCharacterUnchecked(-1, 1);
1192 __ bind(&after_position);
1196void RegExpMacroAssemblerPPC::SetRegister(
int register_index,
int to) {
1197 DCHECK(register_index >= num_saved_registers_);
1198 __ mov(r3, Operand(to));
1199 __ StoreU64(r3, register_location(register_index), r0);
1203bool RegExpMacroAssemblerPPC::Succeed() {
1204 __ b(&success_label_);
1209void RegExpMacroAssemblerPPC::WriteCurrentPositionToRegister(
int reg,
1211 if (cp_offset == 0) {
1212 __ StoreU64(current_input_offset(), register_location(
reg), r0);
1214 __ mov(r0, Operand(cp_offset * char_size()));
1215 __ add(r3, current_input_offset(), r0);
1216 __ StoreU64(r3, register_location(
reg), r0);
1221void RegExpMacroAssemblerPPC::ClearRegisters(
int reg_from,
int reg_to) {
1222 DCHECK(reg_from <= reg_to);
1223 __ LoadU64(r3,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
1224 for (
int reg = reg_from;
reg <= reg_to;
reg++) {
1225 __ StoreU64(r3, register_location(
reg), r0);
1231void RegExpMacroAssemblerPPC::CallCheckStackGuardState(Register scratch,
1232 Operand extra_space) {
1234 DCHECK(!
masm_->options().isolate_independent_code);
1236 int frame_alignment =
masm_->ActivationFrameAlignment();
1238 int stack_passed_arguments = 1;
1243 if (frame_alignment > kSystemPointerSize) {
1248 Operand(-(stack_passed_arguments + 1) * kSystemPointerSize));
1249 DCHECK(base::bits::IsPowerOfTwo(frame_alignment));
1251 Operand(base::bits::WhichPowerOfTwo(frame_alignment)));
1252 __ StoreU64(scratch,
1253 MemOperand(sp, stack_passed_arguments * kSystemPointerSize));
1256 stack_space += stack_passed_arguments;
1260 __ li(r0, Operand::Zero());
1261 __ StoreU64WithUpdate(r0,
MemOperand(sp, -stack_space * kSystemPointerSize));
1264 __ mov(kCArgRegs[3], extra_space);
1266 __ mr(kCArgRegs[2], frame_pointer());
1268 __ mov(kCArgRegs[1], Operand(
masm_->CodeObject()));
1270 __ addi(r3, sp, Operand(kStackFrameExtraParamSlot * kSystemPointerSize));
1272 ExternalReference stack_guard_check =
1273 ExternalReference::re_check_stack_guard_state();
1274 __ mov(ip, Operand(stack_guard_check));
1276 EmbeddedData d = EmbeddedData::FromBlob();
1277 Address entry = d.InstructionStartOf(Builtin::kDirectCEntry);
1278 __ mov(r0, Operand(entry, RelocInfo::OFF_HEAP_TARGET));
1283 if (frame_alignment > kSystemPointerSize) {
1284 __ LoadU64(sp,
MemOperand(sp, stack_space * kSystemPointerSize));
1286 __ addi(sp, sp, Operand(stack_space * kSystemPointerSize));
1289 __ mov(code_pointer(), Operand(
masm_->CodeObject()));
1293template <
typename T>
1294static T& frame_entry(Address re_frame,
int frame_offset) {
1295 return reinterpret_cast<T&
>(Memory<int32_t>(re_frame + frame_offset));
1299template <
typename T>
1300static T* frame_entry_address(Address re_frame,
int frame_offset) {
1301 return reinterpret_cast<T*
>(re_frame + frame_offset);
1304int RegExpMacroAssemblerPPC::CheckStackGuardState(Address* return_address,
1307 uintptr_t extra_space) {
1308 Tagged<InstructionStream> re_code =
1309 Cast<InstructionStream>(Tagged<Object>(raw_code));
1310 return NativeRegExpMacroAssembler::CheckStackGuardState(
1311 frame_entry<Isolate*>(re_frame, kIsolateOffset),
1312 frame_entry<intptr_t>(re_frame, kStartIndexOffset),
1313 static_cast<RegExp::CallOrigin
>(
1314 frame_entry<intptr_t>(re_frame, kDirectCallOffset)),
1315 return_address, re_code,
1316 frame_entry_address<Address>(re_frame, kInputStringOffset),
1317 frame_entry_address<const uint8_t*>(re_frame, kInputStartOffset),
1318 frame_entry_address<const uint8_t*>(re_frame, kInputEndOffset),
1322MemOperand RegExpMacroAssemblerPPC::register_location(
int register_index) {
1323 DCHECK(register_index < (1 << 30));
1324 if (num_registers_ <= register_index) {
1325 num_registers_ = register_index + 1;
1328 kRegisterZeroOffset - register_index * kSystemPointerSize);
1331void RegExpMacroAssemblerPPC::CallCFunctionFromIrregexpCode(
1332 ExternalReference function,
int num_arguments) {
1346void RegExpMacroAssemblerPPC::CheckPosition(
int cp_offset,
1347 Label* on_outside_input) {
1348 if (cp_offset >= 0) {
1349 __ CmpS64(current_input_offset(), Operand(-cp_offset * char_size()), r0);
1350 BranchOrBacktrack(ge, on_outside_input);
1352 __ LoadU64(r4,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
1353 __ addi(r3, current_input_offset(), Operand(cp_offset * char_size()));
1355 BranchOrBacktrack(le, on_outside_input);
1360void RegExpMacroAssemblerPPC::BranchOrBacktrack(Condition
condition, Label* to,
1363 if (to ==
nullptr) {
1370 if (to ==
nullptr) {
1378void RegExpMacroAssemblerPPC::SafeCall(Label* to, Condition cond,
1380 __ b(cond, to, cr, SetLK);
1384void RegExpMacroAssemblerPPC::SafeReturn() {
1386 __ mov(ip, Operand(
masm_->CodeObject()));
1393void RegExpMacroAssemblerPPC::SafeCallTarget(Label* name) {
1396 __ mov(ip, Operand(
masm_->CodeObject()));
1402void RegExpMacroAssemblerPPC::Push(Register source) {
1403 DCHECK(source != backtrack_stackpointer());
1404 __ StoreU64WithUpdate(
1405 source,
MemOperand(backtrack_stackpointer(), -kSystemPointerSize));
1409void RegExpMacroAssemblerPPC::Pop(Register target) {
1410 DCHECK(target != backtrack_stackpointer());
1411 __ LoadU64(target,
MemOperand(backtrack_stackpointer()));
1412 __ addi(backtrack_stackpointer(), backtrack_stackpointer(),
1413 Operand(kSystemPointerSize));
1417void RegExpMacroAssemblerPPC::CheckPreemption() {
1419 ExternalReference stack_limit =
1420 ExternalReference::address_of_jslimit(
isolate());
1421 __ mov(r3, Operand(stack_limit));
1424 SafeCall(&check_preempt_label_, le);
1428void RegExpMacroAssemblerPPC::CheckStackLimit() {
1429 ExternalReference stack_limit =
1430 ExternalReference::address_of_regexp_stack_limit_address(
isolate());
1431 __ mov(r3, Operand(stack_limit));
1433 __ CmpU64(backtrack_stackpointer(), r3);
1434 SafeCall(&stack_overflow_label_, le);
1437void RegExpMacroAssemblerPPC::AssertAboveStackLimitMinusSlack() {
1439 Label no_stack_overflow;
1441 auto l = ExternalReference::address_of_regexp_stack_limit_address(
isolate());
1442 __ mov(r3, Operand(l));
1444 __ SubS64(r3, r3, Operand(RegExpStack::kStackLimitSlackSize));
1445 __ CmpU64(backtrack_stackpointer(), r3);
1446 __ bgt(&no_stack_overflow);
1448 __ bind(&no_stack_overflow);
1451void RegExpMacroAssemblerPPC::LoadCurrentCharacterUnchecked(
int cp_offset,
1454 if (cp_offset != 0) {
1456 if (is_int16(cp_offset * char_size())) {
1457 __ addi(r25, current_input_offset(), Operand(cp_offset * char_size()));
1459 __ mov(r25, Operand(cp_offset * char_size()));
1460 __ add(r25, r25, current_input_offset());
1469 __ add(current_character(), end_of_input_address(),
offset);
1470#if V8_TARGET_LITTLE_ENDIAN
1471 if (
mode_ == LATIN1) {
1472 if (characters == 4) {
1473 __ lwz(current_character(),
MemOperand(current_character()));
1474 }
else if (characters == 2) {
1475 __ lhz(current_character(),
MemOperand(current_character()));
1478 __ lbz(current_character(),
MemOperand(current_character()));
1482 if (characters == 2) {
1483 __ lwz(current_character(),
MemOperand(current_character()));
1486 __ lhz(current_character(),
MemOperand(current_character()));
1490 if (
mode_ == LATIN1) {
1491 if (characters == 4) {
1492 __ lwbrx(current_character(),
MemOperand(r0, current_character()));
1493 }
else if (characters == 2) {
1494 __ lhbrx(current_character(),
MemOperand(r0, current_character()));
1497 __ lbz(current_character(),
MemOperand(current_character()));
1501 if (characters == 2) {
1502 __ lwz(current_character(),
MemOperand(current_character()));
1503 __ rlwinm(current_character(), current_character(), 16, 0, 31);
1506 __ lhz(current_character(),
MemOperand(current_character()));
static constexpr int kRegExpCodeSize
RegExpMacroAssemblerPPC(Isolate *isolate, Zone *zone, Mode mode, int registers_to_save)
#define PROFILE(the_isolate, Call)
RecordWriteMode const mode_
const CodeDesc * code_desc
#define ASM_CODE_COMMENT_STRING(asm,...)
MaglevAssembler *const masm_
void push(LiftoffAssembler *assm, LiftoffRegister reg, ValueKind kind, int padding=0)
Address grow_stack(Isolate *isolate, void *current_sp, size_t frame_size, size_t gap, Address current_fp)
const int kNumRequiredStackFrameSlots
RegListBase< Register > RegList
constexpr int kSystemPointerSize
std::unique_ptr< AssemblerBuffer > NewAssemblerBuffer(int size)
V8_EXPORT_PRIVATE FlagValues v8_flags
const RegList kRegExpCalleeSaved
#define DCHECK_LE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
#define OFFSET_OF_DATA_START(Type)
#define V8_UNLIKELY(condition)