5 #if V8_TARGET_ARCH_MIPS64 7 #include "src/regexp/mips64/regexp-macro-assembler-mips64.h" 9 #include "src/assembler-inl.h" 10 #include "src/code-stubs.h" 12 #include "src/macro-assembler.h" 13 #include "src/objects-inl.h" 14 #include "src/regexp/regexp-macro-assembler.h" 15 #include "src/regexp/regexp-stack.h" 21 #ifndef V8_INTERPRETED_REGEXP 128 #define __ ACCESS_MASM(masm_) 130 RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone,
132 int registers_to_save)
133 : NativeRegExpMacroAssembler(isolate, zone),
134 masm_(new MacroAssembler(isolate, nullptr, kRegExpCodeSize,
135 CodeObjectRequired::kYes)),
137 num_registers_(registers_to_save),
138 num_saved_registers_(registers_to_save),
144 internal_failure_label_() {
145 DCHECK_EQ(0, registers_to_save % 2);
146 __ jmp(&entry_label_);
149 __ bind(&internal_failure_label_);
150 __ li(v0, Operand(FAILURE));
152 __ bind(&start_label_);
156 RegExpMacroAssemblerMIPS::~RegExpMacroAssemblerMIPS() {
159 entry_label_.Unuse();
160 start_label_.Unuse();
161 success_label_.Unuse();
162 backtrack_label_.Unuse();
164 check_preempt_label_.Unuse();
165 stack_overflow_label_.Unuse();
166 internal_failure_label_.Unuse();
170 int RegExpMacroAssemblerMIPS::stack_limit_slack() {
171 return RegExpStack::kStackLimitSlack;
175 void RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(
int by) {
177 __ Daddu(current_input_offset(),
178 current_input_offset(), Operand(by * char_size()));
183 void RegExpMacroAssemblerMIPS::AdvanceRegister(
int reg,
int by) {
185 DCHECK_GT(num_registers_, reg);
187 __ Ld(a0, register_location(reg));
188 __ Daddu(a0, a0, Operand(by));
189 __ Sd(a0, register_location(reg));
194 void RegExpMacroAssemblerMIPS::Backtrack() {
198 __ Daddu(a0, a0, code_pointer());
203 void RegExpMacroAssemblerMIPS::Bind(Label* label) {
208 void RegExpMacroAssemblerMIPS::CheckCharacter(
uint32_t c, Label* on_equal) {
209 BranchOrBacktrack(on_equal, eq, current_character(), Operand(c));
213 void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) {
214 BranchOrBacktrack(on_greater, gt, current_character(), Operand(limit));
218 void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
219 __ Ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne));
220 __ Daddu(a0, current_input_offset(), Operand(-char_size()));
221 BranchOrBacktrack(on_at_start, eq, a0, Operand(a1));
225 void RegExpMacroAssemblerMIPS::CheckNotAtStart(
int cp_offset,
226 Label* on_not_at_start) {
227 __ Ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne));
228 __ Daddu(a0, current_input_offset(),
229 Operand(-char_size() + cp_offset * char_size()));
230 BranchOrBacktrack(on_not_at_start, ne, a0, Operand(a1));
234 void RegExpMacroAssemblerMIPS::CheckCharacterLT(uc16 limit, Label* on_less) {
235 BranchOrBacktrack(on_less, lt, current_character(), Operand(limit));
239 void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) {
240 Label backtrack_non_equal;
241 __ Lw(a0, MemOperand(backtrack_stackpointer(), 0));
242 __ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0));
243 __ Daddu(backtrack_stackpointer(),
244 backtrack_stackpointer(),
246 __ bind(&backtrack_non_equal);
247 BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0));
251 void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
252 int start_reg,
bool read_backward,
bool unicode, Label* on_no_match) {
254 __ Ld(a0, register_location(start_reg));
255 __ Ld(a1, register_location(start_reg + 1));
256 __ Dsubu(a1, a1, a0);
261 __ Branch(&fallthrough, eq, a1, Operand(zero_reg));
264 __ Ld(t1, MemOperand(frame_pointer(), kStringStartMinusOne));
265 __ Daddu(t1, t1, a1);
266 BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t1));
268 __ Daddu(t1, a1, current_input_offset());
270 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg));
273 if (mode_ == LATIN1) {
280 __ Daddu(a0, a0, Operand(end_of_input_address()));
281 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset()));
283 __ Dsubu(a2, a2, Operand(a1));
285 __ Daddu(a1, a0, Operand(a1));
293 __ Lbu(a3, MemOperand(a0, 0));
294 __ daddiu(a0, a0, char_size());
295 __ Lbu(a4, MemOperand(a2, 0));
296 __ daddiu(a2, a2, char_size());
298 __ Branch(&loop_check, eq, a4, Operand(a3));
301 __ Or(a3, a3, Operand(0x20));
302 __ Or(a4, a4, Operand(0x20));
303 __ Branch(&fail, ne, a4, Operand(a3));
304 __ Dsubu(a3, a3, Operand(
'a'));
305 __ Branch(&loop_check, ls, a3, Operand(
'z' -
'a'));
307 __ Dsubu(a3, a3, Operand(224 -
'a'));
309 __ Branch(&fail, hi, a3, Operand(254 - 224));
311 __ Branch(&fail, eq, a3, Operand(247 - 224));
313 __ bind(&loop_check);
314 __ Branch(&loop, lt, a0, Operand(a1));
322 __ Dsubu(current_input_offset(), a2, end_of_input_address());
324 __ Ld(t1, register_location(start_reg));
325 __ Ld(a2, register_location(start_reg + 1));
326 __ Daddu(current_input_offset(), current_input_offset(), Operand(t1));
327 __ Dsubu(current_input_offset(), current_input_offset(), Operand(a2));
330 DCHECK(mode_ == UC16);
332 RegList regexp_registers_to_retain = current_input_offset().bit() |
333 current_character().bit() | backtrack_stackpointer().bit();
334 __ MultiPush(regexp_registers_to_retain);
336 int argument_count = 4;
337 __ PrepareCallCFunction(argument_count, a2);
350 __ Daddu(a0, a0, Operand(end_of_input_address()));
356 __ Daddu(a1, current_input_offset(), Operand(end_of_input_address()));
358 __ Dsubu(a1, a1, Operand(s3));
361 #ifdef V8_INTL_SUPPORT 363 __ mov(a3, zero_reg);
365 #endif // V8_INTL_SUPPORT 367 __ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate())));
371 AllowExternalCallThatCantCauseGC scope(masm_);
372 ExternalReference
function =
373 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate());
374 __ CallCFunction(
function, argument_count);
378 __ MultiPop(regexp_registers_to_retain);
379 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
380 __ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
383 BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg));
386 __ Dsubu(current_input_offset(), current_input_offset(), Operand(s3));
388 __ Daddu(current_input_offset(), current_input_offset(), Operand(s3));
392 __ bind(&fallthrough);
396 void RegExpMacroAssemblerMIPS::CheckNotBackReference(
int start_reg,
398 Label* on_no_match) {
403 __ Ld(a0, register_location(start_reg));
404 __ Ld(a1, register_location(start_reg + 1));
405 __ Dsubu(a1, a1, a0);
410 __ Branch(&fallthrough, eq, a1, Operand(zero_reg));
413 __ Ld(t1, MemOperand(frame_pointer(), kStringStartMinusOne));
414 __ Daddu(t1, t1, a1);
415 BranchOrBacktrack(on_no_match, le, current_input_offset(), Operand(t1));
417 __ Daddu(t1, a1, current_input_offset());
419 BranchOrBacktrack(on_no_match, gt, t1, Operand(zero_reg));
423 __ Daddu(a0, a0, Operand(end_of_input_address()));
424 __ Daddu(a2, end_of_input_address(), Operand(current_input_offset()));
426 __ Dsubu(a2, a2, Operand(a1));
428 __ Daddu(a1, a1, Operand(a0));
432 if (mode_ == LATIN1) {
433 __ Lbu(a3, MemOperand(a0, 0));
434 __ daddiu(a0, a0, char_size());
435 __ Lbu(a4, MemOperand(a2, 0));
436 __ daddiu(a2, a2, char_size());
438 DCHECK(mode_ == UC16);
439 __ Lhu(a3, MemOperand(a0, 0));
440 __ daddiu(a0, a0, char_size());
441 __ Lhu(a4, MemOperand(a2, 0));
442 __ daddiu(a2, a2, char_size());
444 BranchOrBacktrack(on_no_match, ne, a3, Operand(a4));
445 __ Branch(&loop, lt, a0, Operand(a1));
448 __ Dsubu(current_input_offset(), a2, end_of_input_address());
450 __ Ld(t1, register_location(start_reg));
451 __ Ld(a2, register_location(start_reg + 1));
452 __ Daddu(current_input_offset(), current_input_offset(), Operand(t1));
453 __ Dsubu(current_input_offset(), current_input_offset(), Operand(a2));
455 __ bind(&fallthrough);
459 void RegExpMacroAssemblerMIPS::CheckNotCharacter(
uint32_t c,
460 Label* on_not_equal) {
461 BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c));
465 void RegExpMacroAssemblerMIPS::CheckCharacterAfterAnd(
uint32_t c,
468 __ And(a0, current_character(), Operand(mask));
469 Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c);
470 BranchOrBacktrack(on_equal, eq, a0, rhs);
474 void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterAnd(
uint32_t c,
476 Label* on_not_equal) {
477 __ And(a0, current_character(), Operand(mask));
478 Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c);
479 BranchOrBacktrack(on_not_equal, ne, a0, rhs);
483 void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterMinusAnd(
487 Label* on_not_equal) {
488 DCHECK_GT(String::kMaxUtf16CodeUnit, minus);
489 __ Dsubu(a0, current_character(), Operand(minus));
490 __ And(a0, a0, Operand(mask));
491 BranchOrBacktrack(on_not_equal, ne, a0, Operand(c));
495 void RegExpMacroAssemblerMIPS::CheckCharacterInRange(
498 Label* on_in_range) {
499 __ Dsubu(a0, current_character(), Operand(from));
501 BranchOrBacktrack(on_in_range, ls, a0, Operand(to - from));
505 void RegExpMacroAssemblerMIPS::CheckCharacterNotInRange(
508 Label* on_not_in_range) {
509 __ Dsubu(a0, current_character(), Operand(from));
511 BranchOrBacktrack(on_not_in_range, hi, a0, Operand(to - from));
515 void RegExpMacroAssemblerMIPS::CheckBitInTable(
516 Handle<ByteArray> table,
518 __ li(a0, Operand(table));
519 if (mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) {
520 __ And(a1, current_character(), Operand(kTableSize - 1));
521 __ Daddu(a0, a0, a1);
523 __ Daddu(a0, a0, current_character());
526 __ Lbu(a0, FieldMemOperand(a0, ByteArray::kHeaderSize));
527 BranchOrBacktrack(on_bit_set, ne, a0, Operand(zero_reg));
531 bool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(uc16 type,
532 Label* on_no_match) {
538 if (mode_ == LATIN1) {
541 __ Branch(&success, eq, current_character(), Operand(
' '));
543 __ Dsubu(a0, current_character(), Operand(
'\t'));
544 __ Branch(&success, ls, a0, Operand(
'\r' -
'\t'));
546 BranchOrBacktrack(on_no_match, ne, a0, Operand(0x00A0 -
'\t'));
556 __ Dsubu(a0, current_character(), Operand(
'0'));
557 BranchOrBacktrack(on_no_match, hi, a0, Operand(
'9' -
'0'));
561 __ Dsubu(a0, current_character(), Operand(
'0'));
562 BranchOrBacktrack(on_no_match, ls, a0, Operand(
'9' -
'0'));
566 __ Xor(a0, current_character(), Operand(0x01));
568 __ Dsubu(a0, a0, Operand(0x0B));
569 BranchOrBacktrack(on_no_match, ls, a0, Operand(0x0C - 0x0B));
574 __ Dsubu(a0, a0, Operand(0x2028 - 0x0B));
575 BranchOrBacktrack(on_no_match, ls, a0, Operand(1));
581 __ Xor(a0, current_character(), Operand(0x01));
583 __ Dsubu(a0, a0, Operand(0x0B));
584 if (mode_ == LATIN1) {
585 BranchOrBacktrack(on_no_match, hi, a0, Operand(0x0C - 0x0B));
588 BranchOrBacktrack(&done, ls, a0, Operand(0x0C - 0x0B));
592 __ Dsubu(a0, a0, Operand(0x2028 - 0x0B));
593 BranchOrBacktrack(on_no_match, hi, a0, Operand(1));
599 if (mode_ != LATIN1) {
601 BranchOrBacktrack(on_no_match, hi, current_character(), Operand(
'z'));
603 ExternalReference map = ExternalReference::re_word_character_map(isolate());
604 __ li(a0, Operand(map));
605 __ Daddu(a0, a0, current_character());
606 __ Lbu(a0, MemOperand(a0, 0));
607 BranchOrBacktrack(on_no_match, eq, a0, Operand(zero_reg));
612 if (mode_ != LATIN1) {
614 __ Branch(&done, hi, current_character(), Operand(
'z'));
616 ExternalReference map = ExternalReference::re_word_character_map(isolate());
617 __ li(a0, Operand(map));
618 __ Daddu(a0, a0, current_character());
619 __ Lbu(a0, MemOperand(a0, 0));
620 BranchOrBacktrack(on_no_match, ne, a0, Operand(zero_reg));
621 if (mode_ != LATIN1) {
636 void RegExpMacroAssemblerMIPS::Fail() {
637 __ li(v0, Operand(FAILURE));
638 __ jmp(&exit_label_);
642 Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
644 if (masm_->has_exception()) {
648 __ bind_to(&entry_label_, internal_failure_label_.pos());
654 __ bind(&entry_label_);
658 FrameScope scope(masm_, StackFrame::MANUAL);
668 RegList registers_to_retain = s0.bit() | s1.bit() | s2.bit() |
669 s3.bit() | s4.bit() | s5.bit() | s6.bit() | s7.bit() | fp.bit();
670 RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit();
672 argument_registers |= a4.bit() | a5.bit() | a6.bit() | a7.bit();
674 __ MultiPush(argument_registers | registers_to_retain | ra.bit());
678 __ Daddu(frame_pointer(), sp, Operand(8 * kPointerSize));
679 __ mov(a0, zero_reg);
684 Label stack_limit_hit;
687 ExternalReference stack_limit =
688 ExternalReference::address_of_stack_limit(masm_->isolate());
689 __ li(a0, Operand(stack_limit));
690 __ Ld(a0, MemOperand(a0));
691 __ Dsubu(a0, sp, a0);
693 __ Branch(&stack_limit_hit, le, a0, Operand(zero_reg));
696 __ Branch(&stack_ok, hs, a0, Operand(num_registers_ * kPointerSize));
699 __ li(v0, Operand(EXCEPTION));
702 __ bind(&stack_limit_hit);
703 CallCheckStackGuardState(a0);
705 __ Branch(&return_v0, ne, v0, Operand(zero_reg));
709 __ Dsubu(sp, sp, Operand(num_registers_ * kPointerSize));
711 __ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
713 __ Ld(a0, MemOperand(frame_pointer(), kInputStart));
715 __ Dsubu(current_input_offset(), a0, end_of_input_address());
718 __ Ld(a1, MemOperand(frame_pointer(), kStartIndex));
719 __ Dsubu(a0, current_input_offset(), Operand(char_size()));
720 __ dsll(t1, a1, (mode_ == UC16) ? 1 : 0);
721 __ Dsubu(a0, a0, t1);
724 __ Sd(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
727 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
729 Label load_char_start_regexp, start_regexp;
731 __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
732 __ li(current_character(), Operand(
'\n'));
733 __ jmp(&start_regexp);
736 __ bind(&load_char_start_regexp);
738 LoadCurrentCharacterUnchecked(-1, 1);
739 __ bind(&start_regexp);
742 if (num_saved_registers_ > 0) {
744 if (num_saved_registers_ > 8) {
746 __ Daddu(a1, frame_pointer(), Operand(kRegisterZero));
747 __ li(a2, Operand(num_saved_registers_));
750 __ Sd(a0, MemOperand(a1));
751 __ Daddu(a1, a1, Operand(-kPointerSize));
752 __ Dsubu(a2, a2, Operand(1));
753 __ Branch(&init_loop, ne, a2, Operand(zero_reg));
755 for (
int i = 0;
i < num_saved_registers_;
i++) {
756 __ Sd(a0, register_location(
i));
762 __ Ld(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd));
764 __ jmp(&start_label_);
768 if (success_label_.is_linked()) {
770 __ bind(&success_label_);
771 if (num_saved_registers_ > 0) {
773 __ Ld(a1, MemOperand(frame_pointer(), kInputStart));
774 __ Ld(a0, MemOperand(frame_pointer(), kRegisterOutput));
775 __ Ld(a2, MemOperand(frame_pointer(), kStartIndex));
776 __ Dsubu(a1, end_of_input_address(), a1);
782 __ Daddu(a1, a1, Operand(a2));
785 DCHECK_EQ(0, num_saved_registers_ % 2);
789 for (
int i = 0;
i < num_saved_registers_;
i += 2) {
790 __ Ld(a2, register_location(
i));
791 __ Ld(a3, register_location(
i + 1));
792 if (
i == 0 && global_with_zero_length_check()) {
798 __ Daddu(a2, a2, a1);
800 __ Daddu(a3, a3, a1);
802 __ Daddu(a2, a1, Operand(a2));
803 __ Daddu(a3, a1, Operand(a3));
806 __ Sw(a2, MemOperand(a0));
807 __ Daddu(a0, a0, kIntSize);
808 __ Sw(a3, MemOperand(a0));
809 __ Daddu(a0, a0, kIntSize);
815 __ Ld(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
816 __ Ld(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
817 __ Ld(a2, MemOperand(frame_pointer(), kRegisterOutput));
820 __ Sd(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
823 __ Dsubu(a1, a1, num_saved_registers_);
826 __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_));
828 __ Sd(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
830 __ Daddu(a2, a2, num_saved_registers_ * kIntSize);
831 __ Sd(a2, MemOperand(frame_pointer(), kRegisterOutput));
834 __ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
836 if (global_with_zero_length_check()) {
841 &load_char_start_regexp, ne, current_input_offset(), Operand(t3));
843 __ Branch(&exit_label_, eq, current_input_offset(),
848 __ Daddu(current_input_offset(),
849 current_input_offset(),
850 Operand((mode_ == UC16) ? 2 : 1));
851 if (global_unicode()) CheckNotInSurrogatePair(0, &advance);
854 __ Branch(&load_char_start_regexp);
856 __ li(v0, Operand(SUCCESS));
860 __ bind(&exit_label_);
862 __ Ld(v0, MemOperand(frame_pointer(), kSuccessfulCaptures));
867 __ mov(sp, frame_pointer());
869 __ MultiPop(registers_to_retain | ra.bit());
873 if (backtrack_label_.is_linked()) {
874 __ bind(&backtrack_label_);
878 Label exit_with_exception;
881 if (check_preempt_label_.is_linked()) {
882 SafeCallTarget(&check_preempt_label_);
884 RegList regexp_registers_to_retain = current_input_offset().bit() |
885 current_character().bit() | backtrack_stackpointer().bit();
886 __ MultiPush(regexp_registers_to_retain);
887 CallCheckStackGuardState(a0);
888 __ MultiPop(regexp_registers_to_retain);
891 __ Branch(&return_v0, ne, v0, Operand(zero_reg));
894 __ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
895 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
900 if (stack_overflow_label_.is_linked()) {
901 SafeCallTarget(&stack_overflow_label_);
904 RegList regexp_registers = current_input_offset().bit() |
905 current_character().bit();
906 __ MultiPush(regexp_registers);
909 static const int num_arguments = 3;
910 __ PrepareCallCFunction(num_arguments, a0);
911 __ mov(a0, backtrack_stackpointer());
912 __ Daddu(a1, frame_pointer(), Operand(kStackHighEnd));
913 __ li(a2, Operand(ExternalReference::isolate_address(masm_->isolate())));
914 ExternalReference grow_stack =
915 ExternalReference::re_grow_stack(masm_->isolate());
916 __ CallCFunction(grow_stack, num_arguments);
918 __ MultiPop(regexp_registers);
921 __ Branch(&exit_with_exception, eq, v0, Operand(zero_reg));
923 __ mov(backtrack_stackpointer(), v0);
925 __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
926 __ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
930 if (exit_with_exception.is_linked()) {
932 __ bind(&exit_with_exception);
934 __ li(v0, Operand(EXCEPTION));
940 masm_->GetCode(isolate(), &code_desc);
941 Handle<Code> code = isolate()->factory()->NewCode(code_desc, Code::REGEXP,
942 masm_->CodeObject());
943 LOG(masm_->isolate(),
944 RegExpCodeCreateEvent(AbstractCode::cast(*code), *source));
945 return Handle<HeapObject>::cast(code);
949 void RegExpMacroAssemblerMIPS::GoTo(Label* to) {
959 void RegExpMacroAssemblerMIPS::IfRegisterGE(
int reg,
962 __ Ld(a0, register_location(reg));
963 BranchOrBacktrack(if_ge, ge, a0, Operand(comparand));
967 void RegExpMacroAssemblerMIPS::IfRegisterLT(
int reg,
970 __ Ld(a0, register_location(reg));
971 BranchOrBacktrack(if_lt, lt, a0, Operand(comparand));
975 void RegExpMacroAssemblerMIPS::IfRegisterEqPos(
int reg,
977 __ Ld(a0, register_location(reg));
978 BranchOrBacktrack(if_eq, eq, a0, Operand(current_input_offset()));
982 RegExpMacroAssembler::IrregexpImplementation
983 RegExpMacroAssemblerMIPS::Implementation() {
984 return kMIPSImplementation;
988 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(
int cp_offset,
989 Label* on_end_of_input,
992 DCHECK(cp_offset < (1<<30));
994 if (cp_offset >= 0) {
995 CheckPosition(cp_offset + characters - 1, on_end_of_input);
997 CheckPosition(cp_offset, on_end_of_input);
1000 LoadCurrentCharacterUnchecked(cp_offset, characters);
1004 void RegExpMacroAssemblerMIPS::PopCurrentPosition() {
1005 Pop(current_input_offset());
1009 void RegExpMacroAssemblerMIPS::PopRegister(
int register_index) {
1011 __ Sd(a0, register_location(register_index));
1015 void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) {
1016 if (label->is_bound()) {
1017 int target = label->pos();
1018 __ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag));
1020 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
1021 Label after_constant;
1022 __ Branch(&after_constant);
1023 int offset = masm_->pc_offset();
1024 int cp_offset = offset + Code::kHeaderSize - kHeapObjectTag;
1026 masm_->label_at_put(label, offset);
1027 __ bind(&after_constant);
1028 if (is_int16(cp_offset)) {
1029 __ Lwu(a0, MemOperand(code_pointer(), cp_offset));
1031 __ Daddu(a0, code_pointer(), cp_offset);
1032 __ Lwu(a0, MemOperand(a0, 0));
1040 void RegExpMacroAssemblerMIPS::PushCurrentPosition() {
1041 Push(current_input_offset());
1045 void RegExpMacroAssemblerMIPS::PushRegister(
int register_index,
1046 StackCheckFlag check_stack_limit) {
1047 __ Ld(a0, register_location(register_index));
1049 if (check_stack_limit) CheckStackLimit();
1053 void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(
int reg) {
1054 __ Ld(current_input_offset(), register_location(reg));
1058 void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(
int reg) {
1059 __ Ld(backtrack_stackpointer(), register_location(reg));
1060 __ Ld(a0, MemOperand(frame_pointer(), kStackHighEnd));
1061 __ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0));
1065 void RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(
int by) {
1066 Label after_position;
1067 __ Branch(&after_position,
1069 current_input_offset(),
1070 Operand(-by * char_size()));
1071 __ li(current_input_offset(), -by * char_size());
1075 LoadCurrentCharacterUnchecked(-1, 1);
1076 __ bind(&after_position);
1080 void RegExpMacroAssemblerMIPS::SetRegister(
int register_index,
int to) {
1081 DCHECK(register_index >= num_saved_registers_);
1082 __ li(a0, Operand(to));
1083 __ Sd(a0, register_location(register_index));
1087 bool RegExpMacroAssemblerMIPS::Succeed() {
1088 __ jmp(&success_label_);
1093 void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(
int reg,
1095 if (cp_offset == 0) {
1096 __ Sd(current_input_offset(), register_location(reg));
1098 __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1099 __ Sd(a0, register_location(reg));
1104 void RegExpMacroAssemblerMIPS::ClearRegisters(
int reg_from,
int reg_to) {
1105 DCHECK(reg_from <= reg_to);
1106 __ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
1107 for (
int reg = reg_from; reg <= reg_to; reg++) {
1108 __ Sd(a0, register_location(reg));
1113 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(
int reg) {
1114 __ Ld(a1, MemOperand(frame_pointer(), kStackHighEnd));
1115 __ Dsubu(a0, backtrack_stackpointer(), a1);
1116 __ Sd(a0, register_location(reg));
1120 bool RegExpMacroAssemblerMIPS::CanReadUnaligned() {
1127 void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) {
1128 int stack_alignment = base::OS::ActivationFrameAlignment();
1131 __ mov(scratch, sp);
1132 __ Dsubu(sp, sp, Operand(kPointerSize));
1133 DCHECK(base::bits::IsPowerOfTwo(stack_alignment));
1134 __ And(sp, sp, Operand(-stack_alignment));
1135 __ Sd(scratch, MemOperand(sp));
1137 __ mov(a2, frame_pointer());
1139 __ li(a1, Operand(masm_->CodeObject()), CONSTANT_SIZE);
1142 DCHECK(IsAligned(stack_alignment, kPointerSize));
1143 __ Dsubu(sp, sp, Operand(stack_alignment));
1158 ExternalReference stack_guard_check =
1159 ExternalReference::re_check_stack_guard_state(masm_->isolate());
1160 __ li(t9, Operand(stack_guard_check));
1161 DirectCEntryStub stub(isolate());
1162 stub.GenerateCall(masm_, t9);
1175 __ Ld(sp, MemOperand(sp, stack_alignment + kCArgsSlotsSize));
1177 __ li(code_pointer(), Operand(masm_->CodeObject()));
1182 template <
typename T>
1183 static T& frame_entry(Address re_frame,
int frame_offset) {
1184 return reinterpret_cast<T&
>(Memory<int32_t>(re_frame + frame_offset));
1188 template <
typename T>
1189 static T* frame_entry_address(Address re_frame,
int frame_offset) {
1190 return reinterpret_cast<T*
>(re_frame + frame_offset);
1193 int64_t RegExpMacroAssemblerMIPS::CheckStackGuardState(Address* return_address,
1196 Code re_code = Code::cast(ObjectPtr(raw_code));
1197 return NativeRegExpMacroAssembler::CheckStackGuardState(
1198 frame_entry<Isolate*>(re_frame, kIsolate),
1199 static_cast<int>(frame_entry<int64_t>(re_frame, kStartIndex)),
1200 frame_entry<int64_t>(re_frame, kDirectCall) == 1, return_address, re_code,
1201 frame_entry_address<Address>(re_frame, kInputString),
1202 frame_entry_address<const byte*>(re_frame, kInputStart),
1203 frame_entry_address<const byte*>(re_frame, kInputEnd));
1207 MemOperand RegExpMacroAssemblerMIPS::register_location(
int register_index) {
1208 DCHECK(register_index < (1<<30));
1209 if (num_registers_ <= register_index) {
1210 num_registers_ = register_index + 1;
1212 return MemOperand(frame_pointer(),
1213 kRegisterZero - register_index * kPointerSize);
1217 void RegExpMacroAssemblerMIPS::CheckPosition(
int cp_offset,
1218 Label* on_outside_input) {
1219 if (cp_offset >= 0) {
1220 BranchOrBacktrack(on_outside_input, ge, current_input_offset(),
1221 Operand(-cp_offset * char_size()));
1223 __ Ld(a1, MemOperand(frame_pointer(), kStringStartMinusOne));
1224 __ Daddu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1225 BranchOrBacktrack(on_outside_input, le, a0, Operand(a1));
1230 void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to,
1231 Condition condition,
1233 const Operand& rt) {
1234 if (condition == al) {
1235 if (to ==
nullptr) {
1242 if (to ==
nullptr) {
1243 __ Branch(&backtrack_label_, condition, rs, rt);
1246 __ Branch(to, condition, rs, rt);
1250 void RegExpMacroAssemblerMIPS::SafeCall(Label* to,
1253 const Operand& rt) {
1254 __ BranchAndLink(to, cond, rs, rt);
1258 void RegExpMacroAssemblerMIPS::SafeReturn() {
1260 __ Daddu(t1, ra, Operand(masm_->CodeObject()));
1265 void RegExpMacroAssemblerMIPS::SafeCallTarget(Label* name) {
1267 __ Dsubu(ra, ra, Operand(masm_->CodeObject()));
1272 void RegExpMacroAssemblerMIPS::Push(Register source) {
1273 DCHECK(source != backtrack_stackpointer());
1274 __ Daddu(backtrack_stackpointer(),
1275 backtrack_stackpointer(),
1276 Operand(-kIntSize));
1277 __ Sw(source, MemOperand(backtrack_stackpointer()));
1281 void RegExpMacroAssemblerMIPS::Pop(Register target) {
1282 DCHECK(target != backtrack_stackpointer());
1283 __ Lw(target, MemOperand(backtrack_stackpointer()));
1284 __ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), kIntSize);
1288 void RegExpMacroAssemblerMIPS::CheckPreemption() {
1290 ExternalReference stack_limit =
1291 ExternalReference::address_of_stack_limit(masm_->isolate());
1292 __ li(a0, Operand(stack_limit));
1293 __ Ld(a0, MemOperand(a0));
1294 SafeCall(&check_preempt_label_, ls, sp, Operand(a0));
1298 void RegExpMacroAssemblerMIPS::CheckStackLimit() {
1299 ExternalReference stack_limit =
1300 ExternalReference::address_of_regexp_stack_limit(masm_->isolate());
1302 __ li(a0, Operand(stack_limit));
1303 __ Ld(a0, MemOperand(a0));
1304 SafeCall(&stack_overflow_label_, ls, backtrack_stackpointer(), Operand(a0));
1308 void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(
int cp_offset,
1310 Register offset = current_input_offset();
1311 if (cp_offset != 0) {
1313 __ Daddu(t3, current_input_offset(), Operand(cp_offset * char_size()));
1318 DCHECK_EQ(1, characters);
1319 __ Daddu(t1, end_of_input_address(), Operand(offset));
1320 if (mode_ == LATIN1) {
1321 __ Lbu(current_character(), MemOperand(t1, 0));
1323 DCHECK(mode_ == UC16);
1324 __ Lhu(current_character(), MemOperand(t1, 0));
1330 #endif // V8_INTERPRETED_REGEXP 1335 #endif // V8_TARGET_ARCH_MIPS64