7#if V8_TARGET_ARCH_S390X
98#define __ ACCESS_MASM(masm_)
104 int registers_to_save)
105 : NativeRegExpMacroAssembler(isolate, zone),
106 masm_(
std::make_unique<MacroAssembler>(
109 no_root_array_scope_(
masm_.get()),
111 num_registers_(registers_to_save),
112 num_saved_registers_(registers_to_save),
118 internal_failure_label_() {
124 __ bind(&internal_failure_label_);
125 __ mov(r2, Operand(FAILURE));
127 __ bind(&start_label_);
130RegExpMacroAssemblerS390::~RegExpMacroAssemblerS390() {
132 entry_label_.Unuse();
133 start_label_.Unuse();
134 success_label_.Unuse();
135 backtrack_label_.Unuse();
137 check_preempt_label_.Unuse();
138 stack_overflow_label_.Unuse();
139 internal_failure_label_.Unuse();
140 fallback_label_.Unuse();
143int RegExpMacroAssemblerS390::stack_limit_slack_slot_count() {
144 return RegExpStack::kStackLimitSlackSlotCount;
147void RegExpMacroAssemblerS390::AdvanceCurrentPosition(
int by) {
149 __ AddS64(current_input_offset(), Operand(by * char_size()));
153void RegExpMacroAssemblerS390::AdvanceRegister(
int reg,
int by) {
157 if (CpuFeatures::IsSupported(GENERAL_INSTR_EXT) && is_int8(by)) {
158 __ agsi(register_location(
reg), Operand(by));
160 __ LoadU64(r2, register_location(
reg), r0);
161 __ mov(r0, Operand(by));
163 __ StoreU64(r2, register_location(
reg));
168void RegExpMacroAssemblerS390::Backtrack() {
170 if (has_backtrack_limit()) {
172 __ LoadU64(r2,
MemOperand(frame_pointer(), kBacktrackCountOffset), r0);
173 __ AddS64(r2, r2, Operand(1));
174 __ StoreU64(r2,
MemOperand(frame_pointer(), kBacktrackCountOffset), r0);
175 __ CmpU64(r2, Operand(backtrack_limit()));
179 if (can_fallback()) {
180 __ jmp(&fallback_label_);
191 __ AddS64(r2, code_pointer());
195void RegExpMacroAssemblerS390::Bind(Label*
label) {
__ bind(
label); }
197void RegExpMacroAssemblerS390::CheckCharacter(uint32_t c, Label* on_equal) {
198 __ CmpU64(current_character(), Operand(c));
199 BranchOrBacktrack(eq, on_equal);
202void RegExpMacroAssemblerS390::CheckCharacterGT(base::uc16 limit,
204 __ CmpU64(current_character(), Operand(limit));
205 BranchOrBacktrack(gt, on_greater);
208void RegExpMacroAssemblerS390::CheckAtStart(
int cp_offset, Label* on_at_start) {
209 __ LoadU64(r3,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
210 __ AddS64(r2, current_input_offset(),
211 Operand(-char_size() + cp_offset * char_size()));
213 BranchOrBacktrack(eq, on_at_start);
216void RegExpMacroAssemblerS390::CheckNotAtStart(
int cp_offset,
217 Label* on_not_at_start) {
218 __ LoadU64(r3,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
219 __ AddS64(r2, current_input_offset(),
220 Operand(-char_size() + cp_offset * char_size()));
222 BranchOrBacktrack(ne, on_not_at_start);
225void RegExpMacroAssemblerS390::CheckCharacterLT(base::uc16 limit,
227 __ CmpU64(current_character(), Operand(limit));
228 BranchOrBacktrack(lt, on_less);
231void RegExpMacroAssemblerS390::CheckGreedyLoop(Label* on_equal) {
232 Label backtrack_non_equal;
233 __ CmpS64(current_input_offset(),
MemOperand(backtrack_stackpointer(), 0));
234 __ bne(&backtrack_non_equal);
235 __ AddS64(backtrack_stackpointer(), Operand(kSystemPointerSize));
237 BranchOrBacktrack(al, on_equal);
238 __ bind(&backtrack_non_equal);
241void RegExpMacroAssemblerS390::CheckNotBackReferenceIgnoreCase(
242 int start_reg,
bool read_backward,
bool unicode, Label* on_no_match) {
244 __ LoadU64(r2, register_location(start_reg));
246 __ LoadU64(r3, register_location(start_reg + 1));
247 __ SubS64(r3, r3, r2);
252 __ beq(&fallthrough);
256 __ LoadU64(r5,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
257 __ AddS64(r5, r5, r3);
258 __ CmpS64(current_input_offset(), r5);
259 BranchOrBacktrack(le, on_no_match);
261 __ AddS64(r0, r3, current_input_offset());
262 BranchOrBacktrack(gt, on_no_match);
265 if (
mode_ == LATIN1) {
272 __ AddS64(r2, end_of_input_address());
273 __ AddS64(r4, current_input_offset(), end_of_input_address());
275 __ SubS64(r4, r4, r3);
277 __ mov(r1, Operand::Zero());
292 __ Or(r5, Operand(0x20));
293 __ Or(r6, Operand(0x20));
296 __ SubS64(r5, Operand(
'a'));
297 __ CmpU64(r5, Operand(
'z' -
'a'));
300 __ SubS64(r5, Operand(224 -
'a'));
301 __ CmpU64(r5, Operand(254 - 224));
303 __ CmpU64(r5, Operand(247 - 224));
306 __ bind(&loop_check);
313 BranchOrBacktrack(al, on_no_match);
317 __ SubS64(current_input_offset(), r4, end_of_input_address());
320 register_location(start_reg));
322 register_location(start_reg + 1));
323 __ AddS64(current_input_offset(), current_input_offset(), r2);
324 __ SubS64(current_input_offset(), current_input_offset(), r3);
326 __ AddS64(current_input_offset(), r1);
329 int argument_count = 4;
330 __ PrepareCallCFunction(argument_count, r4);
343 __ AddS64(r2, end_of_input_address());
349 __ AddS64(r3, current_input_offset(), end_of_input_address());
351 __ SubS64(r3, r3, r6);
354 __ mov(r5, Operand(ExternalReference::isolate_address(
isolate())));
357 AllowExternalCallThatCantCauseGC scope(
masm_.get());
358 ExternalReference function =
360 ? ExternalReference::re_case_insensitive_compare_unicode()
361 : ExternalReference::re_case_insensitive_compare_non_unicode();
362 CallCFunctionFromIrregexpCode(function, argument_count);
366 __ CmpS64(r2, Operand::Zero());
367 BranchOrBacktrack(eq, on_no_match);
371 __ SubS64(current_input_offset(), current_input_offset(), r6);
373 __ AddS64(current_input_offset(), current_input_offset(), r6);
377 __ bind(&fallthrough);
380void RegExpMacroAssemblerS390::CheckNotBackReference(
int start_reg,
382 Label* on_no_match) {
386 __ LoadU64(r2, register_location(start_reg));
387 __ LoadU64(r3, register_location(start_reg + 1));
388 __ SubS64(r3, r3, r2);
393 __ beq(&fallthrough);
397 __ LoadU64(r5,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
398 __ AddS64(r5, r5, r3);
399 __ CmpS64(current_input_offset(), r5);
400 BranchOrBacktrack(le, on_no_match);
402 __ AddS64(r0, r3, current_input_offset());
403 BranchOrBacktrack(gt, on_no_match, cr0);
409 __ la(r4,
MemOperand(current_input_offset(), end_of_input_address()));
411 __ SubS64(r4, r4, r3);
413 __ mov(r1, Operand::Zero());
417 if (
mode_ == LATIN1) {
427 BranchOrBacktrack(ne, on_no_match);
432 __ SubS64(current_input_offset(), r4, end_of_input_address());
434 __ LoadU64(r2, register_location(start_reg));
436 register_location(start_reg + 1));
437 __ AddS64(current_input_offset(), current_input_offset(), r2);
438 __ SubS64(current_input_offset(), current_input_offset(), r3);
440 __ AddS64(current_input_offset(), r1);
442 __ bind(&fallthrough);
445void RegExpMacroAssemblerS390::CheckNotCharacter(
unsigned c,
446 Label* on_not_equal) {
447 __ CmpU64(current_character(), Operand(c));
448 BranchOrBacktrack(ne, on_not_equal);
451void RegExpMacroAssemblerS390::CheckCharacterAfterAnd(uint32_t c, uint32_t
mask,
453 __ AndP(r2, current_character(), Operand(
mask));
455 __ CmpU64(r2, Operand(c));
457 BranchOrBacktrack(eq, on_equal);
460void RegExpMacroAssemblerS390::CheckNotCharacterAfterAnd(
unsigned c,
462 Label* on_not_equal) {
463 __ AndP(r2, current_character(), Operand(
mask));
465 __ CmpU64(r2, Operand(c));
467 BranchOrBacktrack(ne, on_not_equal);
470void RegExpMacroAssemblerS390::CheckNotCharacterAfterMinusAnd(
471 base::uc16 c, base::uc16 minus, base::uc16
mask, Label* on_not_equal) {
472 DCHECK_GT(String::kMaxUtf16CodeUnit, minus);
476 __ CmpU64(r2, Operand(c));
478 BranchOrBacktrack(ne, on_not_equal);
481void RegExpMacroAssemblerS390::CheckCharacterInRange(base::uc16 from,
483 Label* on_in_range) {
485 __ CmpU64(r2, Operand(to - from));
486 BranchOrBacktrack(le, on_in_range);
489void RegExpMacroAssemblerS390::CheckCharacterNotInRange(
490 base::uc16 from, base::uc16 to, Label* on_not_in_range) {
492 __ CmpU64(r2, Operand(to - from));
493 BranchOrBacktrack(gt, on_not_in_range);
496void RegExpMacroAssemblerS390::CallIsCharacterInRangeArray(
497 const ZoneList<CharacterRange>* ranges) {
498 static const int kNumArguments = 2;
499 __ PrepareCallCFunction(kNumArguments, r0);
501 __ mov(r2, current_character());
502 __ mov(r3, Operand(GetOrAddRangeArray(ranges)));
506 FrameScope scope(
masm_.get(), StackFrame::MANUAL);
507 CallCFunctionFromIrregexpCode(
508 ExternalReference::re_is_character_in_range_array(), kNumArguments);
511 __ mov(code_pointer(), Operand(
masm_->CodeObject()));
514bool RegExpMacroAssemblerS390::CheckCharacterInRangeArray(
515 const ZoneList<CharacterRange>* ranges, Label* on_in_range) {
516 CallIsCharacterInRangeArray(ranges);
517 __ CmpS64(r2, Operand::Zero());
518 BranchOrBacktrack(ne, on_in_range);
522bool RegExpMacroAssemblerS390::CheckCharacterNotInRangeArray(
523 const ZoneList<CharacterRange>* ranges, Label* on_not_in_range) {
524 CallIsCharacterInRangeArray(ranges);
525 __ CmpS64(r2, Operand::Zero());
526 BranchOrBacktrack(eq, on_not_in_range);
530void RegExpMacroAssemblerS390::CheckBitInTable(Handle<ByteArray> table,
532 __ mov(r2, Operand(table));
533 Register index = current_character();
534 if (
mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) {
535 __ AndP(r3, current_character(), Operand(kTableSize - 1));
540 __ CmpS64(r2, Operand::Zero());
541 BranchOrBacktrack(ne, on_bit_set);
544void RegExpMacroAssemblerS390::SkipUntilBitInTable(
545 int cp_offset, Handle<ByteArray> table, Handle<ByteArray> nibble_table,
550 LoadCurrentCharacter(cp_offset, &cont,
true);
551 CheckBitInTable(table, &cont);
552 AdvanceCurrentPosition(advance_by);
557bool RegExpMacroAssemblerS390::CheckSpecialClassRanges(
558 StandardCharacterSet type, Label* on_no_match) {
563 case StandardCharacterSet::kWhitespace:
565 if (
mode_ == LATIN1) {
568 __ CmpS64(current_character(), Operand(
' '));
571 __ SubS64(r2, current_character(), Operand(
'\t'));
572 __ CmpU64(r2, Operand(
'\r' -
'\t'));
575 __ CmpU64(r2, Operand(0x00A0 -
'\t'));
576 BranchOrBacktrack(ne, on_no_match);
581 case StandardCharacterSet::kNotWhitespace:
584 case StandardCharacterSet::kDigit:
586 __ SubS64(r2, current_character(), Operand(
'0'));
587 __ CmpU64(r2, Operand(
'9' -
'0'));
588 BranchOrBacktrack(gt, on_no_match);
590 case StandardCharacterSet::kNotDigit:
592 __ SubS64(r2, current_character(), Operand(
'0'));
593 __ CmpU64(r2, Operand(
'9' -
'0'));
594 BranchOrBacktrack(le, on_no_match);
596 case StandardCharacterSet::kNotLineTerminator: {
598 __ XorP(r2, current_character(), Operand(0x01));
600 __ SubS64(r2, Operand(0x0B));
601 __ CmpU64(r2, Operand(0x0C - 0x0B));
602 BranchOrBacktrack(le, on_no_match);
607 __ SubS64(r2, Operand(0x2028 - 0x0B));
608 __ CmpU64(r2, Operand(1));
609 BranchOrBacktrack(le, on_no_match);
613 case StandardCharacterSet::kLineTerminator: {
615 __ XorP(r2, current_character(), Operand(0x01));
617 __ SubS64(r2, Operand(0x0B));
618 __ CmpU64(r2, Operand(0x0C - 0x0B));
619 if (
mode_ == LATIN1) {
620 BranchOrBacktrack(gt, on_no_match);
627 __ SubS64(r2, Operand(0x2028 - 0x0B));
628 __ CmpU64(r2, Operand(1));
629 BranchOrBacktrack(gt, on_no_match);
634 case StandardCharacterSet::kWord: {
635 if (
mode_ != LATIN1) {
637 __ CmpS64(current_character(), Operand(
'z'));
638 BranchOrBacktrack(gt, on_no_match);
640 ExternalReference map = ExternalReference::re_word_character_map();
641 __ mov(r2, Operand(map));
643 __ CmpU64(r2, Operand::Zero());
644 BranchOrBacktrack(eq, on_no_match);
647 case StandardCharacterSet::kNotWord: {
649 if (
mode_ != LATIN1) {
651 __ CmpU64(current_character(), Operand(
'z'));
654 ExternalReference map = ExternalReference::re_word_character_map();
655 __ mov(r2, Operand(map));
657 __ CmpU64(r2, Operand::Zero());
658 BranchOrBacktrack(ne, on_no_match);
659 if (
mode_ != LATIN1) {
664 case StandardCharacterSet::kEverything:
670void RegExpMacroAssemblerS390::Fail() {
671 __ mov(r2, Operand(FAILURE));
675void RegExpMacroAssemblerS390::LoadRegExpStackPointerFromMemory(Register dst) {
676 ExternalReference ref =
677 ExternalReference::address_of_regexp_stack_stack_pointer(
isolate());
678 __ mov(dst, Operand(ref));
682void RegExpMacroAssemblerS390::StoreRegExpStackPointerToMemory(
683 Register src, Register scratch) {
684 ExternalReference ref =
685 ExternalReference::address_of_regexp_stack_stack_pointer(
isolate());
686 __ mov(scratch, Operand(ref));
690void RegExpMacroAssemblerS390::PushRegExpBasePointer(Register stack_pointer,
692 ExternalReference ref =
693 ExternalReference::address_of_regexp_stack_memory_top_address(
isolate());
694 __ mov(scratch, Operand(ref));
696 __ SubS64(scratch, stack_pointer, scratch);
698 MemOperand(frame_pointer(), kRegExpStackBasePointerOffset));
701void RegExpMacroAssemblerS390::PopRegExpBasePointer(Register stack_pointer_out,
703 ExternalReference ref =
704 ExternalReference::address_of_regexp_stack_memory_top_address(
isolate());
705 __ LoadU64(stack_pointer_out,
706 MemOperand(frame_pointer(), kRegExpStackBasePointerOffset));
707 __ mov(scratch, Operand(ref));
709 __ AddS64(stack_pointer_out, stack_pointer_out, scratch);
710 StoreRegExpStackPointerToMemory(stack_pointer_out, scratch);
713DirectHandle<HeapObject> RegExpMacroAssemblerS390::GetCode(
714 DirectHandle<String> source, RegExpFlags flags) {
721 __ bind(&entry_label_);
725 FrameScope scope(
masm_.get(), StackFrame::MANUAL);
762 (12 * kSystemPointerSize) + kStackPointerBias +
763 (kXPLINKStackFrameExtraParamSlot * kSystemPointerSize)));
770 __ StoreMultipleP(r6, sp,
MemOperand(sp, 6 * kSystemPointerSize));
774 r7, r9,
MemOperand(sp, kStackFrameExtraParamSlot * kSystemPointerSize));
780 __ mov(frame_pointer(), sp);
782 __ mov(r0, Operand(StackFrame::TypeToMarker(StackFrame::IRREGEXP)));
786 __ StoreU64(r10,
MemOperand(frame_pointer(), kIsolateOffset));
790 static_assert(kSuccessfulCapturesOffset ==
792 __ mov(r1, Operand::Zero());
793 static_assert(kStringStartMinusOneOffset ==
797 static_assert(kBacktrackCountOffset ==
800 static_assert(kRegExpStackBasePointerOffset ==
806 static_assert(backtrack_stackpointer() == r13);
807 LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
811 PushRegExpBasePointer(backtrack_stackpointer(), r3);
815 Label stack_limit_hit, stack_ok;
817 ExternalReference stack_limit =
818 ExternalReference::address_of_jslimit(
isolate());
819 __ mov(r2, Operand(stack_limit));
821 __ SubS64(r2, sp, r2);
822 Operand extra_space_for_variables(num_registers_ * kSystemPointerSize);
825 __ ble(&stack_limit_hit);
828 __ CmpU64(r2, extra_space_for_variables);
832 __ mov(r2, Operand(EXCEPTION));
835 __ bind(&stack_limit_hit);
836 CallCheckStackGuardState(r2, extra_space_for_variables);
837 __ CmpS64(r2, Operand::Zero());
845 __ lay(sp,
MemOperand(sp, (-num_registers_ * kSystemPointerSize)));
847 __ LoadU64(end_of_input_address(),
848 MemOperand(frame_pointer(), kInputEndOffset));
850 __ LoadU64(r4,
MemOperand(frame_pointer(), kInputStartOffset));
852 __ SubS64(current_input_offset(), r4, end_of_input_address());
853 __ LoadU64(r3,
MemOperand(frame_pointer(), kStartIndexOffset));
857 __ SubS64(r1, current_input_offset(), Operand(char_size()));
859 __ ShiftLeftU64(r0, r3, Operand(1));
860 __ SubS64(r1, r1, r0);
862 __ SubS64(r1, r1, r3);
866 __ StoreU64(r1,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
869 __ mov(code_pointer(), Operand(
masm_->CodeObject()));
871 Label load_char_start_regexp;
875 __ CmpS64(r3, Operand::Zero());
876 __ bne(&load_char_start_regexp);
877 __ mov(current_character(), Operand(
'\n'));
881 __ bind(&load_char_start_regexp);
883 LoadCurrentCharacterUnchecked(-1, 1);
884 __ bind(&start_regexp);
888 if (num_saved_registers_ > 0) {
890 if (num_saved_registers_ > 8) {
893 kRegisterZeroOffset + kSystemPointerSize));
894 __ mov(r4, Operand(num_saved_registers_));
899 __ BranchOnCount(r4, &init_loop);
901 for (
int i = 0;
i < num_saved_registers_;
i++) {
902 __ StoreU64(r1, register_location(
i));
910 if (success_label_.is_linked()) {
912 __ bind(&success_label_);
913 if (num_saved_registers_ > 0) {
915 __ LoadU64(r0,
MemOperand(frame_pointer(), kInputStartOffset));
916 __ LoadU64(r2,
MemOperand(frame_pointer(), kRegisterOutputOffset));
917 __ LoadU64(r4,
MemOperand(frame_pointer(), kStartIndexOffset));
918 __ SubS64(r0, end_of_input_address(), r0);
921 __ ShiftRightU64(r0, r0, Operand(1));
931 __ lay(r2,
MemOperand(r2, num_saved_registers_ * kIntSize));
932 for (
int i = 0;
i < num_saved_registers_;) {
933 if ((
false) &&
i < num_saved_registers_ - 4) {
935 __ LoadMultipleP(r3, r6, register_location(
i + 3));
937 __ ShiftRightS64(r3, r3, Operand(1));
938 __ ShiftRightS64(r4, r4, Operand(1));
939 __ ShiftRightS64(r5, r5, Operand(1));
940 __ ShiftRightS64(r6, r6, Operand(1));
947 r3,
MemOperand(r2, -(num_saved_registers_ -
i - 3) * kIntSize));
949 r4,
MemOperand(r2, -(num_saved_registers_ -
i - 2) * kIntSize));
951 r5,
MemOperand(r2, -(num_saved_registers_ -
i - 1) * kIntSize));
953 MemOperand(r2, -(num_saved_registers_ -
i) * kIntSize));
956 __ LoadMultipleP(r3, r4, register_location(
i + 1));
958 __ ShiftRightS64(r3, r3, Operand(1));
959 __ ShiftRightS64(r4, r4, Operand(1));
964 r3,
MemOperand(r2, -(num_saved_registers_ -
i - 1) * kIntSize));
966 MemOperand(r2, -(num_saved_registers_ -
i) * kIntSize));
970 if (global_with_zero_length_check()) {
972 __ LoadU64(r6, register_location(0));
978 __ LoadU64(r2,
MemOperand(frame_pointer(), kSuccessfulCapturesOffset));
979 __ LoadU64(r3,
MemOperand(frame_pointer(), kNumOutputRegistersOffset));
980 __ LoadU64(r4,
MemOperand(frame_pointer(), kRegisterOutputOffset));
982 __ AddS64(r2, Operand(1));
983 __ StoreU64(r2,
MemOperand(frame_pointer(), kSuccessfulCapturesOffset));
986 __ SubS64(r3, Operand(num_saved_registers_));
988 __ CmpS64(r3, Operand(num_saved_registers_));
991 __ StoreU64(r3,
MemOperand(frame_pointer(), kNumOutputRegistersOffset));
993 __ AddS64(r4, Operand(num_saved_registers_ * kIntSize));
994 __ StoreU64(r4,
MemOperand(frame_pointer(), kRegisterOutputOffset));
998 PopRegExpBasePointer(backtrack_stackpointer(), r4);
1000 Label reload_string_start_minus_one;
1002 if (global_with_zero_length_check()) {
1005 __ CmpS64(current_input_offset(), r6);
1007 __ bne(&reload_string_start_minus_one);
1009 __ CmpS64(current_input_offset(), Operand::Zero());
1010 __ beq(&exit_label_);
1014 __ AddS64(current_input_offset(), Operand((
mode_ == UC16) ? 2 : 1));
1015 if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
1018 __ bind(&reload_string_start_minus_one);
1021 __ LoadU64(r1,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
1023 __ b(&load_char_start_regexp);
1025 __ mov(r2, Operand(SUCCESS));
1030 __ bind(&exit_label_);
1032 __ LoadU64(r2,
MemOperand(frame_pointer(), kSuccessfulCapturesOffset));
1035 __ bind(&return_r2);
1038 PopRegExpBasePointer(backtrack_stackpointer(), r4);
1041 __ mov(sp, frame_pointer());
1052 __ LoadMultipleP(r6, sp,
MemOperand(sp, 6 * kSystemPointerSize));
1058 if (backtrack_label_.is_linked()) {
1059 __ bind(&backtrack_label_);
1063 Label exit_with_exception;
1066 if (check_preempt_label_.is_linked()) {
1067 SafeCallTarget(&check_preempt_label_);
1069 StoreRegExpStackPointerToMemory(backtrack_stackpointer(), r3);
1071 CallCheckStackGuardState(r2);
1072 __ CmpS64(r2, Operand::Zero());
1077 LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
1080 __ LoadU64(end_of_input_address(),
1081 MemOperand(frame_pointer(), kInputEndOffset));
1086 if (stack_overflow_label_.is_linked()) {
1087 SafeCallTarget(&stack_overflow_label_);
1092 StoreRegExpStackPointerToMemory(backtrack_stackpointer(), r3);
1094 static constexpr int kNumArguments = 1;
1095 __ PrepareCallCFunction(kNumArguments, r2);
1096 __ mov(r2, Operand(ExternalReference::isolate_address(
isolate())));
1097 ExternalReference
grow_stack = ExternalReference::re_grow_stack();
1098 CallCFunctionFromIrregexpCode(grow_stack, kNumArguments);
1101 __ CmpS64(r2, Operand::Zero());
1102 __ beq(&exit_with_exception);
1104 __ mov(backtrack_stackpointer(), r2);
1109 if (exit_with_exception.is_linked()) {
1111 __ bind(&exit_with_exception);
1113 __ mov(r2, Operand(EXCEPTION));
1117 if (fallback_label_.is_linked()) {
1118 __ bind(&fallback_label_);
1119 __ mov(r2, Operand(FALLBACK_TO_EXPERIMENTAL));
1127 .set_self_reference(
masm_->CodeObject())
1128 .set_empty_source_position_table()
1131 RegExpCodeCreateEvent(Cast<AbstractCode>(code), source, flags));
1132 return Cast<HeapObject>(code);
1135void RegExpMacroAssemblerS390::GoTo(Label* to) { BranchOrBacktrack(al, to); }
1137void RegExpMacroAssemblerS390::IfRegisterGE(
int reg,
int comparand,
1139 __ LoadU64(r2, register_location(
reg), r0);
1140 __ CmpS64(r2, Operand(comparand));
1141 BranchOrBacktrack(ge, if_ge);
1144void RegExpMacroAssemblerS390::IfRegisterLT(
int reg,
int comparand,
1146 __ LoadU64(r2, register_location(
reg), r0);
1147 __ CmpS64(r2, Operand(comparand));
1148 BranchOrBacktrack(lt, if_lt);
1151void RegExpMacroAssemblerS390::IfRegisterEqPos(
int reg, Label* if_eq) {
1152 __ LoadU64(r2, register_location(
reg), r0);
1153 __ CmpS64(r2, current_input_offset());
1154 BranchOrBacktrack(eq, if_eq);
1157RegExpMacroAssembler::IrregexpImplementation
1158RegExpMacroAssemblerS390::Implementation() {
1159 return kS390Implementation;
1162void RegExpMacroAssemblerS390::PopCurrentPosition() {
1163 Pop(current_input_offset());
1166void RegExpMacroAssemblerS390::PopRegister(
int register_index) {
1168 __ StoreU64(r2, register_location(register_index));
1171void RegExpMacroAssemblerS390::PushBacktrack(Label*
label) {
1172 if (
label->is_bound()) {
1173 int target =
label->pos();
1175 Operand(target + InstructionStream::kHeaderSize - kHeapObjectTag));
1183void RegExpMacroAssemblerS390::PushCurrentPosition() {
1184 Push(current_input_offset());
1188void RegExpMacroAssemblerS390::PushRegister(
int register_index,
1189 StackCheckFlag check_stack_limit) {
1190 __ LoadU64(r2, register_location(register_index), r0);
1192 if (check_stack_limit) {
1195 AssertAboveStackLimitMinusSlack();
1199void RegExpMacroAssemblerS390::ReadCurrentPositionFromRegister(
int reg) {
1200 __ LoadU64(current_input_offset(), register_location(
reg), r0);
1203void RegExpMacroAssemblerS390::WriteStackPointerToRegister(
int reg) {
1204 ExternalReference ref =
1205 ExternalReference::address_of_regexp_stack_memory_top_address(
isolate());
1206 __ mov(r3, Operand(ref));
1208 __ SubS64(r2, backtrack_stackpointer(), r3);
1209 __ StoreU64(r2, register_location(
reg));
1212void RegExpMacroAssemblerS390::ReadStackPointerFromRegister(
int reg) {
1213 ExternalReference ref =
1214 ExternalReference::address_of_regexp_stack_memory_top_address(
isolate());
1215 __ mov(r2, Operand(ref));
1217 __ LoadU64(backtrack_stackpointer(), register_location(
reg), r0);
1218 __ AddS64(backtrack_stackpointer(), backtrack_stackpointer(), r2);
1221void RegExpMacroAssemblerS390::SetCurrentPositionFromEnd(
int by) {
1222 Label after_position;
1223 __ CmpS64(current_input_offset(), Operand(-by * char_size()));
1224 __ bge(&after_position);
1225 __ mov(current_input_offset(), Operand(-by * char_size()));
1229 LoadCurrentCharacterUnchecked(-1, 1);
1230 __ bind(&after_position);
1233void RegExpMacroAssemblerS390::SetRegister(
int register_index,
int to) {
1234 DCHECK(register_index >= num_saved_registers_);
1235 __ mov(r2, Operand(to));
1236 __ StoreU64(r2, register_location(register_index));
1239bool RegExpMacroAssemblerS390::Succeed() {
1240 __ b(&success_label_);
1244void RegExpMacroAssemblerS390::WriteCurrentPositionToRegister(
int reg,
1246 if (cp_offset == 0) {
1247 __ StoreU64(current_input_offset(), register_location(
reg));
1249 __ AddS64(r2, current_input_offset(), Operand(cp_offset * char_size()));
1250 __ StoreU64(r2, register_location(
reg));
1254void RegExpMacroAssemblerS390::ClearRegisters(
int reg_from,
int reg_to) {
1255 DCHECK(reg_from <= reg_to);
1256 __ LoadU64(r2,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
1257 for (
int reg = reg_from;
reg <= reg_to;
reg++) {
1258 __ StoreU64(r2, register_location(
reg));
1264void RegExpMacroAssemblerS390::CallCheckStackGuardState(Register scratch,
1265 Operand extra_space) {
1267 DCHECK(!
masm_->options().isolate_independent_code);
1269 static constexpr int num_arguments = 4;
1270 __ PrepareCallCFunction(num_arguments, scratch);
1272 __ mov(kCArgRegs[3], extra_space);
1274 __ mov(kCArgRegs[2], frame_pointer());
1276 __ mov(kCArgRegs[1], Operand(
masm_->CodeObject()));
1278 __ lay(r2,
MemOperand(sp, kStackFrameRASlot * kSystemPointerSize));
1279 ExternalReference stack_guard_check =
1280 ExternalReference::re_check_stack_guard_state();
1282 __ mov(ip, Operand(stack_guard_check));
1294 const int stack_slots = kXPLINKStackFrameExtraParamSlot + num_arguments;
1296 kStackPointerBias)));
1300 kXPLINKStackFrameExtraParamSlot * kSystemPointerSize));
1306 __ StoreReturnAddressAndCall(r6);
1311 kXPLINKStackFrameExtraParamSlot * kSystemPointerSize));
1319 __ StoreReturnAddressAndCall(ip);
1322 if (base::OS::ActivationFrameAlignment() > kSystemPointerSize) {
1324 sp,
MemOperand(sp, (kNumRequiredStackFrameSlots * kSystemPointerSize)));
1327 MemOperand(sp, (kNumRequiredStackFrameSlots * kSystemPointerSize)));
1330 __ mov(code_pointer(), Operand(
masm_->CodeObject()));
1334template <
typename T>
1335static T& frame_entry(Address re_frame,
int frame_offset) {
1336 DCHECK_EQ(kSystemPointerSize,
sizeof(T));
1337 return reinterpret_cast<T&
>(Memory<uint64_t>(re_frame + frame_offset));
1340template <
typename T>
1341static T* frame_entry_address(Address re_frame,
int frame_offset) {
1342 return reinterpret_cast<T*
>(re_frame + frame_offset);
1345int RegExpMacroAssemblerS390::CheckStackGuardState(Address* return_address,
1348 uintptr_t extra_space) {
1349 Tagged<InstructionStream> re_code =
1350 Cast<InstructionStream>(Tagged<Object>(raw_code));
1351 return NativeRegExpMacroAssembler::CheckStackGuardState(
1352 frame_entry<Isolate*>(re_frame, kIsolateOffset),
1353 frame_entry<intptr_t>(re_frame, kStartIndexOffset),
1354 static_cast<RegExp::CallOrigin
>(
1355 frame_entry<intptr_t>(re_frame, kDirectCallOffset)),
1356 return_address, re_code,
1357 frame_entry_address<Address>(re_frame, kInputStringOffset),
1358 frame_entry_address<const uint8_t*>(re_frame, kInputStartOffset),
1359 frame_entry_address<const uint8_t*>(re_frame, kInputEndOffset),
1363MemOperand RegExpMacroAssemblerS390::register_location(
int register_index) {
1364 DCHECK(register_index < (1 << 30));
1365 if (num_registers_ <= register_index) {
1366 num_registers_ = register_index + 1;
1369 kRegisterZeroOffset - register_index * kSystemPointerSize);
1372void RegExpMacroAssemblerS390::CheckPosition(
int cp_offset,
1373 Label* on_outside_input) {
1374 if (cp_offset >= 0) {
1375 __ CmpS64(current_input_offset(), Operand(-cp_offset * char_size()));
1376 BranchOrBacktrack(ge, on_outside_input);
1378 __ LoadU64(r3,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
1379 __ AddS64(r2, current_input_offset(), Operand(cp_offset * char_size()));
1381 BranchOrBacktrack(le, on_outside_input);
1385void RegExpMacroAssemblerS390::BranchOrBacktrack(Condition
condition, Label* to,
1388 if (to ==
nullptr) {
1395 if (to ==
nullptr) {
1402void RegExpMacroAssemblerS390::SafeCall(Label* to, Condition cond,
1410void RegExpMacroAssemblerS390::SafeReturn() {
1412 __ mov(ip, Operand(
masm_->CodeObject()));
1417void RegExpMacroAssemblerS390::SafeCallTarget(Label* name) {
1420 __ mov(ip, Operand(
masm_->CodeObject()));
1421 __ SubS64(r0, r0, ip);
1425void RegExpMacroAssemblerS390::Push(Register source) {
1426 DCHECK(source != backtrack_stackpointer());
1427 __ lay(backtrack_stackpointer(),
1428 MemOperand(backtrack_stackpointer(), -kSystemPointerSize));
1429 __ StoreU64(source,
MemOperand(backtrack_stackpointer()));
1432void RegExpMacroAssemblerS390::Pop(Register target) {
1433 DCHECK(target != backtrack_stackpointer());
1434 __ LoadU64(target,
MemOperand(backtrack_stackpointer()));
1435 __ la(backtrack_stackpointer(),
1436 MemOperand(backtrack_stackpointer(), kSystemPointerSize));
1439void RegExpMacroAssemblerS390::CallCFunctionFromIrregexpCode(
1440 ExternalReference function,
int num_arguments) {
1455void RegExpMacroAssemblerS390::CheckPreemption() {
1457 ExternalReference stack_limit =
1458 ExternalReference::address_of_jslimit(
isolate());
1459 __ mov(r2, Operand(stack_limit));
1461 SafeCall(&check_preempt_label_, le);
1464void RegExpMacroAssemblerS390::CheckStackLimit() {
1465 ExternalReference stack_limit =
1466 ExternalReference::address_of_regexp_stack_limit_address(
isolate());
1467 __ mov(r2, Operand(stack_limit));
1469 SafeCall(&stack_overflow_label_, le);
1472void RegExpMacroAssemblerS390::AssertAboveStackLimitMinusSlack() {
1474 Label no_stack_overflow;
1476 auto l = ExternalReference::address_of_regexp_stack_limit_address(
isolate());
1477 __ mov(r2, Operand(l));
1479 __ SubS64(r2, r2, Operand(RegExpStack::kStackLimitSlackSize));
1480 __ CmpU64(backtrack_stackpointer(), r2);
1481 __ bgt(&no_stack_overflow);
1483 __ bind(&no_stack_overflow);
1486void RegExpMacroAssemblerS390::CallCFunctionUsingStub(
1487 ExternalReference function,
int num_arguments) {
1490 __ mov(code_pointer(), Operand(function));
1493 __ StoreU64(r14,
MemOperand(sp, kStackFrameRASlot * kSystemPointerSize));
1494 __ b(code_pointer());
1496 if (base::OS::ActivationFrameAlignment() > kSystemPointerSize) {
1498 sp,
MemOperand(sp, (kNumRequiredStackFrameSlots * kSystemPointerSize)));
1501 MemOperand(sp, (kNumRequiredStackFrameSlots * kSystemPointerSize)));
1503 __ mov(code_pointer(), Operand(
masm_->CodeObject()));
1507void RegExpMacroAssemblerS390::LoadCurrentCharacterUnchecked(
int cp_offset,
1509 if (
mode_ == LATIN1) {
1511 if (characters == 4) {
1512 __ LoadU32LE(current_character(),
1513 MemOperand(current_input_offset(), end_of_input_address(),
1514 cp_offset * char_size()));
1515 }
else if (characters == 2) {
1516 __ LoadU16LE(current_character(),
1517 MemOperand(current_input_offset(), end_of_input_address(),
1518 cp_offset * char_size()));
1521 __ LoadU8(current_character(),
1522 MemOperand(current_input_offset(), end_of_input_address(),
1523 cp_offset * char_size()));
1527 if (characters == 2) {
1528 __ LoadU32(current_character(),
1529 MemOperand(current_input_offset(), end_of_input_address(),
1530 cp_offset * char_size()));
1531#if !V8_TARGET_LITTLE_ENDIAN
1533 __ rll(current_character(), current_character(), Operand(16));
1538 current_character(),
1539 MemOperand(current_input_offset(), end_of_input_address(),
1540 cp_offset * char_size()));
static const int kRegExpCodeSize
RegExpMacroAssemblerS390(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,...)
#define ABI_USES_FUNCTION_DESCRIPTORS
base::SmallVector< int32_t, 1 > stack_slots
MaglevAssembler *const masm_
void Or(LiftoffAssembler *lasm, Register dst, Register lhs, Register rhs)
void And(LiftoffAssembler *lasm, Register dst, Register lhs, Register rhs)
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)
constexpr int kSystemPointerSize
std::unique_ptr< AssemblerBuffer > NewAssemblerBuffer(int size)
Condition NegateCondition(Condition cond)
V8_EXPORT_PRIVATE FlagValues v8_flags
const RegList kRegExpCalleeSaved
#define DCHECK_LE(v1, v2)
#define DCHECK_GE(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)