5#if V8_TARGET_ARCH_MIPS64
29#if V8_ENABLE_WEBASSEMBLY
38#define __ ACCESS_MASM(masm)
41 int formal_parameter_count,
Address address) {
49enum class ArgumentsElementType {
54void Generate_PushArguments(MacroAssembler* masm, Register array, Register argc,
55 Register scratch, Register scratch2,
56 ArgumentsElementType element_type) {
64 if (element_type == ArgumentsElementType::kHandle) {
69 __ Daddu(scratch, scratch, Operand(-1));
73void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) {
85 FrameScope scope(masm, StackFrame::CONSTRUCT);
97 Generate_PushArguments(masm, t2, a0, t3, t0, ArgumentsElementType::kRaw);
99 __ PushRoot(RootIndex::kTheHoleValue);
115 __ DropArguments(t3);
122void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
134 Label post_instantiation_deopt_entry, not_create_implicit_receiver;
135 __ EnterFrame(StackFrame::CONSTRUCT);
139 __ PushRoot(RootIndex::kUndefinedValue);
152 __ DecodeField<SharedFunctionInfo::FunctionKindBits>(t2);
156 ¬_create_implicit_receiver);
159 __ CallBuiltin(Builtin::kFastNewObject);
160 __ Branch(&post_instantiation_deopt_entry);
163 __ bind(¬_create_implicit_receiver);
164 __ LoadRoot(v0, RootIndex::kTheHoleValue);
175 masm->isolate()->heap()->SetConstructStubCreateDeoptPCOffset(
177 __ bind(&post_instantiation_deopt_entry);
209 Label stack_overflow;
210 __ StackOverflowCheck(a0, t0, t1, &stack_overflow);
220 Generate_PushArguments(masm, t2, a0, t0, t1, ArgumentsElementType::kRaw);
232 Label use_receiver, do_throw, leave_and_return, check_receiver;
235 __ JumpIfNotRoot(v0, RootIndex::kUndefinedValue, &check_receiver);
242 __ bind(&use_receiver);
244 __ JumpIfRoot(v0, RootIndex::kTheHoleValue, &do_throw);
246 __ bind(&leave_and_return);
250 __ LeaveFrame(StackFrame::CONSTRUCT);
253 __ DropArguments(a1);
256 __ bind(&check_receiver);
257 __ JumpIfSmi(v0, &use_receiver);
261 __ GetObjectType(v0, t2, t2);
262 static_assert(LAST_JS_RECEIVER_TYPE ==
LAST_TYPE);
264 Operand(FIRST_JS_RECEIVER_TYPE));
265 __ Branch(&use_receiver);
270 __ CallRuntime(Runtime::kThrowConstructorReturnedNonObject);
273 __ bind(&stack_overflow);
276 __ CallRuntime(Runtime::kThrowStackOverflow);
280void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
281 Generate_JSBuiltinsConstructStubHelper(masm);
289 __ DecodeField<Code::KindField>(scratch);
290 __ Assert(
eq, AbortReason::kExpectedBaselineData, scratch,
291 Operand(
static_cast<int>(CodeKind::BASELINE)));
297 MacroAssembler* masm, Register sfi, Register bytecode, Register scratch1,
298 Label* is_baseline, Label* is_unavailable) {
306 __ GetObjectType(data, scratch1, scratch1);
311 __ Branch(¬_baseline,
ne, scratch1, Operand(CODE_TYPE));
313 __ Branch(is_baseline);
314 __ bind(¬_baseline);
316 __ Branch(is_baseline,
eq, scratch1, Operand(CODE_TYPE));
320 __ Branch(&done,
eq, scratch1, Operand(BYTECODE_ARRAY_TYPE));
322 __ Branch(is_unavailable,
ne, scratch1, Operand(INTERPRETER_DATA_TYPE));
328void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
336 __ RecordWriteField(a1, JSGeneratorObject::kInputOrDebugPosOffset, v0, a3,
339 __ AssertGeneratorObject(a1);
346 Label prepare_step_in_if_stepping, prepare_step_in_suspended_generator;
347 Label stepping_prepared;
348 ExternalReference debug_hook =
349 ExternalReference::debug_hook_on_function_call_address(masm->isolate());
350 __ li(a6, debug_hook);
352 __ Branch(&prepare_step_in_if_stepping,
ne, a6, Operand(zero_reg));
355 ExternalReference debug_suspended_generator =
356 ExternalReference::debug_suspended_generator_address(masm->isolate());
357 __ li(a6, debug_suspended_generator);
359 __ Branch(&prepare_step_in_suspended_generator,
eq, a1, Operand(a6));
360 __ bind(&stepping_prepared);
364 Label stack_overflow;
366 MacroAssembler::StackLimitKind::kRealStackLimit);
381#if V8_ENABLE_LEAPTIERING
384 __ Lw(dispatch_handle,
386 __ LoadEntrypointAndParameterCountFromJSDispatchTable(code, argc,
387 dispatch_handle, t3);
392 __ slt(t3, argc, t1);
393 __ movn(argc, t1, t3);
398 argc, SharedFunctionInfo::kFormalParameterCountOffset));
401 Label done_loop, loop;
404 a1, JSGeneratorObject::kParametersAndRegistersOffset));
406 __ Dsubu(a3, a3, Operand(1));
407 __ Branch(&done_loop,
lt, a3, Operand(zero_reg));
421 Label is_baseline, is_unavailable, ok;
427 __ bind(&is_unavailable);
428 __ Abort(AbortReason::kMissingBytecodeArray);
430 __ bind(&is_baseline);
431 __ GetObjectType(a3, a3, a3);
432 __ Assert(
eq, AbortReason::kMissingBytecodeArray, a3, Operand(CODE_TYPE));
444#if V8_ENABLE_LEAPTIERING
448 __ JumpJSFunction(a1);
452 __ bind(&prepare_step_in_if_stepping);
454 FrameScope scope(masm, StackFrame::INTERNAL);
457 __ PushRoot(RootIndex::kTheHoleValue);
458 __ CallRuntime(Runtime::kDebugOnFunctionCall);
464 __ bind(&prepare_step_in_suspended_generator);
466 FrameScope scope(masm, StackFrame::INTERNAL);
468 __ CallRuntime(Runtime::kDebugPrepareStepInSuspendedGenerator);
474 __ bind(&stack_overflow);
476 FrameScope scope(masm, StackFrame::INTERNAL);
477 __ CallRuntime(Runtime::kThrowStackOverflow);
482void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
483 FrameScope scope(masm, StackFrame::INTERNAL);
485 __ CallRuntime(Runtime::kThrowConstructedNonConstructable);
490 Register scratch1, Register scratch2) {
495 __ LoadStackLimit(scratch1, MacroAssembler::StackLimitKind::kRealStackLimit);
498 __ dsubu(scratch1, sp, scratch1);
501 __ Branch(&okay,
gt, scratch1, Operand(scratch2));
504 __ CallRuntime(Runtime::kThrowStackOverflow);
522 Label
invoke, handler_entry, exit;
525 NoRootArrayScope no_root_array(masm);
563 __ li(s1, Operand(-1));
567 IsolateAddressId::kCEntryFPAddress, masm->isolate());
568 __ li(s5, c_entry_fp);
570 __ Push(s1, s2, s3, s4);
578 __ LoadIsolateField(s1, IsolateFieldId::kFastCCallCallerFP);
581 __ LoadIsolateField(s1, IsolateFieldId::kFastCCallCallerPC);
609 Label non_outermost_js;
611 IsolateAddressId::kJSEntrySPAddress, masm->isolate());
612 __ li(s1, js_entry_sp);
614 __ Branch(&non_outermost_js,
ne, s2, Operand(zero_reg));
620 __ bind(&non_outermost_js);
628 __ bind(&handler_entry);
632 masm->isolate()->builtins()->SetJSEntryHandlerOffset(handler_entry.pos());
641 __ LoadRoot(v0, RootIndex::kException);
647 __ PushStackHandler();
678 __ CallBuiltin(entry_trampoline);
681 __ PopStackHandler();
685 Label non_outermost_js_2;
687 __ Branch(&non_outermost_js_2,
ne, a5,
689 __ li(a5, js_entry_sp);
691 __ bind(&non_outermost_js_2);
695 __ LoadIsolateField(a6, IsolateFieldId::kFastCCallCallerFP);
697 __ LoadIsolateField(a6, IsolateFieldId::kFastCCallCallerPC);
719void Builtins::Generate_JSEntry(MacroAssembler* masm) {
720 Generate_JSEntryVariant(masm, StackFrame::ENTRY, Builtin::kJSEntryTrampoline);
723void Builtins::Generate_JSConstructEntry(MacroAssembler* masm) {
724 Generate_JSEntryVariant(masm, StackFrame::CONSTRUCT_ENTRY,
725 Builtin::kJSConstructEntryTrampoline);
728void Builtins::Generate_JSRunMicrotasksEntry(MacroAssembler* masm) {
729 Generate_JSEntryVariant(masm, StackFrame::ENTRY,
730 Builtin::kRunMicrotasksTrampoline);
745 FrameScope scope(masm, StackFrame::INTERNAL);
749 IsolateAddressId::kContextAddress, masm->isolate());
750 __ li(
cp, context_address);
763 Generate_PushArguments(masm, a5, a4, s1, s2, ArgumentsElementType::kHandle);
777 __ LoadRoot(a4, RootIndex::kUndefinedValue);
789 __ CallBuiltin(builtin);
796void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
800void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
804void Builtins::Generate_RunMicrotasksTrampoline(MacroAssembler* masm) {
807 __ TailCallBuiltin(Builtin::kRunMicrotasks);
820 Register actual_params_size = scratch2;
822 __ Ld(actual_params_size,
827 __ slt(t2, params_size, actual_params_size);
828 __ movn(params_size, actual_params_size, t2);
831 __ LeaveFrame(StackFrame::INTERPRETED);
834 __ DropArguments(params_size);
843 Register bytecode_array,
844 Register bytecode_offset,
845 Register bytecode, Register scratch1,
846 Register scratch2, Register scratch3,
848 Register bytecode_size_table = scratch1;
854 Register original_bytecode_offset = scratch3;
856 bytecode_size_table, original_bytecode_offset));
857 __ Move(original_bytecode_offset, bytecode_offset);
858 __ li(bytecode_size_table, ExternalReference::bytecode_size_table_address());
861 Label process_bytecode, extra_wide;
862 static_assert(0 ==
static_cast<int>(interpreter::Bytecode::kWide));
863 static_assert(1 ==
static_cast<int>(interpreter::Bytecode::kExtraWide));
864 static_assert(2 ==
static_cast<int>(interpreter::Bytecode::kDebugBreakWide));
866 static_cast<int>(interpreter::Bytecode::kDebugBreakExtraWide));
867 __ Branch(&process_bytecode,
hi, bytecode, Operand(3));
868 __ And(scratch2, bytecode, Operand(1));
869 __ Branch(&extra_wide,
ne, scratch2, Operand(zero_reg));
872 __ Daddu(bytecode_offset, bytecode_offset, Operand(1));
873 __ Daddu(scratch2, bytecode_array, bytecode_offset);
875 __ Daddu(bytecode_size_table, bytecode_size_table,
877 __ jmp(&process_bytecode);
879 __ bind(&extra_wide);
881 __ Daddu(bytecode_offset, bytecode_offset, Operand(1));
882 __ Daddu(scratch2, bytecode_array, bytecode_offset);
884 __ Daddu(bytecode_size_table, bytecode_size_table,
887 __ bind(&process_bytecode);
890#define JUMP_IF_EQUAL(NAME) \
891 __ Branch(if_return, eq, bytecode, \
892 Operand(static_cast<int>(interpreter::Bytecode::k##NAME)));
898 Label
end, not_jump_loop;
899 __ Branch(¬_jump_loop,
ne, bytecode,
900 Operand(
static_cast<int>(interpreter::Bytecode::kJumpLoop)));
903 __ Move(bytecode_offset, original_bytecode_offset);
906 __ bind(¬_jump_loop);
908 __ Daddu(scratch2, bytecode_size_table, bytecode);
910 __ Daddu(bytecode_offset, bytecode_offset, scratch2);
917void ResetSharedFunctionInfoAge(MacroAssembler* masm, Register sfi) {
921void ResetJSFunctionAge(MacroAssembler* masm, Register js_function,
925 ResetSharedFunctionInfoAge(masm, scratch);
928void ResetFeedbackVectorOsrUrgency(MacroAssembler* masm,
929 Register feedback_vector, Register scratch) {
933 __ And(scratch, scratch, Operand(~FeedbackVector::OsrUrgencyBits::kMask));
940void Builtins::Generate_BaselineOutOfLinePrologue(MacroAssembler* masm) {
941 UseScratchRegisterScope temps(masm);
942 temps.Include({s1, s2, s3});
945 Register closure = descriptor.GetRegisterParameter(
946 BaselineOutOfLinePrologueDescriptor::kClosure);
948 Register feedback_cell = temps.Acquire();
949 Register feedback_vector = temps.Acquire();
952 __ Ld(feedback_vector,
955 UseScratchRegisterScope temps(masm);
957 __ AssertFeedbackVector(feedback_vector, scratch);
960#ifndef V8_ENABLE_LEAPTIERING
962 Label flags_need_processing;
965 UseScratchRegisterScope temps(masm);
966 flags = temps.Acquire();
969 __ LoadFeedbackVectorFlagsAndJumpIfNeedsProcessing(
970 flags, feedback_vector, CodeKind::BASELINE, &flags_need_processing);
975 UseScratchRegisterScope temps(masm);
976 ResetFeedbackVectorOsrUrgency(masm, feedback_vector, temps.Acquire());
980 UseScratchRegisterScope temps(masm);
981 Register invocation_count = temps.Acquire();
982 __ Lw(invocation_count,
984 FeedbackVector::kInvocationCountOffset));
985 __ Addu(invocation_count, invocation_count, Operand(1));
986 __ Sw(invocation_count,
988 FeedbackVector::kInvocationCountOffset));
997 Register callee_context = descriptor.GetRegisterParameter(
998 BaselineOutOfLinePrologueDescriptor::kCalleeContext);
999 Register callee_js_function = descriptor.GetRegisterParameter(
1000 BaselineOutOfLinePrologueDescriptor::kClosure);
1002 UseScratchRegisterScope temps(masm);
1003 ResetJSFunctionAge(masm, callee_js_function, temps.Acquire());
1005 __ Push(callee_context, callee_js_function);
1009 Register argc = descriptor.GetRegisterParameter(
1010 BaselineOutOfLinePrologueDescriptor::kJavaScriptCallArgCount);
1013 Register bytecode_array = descriptor.GetRegisterParameter(
1014 BaselineOutOfLinePrologueDescriptor::kInterpreterBytecodeArray);
1015 __ Push(argc, bytecode_array, feedback_cell, feedback_vector);
1018 UseScratchRegisterScope temps(masm);
1019 Register invocation_count = temps.Acquire();
1020 __ AssertFeedbackVector(feedback_vector, invocation_count);
1024 Label call_stack_guard;
1025 Register frame_size = descriptor.GetRegisterParameter(
1026 BaselineOutOfLinePrologueDescriptor::kStackFrameSize);
1034 UseScratchRegisterScope temps(masm);
1035 Register sp_minus_frame_size = temps.Acquire();
1036 __ Dsubu(sp_minus_frame_size, sp, frame_size);
1037 Register interrupt_limit = temps.Acquire();
1038 __ LoadStackLimit(interrupt_limit,
1039 MacroAssembler::StackLimitKind::kInterruptStackLimit);
1040 __ Branch(&call_stack_guard,
Uless, sp_minus_frame_size,
1041 Operand(interrupt_limit));
1048#ifndef V8_ENABLE_LEAPTIERING
1049 __ bind(&flags_need_processing);
1052 UseScratchRegisterScope temps(masm);
1053 temps.Exclude(flags);
1057 __ OptimizeCodeOrTailCallOptimizedCodeSlot(flags, feedback_vector);
1062 __ bind(&call_stack_guard);
1065 FrameScope frame_scope(masm, StackFrame::INTERNAL);
1068#ifdef V8_ENABLE_LEAPTIERING
1070 static_assert(kJSDispatchHandleShift > 0);
1073 __ SmiTag(frame_size);
1074 __ Push(frame_size);
1075 __ CallRuntime(Runtime::kStackGuardWithGap);
1076#ifdef V8_ENABLE_LEAPTIERING
1082 temps.Exclude({s1, s2, s3});
1086void Builtins::Generate_BaselineOutOfLinePrologueDeopt(MacroAssembler* masm) {
1099 __ LeaveFrame(StackFrame::BASELINE);
1102 __ TailCallBuiltin(Builtin::kInterpreterEntryTrampoline);
1121 MacroAssembler* masm, InterpreterEntryTrampolineMode mode) {
1128 ResetSharedFunctionInfoAge(masm, sfi);
1132 Label is_baseline, compile_lazy;
1137 Label push_stack_frame;
1139 __ LoadFeedbackVector(feedback_vector, closure, a5, &push_stack_frame);
1142#ifndef V8_ENABLE_LEAPTIERING
1147 Label flags_need_processing;
1149 __ LoadFeedbackVectorFlagsAndJumpIfNeedsProcessing(
1150 flags, feedback_vector, CodeKind::INTERPRETED_FUNCTION,
1151 &flags_need_processing);
1153 ResetFeedbackVectorOsrUrgency(masm, feedback_vector, a5);
1156 FeedbackVector::kInvocationCountOffset));
1157 __ Addu(a5, a5, Operand(1));
1159 FeedbackVector::kInvocationCountOffset));
1171 __ bind(&push_stack_frame);
1173 __ PushStandardFrame(closure);
1185 Label stack_overflow;
1189 BytecodeArray::kFrameSizeOffset));
1192 __ Dsubu(a6, sp, Operand(a5));
1193 __ LoadStackLimit(a2, MacroAssembler::StackLimitKind::kRealStackLimit);
1194 __ Branch(&stack_overflow,
lo, a6, Operand(a2));
1200 __ Branch(&loop_check);
1201 __ bind(&loop_header);
1205 __ bind(&loop_check);
1207 __ Branch(&loop_header,
ge, a5, Operand(zero_reg));
1212 Label no_incoming_new_target_or_generator_register;
1215 BytecodeArray::kIncomingNewTargetOrGeneratorRegisterOffset));
1216 __ Branch(&no_incoming_new_target_or_generator_register,
eq, a5,
1220 __ bind(&no_incoming_new_target_or_generator_register);
1224 Label stack_check_interrupt, after_stack_check_interrupt;
1225 __ LoadStackLimit(a5, MacroAssembler::StackLimitKind::kInterruptStackLimit);
1226 __ Branch(&stack_check_interrupt,
lo, sp, Operand(a5));
1227 __ bind(&after_stack_check_interrupt);
1234 __ bind(&do_dispatch);
1236 ExternalReference::interpreter_dispatch_table_address(masm->isolate()));
1245 __ RecordComment(
"--- InterpreterEntryReturnPC point ---");
1247 masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(
1254 masm->isolate()->heap()->interpreter_entry_return_pc_offset().value(),
1276 __ jmp(&do_dispatch);
1278 __ bind(&do_return);
1283 __ bind(&stack_check_interrupt);
1291 __ CallRuntime(Runtime::kStackGuard);
1305 __ jmp(&after_stack_check_interrupt);
1308#ifndef V8_ENABLE_LEAPTIERING
1309 __ bind(&flags_need_processing);
1310 __ OptimizeCodeOrTailCallOptimizedCodeSlot(flags, feedback_vector);
1312 __ bind(&is_baseline);
1314#ifndef V8_ENABLE_LEAPTIERING
1316 __ Ld(feedback_vector,
1318 __ Ld(feedback_vector,
1321 Label install_baseline_code;
1326 __ Branch(&install_baseline_code,
ne, t0, Operand(FEEDBACK_VECTOR_TYPE));
1329 __ LoadFeedbackVectorFlagsAndJumpIfNeedsProcessing(
1330 flags, feedback_vector, CodeKind::BASELINE, &flags_need_processing);
1340 __ ReplaceClosureCodeWithOptimizedCode(a2, closure, t0, t1);
1343 __ bind(&install_baseline_code);
1346 __ GenerateTailCallToReturnedCode(Runtime::kInstallBaselineCode);
1350 __ bind(&compile_lazy);
1351 __ GenerateTailCallToReturnedCode(Runtime::kCompileLazy);
1355 __ bind(&stack_overflow);
1356 __ CallRuntime(Runtime::kThrowStackOverflow);
1362 Register start_address,
1363 Register scratch, Register scratch2) {
1365 __ Dsubu(scratch, num_args, Operand(1));
1367 __ Dsubu(start_address, start_address, scratch);
1370 __ PushArray(start_address, num_args, scratch, scratch2,
1386 Label stack_overflow;
1389 __ Dsubu(a0, a0, Operand(1));
1398 __ StackOverflowCheck(a3, a4, t0, &stack_overflow);
1404 __ PushRoot(RootIndex::kUndefinedValue);
1416 __ TailCallBuiltin(Builtin::kCallWithSpread);
1421 __ bind(&stack_overflow);
1423 __ TailCallRuntime(Runtime::kThrowStackOverflow);
1439 Label stack_overflow;
1440 __ StackOverflowCheck(a0, a5, t0, &stack_overflow);
1444 __ Dsubu(a0, a0, Operand(1));
1447 Register argc_without_receiver = a6;
1461 __ AssertUndefinedOrAllocationSite(a2, t0);
1465 __ AssertFunction(a1);
1469 __ TailCallBuiltin(Builtin::kArrayConstructorImpl);
1472 __ TailCallBuiltin(Builtin::kConstructWithSpread);
1476 __ TailCallBuiltin(Builtin::kConstruct);
1479 __ bind(&stack_overflow);
1481 __ TailCallRuntime(Runtime::kThrowStackOverflow);
1489 MacroAssembler* masm, ForwardWhichFrame which_frame) {
1494 Label stack_overflow;
1497 switch (which_frame) {
1508 __ StackOverflowCheck(a0, a5, t0, &stack_overflow);
1517 Register argc_without_receiver = a6;
1519 __ PushArray(a4, argc_without_receiver, a5, t0);
1525 __ TailCallBuiltin(Builtin::kConstruct);
1527 __ bind(&stack_overflow);
1529 __ TailCallRuntime(Runtime::kThrowStackOverflow);
1537void NewImplicitReceiver(MacroAssembler* masm) {
1554 __ Push(a0, a1, a3);
1555 __ CallBuiltin(Builtin::kFastNewObject);
1560 __ StoreReceiver(v0);
1572void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
1573 MacroAssembler* masm) {
1581 __ AssertFunction(a1);
1584 Label non_constructor;
1587 __ And(a2, a2, Operand(Map::Bits1::IsConstructorBit::kMask));
1588 __ Branch(&non_constructor,
eq, a2, Operand(zero_reg));
1591 Label stack_overflow;
1592 __ StackOverflowCheck(a0, a2, a5, &stack_overflow);
1596 __ EnterFrame(StackFrame::FAST_CONSTRUCT);
1599 __ LoadRoot(a2, RootIndex::kTheHoleValue);
1603 Register argc_without_receiver = a7;
1612 __ And(a5, a2, Operand(SharedFunctionInfo::ConstructAsBuiltinBit::kMask));
1613 __ Branch(&builtin_call,
ne, a5, Operand(zero_reg));
1616 Label not_create_implicit_receiver;
1617 __ DecodeField<SharedFunctionInfo::FunctionKindBits>(a2);
1621 ¬_create_implicit_receiver);
1622 NewImplicitReceiver(masm);
1623 __ bind(¬_create_implicit_receiver);
1639 masm->isolate()->heap()->SetConstructStubInvokeDeoptPCOffset(
1645 Label use_receiver, do_throw, leave_and_return, check_receiver;
1648 __ JumpIfNotRoot(v0, RootIndex::kUndefinedValue, &check_receiver);
1652 __ bind(&use_receiver);
1655 __ JumpIfRoot(v0, RootIndex::kTheHoleValue, &do_throw);
1657 __ bind(&leave_and_return);
1659 __ LeaveFrame(StackFrame::FAST_CONSTRUCT);
1664 __ bind(&check_receiver);
1667 __ JumpIfSmi(v0, &use_receiver);
1670 __ GetObjectType(v0, a4, a4);
1671 __ Branch(&leave_and_return,
hs, a4, Operand(FIRST_JS_RECEIVER_TYPE));
1672 __ Branch(&use_receiver);
1674 __ bind(&builtin_call);
1677 __ LeaveFrame(StackFrame::FAST_CONSTRUCT);
1683 __ CallRuntime(Runtime::kThrowConstructorReturnedNonObject);
1687 __ bind(&stack_overflow);
1688 __ TailCallRuntime(Runtime::kThrowStackOverflow);
1694 __ bind(&non_constructor);
1695 __ TailCallBuiltin(Builtin::kConstructedNonConstructable);
1701 Label builtin_trampoline, trampoline_loaded;
1703 masm->isolate()->heap()->interpreter_entry_return_pc_offset());
1717 Operand(INTERPRETER_DATA_TYPE));
1721 __ Branch(&trampoline_loaded);
1723 __ bind(&builtin_trampoline);
1724 __ li(t0, ExternalReference::
1725 address_of_interpreter_entry_trampoline_instruction_start(
1729 __ bind(&trampoline_loaded);
1730 __ Daddu(ra, t0, Operand(interpreter_entry_return_pc_offset.value()));
1734 ExternalReference::interpreter_dispatch_table_address(masm->isolate()));
1744 AbortReason::kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry,
1748 AbortReason::kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry,
1749 a1, Operand(BYTECODE_ARRAY_TYPE));
1774void Builtins::Generate_InterpreterEnterAtNextBytecode(MacroAssembler* masm) {
1784 Label enter_bytecode, function_entry_bytecode;
1800 __ bind(&enter_bytecode);
1807 __ bind(&function_entry_bytecode);
1814 __ Branch(&enter_bytecode);
1817 __ bind(&if_return);
1818 __ Abort(AbortReason::kInvalidBytecodeAdvance);
1821void Builtins::Generate_InterpreterEnterAtBytecode(MacroAssembler* masm) {
1826void Generate_ContinueToBuiltinHelper(MacroAssembler* masm,
1827 bool javascript_builtin,
1830 int allocatable_register_count = config->num_allocatable_general_registers();
1831 UseScratchRegisterScope temps(masm);
1832 Register scratch = temps.Acquire();
1835 if (javascript_builtin) {
1836 __ mov(scratch, v0);
1842 config->num_allocatable_general_registers() *
1847 for (
int i = allocatable_register_count - 1;
i >= 0; --
i) {
1848 int code = config->GetAllocatableGeneralCode(
i);
1855 if (with_result && javascript_builtin) {
1859 constexpr int return_value_offset =
1862 __ Daddu(a0, a0, Operand(return_value_offset));
1866 __ Dsubu(a0, a0, Operand(return_value_offset));
1877 __ LoadEntryFromBuiltinIndex(t0, t0);
1882void Builtins::Generate_ContinueToCodeStubBuiltin(MacroAssembler* masm) {
1883 Generate_ContinueToBuiltinHelper(masm,
false,
false);
1886void Builtins::Generate_ContinueToCodeStubBuiltinWithResult(
1887 MacroAssembler* masm) {
1888 Generate_ContinueToBuiltinHelper(masm,
false,
true);
1891void Builtins::Generate_ContinueToJavaScriptBuiltin(MacroAssembler* masm) {
1892 Generate_ContinueToBuiltinHelper(masm,
true,
false);
1895void Builtins::Generate_ContinueToJavaScriptBuiltinWithResult(
1896 MacroAssembler* masm) {
1897 Generate_ContinueToBuiltinHelper(masm,
true,
true);
1900void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
1902 FrameScope scope(masm, StackFrame::INTERNAL);
1903 __ CallRuntime(Runtime::kNotifyDeoptimized);
1915void Generate_OSREntry(MacroAssembler* masm, Register entry_address,
1916 Operand
offset = Operand(zero_reg)) {
1917 __ Daddu(ra, entry_address,
offset);
1922enum class OsrSourceTier {
1927void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
1928 Register maybe_target_code,
1929 Register expected_param_count) {
1930 Label jump_to_optimized_code;
1936 __ Branch(&jump_to_optimized_code,
ne, maybe_target_code,
1942 FrameScope scope(masm, StackFrame::INTERNAL);
1943 __ Push(expected_param_count);
1944 __ CallRuntime(Runtime::kCompileOptimizedOSR);
1945 __ Pop(expected_param_count);
1950 __ bind(&jump_to_optimized_code);
1957 __ li(scratch, ExternalReference::address_of_log_or_trace_osr());
1959 __ Branch(&next,
eq, scratch, Operand(zero_reg));
1962 FrameScope scope(masm, StackFrame::INTERNAL);
1963 __ Push(maybe_target_code, expected_param_count);
1964 __ CallRuntime(Runtime::kLogOrTraceOptimizedOSREntry, 0);
1965 __ Pop(maybe_target_code, expected_param_count);
1971 if (source == OsrSourceTier::kInterpreter) {
1974 __ LeaveFrame(StackFrame::STUB);
1980 __ Check(
ne, AbortReason::kExpectedOsrCode, scratch,
1988 __ Check(
eq, AbortReason::kOsrUnexpectedStackSize, scratch,
1989 Operand(expected_param_count));
1994 Code::kDeoptimizationDataOrInterpreterDataOffset -
2004 __ LoadCodeInstructionStart(maybe_target_code, maybe_target_code,
2009 Generate_OSREntry(masm, maybe_target_code, Operand(scratch));
2013void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
2014 using D = OnStackReplacementDescriptor;
2015 static_assert(D::kParameterCount == 2);
2016 OnStackReplacement(masm, OsrSourceTier::kInterpreter,
2017 D::MaybeTargetCodeRegister(),
2018 D::ExpectedParameterCountRegister());
2021void Builtins::Generate_BaselineOnStackReplacement(MacroAssembler* masm) {
2022 using D = OnStackReplacementDescriptor;
2023 static_assert(D::kParameterCount == 2);
2027 OnStackReplacement(masm, OsrSourceTier::kBaseline,
2028 D::MaybeTargetCodeRegister(),
2029 D::ExpectedParameterCountRegister());
2033void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
2048 __ LoadRoot(undefined_value, RootIndex::kUndefinedValue);
2057 __ Movz(arg_array, undefined_value, scratch);
2059 __ Dsubu(scratch, scratch, Operand(1));
2060 __ Movz(arg_array, undefined_value, scratch);
2062 __ DropArgumentsAndPushNewReceiver(argc,
this_arg);
2078 __ JumpIfRoot(arg_array, RootIndex::kNullValue, &no_arguments);
2079 __ Branch(&no_arguments,
eq, arg_array, Operand(undefined_value));
2082 __ TailCallBuiltin(Builtin::kCallWithArrayLike);
2086 __ bind(&no_arguments);
2095void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) {
2106 __ PushRoot(RootIndex::kUndefinedValue);
2107 __ Daddu(a0, a0, Operand(1));
2112 __ daddiu(a0, a0, -1);
2118void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
2134 __ LoadRoot(undefined_value, RootIndex::kUndefinedValue);
2147 __ Movz(arguments_list, undefined_value, scratch);
2148 __ Movz(this_argument, undefined_value, scratch);
2149 __ Movz(target, undefined_value, scratch);
2150 __ Dsubu(scratch, scratch, Operand(1));
2151 __ Movz(arguments_list, undefined_value, scratch);
2152 __ Movz(this_argument, undefined_value, scratch);
2153 __ Dsubu(scratch, scratch, Operand(1));
2154 __ Movz(arguments_list, undefined_value, scratch);
2156 __ DropArgumentsAndPushNewReceiver(argc, this_argument);
2171 __ TailCallBuiltin(Builtin::kCallWithArrayLike);
2174void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
2190 __ LoadRoot(undefined_value, RootIndex::kUndefinedValue);
2204 __ Movz(arguments_list, undefined_value, scratch);
2206 __ Movz(target, undefined_value, scratch);
2207 __ Dsubu(scratch, scratch, Operand(1));
2208 __ Movz(arguments_list, undefined_value, scratch);
2210 __ Dsubu(scratch, scratch, Operand(1));
2213 __ DropArgumentsAndPushNewReceiver(argc, undefined_value);
2232 __ TailCallBuiltin(Builtin::kConstructWithArrayLike);
2241void Generate_AllocateSpaceAndShiftExistingArguments(
2242 MacroAssembler* masm, Register count, Register argc_in_out,
2243 Register pointer_to_new_space_out, Register scratch1, Register scratch2,
2244 Register scratch3) {
2251 __ Dsubu(sp, sp, Operand(new_space));
2255 Register dest = pointer_to_new_space_out;
2259 __ Branch(&done,
ge, old_sp, Operand(
end));
2265 __ Branch(&loop,
lt, old_sp, Operand(
end));
2269 __ Daddu(argc_in_out, argc_in_out, count);
2287 __ AssertNotSmi(a2);
2288 __ GetObjectType(a2, t8, t8);
2289 __ Branch(&ok,
eq, t8, Operand(FIXED_ARRAY_TYPE));
2290 __ Branch(&fail,
ne, t8, Operand(FIXED_DOUBLE_ARRAY_TYPE));
2291 __ Branch(&ok,
eq, a4, Operand(zero_reg));
2294 __ Abort(AbortReason::kOperandIsNotAFixedArray);
2303 Label stack_overflow;
2304 __ StackOverflowCheck(len,
kScratchReg, a5, &stack_overflow);
2311 Generate_AllocateSpaceAndShiftExistingArguments(masm, a4, a0, a7, a6, t0, t1);
2315 Label done,
push, loop;
2322 __ Dsubu(scratch, sp, Operand(scratch));
2323 __ LoadRoot(t1, RootIndex::kTheHoleValue);
2327 __ Branch(&push,
ne, a5, Operand(t1));
2328 __ LoadRoot(a5, RootIndex::kUndefinedValue);
2333 __ Branch(&loop,
ne, scratch, Operand(sp));
2338 __ TailCallBuiltin(target_builtin);
2340 __ bind(&stack_overflow);
2341 __ TailCallRuntime(Runtime::kThrowStackOverflow);
2346 CallOrConstructMode mode,
2357 Label new_target_constructor, new_target_not_constructor;
2358 __ JumpIfSmi(a3, &new_target_not_constructor);
2361 __ And(t1, t1, Operand(Map::Bits1::IsConstructorBit::kMask));
2362 __ Branch(&new_target_constructor,
ne, t1, Operand(zero_reg));
2363 __ bind(&new_target_not_constructor);
2366 __ EnterFrame(StackFrame::INTERNAL);
2368 __ CallRuntime(Runtime::kThrowNotConstructor);
2370 __ bind(&new_target_constructor);
2373 Label stack_done, stack_overflow;
2376 __ Dsubu(a7, a7, a2);
2377 __ Branch(&stack_done,
le, a7, Operand(zero_reg));
2380 __ StackOverflowCheck(a7, a4, a5, &stack_overflow);
2395 Generate_AllocateSpaceAndShiftExistingArguments(masm, a7, a0, a2, t0, t1,
2405 __ Subu(a7, a7, Operand(1));
2410 __ Branch(&loop,
ne, a7, Operand(zero_reg));
2414 __ bind(&stack_done);
2416 __ TailCallBuiltin(target_builtin);
2418 __ bind(&stack_overflow);
2419 __ TailCallRuntime(Runtime::kThrowStackOverflow);
2429 __ AssertCallableFunction(a1);
2441 Operand(SharedFunctionInfo::IsNativeBit::kMask |
2442 SharedFunctionInfo::IsStrictBit::kMask));
2454 __ LoadGlobalProxy(a3);
2456 Label convert_to_object, convert_receiver;
2457 __ LoadReceiver(a3);
2458 __ JumpIfSmi(a3, &convert_to_object);
2459 static_assert(LAST_JS_RECEIVER_TYPE ==
LAST_TYPE);
2460 __ GetObjectType(a3, a4, a4);
2461 __ Branch(&done_convert,
hs, a4, Operand(FIRST_JS_RECEIVER_TYPE));
2463 Label convert_global_proxy;
2464 __ JumpIfRoot(a3, RootIndex::kUndefinedValue, &convert_global_proxy);
2465 __ JumpIfNotRoot(a3, RootIndex::kNullValue, &convert_to_object);
2466 __ bind(&convert_global_proxy);
2469 __ LoadGlobalProxy(a3);
2471 __ Branch(&convert_receiver);
2473 __ bind(&convert_to_object);
2478 FrameScope scope(masm, StackFrame::INTERNAL);
2483 __ CallBuiltin(Builtin::kToObject);
2490 __ bind(&convert_receiver);
2492 __ StoreReceiver(a3);
2494 __ bind(&done_convert);
2502#ifdef V8_ENABLE_LEAPTIERING
2506 FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset));
2517 __ AssertBoundFunction(a1);
2522 __ StoreReceiver(t0);
2540 __ Dsubu(t0, sp, Operand(a5));
2544 MacroAssembler::StackLimitKind::kRealStackLimit);
2548 __ EnterFrame(StackFrame::INTERNAL);
2549 __ CallRuntime(Runtime::kThrowStackOverflow);
2559 Label loop, done_loop;
2561 __ Daddu(a0, a0, Operand(a4));
2565 __ Dsubu(a4, a4, Operand(1));
2566 __ Branch(&done_loop,
lt, a4, Operand(zero_reg));
2571 __ bind(&done_loop);
2594 Label non_callable, class_constructor;
2595 __ JumpIfSmi(target, &non_callable);
2596 __ LoadMap(map, target);
2602 __ TailCallBuiltin(Builtin::kCallBoundFunction,
eq, instance_type,
2603 Operand(JS_BOUND_FUNCTION_TYPE));
2610 __ And(flags, flags, Operand(Map::Bits1::IsCallableBit::kMask));
2611 __ Branch(&non_callable,
eq, flags, Operand(zero_reg));
2614 __ TailCallBuiltin(Builtin::kCallProxy,
eq, instance_type,
2615 Operand(JS_PROXY_TYPE));
2619 __ TailCallBuiltin(Builtin::kCallWrappedFunction,
eq, instance_type,
2620 Operand(JS_WRAPPED_FUNCTION_TYPE));
2624 __ Branch(&class_constructor,
eq, instance_type,
2625 Operand(JS_CLASS_CONSTRUCTOR_TYPE));
2630 __ StoreReceiver(target);
2632 __ LoadNativeContextSlot(target, Context::CALL_AS_FUNCTION_DELEGATE_INDEX);
2637 __ bind(&non_callable);
2639 FrameScope scope(masm, StackFrame::INTERNAL);
2641 __ CallRuntime(Runtime::kThrowCalledNonCallable);
2645 __ bind(&class_constructor);
2647 FrameScope frame(masm, StackFrame::INTERNAL);
2649 __ CallRuntime(Runtime::kThrowConstructorNonCallableError);
2653void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
2659 __ AssertConstructor(a1);
2660 __ AssertFunction(a1);
2664 __ LoadRoot(a2, RootIndex::kUndefinedValue);
2666 Label call_generic_stub;
2671 __ And(a4, a4, Operand(SharedFunctionInfo::ConstructAsBuiltinBit::kMask));
2672 __ Branch(&call_generic_stub,
eq, a4, Operand(zero_reg));
2674 __ TailCallBuiltin(Builtin::kJSBuiltinsConstructStub);
2676 __ bind(&call_generic_stub);
2677 __ TailCallBuiltin(Builtin::kJSConstructStubGeneric);
2681void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
2687 __ AssertConstructor(a1);
2688 __ AssertBoundFunction(a1);
2706 __ Dsubu(t0, sp, Operand(a5));
2710 MacroAssembler::StackLimitKind::kRealStackLimit);
2714 __ EnterFrame(StackFrame::INTERNAL);
2715 __ CallRuntime(Runtime::kThrowStackOverflow);
2725 Label loop, done_loop;
2727 __ Daddu(a0, a0, Operand(a4));
2731 __ Dsubu(a4, a4, Operand(1));
2732 __ Branch(&done_loop,
lt, a4, Operand(zero_reg));
2737 __ bind(&done_loop);
2746 __ Branch(&skip_load,
ne, a1, Operand(a3));
2748 __ bind(&skip_load);
2753 __ TailCallBuiltin(Builtin::kConstruct);
2757void Builtins::Generate_Construct(MacroAssembler* masm) {
2772 Label non_constructor, non_proxy;
2773 __ JumpIfSmi(target, &non_constructor);
2780 __ And(flags, flags, Operand(Map::Bits1::IsConstructorBit::kMask));
2781 __ Branch(&non_constructor,
eq, flags, Operand(zero_reg));
2785 __ GetInstanceTypeRange(map, instance_type, FIRST_JS_FUNCTION_TYPE, scratch);
2786 __ TailCallBuiltin(Builtin::kConstructFunction,
ls, scratch,
2787 Operand(LAST_JS_FUNCTION_TYPE - FIRST_JS_FUNCTION_TYPE));
2791 __ TailCallBuiltin(Builtin::kConstructBoundFunction,
eq, instance_type,
2792 Operand(JS_BOUND_FUNCTION_TYPE));
2795 __ Branch(&non_proxy,
ne, instance_type, Operand(JS_PROXY_TYPE));
2796 __ TailCallBuiltin(Builtin::kConstructProxy);
2799 __ bind(&non_proxy);
2802 __ StoreReceiver(target);
2804 __ LoadNativeContextSlot(target,
2805 Context::CALL_AS_CONSTRUCTOR_DELEGATE_INDEX);
2811 __ bind(&non_constructor);
2812 __ TailCallBuiltin(Builtin::kConstructedNonConstructable);
2815#if V8_ENABLE_WEBASSEMBLY
2820constexpr RegList kSavedGpRegs = ([]()
constexpr {
2823 saved_gp_regs.set(gp_param_reg);
2831 saved_gp_regs.Count());
2832 return saved_gp_regs;
2838 saved_fp_regs.set(fp_param_reg);
2843 saved_fp_regs.Count());
2844 return saved_fp_regs;
2859void Builtins::Generate_WasmLiftoffFrameSetup(MacroAssembler* masm) {
2860 Register func_index = wasm::kLiftoffFrameSetupFunctionReg;
2863 Label allocate_vector, done;
2867 WasmTrustedInstanceData::kFeedbackVectorsOffset));
2870 __ JumpIfSmi(vector, &allocate_vector);
2875 __ bind(&allocate_vector);
2883 __ MultiPush(kSavedGpRegs);
2884 __ MultiPushFPU(kSavedFpRegs);
2889 __ SmiTag(func_index);
2892 __ CallRuntime(Runtime::kWasmAllocateFeedbackVector, 3);
2897 __ MultiPopFPU(kSavedFpRegs);
2898 __ MultiPop(kSavedGpRegs);
2900 MemOperand(fp, WasmFrameConstants::kWasmInstanceDataOffset));
2906void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
2912 HardAbortScope hard_abort(masm);
2913 FrameScope scope(masm, StackFrame::INTERNAL);
2917 __ MultiPush(kSavedGpRegs);
2920 Label push_doubles, simd_pushed;
2921 __ li(a1, ExternalReference::supports_wasm_simd_128_address());
2924 __ Branch(&push_doubles,
le, a1, Operand(zero_reg));
2927 CpuFeatureScope msa_scope(
2929 __ MultiPushMSA(kSavedFpRegs);
2931 __ Branch(&simd_pushed);
2932 __ bind(&push_doubles);
2933 __ MultiPushFPU(kSavedFpRegs);
2938 __ bind(&simd_pushed);
2945 __ CallRuntime(Runtime::kWasmCompileLazy, 2);
2948 Label pop_doubles, simd_popped;
2949 __ li(a1, ExternalReference::supports_wasm_simd_128_address());
2952 __ Branch(&pop_doubles,
le, a1, Operand(zero_reg));
2955 CpuFeatureScope msa_scope(
2957 __ MultiPopMSA(kSavedFpRegs);
2959 __ Branch(&simd_popped);
2960 __ bind(&pop_doubles);
2962 __ MultiPopFPU(kSavedFpRegs);
2963 __ bind(&simd_popped);
2964 __ MultiPop(kSavedGpRegs);
2969 static_assert(!kSavedGpRegs.has(v0));
2974 static_assert(!kSavedGpRegs.has(t8));
2976 WasmTrustedInstanceData::kJumpTableStartOffset));
2977 __ Daddu(t8, v0, t8);
2983void Builtins::Generate_WasmDebugBreak(MacroAssembler* masm) {
2984 HardAbortScope hard_abort(masm);
2986 FrameScope scope(masm, StackFrame::WASM_DEBUG_BREAK);
2996 __ CallRuntime(Runtime::kWasmDebugBreak, 0);
3005void Builtins::Generate_WasmReturnPromiseOnSuspendAsm(MacroAssembler* masm) {
3009void Builtins::Generate_JSToWasmStressSwitchStacksAsm(MacroAssembler* masm) {
3013void Builtins::Generate_WasmToJsWrapperAsm(MacroAssembler* masm) {
3019 __ Dsubu(sp, sp, Operand(required_stack_space));
3020 for (
int i = cnt_fp - 1;
i >= 0;
i--) {
3026 for (
int i = cnt_gp;
i >= 1;
i--) {
3032 __ TailCallBuiltin(Builtin::kWasmToJsWrapperCSA);
3035void Builtins::Generate_WasmTrapHandlerLandingPad(MacroAssembler* masm) {
3039void Builtins::Generate_WasmSuspend(MacroAssembler* masm) {
3044void Builtins::Generate_WasmResume(MacroAssembler* masm) {
3049void Builtins::Generate_WasmReject(MacroAssembler* masm) {
3054void Builtins::Generate_WasmOnStackReplace(MacroAssembler* masm) {
3059void Builtins::Generate_JSToWasmWrapperAsm(MacroAssembler* masm) {
__ Trap(); }
3064 ArgvMode argv_mode,
bool builtin_exit_frame,
3065 bool switch_to_central_stack) {
3076 using ER = ExternalReference;
3079 static constexpr Register argc_input = a0;
3080 static constexpr Register target_fun = s1;
3081 static constexpr Register argv = a1;
3082 static constexpr Register scratch = a3;
3083 static constexpr Register argc_sav = s0;
3085 __ mov(target_fun, argv);
3100 builtin_exit_frame ? StackFrame::BUILTIN_EXIT : StackFrame::EXIT);
3103 __ mov(argc_sav, argc_input);
3113 __ AssertStackIsAligned();
3121 __ StoreReturnAddressAndCall(target_fun);
3126 Label exception_returned;
3127 __ LoadRoot(a4, RootIndex::kException);
3128 __ Branch(&exception_returned,
eq, a4, Operand(v0));
3134 ER exception_address =
3135 ER::Create(IsolateAddressId::kExceptionAddress, masm->isolate());
3136 __ Ld(scratch,
__ ExternalReferenceAsOperand(exception_address,
no_reg));
3137 __ LoadRoot(a4, RootIndex::kTheHoleValue);
3139 __ Branch(&okay,
eq, a4, Operand(scratch));
3149 __ LeaveExitFrame(scratch);
3158 __ bind(&exception_returned);
3160 ER pending_handler_context_address = ER::Create(
3161 IsolateAddressId::kPendingHandlerContextAddress, masm->isolate());
3162 ER pending_handler_entrypoint_address = ER::Create(
3163 IsolateAddressId::kPendingHandlerEntrypointAddress, masm->isolate());
3164 ER pending_handler_fp_address =
3165 ER::Create(IsolateAddressId::kPendingHandlerFPAddress, masm->isolate());
3166 ER pending_handler_sp_address =
3167 ER::Create(IsolateAddressId::kPendingHandlerSPAddress, masm->isolate());
3173 __ PrepareCallCFunction(3, 0, a0);
3177 __ CallCFunction(ER::Create(Runtime::kUnwindAndFindExceptionHandler), 3,
3182 __ li(
cp, pending_handler_context_address);
3184 __ li(sp, pending_handler_sp_address);
3186 __ li(fp, pending_handler_fp_address);
3192 __ Branch(&zero,
eq,
cp, Operand(zero_reg));
3197 ER c_entry_fp_address =
3198 ER::Create(IsolateAddressId::kCEntryFPAddress, masm->isolate());
3199 __ Sd(zero_reg,
__ ExternalReferenceAsOperand(c_entry_fp_address,
no_reg));
3202 __ Ld(t9,
__ ExternalReferenceAsOperand(pending_handler_entrypoint_address,
3207#if V8_ENABLE_WEBASSEMBLY
3208void Builtins::Generate_WasmHandleStackOverflow(MacroAssembler* masm) {
3213void Builtins::Generate_DoubleToI(MacroAssembler* masm) {
3225 __ Push(result_reg);
3226 __ Push(scratch, scratch2, scratch3);
3229 __ Ldc1(double_scratch,
MemOperand(sp, kArgumentOffset));
3232 __ Trunc_w_d(double_scratch, double_scratch);
3234 __ mfc1(scratch3, double_scratch);
3240 __ And(scratch, scratch,
3245 __ Branch(&error,
ne, scratch, Operand(zero_reg));
3246 __ Move(result_reg, scratch3);
3258 Label normal_exponent;
3265 __ Movz(result_reg, zero_reg, scratch);
3266 __ Branch(&done,
eq, scratch, Operand(zero_reg));
3269 __ Subu(result_reg, result_reg,
3274 __ Branch(&normal_exponent,
le, result_reg, Operand(zero_reg));
3275 __ mov(result_reg, zero_reg);
3278 __ bind(&normal_exponent);
3290 Label high_shift_needed, high_shift_done;
3291 __ Branch(&high_shift_needed,
lt, scratch, Operand(32));
3292 __ mov(input_high, zero_reg);
3293 __ Branch(&high_shift_done);
3294 __ bind(&high_shift_needed);
3297 __ Or(input_high, input_high,
3302 __ sllv(input_high, input_high, scratch);
3304 __ bind(&high_shift_done);
3307 Label pos_shift, shift_done;
3310 __ Branch(&pos_shift,
ge, scratch, Operand(zero_reg));
3313 __ Subu(scratch, zero_reg, scratch);
3314 __ sllv(input_low, input_low, scratch);
3315 __ Branch(&shift_done);
3317 __ bind(&pos_shift);
3318 __ srlv(input_low, input_low, scratch);
3320 __ bind(&shift_done);
3321 __ Or(input_high, input_high, Operand(input_low));
3326 __ Subu(result_reg, zero_reg, input_high);
3327 __ Movz(result_reg, input_high, scratch);
3332 __ Pop(scratch, scratch2, scratch3);
3362 argc = CallApiCallbackGenericDescriptor::ActualArgumentsCountRegister();
3374 api_function_address =
3375 CallApiCallbackOptimizedDescriptor::ApiFunctionAddressRegister();
3381 DCHECK(!
AreAliased(api_function_address, topmost_script_having_context, argc,
3382 func_templ, scratch));
3384 using FCA = FunctionCallbackArguments;
3385 using ER = ExternalReference;
3386 using FC = ApiCallbackExitFrameConstants;
3388 static_assert(FCA::kArgsLength == 6);
3389 static_assert(FCA::kNewTargetIndex == 5);
3390 static_assert(FCA::kTargetIndex == 4);
3391 static_assert(FCA::kReturnValueIndex == 3);
3392 static_assert(FCA::kContextIndex == 2);
3393 static_assert(FCA::kIsolateIndex == 1);
3394 static_assert(FCA::kUnusedIndex == 0);
3408 __ StoreRootRelative(IsolateData::topmost_script_having_context_offset(),
3409 topmost_script_having_context);
3418 __ li(scratch, ER::isolate_address());
3425 __ LoadRoot(scratch, RootIndex::kUndefinedValue);
3440 api_function_address,
3442 FunctionTemplateInfo::kMaybeRedirectedCallbackOffset));
3445 __ EnterExitFrame(scratch, FC::getExtraSlotsCountFrom<ExitFrameConstants>(),
3446 StackFrame::API_CALLBACK_EXIT);
3454 __ Sd(argc, argc_operand);
3457 __ Daddu(scratch, fp, Operand(FC::kImplicitArgsArrayOffset));
3458 __ Sd(scratch,
MemOperand(fp, FC::kFCIImplicitArgsOffset));
3461 __ Daddu(scratch, fp, Operand(FC::kFirstArgumentOffset));
3465 __ RecordComment(
"v8::FunctionCallback's argument.");
3467 __ Daddu(function_callback_info_arg, fp,
3468 Operand(FC::kFunctionCallbackInfoOffset));
3471 !
AreAliased(api_function_address, scratch, function_callback_info_arg));
3473 ExternalReference thunk_ref = ER::invoke_function_callback(mode);
3477 static constexpr int kSlotsToDropOnReturn =
3480 const bool with_profiling =
3483 thunk_ref, no_thunk_arg, kSlotsToDropOnReturn,
3484 &argc_operand, return_value_operand);
3487void Builtins::Generate_CallApiGetter(MacroAssembler* masm) {
3498 Register api_function_address = a2;
3510 using PCA = PropertyCallbackArguments;
3511 using ER = ExternalReference;
3512 using FC = ApiAccessorExitFrameConstants;
3514 static_assert(PCA::kPropertyKeyIndex == 0);
3515 static_assert(PCA::kShouldThrowOnErrorIndex == 1);
3516 static_assert(PCA::kHolderIndex == 2);
3517 static_assert(PCA::kIsolateIndex == 3);
3518 static_assert(PCA::kHolderV2Index == 4);
3519 static_assert(PCA::kReturnValueIndex == 5);
3520 static_assert(PCA::kDataIndex == 6);
3521 static_assert(PCA::kThisIndex == 7);
3522 static_assert(PCA::kArgsLength == 8);
3536 __ LoadRoot(undef, RootIndex::kUndefinedValue);
3537 __ li(scratch2, ER::isolate_address());
3541 __ Push(scratch2, holder);
3549 __ Push(should_throw_on_error, name_arg);
3551 __ RecordComment(
"Load api_function_address");
3552 __ Ld(api_function_address,
3556 __ EnterExitFrame(scratch, FC::getExtraSlotsCountFrom<ExitFrameConstants>(),
3557 StackFrame::API_ACCESSOR_EXIT);
3559 __ RecordComment(
"Create v8::PropertyCallbackInfo object on the stack.");
3561 __ Daddu(property_callback_info_arg, fp, Operand(FC::kArgsArrayOffset));
3563 DCHECK(!
AreAliased(api_function_address, property_callback_info_arg, name_arg,
3566#ifdef V8_ENABLE_DIRECT_HANDLE
3571 static_assert(PCA::kPropertyKeyIndex == 0);
3572 __ mov(name_arg, property_callback_info_arg);
3575 ER thunk_ref = ER::invoke_accessor_getter_callback();
3581 static constexpr int kSlotsToDropOnReturn =
3582 FC::kPropertyCallbackInfoArgsLength;
3583 MemOperand*
const kUseStackSpaceConstant =
nullptr;
3585 const bool with_profiling =
true;
3587 thunk_ref, thunk_arg, kSlotsToDropOnReturn,
3588 kUseStackSpaceConstant, return_value_operand);
3591void Builtins::Generate_DirectCEntry(MacroAssembler* masm) {
3614 __ Assert(
ne, AbortReason::kReceivedInvalidReturnAddress, a4,
3615 Operand(
reinterpret_cast<uint64_t
>(
kZapValue)));
3625void Generate_DeoptimizationEntry(MacroAssembler* masm,
3627 Isolate* isolate = masm->isolate();
3634 RegList saved_regs = restored_regs |
sp | ra;
3639 __ Dsubu(sp, sp, Operand(kMSARegsSize));
3644 Label no_simd, done;
3645 UseScratchRegisterScope temps(masm);
3646 Register scratch = temps.Acquire();
3648 __ li(scratch, ExternalReference::supports_wasm_simd_128_address());
3651 __ Branch(&no_simd,
le, scratch, Operand(zero_reg));
3653 CpuFeatureScope msa_scope(
3655 for (
int i = 0;
i < config->num_allocatable_simd128_registers(); ++
i) {
3656 int code = config->GetAllocatableSimd128Code(
i);
3664 for (
int i = 0;
i < config->num_allocatable_simd128_registers(); ++
i) {
3665 int code = config->GetAllocatableSimd128Code(
i);
3678 if ((saved_regs.bits() & (1 <<
i)) != 0) {
3687 const int kSavedRegistersAreaSize =
3694 __ Daddu(a3, sp, Operand(kSavedRegistersAreaSize));
3696 __ Dsubu(a3, fp, a3);
3699 __ PrepareCallCFunction(5, a4);
3701 __ mov(a0, zero_reg);
3702 Label context_check;
3704 __ JumpIfSmi(a1, &context_check);
3706 __ bind(&context_check);
3707 __ li(a1, Operand(
static_cast<int>(deopt_kind)));
3714 AllowExternalCallThatCantCauseGC scope(masm);
3715 __ CallCFunction(ExternalReference::new_deoptimizer_function(), 5);
3729 if ((saved_regs.bits() & (1 <<
i)) != 0) {
3743 Label no_simd, done;
3744 UseScratchRegisterScope temps(masm);
3745 Register scratch = temps.Acquire();
3747 __ li(scratch, ExternalReference::supports_wasm_simd_128_address());
3750 __ Branch(&no_simd,
le, scratch, Operand(zero_reg));
3752 CpuFeatureScope msa_scope(
3754 for (
int i = 0;
i < config->num_allocatable_simd128_registers(); ++
i) {
3755 int code = config->GetAllocatableSimd128Code(
i);
3756 int dst_offset = code *
kSimd128Size + simd128_regs_offset;
3765 for (
int i = 0;
i < config->num_allocatable_simd128_registers(); ++
i) {
3766 int code = config->GetAllocatableSimd128Code(
i);
3767 int dst_offset = code *
kSimd128Size + simd128_regs_offset;
3778 __ Daddu(sp, sp, Operand(kSavedRegistersAreaSize));
3783 __ Daddu(a2, a2, sp);
3790 Label pop_loop_header;
3791 __ BranchShort(&pop_loop_header);
3795 __ daddiu(a3, a3,
sizeof(uint64_t));
3796 __ bind(&pop_loop_header);
3797 __ BranchShort(&pop_loop,
ne, a2, Operand(sp));
3801 __ PrepareCallCFunction(1, a1);
3804 AllowExternalCallThatCantCauseGC scope(masm);
3805 __ CallCFunction(ExternalReference::compute_output_frames_function(), 1);
3812 Label outer_push_loop, inner_push_loop, outer_loop_header, inner_loop_header;
3818 __ BranchShort(&outer_loop_header);
3820 __ bind(&outer_push_loop);
3826 __ BranchShort(&inner_loop_header);
3828 __ bind(&inner_push_loop);
3829 __ Dsubu(frame_size, frame_size, Operand(
sizeof(uint64_t)));
3830 __ Daddu(a6, current_frame, Operand(frame_size));
3834 __ bind(&inner_loop_header);
3835 __ BranchShort(&inner_push_loop,
ne, frame_size, Operand(zero_reg));
3839 __ bind(&outer_loop_header);
3840 __ BranchShort(&outer_push_loop,
lt, a4, Operand(a1));
3845 Label no_simd, done;
3846 UseScratchRegisterScope temps(masm);
3847 Register scratch = temps.Acquire();
3849 __ li(scratch, ExternalReference::supports_wasm_simd_128_address());
3852 __ Branch(&no_simd,
le, scratch, Operand(zero_reg));
3854 CpuFeatureScope msa_scope(
3856 for (
int i = 0;
i < config->num_allocatable_simd128_registers(); ++
i) {
3857 int code = config->GetAllocatableSimd128Code(
i);
3858 int src_offset = code *
kSimd128Size + simd128_regs_offset;
3860 __ ld_d(fpu_reg,
MemOperand(current_frame, src_offset));
3865 for (
int i = 0;
i < config->num_allocatable_simd128_registers(); ++
i) {
3866 int code = config->GetAllocatableSimd128Code(
i);
3867 int src_offset = code *
kSimd128Size + simd128_regs_offset;
3869 __ Ldc1(fpu_reg,
MemOperand(current_frame, src_offset));
3883 DCHECK(!(restored_regs.has(at)));
3885 __ mov(at, current_frame);
3889 if ((restored_regs.bits() & (1 <<
i)) != 0) {
3900 __ Branch(&
end,
eq, at, Operand(zero_reg));
3909void Builtins::Generate_DeoptimizationEntry_Eager(MacroAssembler* masm) {
3913void Builtins::Generate_DeoptimizationEntry_Lazy(MacroAssembler* masm) {
3920void Builtins::Generate_InterpreterOnStackReplacement_ToBaseline(
3921 MacroAssembler* masm) {
3934 ResetSharedFunctionInfoAge(masm, code_obj);
3938 SharedFunctionInfo::kTrustedFunctionDataOffset));
3942 __ GetObjectType(code_obj, t2, t2);
3943 __ Assert(
eq, AbortReason::kExpectedBaselineData, t2, Operand(CODE_TYPE));
3950 __ Ld(feedback_cell,
3952 __ Ld(feedback_vector,
3955 Label install_baseline_code;
3958 __ GetObjectType(feedback_vector, t2, t2);
3959 __ Branch(&install_baseline_code,
ne, t2, Operand(FEEDBACK_VECTOR_TYPE));
3967 __ Sd(feedback_cell,
3973 __ Sd(feedback_vector,
3975 feedback_vector =
no_reg;
3979 __ li(get_baseline_pc,
3980 ExternalReference::baseline_pc_for_next_executed_bytecode());
3995 FrameScope scope(masm, StackFrame::INTERNAL);
3996 __ PrepareCallCFunction(3, 0, a4);
3997 __ CallCFunction(get_baseline_pc, 3, 0);
4006 Generate_OSREntry(masm, code_obj);
4009 __ bind(&install_baseline_code);
4011 FrameScope scope(masm, StackFrame::INTERNAL);
4014 __ CallRuntime(Runtime::kInstallBaselineCode, 1);
4021void Builtins::Generate_RestartFrameTrampoline(MacroAssembler* masm) {
4031 __ LeaveFrame(StackFrame::INTERPRETED);
4032#ifdef V8_ENABLE_LEAPTIERING
#define Assert(condition)
#define JUMP_IF_EQUAL(NAME)
interpreter::Bytecode bytecode
#define RETURN_BYTECODE_LIST(V)
static constexpr Register HolderRegister()
static constexpr Register CallbackRegister()
static constexpr int kFeedbackCellFromFp
static void Generate_InterpreterPushArgsThenConstructImpl(MacroAssembler *masm, InterpreterPushArgsMode mode)
static void Generate_CallOrConstructForwardVarargs(MacroAssembler *masm, CallOrConstructMode mode, Builtin target_builtin)
static CallInterfaceDescriptor CallInterfaceDescriptorFor(Builtin builtin)
static void Generate_InterpreterEntryTrampoline(MacroAssembler *masm, InterpreterEntryTrampolineMode mode)
static void Generate_Adaptor(MacroAssembler *masm, int formal_parameter_count, Address builtin_address)
static void Generate_CEntry(MacroAssembler *masm, int result_size, ArgvMode argv_mode, bool builtin_exit_frame, bool switch_to_central_stack)
static constexpr Builtin CallFunction(ConvertReceiverMode=ConvertReceiverMode::kAny)
static constexpr Builtin AdaptorWithBuiltinExitFrame(int formal_parameter_count)
static void Generate_Call(MacroAssembler *masm, ConvertReceiverMode mode)
static void Generate_CallFunction(MacroAssembler *masm, ConvertReceiverMode mode)
static void Generate_CallOrConstructVarargs(MacroAssembler *masm, Builtin target_builtin)
static void Generate_CallApiCallbackImpl(MacroAssembler *masm, CallApiCallbackMode mode)
static constexpr Builtin Call(ConvertReceiverMode=ConvertReceiverMode::kAny)
static void Generate_CallBoundFunctionImpl(MacroAssembler *masm)
static void Generate_ConstructForwardAllArgsImpl(MacroAssembler *masm, ForwardWhichFrame which_frame)
static void Generate_InterpreterPushArgsThenCallImpl(MacroAssembler *masm, ConvertReceiverMode receiver_mode, InterpreterPushArgsMode mode)
static constexpr BytecodeOffset None()
static constexpr Register FunctionTemplateInfoRegister()
static DEFINE_PARAMETERS_VARARGS(kActualArgumentsCount, kTopmostScriptHavingContext, kFunctionTemplateInfo) DEFINE_PARAMETER_TYPES(MachineType constexpr Register TopmostScriptHavingContextRegister()
static constexpr Register FunctionTemplateInfoRegister()
static DEFINE_PARAMETERS_VARARGS(kApiFunctionAddress, kActualArgumentsCount, kFunctionTemplateInfo) DEFINE_PARAMETER_TYPES(MachineType constexpr Register ActualArgumentsCountRegister()
static constexpr int kContextOrFrameTypeOffset
static constexpr int kCallerSPOffset
static constexpr int kCallerFPOffset
static constexpr int kFixedSlotCountAboveFp
static constexpr int kFixedFrameSizeAboveFp
static constexpr int kConstructorOffset
static constexpr int kLengthOffset
static constexpr int kContextOffset
static const int kOsrPcOffsetIndex
static int caller_frame_top_offset()
static int output_offset()
static int input_offset()
static int output_count_offset()
static constexpr int kNextExitFrameFPOffset
static constexpr int kNextFastCallFramePCOffset
static V8_EXPORT_PRIVATE ExternalReference isolate_address()
static ExternalReference Create(const SCTableReference &table_ref)
static constexpr int kImplicitReceiverOffset
static constexpr int kContextOffset
static constexpr int simd128_registers_offset()
static int frame_size_offset()
static int continuation_offset()
static int frame_content_offset()
static int registers_offset()
static const int kMantissaBits
static const uint32_t kSignMask
static const uint32_t kExponentMask
static const int kMantissaBitsInTopWord
static const int kExponentBits
static const int kExponentBias
static const int kExponentShift
static const int kNonMantissaBitsInTopWord
static constexpr int kHeaderSize
static constexpr int kMapOffset
static constexpr int kBytecodeOffsetFromFp
constexpr void clear(RegisterT reg)
static constexpr int8_t kNumRegisters
static constexpr MSARegister from_code(int8_t code)
constexpr int8_t code() const
static const RegisterConfiguration * Default()
static constexpr Register from_code(int code)
static constexpr int kMantissaOffset
static constexpr int kExponentOffset
static constexpr Register MicrotaskQueueRegister()
static constexpr Tagged< Smi > FromInt(int value)
static constexpr Tagged< Smi > zero()
static constexpr int32_t TypeToMarker(Type type)
@ OUTERMOST_JSENTRY_FRAME
static constexpr int kContextOffset
static constexpr int kArgCOffset
static constexpr int kFunctionOffset
static constexpr int OffsetOfElementAt(int index)
static constexpr int kFixedFrameSize
static constexpr int kFixedSlotCount
static constexpr int kFixedFrameSizeFromFp
static constexpr int kFrameTypeOffset
static constexpr int kFeedbackVectorFromFp
static constexpr int kBytecodeArrayFromFp
static constexpr RegList kPushedGpRegs
static constexpr DoubleRegList kPushedFpRegs
static constexpr int kNumberOfSavedGpParamRegs
static constexpr int kNumberOfSavedFpParamRegs
static const int kBytecodeCount
#define ASM_CODE_COMMENT_STRING(asm,...)
#define ASM_CODE_COMMENT(asm)
base::Vector< const DirectHandle< Object > > args
DirectHandle< Object > new_target
ApiCallbackExitFrameConstants FC
FunctionCallbackArguments FCA
int invoke(const char *params)
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)
constexpr Register kGpParamRegisters[]
constexpr DoubleRegister kFpParamRegisters[]
constexpr Register no_reg
constexpr Register kRootRegister
constexpr int kFunctionEntryBytecodeOffset
RegListBase< DoubleRegister > DoubleRegList
constexpr int kSimd128Size
constexpr int kPointerSizeLog2
DwVfpRegister DoubleRegister
const uint32_t kFCSRInvalidOpCauseMask
static void Generate_CheckStackOverflow(MacroAssembler *masm, Register argc, Register scratch1, Register scratch2)
constexpr DoubleRegister kScratchDoubleReg
const RegList kCalleeSaved
static void Generate_InterpreterEnterBytecode(MacroAssembler *masm)
RegListBase< Register > RegList
constexpr Register kJavaScriptCallTargetRegister
constexpr int kNumberOfRegisters
constexpr FPUControlRegister FCSR
constexpr uint16_t kDontAdaptArgumentsSentinel
constexpr Register kJavaScriptCallArgCountRegister
constexpr Register kInterpreterAccumulatorRegister
constexpr Register kScratchReg2
constexpr int kSystemPointerSizeLog2
constexpr Register kScratchReg
constexpr int kJSArgcReceiverSlots
static void GenerateInterpreterPushArgs(MacroAssembler *masm, Register num_args, Register start_address, Register scratch)
static void AdvanceBytecodeOffsetOrReturn(MacroAssembler *masm, Register bytecode_array, Register bytecode_offset, Register bytecode, Register scratch1, Register scratch2, Register scratch3, Label *if_return)
MemOperand FieldMemOperand(Register object, int offset)
constexpr int kSystemPointerSize
static void LeaveInterpreterFrame(MacroAssembler *masm, Register scratch1, Register scratch2)
constexpr int kTaggedSizeLog2
constexpr uint32_t kDebugZapValue
constexpr uint32_t kZapValue
constexpr Register kReturnRegister0
const uint32_t kFCSROverflowCauseMask
@ LAST_CALLABLE_JS_FUNCTION_TYPE
@ FIRST_CALLABLE_JS_FUNCTION_TYPE
constexpr Register kWasmImplicitArgRegister
constexpr Register kContextRegister
V8_EXPORT_PRIVATE bool AreAliased(const CPURegister ®1, const CPURegister ®2, const CPURegister ®3=NoReg, const CPURegister ®4=NoReg, const CPURegister ®5=NoReg, const CPURegister ®6=NoReg, const CPURegister ®7=NoReg, const CPURegister ®8=NoReg)
const int kCArgsSlotsSize
constexpr Register kInterpreterDispatchTableRegister
constexpr LowDwVfpRegister kDoubleRegZero
V8_EXPORT_PRIVATE FlagValues v8_flags
constexpr Register kJavaScriptCallExtraArg1Register
const RegList kJSCallerSaved
constexpr int JSParameterCount(int param_count_without_receiver)
Register ToRegister(int num)
const uint32_t kFCSRUnderflowCauseMask
const DoubleRegList kCalleeSavedFPU
constexpr Register kJavaScriptCallCodeStartRegister
Register ReassignRegister(Register &source)
constexpr Register kWasmCompileLazyFuncIndexRegister
static void AssertCodeIsBaseline(MacroAssembler *masm, Register code, Register scratch)
static void Generate_JSEntryTrampolineHelper(MacroAssembler *masm, bool is_construct)
void CallApiFunctionAndReturn(MacroAssembler *masm, bool with_profiling, Register function_address, ExternalReference thunk_ref, Register thunk_arg, int slots_to_drop_on_return, MemOperand *argc_operand, MemOperand return_value_operand)
Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2=no_reg, Register reg3=no_reg, Register reg4=no_reg, Register reg5=no_reg, Register reg6=no_reg)
@ kDefaultDerivedConstructor
constexpr Register kCArgRegs[]
constexpr int kDoubleSize
constexpr Register kJavaScriptCallDispatchHandleRegister
static void GetSharedFunctionInfoBytecodeOrBaseline(MacroAssembler *masm, Register sfi, Register bytecode, Register scratch1, Label *is_baseline, Label *is_unavailable)
constexpr Register kInterpreterBytecodeOffsetRegister
constexpr Register kJavaScriptCallNewTargetRegister
constexpr Register kJSFunctionRegister
constexpr Register kInterpreterBytecodeArrayRegister
#define DCHECK_NE(v1, v2)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define OFFSET_OF_DATA_START(Type)