5#if V8_TARGET_ARCH_LOONG64
86#define __ ACCESS_MASM(masm_)
89 Zone* zone, Mode mode,
90 int registers_to_save)
91 : NativeRegExpMacroAssembler(isolate, zone),
92 masm_(
std::make_unique<MacroAssembler>(
95 no_root_array_scope_(
masm_.get()),
97 num_registers_(registers_to_save),
98 num_saved_registers_(registers_to_save),
104 internal_failure_label_() {
106 __ jmp(&entry_label_);
109 __ bind(&internal_failure_label_);
110 __ li(a0, Operand(FAILURE));
112 __ bind(&start_label_);
115RegExpMacroAssemblerLOONG64::~RegExpMacroAssemblerLOONG64() {
117 entry_label_.Unuse();
118 start_label_.Unuse();
119 success_label_.Unuse();
120 backtrack_label_.Unuse();
122 check_preempt_label_.Unuse();
123 stack_overflow_label_.Unuse();
124 internal_failure_label_.Unuse();
125 fallback_label_.Unuse();
128int RegExpMacroAssemblerLOONG64::stack_limit_slack_slot_count() {
129 return RegExpStack::kStackLimitSlackSlotCount;
132void RegExpMacroAssemblerLOONG64::AdvanceCurrentPosition(
int by) {
134 __ Add_d(current_input_offset(), current_input_offset(),
135 Operand(by * char_size()));
139void RegExpMacroAssemblerLOONG64::AdvanceRegister(
int reg,
int by) {
143 __ Ld_d(a0, register_location(
reg));
144 __ Add_d(a0, a0, Operand(by));
145 __ St_d(a0, register_location(
reg));
149void RegExpMacroAssemblerLOONG64::Backtrack() {
151 if (has_backtrack_limit()) {
153 __ Ld_d(a0,
MemOperand(frame_pointer(), kBacktrackCountOffset));
154 __ Add_d(a0, a0, Operand(1));
155 __ St_d(a0,
MemOperand(frame_pointer(), kBacktrackCountOffset));
156 __ Branch(&next, ne, a0, Operand(backtrack_limit()));
159 if (can_fallback()) {
160 __ jmp(&fallback_label_);
170 __ Add_d(a0, a0, code_pointer());
174void RegExpMacroAssemblerLOONG64::Bind(Label*
label) {
__ bind(
label); }
176void RegExpMacroAssemblerLOONG64::CheckCharacter(uint32_t c, Label* on_equal) {
177 BranchOrBacktrack(on_equal, eq, current_character(), Operand(c));
180void RegExpMacroAssemblerLOONG64::CheckCharacterGT(base::uc16 limit,
182 BranchOrBacktrack(on_greater, gt, current_character(), Operand(limit));
185void RegExpMacroAssemblerLOONG64::CheckAtStart(
int cp_offset,
186 Label* on_at_start) {
187 __ Ld_d(a1,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
188 __ Add_d(a0, current_input_offset(),
189 Operand(-char_size() + cp_offset * char_size()));
190 BranchOrBacktrack(on_at_start, eq, a0, Operand(a1));
193void RegExpMacroAssemblerLOONG64::CheckNotAtStart(
int cp_offset,
194 Label* on_not_at_start) {
195 __ Ld_d(a1,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
196 __ Add_d(a0, current_input_offset(),
197 Operand(-char_size() + cp_offset * char_size()));
198 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(a1));
201void RegExpMacroAssemblerLOONG64::CheckCharacterLT(base::uc16 limit,
203 BranchOrBacktrack(on_less, lt, current_character(), Operand(limit));
206void RegExpMacroAssemblerLOONG64::CheckGreedyLoop(Label* on_equal) {
207 Label backtrack_non_equal;
209 __ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0));
210 __ Add_d(backtrack_stackpointer(), backtrack_stackpointer(),
212 __ bind(&backtrack_non_equal);
213 BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0));
216void RegExpMacroAssemblerLOONG64::CheckNotBackReferenceIgnoreCase(
217 int start_reg,
bool read_backward,
bool unicode, Label* on_no_match) {
219 __ Ld_d(a0, register_location(start_reg));
220 __ Ld_d(a1, register_location(start_reg + 1));
221 __ Sub_d(a1, a1, a0);
226 __ Branch(&fallthrough, eq, a1, Operand(zero_reg));
229 __ Ld_d(t1,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
230 __ Add_d(t1, t1, a1);
231 BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t1));
233 __ Add_d(t1, a1, current_input_offset());
235 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg));
238 if (
mode_ == LATIN1) {
245 __ Add_d(a0, a0, Operand(end_of_input_address()));
246 __ Add_d(a2, end_of_input_address(), Operand(current_input_offset()));
248 __ Sub_d(a2, a2, Operand(a1));
250 __ Add_d(a1, a0, Operand(a1));
259 __ addi_d(a0, a0, char_size());
261 __ addi_d(a2, a2, char_size());
263 __ Branch(&loop_check, eq, a4, Operand(a3));
266 __ Or(a3, a3, Operand(0x20));
267 __ Or(a4, a4, Operand(0x20));
268 __ Branch(&fail, ne, a4, Operand(a3));
269 __ Sub_d(a3, a3, Operand(
'a'));
270 __ Branch(&loop_check, ls, a3, Operand(
'z' -
'a'));
272 __ Sub_d(a3, a3, Operand(224 -
'a'));
274 __ Branch(&fail, hi, a3, Operand(254 - 224));
276 __ Branch(&fail, eq, a3, Operand(247 - 224));
278 __ bind(&loop_check);
279 __ Branch(&loop, lt, a0, Operand(a1));
287 __ Sub_d(current_input_offset(), a2, end_of_input_address());
289 __ Ld_d(t1, register_location(start_reg));
291 register_location(start_reg + 1));
292 __ Add_d(current_input_offset(), current_input_offset(), Operand(t1));
293 __ Sub_d(current_input_offset(), current_input_offset(), Operand(a2));
298 int argument_count = 4;
299 __ PrepareCallCFunction(argument_count, a2);
312 __ Add_d(a0, a0, Operand(end_of_input_address()));
318 __ Add_d(a1, current_input_offset(), Operand(end_of_input_address()));
320 __ Sub_d(a1, a1, Operand(s3));
323 __ li(a3, Operand(ExternalReference::isolate_address(
masm_->isolate())));
326 AllowExternalCallThatCantCauseGC scope(
masm_.get());
327 ExternalReference function =
329 ? ExternalReference::re_case_insensitive_compare_unicode()
330 : ExternalReference::re_case_insensitive_compare_non_unicode();
331 CallCFunctionFromIrregexpCode(function, argument_count);
335 BranchOrBacktrack(on_no_match, eq, a0, Operand(zero_reg));
338 __ Sub_d(current_input_offset(), current_input_offset(), Operand(s3));
340 __ Add_d(current_input_offset(), current_input_offset(), Operand(s3));
344 __ bind(&fallthrough);
347void RegExpMacroAssemblerLOONG64::CheckNotBackReference(
int start_reg,
349 Label* on_no_match) {
353 __ Ld_d(a0, register_location(start_reg));
354 __ Ld_d(a1, register_location(start_reg + 1));
355 __ Sub_d(a1, a1, a0);
360 __ Branch(&fallthrough, eq, a1, Operand(zero_reg));
363 __ Ld_d(t1,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
364 __ Add_d(t1, t1, a1);
365 BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t1));
367 __ Add_d(t1, a1, current_input_offset());
369 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg));
373 __ Add_d(a0, a0, Operand(end_of_input_address()));
374 __ Add_d(a2, end_of_input_address(), Operand(current_input_offset()));
376 __ Sub_d(a2, a2, Operand(a1));
378 __ Add_d(a1, a1, Operand(a0));
382 if (
mode_ == LATIN1) {
384 __ addi_d(a0, a0, char_size());
386 __ addi_d(a2, a2, char_size());
390 __ addi_d(a0, a0, char_size());
392 __ addi_d(a2, a2, char_size());
394 BranchOrBacktrack(on_no_match, ne, a3, Operand(a4));
395 __ Branch(&loop, lt, a0, Operand(a1));
398 __ Sub_d(current_input_offset(), a2, end_of_input_address());
400 __ Ld_d(t1, register_location(start_reg));
401 __ Ld_d(a2, register_location(start_reg + 1));
402 __ Add_d(current_input_offset(), current_input_offset(), Operand(t1));
403 __ Sub_d(current_input_offset(), current_input_offset(), Operand(a2));
405 __ bind(&fallthrough);
408void RegExpMacroAssemblerLOONG64::CheckNotCharacter(uint32_t c,
409 Label* on_not_equal) {
410 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c));
413void RegExpMacroAssemblerLOONG64::CheckCharacterAfterAnd(uint32_t c,
416 __ And(a0, current_character(), Operand(
mask));
417 Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c);
418 BranchOrBacktrack(on_equal, eq, a0, rhs);
421void RegExpMacroAssemblerLOONG64::CheckNotCharacterAfterAnd(
422 uint32_t c, uint32_t
mask, Label* on_not_equal) {
423 __ And(a0, current_character(), Operand(
mask));
424 Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c);
425 BranchOrBacktrack(on_not_equal, ne, a0, rhs);
428void RegExpMacroAssemblerLOONG64::CheckNotCharacterAfterMinusAnd(
429 base::uc16 c, base::uc16 minus, base::uc16
mask, Label* on_not_equal) {
430 DCHECK_GT(String::kMaxUtf16CodeUnit, minus);
431 __ Sub_d(a0, current_character(), Operand(minus));
433 BranchOrBacktrack(on_not_equal, ne, a0, Operand(c));
436void RegExpMacroAssemblerLOONG64::CheckCharacterInRange(base::uc16 from,
438 Label* on_in_range) {
439 __ Sub_d(a0, current_character(), Operand(from));
441 BranchOrBacktrack(on_in_range, ls, a0, Operand(to - from));
444void RegExpMacroAssemblerLOONG64::CheckCharacterNotInRange(
445 base::uc16 from, base::uc16 to, Label* on_not_in_range) {
446 __ Sub_d(a0, current_character(), Operand(from));
448 BranchOrBacktrack(on_not_in_range, hi, a0, Operand(to - from));
451void RegExpMacroAssemblerLOONG64::CallIsCharacterInRangeArray(
452 const ZoneList<CharacterRange>* ranges) {
453 static const int kNumArguments = 3;
454 __ PrepareCallCFunction(kNumArguments, a0);
456 __ mov(a0, current_character());
457 __ li(a1, Operand(GetOrAddRangeArray(ranges)));
458 __ li(a2, Operand(ExternalReference::isolate_address(
isolate())));
462 FrameScope scope(
masm_.get(), StackFrame::MANUAL);
463 CallCFunctionFromIrregexpCode(
464 ExternalReference::re_is_character_in_range_array(), kNumArguments);
467 __ li(code_pointer(), Operand(
masm_->CodeObject()));
470bool RegExpMacroAssemblerLOONG64::CheckCharacterInRangeArray(
471 const ZoneList<CharacterRange>* ranges, Label* on_in_range) {
472 CallIsCharacterInRangeArray(ranges);
473 BranchOrBacktrack(on_in_range, ne, a0, Operand(zero_reg));
477bool RegExpMacroAssemblerLOONG64::CheckCharacterNotInRangeArray(
478 const ZoneList<CharacterRange>* ranges, Label* on_not_in_range) {
479 CallIsCharacterInRangeArray(ranges);
480 BranchOrBacktrack(on_not_in_range, eq, a0, Operand(zero_reg));
484void RegExpMacroAssemblerLOONG64::CheckBitInTable(Handle<ByteArray> table,
486 __ li(a0, Operand(table));
487 if (
mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) {
488 __ And(a1, current_character(), Operand(kTableSize - 1));
489 __ Add_d(a0, a0, a1);
491 __ Add_d(a0, a0, current_character());
495 BranchOrBacktrack(on_bit_set, ne, a0, Operand(zero_reg));
498void RegExpMacroAssemblerLOONG64::SkipUntilBitInTable(
499 int cp_offset, Handle<ByteArray> table, Handle<ByteArray> nibble_table,
504 LoadCurrentCharacter(cp_offset, &cont,
true);
505 CheckBitInTable(table, &cont);
506 AdvanceCurrentPosition(advance_by);
511bool RegExpMacroAssemblerLOONG64::CheckSpecialClassRanges(
512 StandardCharacterSet type, Label* on_no_match) {
517 case StandardCharacterSet::kWhitespace:
519 if (
mode_ == LATIN1) {
522 __ Branch(&success, eq, current_character(), Operand(
' '));
524 __ Sub_d(a0, current_character(), Operand(
'\t'));
525 __ Branch(&success, ls, a0, Operand(
'\r' -
'\t'));
527 BranchOrBacktrack(on_no_match, ne, a0, Operand(0x00A0 -
'\t'));
532 case StandardCharacterSet::kNotWhitespace:
535 case StandardCharacterSet::kDigit:
537 __ Sub_d(a0, current_character(), Operand(
'0'));
538 BranchOrBacktrack(on_no_match, hi, a0, Operand(
'9' -
'0'));
540 case StandardCharacterSet::kNotDigit:
542 __ Sub_d(a0, current_character(), Operand(
'0'));
543 BranchOrBacktrack(on_no_match, ls, a0, Operand(
'9' -
'0'));
545 case StandardCharacterSet::kNotLineTerminator: {
547 __ Xor(a0, current_character(), Operand(0x01));
549 __ Sub_d(a0, a0, Operand(0x0B));
550 BranchOrBacktrack(on_no_match, ls, a0, Operand(0x0C - 0x0B));
555 __ Sub_d(a0, a0, Operand(0x2028 - 0x0B));
556 BranchOrBacktrack(on_no_match, ls, a0, Operand(1));
560 case StandardCharacterSet::kLineTerminator: {
562 __ Xor(a0, current_character(), Operand(0x01));
564 __ Sub_d(a0, a0, Operand(0x0B));
565 if (
mode_ == LATIN1) {
566 BranchOrBacktrack(on_no_match, hi, a0, Operand(0x0C - 0x0B));
569 BranchOrBacktrack(&done, ls, a0, Operand(0x0C - 0x0B));
573 __ Sub_d(a0, a0, Operand(0x2028 - 0x0B));
574 BranchOrBacktrack(on_no_match, hi, a0, Operand(1));
579 case StandardCharacterSet::kWord: {
580 if (
mode_ != LATIN1) {
582 BranchOrBacktrack(on_no_match, hi, current_character(), Operand(
'z'));
584 ExternalReference map = ExternalReference::re_word_character_map();
585 __ li(a0, Operand(map));
586 __ Add_d(a0, a0, current_character());
588 BranchOrBacktrack(on_no_match, eq, a0, Operand(zero_reg));
591 case StandardCharacterSet::kNotWord: {
593 if (
mode_ != LATIN1) {
595 __ Branch(&done, hi, current_character(), Operand(
'z'));
597 ExternalReference map = ExternalReference::re_word_character_map();
598 __ li(a0, Operand(map));
599 __ Add_d(a0, a0, current_character());
601 BranchOrBacktrack(on_no_match, ne, a0, Operand(zero_reg));
602 if (
mode_ != LATIN1) {
607 case StandardCharacterSet::kEverything:
613void RegExpMacroAssemblerLOONG64::Fail() {
614 __ li(a0, Operand(FAILURE));
615 __ jmp(&exit_label_);
618void RegExpMacroAssemblerLOONG64::LoadRegExpStackPointerFromMemory(
620 ExternalReference ref =
621 ExternalReference::address_of_regexp_stack_stack_pointer(
isolate());
626void RegExpMacroAssemblerLOONG64::StoreRegExpStackPointerToMemory(
627 Register src, Register scratch) {
628 ExternalReference ref =
629 ExternalReference::address_of_regexp_stack_stack_pointer(
isolate());
634void RegExpMacroAssemblerLOONG64::PushRegExpBasePointer(Register stack_pointer,
636 ExternalReference ref =
637 ExternalReference::address_of_regexp_stack_memory_top_address(
isolate());
640 __ Sub_d(scratch, stack_pointer, scratch);
641 __ St_d(scratch,
MemOperand(frame_pointer(), kRegExpStackBasePointerOffset));
644void RegExpMacroAssemblerLOONG64::PopRegExpBasePointer(
645 Register stack_pointer_out, Register scratch) {
646 ExternalReference ref =
647 ExternalReference::address_of_regexp_stack_memory_top_address(
isolate());
648 __ Ld_d(stack_pointer_out,
649 MemOperand(frame_pointer(), kRegExpStackBasePointerOffset));
652 __ Add_d(stack_pointer_out, stack_pointer_out, scratch);
653 StoreRegExpStackPointerToMemory(stack_pointer_out, scratch);
656DirectHandle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(
657 DirectHandle<String> source, RegExpFlags flags) {
669 __ bind(&entry_label_);
673 FrameScope scope(
masm_.get(), StackFrame::MANUAL);
680 RegList registers_to_retain = {s0, s1, s2, s3, s4, s5, s6, s7};
682 __ MultiPush({ra}, {fp}, registers_to_retain);
683 __ mov(frame_pointer(), sp);
692 RegList argument_registers = {a0, a1, a2, a3};
693 argument_registers |= {a4, a5, a6, a7};
696 __ li(
kScratchReg, Operand(StackFrame::TypeToMarker(StackFrame::IRREGEXP)));
698 static_assert(kInputEndOffset ==
705 static_assert(kSuccessfulCapturesOffset ==
707 __ mov(a0, zero_reg);
709 static_assert(kStringStartMinusOneOffset ==
712 static_assert(kBacktrackCountOffset ==
715 static_assert(kRegExpStackBasePointerOffset ==
721 static_assert(backtrack_stackpointer() == s7);
722 LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
726 PushRegExpBasePointer(backtrack_stackpointer(), a1);
730 Label stack_limit_hit, stack_ok;
732 ExternalReference stack_limit =
733 ExternalReference::address_of_jslimit(
masm_->isolate());
734 Operand extra_space_for_variables(num_registers_ * kSystemPointerSize);
736 __ li(a0, Operand(stack_limit));
738 __ Sub_d(a0, sp, a0);
740 __ Branch(&stack_limit_hit, le, a0, Operand(zero_reg));
743 __ Branch(&stack_ok, hs, a0, extra_space_for_variables);
746 __ li(a0, Operand(EXCEPTION));
749 __ bind(&stack_limit_hit);
750 CallCheckStackGuardState(a0, extra_space_for_variables);
753 __ Branch(&return_v0, ne, a0, Operand(zero_reg));
759 __ Sub_d(sp, sp, Operand(num_registers_ * kSystemPointerSize));
761 __ Ld_d(end_of_input_address(),
762 MemOperand(frame_pointer(), kInputEndOffset));
764 __ Ld_d(a0,
MemOperand(frame_pointer(), kInputStartOffset));
766 __ Sub_d(current_input_offset(), a0, end_of_input_address());
769 __ Ld_d(a1,
MemOperand(frame_pointer(), kStartIndexOffset));
770 __ Sub_d(a0, current_input_offset(), Operand(char_size()));
771 __ slli_d(t1, a1, (
mode_ == UC16) ? 1 : 0);
772 __ Sub_d(a0, a0, t1);
775 __ St_d(a0,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
778 __ li(code_pointer(), Operand(
masm_->CodeObject()), CONSTANT_SIZE);
780 Label load_char_start_regexp;
784 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
785 __ li(current_character(), Operand(
'\n'));
786 __ jmp(&start_regexp);
789 __ bind(&load_char_start_regexp);
791 LoadCurrentCharacterUnchecked(-1, 1);
792 __ bind(&start_regexp);
796 if (num_saved_registers_ > 0) {
798 if (num_saved_registers_ > 8) {
800 __ Add_d(a1, frame_pointer(), Operand(kRegisterZeroOffset));
801 __ li(a2, Operand(num_saved_registers_));
805 __ Add_d(a1, a1, Operand(-kSystemPointerSize));
806 __ Sub_d(a2, a2, Operand(1));
807 __ Branch(&init_loop, ne, a2, Operand(zero_reg));
809 for (
int i = 0;
i < num_saved_registers_;
i++) {
810 __ St_d(a0, register_location(
i));
815 __ jmp(&start_label_);
818 if (success_label_.is_linked()) {
820 __ bind(&success_label_);
821 if (num_saved_registers_ > 0) {
823 __ Ld_d(a1,
MemOperand(frame_pointer(), kInputStartOffset));
824 __ Ld_d(a0,
MemOperand(frame_pointer(), kRegisterOutputOffset));
825 __ Ld_d(a2,
MemOperand(frame_pointer(), kStartIndexOffset));
826 __ Sub_d(a1, end_of_input_address(), a1);
829 __ srli_d(a1, a1, 1);
832 __ Add_d(a1, a1, Operand(a2));
839 for (
int i = 0;
i < num_saved_registers_;
i += 2) {
840 __ Ld_d(a2, register_location(
i));
841 __ Ld_d(a3, register_location(
i + 1));
842 if (
i == 0 && global_with_zero_length_check()) {
847 __ srai_d(a2, a2, 1);
848 __ Add_d(a2, a2, a1);
849 __ srai_d(a3, a3, 1);
850 __ Add_d(a3, a3, a1);
852 __ Add_d(a2, a1, Operand(a2));
853 __ Add_d(a3, a1, Operand(a3));
857 __ Add_d(a0, a0, kIntSize);
859 __ Add_d(a0, a0, kIntSize);
865 __ Ld_d(a0,
MemOperand(frame_pointer(), kSuccessfulCapturesOffset));
866 __ Ld_d(a1,
MemOperand(frame_pointer(), kNumOutputRegistersOffset));
867 __ Ld_d(a2,
MemOperand(frame_pointer(), kRegisterOutputOffset));
870 __ St_d(a0,
MemOperand(frame_pointer(), kSuccessfulCapturesOffset));
873 __ Sub_d(a1, a1, num_saved_registers_);
876 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_));
878 __ St_d(a1,
MemOperand(frame_pointer(), kNumOutputRegistersOffset));
880 __ Add_d(a2, a2, num_saved_registers_ * kIntSize);
881 __ St_d(a2,
MemOperand(frame_pointer(), kRegisterOutputOffset));
885 PopRegExpBasePointer(backtrack_stackpointer(), a2);
887 Label reload_string_start_minus_one;
889 if (global_with_zero_length_check()) {
893 __ Branch(&reload_string_start_minus_one, ne, current_input_offset(),
896 __ Branch(&exit_label_, eq, current_input_offset(),
901 __ Add_d(current_input_offset(), current_input_offset(),
902 Operand((
mode_ == UC16) ? 2 : 1));
903 if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
906 __ bind(&reload_string_start_minus_one);
909 __ Ld_d(a0,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
911 __ Branch(&load_char_start_regexp);
913 __ li(a0, Operand(SUCCESS));
917 __ bind(&exit_label_);
919 __ Ld_d(a0,
MemOperand(frame_pointer(), kSuccessfulCapturesOffset));
925 PopRegExpBasePointer(backtrack_stackpointer(), a2);
928 __ mov(sp, frame_pointer());
930 __ MultiPop({ra}, {fp}, registers_to_retain);
934 if (backtrack_label_.is_linked()) {
935 __ bind(&backtrack_label_);
939 Label exit_with_exception;
942 if (check_preempt_label_.is_linked()) {
943 SafeCallTarget(&check_preempt_label_);
945 StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
947 CallCheckStackGuardState(a0);
950 __ Branch(&return_v0, ne, a0, Operand(zero_reg));
952 LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
955 __ Ld_d(end_of_input_address(),
956 MemOperand(frame_pointer(), kInputEndOffset));
962 if (stack_overflow_label_.is_linked()) {
963 SafeCallTarget(&stack_overflow_label_);
964 StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
968 static const int kNumArguments = 1;
969 __ PrepareCallCFunction(kNumArguments, a0);
970 __ li(a0, Operand(ExternalReference::isolate_address(
masm_->isolate())));
971 ExternalReference
grow_stack = ExternalReference::re_grow_stack();
972 CallCFunctionFromIrregexpCode(grow_stack, kNumArguments);
975 __ Branch(&exit_with_exception, eq, a0, Operand(zero_reg));
977 __ mov(backtrack_stackpointer(), a0);
981 if (exit_with_exception.is_linked()) {
983 __ bind(&exit_with_exception);
985 __ li(a0, Operand(EXCEPTION));
989 if (fallback_label_.is_linked()) {
990 __ bind(&fallback_label_);
991 __ li(a0, Operand(FALLBACK_TO_EXPERIMENTAL));
1000 .set_self_reference(
masm_->CodeObject())
1001 .set_empty_source_position_table()
1004 RegExpCodeCreateEvent(Cast<AbstractCode>(code), source, flags));
1005 return Cast<HeapObject>(code);
1008void RegExpMacroAssemblerLOONG64::GoTo(Label* to) {
1009 if (to ==
nullptr) {
1017void RegExpMacroAssemblerLOONG64::IfRegisterGE(
int reg,
int comparand,
1019 __ Ld_d(a0, register_location(
reg));
1020 BranchOrBacktrack(if_ge, ge, a0, Operand(comparand));
1023void RegExpMacroAssemblerLOONG64::IfRegisterLT(
int reg,
int comparand,
1025 __ Ld_d(a0, register_location(
reg));
1026 BranchOrBacktrack(if_lt, lt, a0, Operand(comparand));
1029void RegExpMacroAssemblerLOONG64::IfRegisterEqPos(
int reg, Label* if_eq) {
1030 __ Ld_d(a0, register_location(
reg));
1031 BranchOrBacktrack(if_eq, eq, a0, Operand(current_input_offset()));
1034RegExpMacroAssembler::IrregexpImplementation
1035RegExpMacroAssemblerLOONG64::Implementation() {
1036 return kLOONG64Implementation;
1039void RegExpMacroAssemblerLOONG64::PopCurrentPosition() {
1040 Pop(current_input_offset());
1043void RegExpMacroAssemblerLOONG64::PopRegister(
int register_index) {
1045 __ St_d(a0, register_location(register_index));
1048void RegExpMacroAssemblerLOONG64::PushBacktrack(Label*
label) {
1049 if (
label->is_bound()) {
1050 int target =
label->pos();
1052 Operand(target + InstructionStream::kHeaderSize - kHeapObjectTag));
1054 Assembler::BlockTrampolinePoolScope block_trampoline_pool(
masm_.get());
1055 Label after_constant;
1056 __ Branch(&after_constant);
1062 __ bind(&after_constant);
1063 if (is_int12(cp_offset)) {
1066 __ Add_d(a0, code_pointer(), cp_offset);
1074void RegExpMacroAssemblerLOONG64::PushCurrentPosition() {
1075 Push(current_input_offset());
1079void RegExpMacroAssemblerLOONG64::PushRegister(
1080 int register_index, StackCheckFlag check_stack_limit) {
1081 __ Ld_d(a0, register_location(register_index));
1083 if (check_stack_limit) {
1086 AssertAboveStackLimitMinusSlack();
1090void RegExpMacroAssemblerLOONG64::ReadCurrentPositionFromRegister(
int reg) {
1091 __ Ld_d(current_input_offset(), register_location(
reg));
1094void RegExpMacroAssemblerLOONG64::WriteStackPointerToRegister(
int reg) {
1095 ExternalReference stack_top_address =
1096 ExternalReference::address_of_regexp_stack_memory_top_address(
isolate());
1097 __ li(a0, stack_top_address);
1099 __ Sub_d(a0, backtrack_stackpointer(), a0);
1100 __ St_d(a0, register_location(
reg));
1103void RegExpMacroAssemblerLOONG64::ReadStackPointerFromRegister(
int reg) {
1104 ExternalReference stack_top_address =
1105 ExternalReference::address_of_regexp_stack_memory_top_address(
isolate());
1106 __ li(backtrack_stackpointer(), stack_top_address);
1107 __ Ld_d(backtrack_stackpointer(),
MemOperand(backtrack_stackpointer(), 0));
1108 __ Ld_d(a0, register_location(
reg));
1109 __ Add_d(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0));
1112void RegExpMacroAssemblerLOONG64::SetCurrentPositionFromEnd(
int by) {
1113 Label after_position;
1114 __ Branch(&after_position, ge, current_input_offset(),
1115 Operand(-by * char_size()));
1116 __ li(current_input_offset(), -by * char_size());
1120 LoadCurrentCharacterUnchecked(-1, 1);
1121 __ bind(&after_position);
1124void RegExpMacroAssemblerLOONG64::SetRegister(
int register_index,
int to) {
1125 DCHECK(register_index >= num_saved_registers_);
1126 __ li(a0, Operand(to));
1127 __ St_d(a0, register_location(register_index));
1130bool RegExpMacroAssemblerLOONG64::Succeed() {
1131 __ jmp(&success_label_);
1135void RegExpMacroAssemblerLOONG64::WriteCurrentPositionToRegister(
1136 int reg,
int cp_offset) {
1137 if (cp_offset == 0) {
1138 __ St_d(current_input_offset(), register_location(
reg));
1140 __ Add_d(a0, current_input_offset(), Operand(cp_offset * char_size()));
1141 __ St_d(a0, register_location(
reg));
1145void RegExpMacroAssemblerLOONG64::ClearRegisters(
int reg_from,
int reg_to) {
1146 DCHECK(reg_from <= reg_to);
1147 __ Ld_d(a0,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
1148 for (
int reg = reg_from;
reg <= reg_to;
reg++) {
1149 __ St_d(a0, register_location(
reg));
1155void RegExpMacroAssemblerLOONG64::CallCheckStackGuardState(
1156 Register scratch, Operand extra_space) {
1158 DCHECK(!
masm_->options().isolate_independent_code);
1160 int stack_alignment = base::OS::ActivationFrameAlignment();
1163 __ mov(scratch, sp);
1164 __ Sub_d(sp, sp, Operand(kSystemPointerSize));
1165 DCHECK(base::bits::IsPowerOfTwo(stack_alignment));
1166 __ And(sp, sp, Operand(-stack_alignment));
1170 __ li(a3, extra_space);
1172 __ mov(a2, frame_pointer());
1174 __ li(a1, Operand(
masm_->CodeObject()), CONSTANT_SIZE);
1178 __ Sub_d(sp, sp, Operand(stack_alignment));
1183 ExternalReference stack_guard_check =
1184 ExternalReference::re_check_stack_guard_state();
1185 __ li(t5, Operand(stack_guard_check));
1187 EmbeddedData d = EmbeddedData::FromBlob();
1188 CHECK(Builtins::IsIsolateIndependent(Builtin::kDirectCEntry));
1189 Address entry = d.InstructionStartOf(Builtin::kDirectCEntry);
1190 __ li(
kScratchReg, Operand(entry, RelocInfo::OFF_HEAP_TARGET));
1195 __ li(code_pointer(), Operand(
masm_->CodeObject()));
1199template <
typename T>
1200static T& frame_entry(Address re_frame,
int frame_offset) {
1201 return reinterpret_cast<T&
>(Memory<int32_t>(re_frame + frame_offset));
1204template <
typename T>
1205static T* frame_entry_address(Address re_frame,
int frame_offset) {
1206 return reinterpret_cast<T*
>(re_frame + frame_offset);
1209int64_t RegExpMacroAssemblerLOONG64::CheckStackGuardState(
1210 Address* return_address, Address raw_code, Address re_frame,
1211 uintptr_t extra_space) {
1212 Tagged<InstructionStream> re_code =
1213 Cast<InstructionStream>(Tagged<Object>(raw_code));
1214 return NativeRegExpMacroAssembler::CheckStackGuardState(
1215 frame_entry<Isolate*>(re_frame, kIsolateOffset),
1216 static_cast<int>(frame_entry<int64_t>(re_frame, kStartIndexOffset)),
1217 static_cast<RegExp::CallOrigin
>(
1218 frame_entry<int64_t>(re_frame, kDirectCallOffset)),
1219 return_address, re_code,
1220 frame_entry_address<Address>(re_frame, kInputStringOffset),
1221 frame_entry_address<const uint8_t*>(re_frame, kInputStartOffset),
1222 frame_entry_address<const uint8_t*>(re_frame, kInputEndOffset),
1226MemOperand RegExpMacroAssemblerLOONG64::register_location(
int register_index) {
1227 DCHECK(register_index < (1 << 30));
1228 if (num_registers_ <= register_index) {
1229 num_registers_ = register_index + 1;
1232 kRegisterZeroOffset - register_index * kSystemPointerSize);
1235void RegExpMacroAssemblerLOONG64::CheckPosition(
int cp_offset,
1236 Label* on_outside_input) {
1237 if (cp_offset >= 0) {
1238 BranchOrBacktrack(on_outside_input, ge, current_input_offset(),
1239 Operand(-cp_offset * char_size()));
1241 __ Ld_d(a1,
MemOperand(frame_pointer(), kStringStartMinusOneOffset));
1242 __ Add_d(a0, current_input_offset(), Operand(cp_offset * char_size()));
1243 BranchOrBacktrack(on_outside_input, le, a0, Operand(a1));
1247void RegExpMacroAssemblerLOONG64::BranchOrBacktrack(Label* to,
1250 const Operand& rt) {
1252 if (to ==
nullptr) {
1259 if (to ==
nullptr) {
1266void RegExpMacroAssemblerLOONG64::SafeCall(Label* to, Condition cond,
1267 Register rs,
const Operand& rt) {
1268 __ Branch(to, cond, rs, rt,
true);
1271void RegExpMacroAssemblerLOONG64::SafeReturn() {
1273 __ Add_d(t1, ra, Operand(
masm_->CodeObject()));
1277void RegExpMacroAssemblerLOONG64::SafeCallTarget(Label* name) {
1279 __ Sub_d(ra, ra, Operand(
masm_->CodeObject()));
1283void RegExpMacroAssemblerLOONG64::Push(Register source) {
1284 DCHECK(source != backtrack_stackpointer());
1285 __ Add_d(backtrack_stackpointer(), backtrack_stackpointer(),
1286 Operand(-kIntSize));
1287 __ St_w(source,
MemOperand(backtrack_stackpointer(), 0));
1290void RegExpMacroAssemblerLOONG64::Pop(Register target) {
1291 DCHECK(target != backtrack_stackpointer());
1292 __ Ld_w(target,
MemOperand(backtrack_stackpointer(), 0));
1293 __ Add_d(backtrack_stackpointer(), backtrack_stackpointer(), kIntSize);
1296void RegExpMacroAssemblerLOONG64::CallCFunctionFromIrregexpCode(
1297 ExternalReference function,
int num_arguments) {
1311void RegExpMacroAssemblerLOONG64::CheckPreemption() {
1313 ExternalReference stack_limit =
1314 ExternalReference::address_of_jslimit(
masm_->isolate());
1315 __ li(a0, Operand(stack_limit));
1317 SafeCall(&check_preempt_label_, ls, sp, Operand(a0));
1320void RegExpMacroAssemblerLOONG64::CheckStackLimit() {
1321 ExternalReference stack_limit =
1322 ExternalReference::address_of_regexp_stack_limit_address(
1325 __ li(a0, Operand(stack_limit));
1327 SafeCall(&stack_overflow_label_, ls, backtrack_stackpointer(), Operand(a0));
1330void RegExpMacroAssemblerLOONG64::AssertAboveStackLimitMinusSlack() {
1331 ExternalReference stack_limit =
1332 ExternalReference::address_of_regexp_stack_limit_address(
1335 __ li(a0, Operand(stack_limit));
1337 SafeCall(&stack_overflow_label_, ls, backtrack_stackpointer(), Operand(a0));
1340 Label no_stack_overflow;
1342 auto l = ExternalReference::address_of_regexp_stack_limit_address(
isolate());
1345 __ Sub_d(a0, a0, Operand(RegExpStack::kStackLimitSlackSize));
1346 __ Branch(&no_stack_overflow, hi, backtrack_stackpointer(), Operand(a0));
1348 __ bind(&no_stack_overflow);
1351void RegExpMacroAssemblerLOONG64::LoadCurrentCharacterUnchecked(
1352 int cp_offset,
int characters) {
1357 if (!CanReadUnaligned()) {
1361 if (cp_offset != 0) {
1363 __ Add_d(t3, current_input_offset(), Operand(cp_offset * char_size()));
1367 if (
mode_ == LATIN1) {
1368 if (characters == 4) {
1370 }
else if (characters == 2) {
1378 if (characters == 2) {
RegExpMacroAssemblerLOONG64(Isolate *isolate, Zone *zone, Mode mode, int registers_to_save)
RecordWriteMode const mode_
const CodeDesc * code_desc
#define ASM_CODE_COMMENT_STRING(asm,...)
#define LOG(isolate, Call)
MaglevAssembler *const masm_
void Or(LiftoffAssembler *lasm, Register dst, Register lhs, Register rhs)
void Xor(LiftoffAssembler *lasm, Register dst, Register lhs, Register rhs)
void And(LiftoffAssembler *lasm, Register dst, Register lhs, Register rhs)
Address grow_stack(Isolate *isolate, void *current_sp, size_t frame_size, size_t gap, Address current_fp)
RegListBase< Register > RegList
MemOperand FieldMemOperand(Register object, int offset)
constexpr int kSystemPointerSize
std::unique_ptr< AssemblerBuffer > NewAssemblerBuffer(int size)
V8_EXPORT_PRIVATE FlagValues v8_flags
#define DCHECK_LE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
constexpr bool IsAligned(T value, U alignment)
#define OFFSET_OF_DATA_START(Type)
#define V8_UNLIKELY(condition)