13#if V8_ENABLE_WEBASSEMBLY
22#define __ ACCESS_MASM(masm)
24#if V8_ENABLE_WEBASSEMBLY
29void PrepareForJsToWasmConversionBuiltinCall(MacroAssembler* masm,
30 Register current_param_slot,
31 Register valuetypes_array_ptr,
32 Register wasm_instance,
33 Register function_data) {
34 UseScratchRegisterScope temps(masm);
35 Register GCScanCount = temps.AcquireX();
40 __ Mov(GCScanCount, 2);
44 fp, BuiltinWasmInterpreterWrapperConstants::kGCScanSlotCountOffset));
45 __ Push(current_param_slot, valuetypes_array_ptr, wasm_instance,
49 Register wasm_trusted_instance = wasm_instance;
50 __ LoadTrustedPointerField(
51 wasm_trusted_instance,
53 kWasmTrustedInstanceDataIndirectPointerTag);
58 WasmTrustedInstanceData::kNativeContextOffset)));
61void RestoreAfterJsToWasmConversionBuiltinCall(MacroAssembler* masm,
62 Register function_data,
63 Register wasm_instance,
64 Register valuetypes_array_ptr,
65 Register current_param_slot) {
68 __ Pop(function_data, wasm_instance, valuetypes_array_ptr,
73 fp, BuiltinWasmInterpreterWrapperConstants::kGCScanSlotCountOffset));
76void PrepareForBuiltinCall(MacroAssembler* masm, Register array_start,
77 Register return_count, Register wasm_instance) {
78 UseScratchRegisterScope temps(masm);
79 Register GCScanCount = temps.AcquireX();
82 __ Mov(GCScanCount, 1);
86 fp, BuiltinWasmInterpreterWrapperConstants::kGCScanSlotCountOffset));
88 __ Push(array_start, return_count, xzr, wasm_instance);
91 Register wasm_trusted_instance = wasm_instance;
92 __ LoadTrustedPointerField(
93 wasm_trusted_instance,
95 kWasmTrustedInstanceDataIndirectPointerTag);
100 WasmTrustedInstanceData::kNativeContextOffset)));
103void RestoreAfterBuiltinCall(MacroAssembler* masm, Register wasm_instance,
104 Register return_count, Register array_start) {
107 __ Pop(wasm_instance, xzr, return_count, array_start);
110void PrepareForWasmToJsConversionBuiltinCall(
111 MacroAssembler* masm, Register return_count, Register result_index,
112 Register current_return_slot, Register valuetypes_array_ptr,
113 Register wasm_instance, Register fixed_array, Register jsarray,
114 bool load_native_context =
true) {
115 UseScratchRegisterScope temps(masm);
116 Register GCScanCount = temps.AcquireX();
121 __ Mov(GCScanCount, 3);
125 fp, BuiltinWasmInterpreterWrapperConstants::kGCScanSlotCountOffset));
126 __ Push(return_count, result_index, current_return_slot, valuetypes_array_ptr,
127 xzr, wasm_instance, fixed_array, jsarray);
128 if (load_native_context) {
130 Register wasm_trusted_instance = wasm_instance;
131 __ LoadTrustedPointerField(
132 wasm_trusted_instance,
133 FieldMemOperand(wasm_instance, WasmInstanceObject::kTrustedDataOffset),
134 kWasmTrustedInstanceDataIndirectPointerTag);
139 WasmTrustedInstanceData::kNativeContextOffset)));
143void RestoreAfterWasmToJsConversionBuiltinCall(
144 MacroAssembler* masm, Register jsarray, Register fixed_array,
145 Register wasm_instance, Register valuetypes_array_ptr,
146 Register current_return_slot, Register result_index,
147 Register return_count) {
150 __ Pop(jsarray, fixed_array, wasm_instance, xzr, valuetypes_array_ptr,
151 current_return_slot, result_index, return_count);
155 fp, BuiltinWasmInterpreterWrapperConstants::kGCScanSlotCountOffset));
160void Builtins::Generate_WasmInterpreterEntry(MacroAssembler* masm) {
173 __ EnterFrame(StackFrame::WASM_INTERPRETER_ENTRY);
176 __ Push(function_index, array_start);
178 __ CallRuntime(Runtime::kWasmRunInterpreter, 3);
181 __ LeaveFrame(StackFrame::WASM_INTERPRETER_ENTRY);
185void LoadFunctionDataAndWasmInstance(MacroAssembler* masm,
186 Register function_data,
187 Register wasm_instance) {
189 Register shared_function_info = closure;
191 shared_function_info,
196 __ LoadTrustedPointerField(
199 SharedFunctionInfo::kTrustedFunctionDataOffset),
202 shared_function_info =
no_reg;
204 Register trusted_instance_data = wasm_instance;
206 __ DecompressProtected(
207 trusted_instance_data,
209 WasmExportedFunctionData::kProtectedInstanceDataOffset -
213 trusted_instance_data,
215 WasmExportedFunctionData::kProtectedInstanceDataOffset -
221 WasmTrustedInstanceData::kInstanceObjectOffset));
224void LoadFromSignature(MacroAssembler* masm, Register valuetypes_array_ptr,
225 Register return_count, Register param_count) {
226 Register signature = valuetypes_array_ptr;
231 valuetypes_array_ptr = signature;
232 __ Ldr(valuetypes_array_ptr,
236void LoadValueTypesArray(MacroAssembler* masm, Register function_data,
237 Register valuetypes_array_ptr, Register return_count,
238 Register param_count, Register signature_data) {
242 WasmExportedFunctionData::kPackedArgsSizeOffset));
243 __ SmiToInt32(signature_data);
245 Register signature = valuetypes_array_ptr;
249 LoadFromSignature(masm, valuetypes_array_ptr, return_count, param_count);
252class RegisterAllocator {
256 Scoped(RegisterAllocator* allocator, Register*
reg)
265 explicit RegisterAllocator(
const CPURegList&
registers)
267 void Ask(Register*
reg) {
274 void Pinned(
const Register& requested, Register*
reg) {
289 void Reserve(
const Register&
reg) {
297 void Reserve(
const Register& reg1,
const Register& reg2,
298 const Register& reg3 =
NoReg,
const Register& reg4 =
NoReg,
299 const Register& reg5 =
NoReg,
const Register& reg6 =
NoReg) {
308 bool IsUsed(
const Register&
reg) {
312 void ResetExcept(
const Register& reg1 =
NoReg,
const Register& reg2 =
NoReg,
313 const Register& reg3 =
NoReg,
const Register& reg4 =
NoReg,
314 const Register& reg5 =
NoReg,
const Register& reg6 =
NoReg,
315 const Register& reg7 =
NoReg) {
334 static RegisterAllocator WithAllocatableGeneralRegisters() {
339 list.set_bits(0xffff);
340 return RegisterAllocator(list);
349#define DEFINE_REG(Name) \
350 Register Name = no_reg; \
353#define DEFINE_REG_W(Name) \
357#define ASSIGN_REG(Name) regs.Ask(&Name);
359#define ASSIGN_REG_W(Name) \
363#define DEFINE_PINNED(Name, Reg) \
364 Register Name = no_reg; \
365 regs.Pinned(Reg, &Name);
367#define DEFINE_SCOPED(Name) \
369 RegisterAllocator::Scoped scope_##Name(®s, &Name);
371#define FREE_REG(Name) regs.Free(&Name);
375void Builtins::Generate_GenericJSToWasmInterpreterWrapper(
376 MacroAssembler* masm) {
377 auto regs = RegisterAllocator::WithAllocatableGeneralRegisters();
379 __ EnterFrame(StackFrame::JS_TO_WASM);
400 constexpr int kMarkerOffset =
401 BuiltinWasmInterpreterWrapperConstants::kGCScanSlotCountOffset +
404 constexpr int kInParamCountOffset =
405 BuiltinWasmInterpreterWrapperConstants::kGCScanSlotCountOffset -
408 constexpr int kParamCountOffset =
409 BuiltinWasmInterpreterWrapperConstants::kParamCountOffset;
410 constexpr int kReturnCountOffset =
411 BuiltinWasmInterpreterWrapperConstants::kReturnCountOffset;
412 constexpr int kSigRepsOffset =
413 BuiltinWasmInterpreterWrapperConstants::kSigRepsOffset;
414 constexpr int kValueTypesArrayStartOffset =
415 BuiltinWasmInterpreterWrapperConstants::kValueTypesArrayStartOffset;
417 constexpr int kArgRetsAddressOffset =
418 BuiltinWasmInterpreterWrapperConstants::kArgRetsAddressOffset;
421 constexpr int kArgRetsIsArgsOffset =
422 BuiltinWasmInterpreterWrapperConstants::kArgRetsIsArgsOffset;
424 constexpr int kCurrentIndexOffset =
425 BuiltinWasmInterpreterWrapperConstants::kCurrentIndexOffset;
430 constexpr int kSignatureDataOffset =
431 BuiltinWasmInterpreterWrapperConstants::kSignatureDataOffset;
434 constexpr int kNumSpillSlots =
436 constexpr int kNum16BytesAlignedSpillSlots = 2 * ((kNumSpillSlots + 1) / 2);
449 LoadFunctionDataAndWasmInstance(masm, function_data, wasm_instance);
451 regs.ResetExcept(function_data, wasm_instance);
471 LoadValueTypesArray(masm, function_data, valuetypes_array_ptr, return_count,
472 param_count, signature_data);
473 __ Str(signature_data,
MemOperand(fp, kSignatureDataOffset));
474 Register array_size = signature_data;
475 __ And(array_size, array_size,
485 __ Str(return_count,
MemOperand(fp, kReturnCountOffset));
486 __ Str(valuetypes_array_ptr,
MemOperand(fp, kSigRepsOffset));
487 __ Str(valuetypes_array_ptr,
MemOperand(fp, kValueTypesArrayStartOffset));
496 __ Add(scratch, array_size, Immediate(8));
497 __ And(array_size, scratch, Immediate(-16));
500 __ Sub(array_start, sp, array_size);
501 __ Mov(sp, array_start);
512 __ Str(current_param_slot,
MemOperand(fp, kArgRetsAddressOffset));
514 Label prepare_for_wasm_call;
515 __ Cmp(param_count, 0);
518 __ B(&prepare_for_wasm_call,
eq);
535 constexpr int kValueTypeSize =
sizeof(wasm::ValueType);
536 static_assert(kValueTypeSize == 4);
537 const int32_t kValueTypeSizeLog2 =
log2(kValueTypeSize);
539 __ Add(valuetypes_array_ptr, valuetypes_array_ptr,
540 Operand(return_count,
LSL, kValueTypeSizeLog2));
543 __ Mov(current_index, xzr);
548 Label loop_through_params;
549 __ bind(&loop_through_params);
552 constexpr int kArgsOffset =
555 __ Add(scratch, fp, kArgsOffset);
558 __ Str(current_index,
MemOperand(fp, kCurrentIndexOffset));
560 DEFINE_REG_W(valuetype);
568 Label param_conversion_done;
569 Label check_ref_param;
572 __ B(&check_ref_param,
ne);
573 __ JumpIfNotSmi(param, &convert_param);
579 __ Add(current_param_slot, current_param_slot, Immediate(
sizeof(int32_t)));
580 __ jmp(¶m_conversion_done);
582 Label handle_ref_param;
583 __ bind(&check_ref_param);
586 __ Tst(valuetype, Immediate(1));
587 __ B(&convert_param,
eq);
590 __ bind(&handle_ref_param);
592 __ And(scratch, current_param_slot, Immediate(0x04));
593 __ Add(current_param_slot, current_param_slot, scratch);
600 __ bind(¶m_conversion_done);
602 __ Add(valuetypes_array_ptr, valuetypes_array_ptr, kValueTypeSize);
604 __ Ldr(current_index,
MemOperand(fp, kCurrentIndexOffset));
606 __ Add(current_index, current_index, 1);
607 __ cmp(current_index, scratch);
608 __ B(&loop_through_params,
lt);
609 __ Str(current_index,
MemOperand(fp, kCurrentIndexOffset));
610 __ jmp(&prepare_for_wasm_call);
615 __ bind(&convert_param);
624 PrepareForJsToWasmConversionBuiltinCall(masm, current_param_slot,
625 valuetypes_array_ptr, wasm_instance,
628 Label param_kWasmI32_not_smi, param_kWasmI64, param_kWasmF32, param_kWasmF64,
632 __ B(¶m_kWasmI32_not_smi,
eq);
634 __ B(¶m_kWasmI64,
eq);
636 __ B(¶m_kWasmF32,
eq);
638 __ B(¶m_kWasmF64,
eq);
642 __ B(&throw_type_error,
eq);
647 __ bind(¶m_kWasmI32_not_smi);
651 RestoreAfterJsToWasmConversionBuiltinCall(masm, function_data, wasm_instance,
652 valuetypes_array_ptr,
655 __ Add(current_param_slot, current_param_slot, Immediate(
sizeof(int32_t)));
656 __ jmp(¶m_conversion_done);
658 __ bind(¶m_kWasmI64);
660 RestoreAfterJsToWasmConversionBuiltinCall(masm, function_data, wasm_instance,
661 valuetypes_array_ptr,
664 __ Add(current_param_slot, current_param_slot, Immediate(
sizeof(int64_t)));
665 __ jmp(¶m_conversion_done);
667 __ bind(¶m_kWasmF32);
670 RestoreAfterJsToWasmConversionBuiltinCall(masm, function_data, wasm_instance,
671 valuetypes_array_ptr,
674 __ Add(current_param_slot, current_param_slot, Immediate(
sizeof(
float)));
675 __ jmp(¶m_conversion_done);
677 __ bind(¶m_kWasmF64);
680 RestoreAfterJsToWasmConversionBuiltinCall(masm, function_data, wasm_instance,
681 valuetypes_array_ptr,
684 __ Add(current_param_slot, current_param_slot, Immediate(
sizeof(
double)));
685 __ jmp(¶m_conversion_done);
687 __ bind(&throw_type_error);
689 __ CallRuntime(Runtime::kWasmThrowJSTypeError);
696 regs.ResetExcept(function_data, wasm_instance, array_start, scratch);
698 __ bind(&prepare_for_wasm_call);
701 DEFINE_REG_W(scratch32);
704 __ Mov(scratch32, 1);
710 MemOperand(function_data, WasmExportedFunctionData::kFunctionIndexOffset -
716 constexpr int kWasmCallGCScanSlotCount = 1;
717 __ Mov(scratch, kWasmCallGCScanSlotCount);
721 fp, BuiltinWasmInterpreterWrapperConstants::kGCScanSlotCountOffset));
730 __ Ldr(array_start,
MemOperand(fp, kArgRetsAddressOffset));
735 __ Ldr(array_start,
MemOperand(fp, kArgRetsAddressOffset));
744 regs.ResetExcept(wasm_instance, array_start, scratch);
751 __ Ldr(return_count,
MemOperand(fp, kReturnCountOffset));
756 fp, BuiltinWasmInterpreterWrapperConstants::kCurrentIndexOffset));
759 __ Mov(fixed_array, xzr);
761 __ Mov(jsarray, xzr);
763 Label all_results_conversion_done, start_return_conversion, return_jsarray;
765 __ cmp(return_count, 1);
766 __ B(&start_return_conversion,
eq);
767 __ B(&return_jsarray,
gt);
770 __ LoadRoot(return_value, RootIndex::kUndefinedValue);
771 __ jmp(&all_results_conversion_done);
774 __ bind(&return_jsarray);
775 PrepareForBuiltinCall(masm, array_start, return_count, wasm_instance);
776 __ Mov(return_value, return_count);
777 __ SmiTag(return_value);
782 __ Mov(jsarray, return_value);
784 RestoreAfterBuiltinCall(masm, wasm_instance, return_count, array_start);
785 __ LoadTaggedField(fixed_array,
MemOperand(jsarray, JSArray::kElementsOffset -
788 __ bind(&start_return_conversion);
789 Register current_return_slot = array_start;
790 __ Ldr(current_return_slot,
MemOperand(fp, kArgRetsAddressOffset));
793 __ Mov(result_index, xzr);
796 __ Ldr(valuetypes_array_ptr,
MemOperand(fp, kValueTypesArrayStartOffset));
801 Label convert_return_value;
802 __ bind(&convert_return_value);
809 ASSIGN_REG_W(valuetype);
812 Label return_kWasmI32, return_kWasmI64, return_kWasmF32, return_kWasmF64,
816 __ B(&return_kWasmI32,
eq);
818 __ B(&return_kWasmI64,
eq);
820 __ B(&return_kWasmF32,
eq);
822 __ B(&return_kWasmF64,
eq);
825 __ Tst(valuetype, Immediate(1));
826 __ B(&return_kWasmRef,
ne);
832 Label return_value_done;
836 __ bind(&return_kWasmI32);
837 __ Ldr(return_value,
MemOperand(current_return_slot, 0));
838 __ Add(current_return_slot, current_return_slot,
839 Immediate(
sizeof(int32_t)));
842 __ SmiTag(return_value);
845 __ Adds(wzr, return_value.W(), return_value.W());
847 __ B(&to_heapnumber,
vs);
849 __ SmiTag(return_value);
852 __ jmp(&return_value_done);
856 __ bind(&to_heapnumber);
858 PrepareForWasmToJsConversionBuiltinCall(
859 masm, return_count, result_index, current_return_slot,
860 valuetypes_array_ptr, wasm_instance, fixed_array, jsarray);
863 RestoreAfterWasmToJsConversionBuiltinCall(
864 masm, jsarray, fixed_array, wasm_instance, valuetypes_array_ptr,
865 current_return_slot, result_index, return_count);
866 __ jmp(&return_value_done);
868 __ bind(&return_kWasmI64);
869 __ Ldr(return_value,
MemOperand(current_return_slot, 0));
870 __ Add(current_return_slot, current_return_slot, Immediate(
sizeof(int64_t)));
871 PrepareForWasmToJsConversionBuiltinCall(
872 masm, return_count, result_index, current_return_slot,
873 valuetypes_array_ptr, wasm_instance, fixed_array, jsarray);
875 RestoreAfterWasmToJsConversionBuiltinCall(
876 masm, jsarray, fixed_array, wasm_instance, valuetypes_array_ptr,
877 current_return_slot, result_index, return_count);
878 __ jmp(&return_value_done);
880 __ bind(&return_kWasmF32);
882 __ Add(current_return_slot, current_return_slot, Immediate(
sizeof(
float)));
883 PrepareForWasmToJsConversionBuiltinCall(
884 masm, return_count, result_index, current_return_slot,
885 valuetypes_array_ptr, wasm_instance, fixed_array, jsarray);
888 RestoreAfterWasmToJsConversionBuiltinCall(
889 masm, jsarray, fixed_array, wasm_instance, valuetypes_array_ptr,
890 current_return_slot, result_index, return_count);
891 __ jmp(&return_value_done);
893 __ bind(&return_kWasmF64);
895 __ Add(current_return_slot, current_return_slot, Immediate(
sizeof(
double)));
896 PrepareForWasmToJsConversionBuiltinCall(
897 masm, return_count, result_index, current_return_slot,
898 valuetypes_array_ptr, wasm_instance, fixed_array, jsarray);
901 RestoreAfterWasmToJsConversionBuiltinCall(
902 masm, jsarray, fixed_array, wasm_instance, valuetypes_array_ptr,
903 current_return_slot, result_index, return_count);
904 __ jmp(&return_value_done);
906 __ bind(&return_kWasmRef);
908 __ And(scratch, current_return_slot, Immediate(0x04));
909 __ Add(current_return_slot, current_return_slot, scratch);
910 __ Ldr(return_value,
MemOperand(current_return_slot, 0));
911 __ Add(current_return_slot, current_return_slot,
914 Label next_return_value;
916 __ bind(&return_value_done);
917 __ Add(valuetypes_array_ptr, valuetypes_array_ptr, Immediate(kValueTypeSize));
918 __ cmp(fixed_array, xzr);
919 __ B(&next_return_value,
eq);
923 __ Add(array_items, fixed_array,
925 __ StoreTaggedField(return_value,
MemOperand(array_items, result_index,
LSL,
928 Label skip_write_barrier;
930 __ CheckPageFlag(array_items,
932 &skip_write_barrier);
933 __ JumpIfSmi(return_value, &skip_write_barrier);
935 eq, &skip_write_barrier);
936 PrepareForWasmToJsConversionBuiltinCall(
937 masm, return_count, result_index, current_return_slot,
938 valuetypes_array_ptr, wasm_instance, fixed_array, jsarray,
false);
942 __ CallRecordWriteStubSaveRegisters(fixed_array, Operand(
offset),
944 RestoreAfterWasmToJsConversionBuiltinCall(
945 masm, jsarray, fixed_array, wasm_instance, valuetypes_array_ptr,
946 current_return_slot, result_index, return_count);
947 __ bind(&skip_write_barrier);
949 __ bind(&next_return_value);
950 __ Add(result_index, result_index, 1);
951 __ cmp(result_index, return_count);
952 __ B(&convert_return_value,
lt);
954 __ bind(&all_results_conversion_done);
959 __ cmp(fixed_array, xzr);
960 __ B(&do_return,
eq);
962 __ Mov(return_value, jsarray);
968 __ Ldr(in_param_count,
MemOperand(fp, kInParamCountOffset));
969 __ cmp(param_count, in_param_count);
970 __ csel(param_count, in_param_count, param_count,
lt);
975 __ LeaveFrame(StackFrame::JS_TO_WASM);
984 __ DropArguments(param_count);
988void Builtins::Generate_WasmInterpreterCWasmEntry(MacroAssembler* masm) {
989 Label
invoke, handler_entry, exit;
991 __ EnterFrame(StackFrame::C_WASM_ENTRY);
997 NoRootArrayScope no_root_array(masm);
1011 __ Fmov(fp_zero, 0.0);
1016#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
1019 IsolateData::cage_base_offset());
1024 UseScratchRegisterScope temps(masm);
1025 Register scratch = temps.AcquireX();
1026 __ Mov(scratch, sp);
1028 MemOperand(fp, WasmInterpreterCWasmEntryConstants::kSPFPOffset));
1036 MemOperand(fp, WasmInterpreterCWasmEntryConstants::kCEntryFPOffset));
1048 Assembler::BlockPoolsScope block_pools(masm);
1050 __ BindExceptionHandler(&handler_entry);
1054 masm->isolate()->builtins()->SetCWasmInterpreterEntryHandlerOffset(
1055 handler_entry.pos());
1070 UseScratchRegisterScope temps(masm);
1071 Register scratch = temps.AcquireX();
1072 __ Mov(scratch, sp);
1082 "Unexpected offset for StackHandlerConstants::kNextOffset");
1103 __ LeaveFrame(StackFrame::C_WASM_ENTRY);
1107void Builtins::Generate_GenericWasmToJSInterpreterWrapper(
1108 MacroAssembler* masm) {
1109 auto regs = RegisterAllocator::WithAllocatableGeneralRegisters();
1117 __ EnterFrame(StackFrame::WASM_TO_JS);
1149 static_assert(WasmToJSInterpreterFrameConstants::kGCSPOffset ==
1150 WasmToJSInterpreterFrameConstants::kGCScanSlotLimitOffset -
1152 constexpr int kPackedArrayOffset =
1159 constexpr int kResultIndexOffset = kParamIndexOffset;
1160 constexpr int kValueTypesArrayStartOffset =
1162 constexpr int kCurrentParamOffset =
1165 constexpr int kCurrentResultOffset = kCurrentParamOffset;
1168 constexpr int kNumSpillSlots =
1169 (WasmToJSInterpreterFrameConstants::kGCScanSlotLimitOffset -
1170 kCurrentParamOffset) /
1172 static_assert((kNumSpillSlots % 2) == 0);
1176 __ Str(packed_args,
MemOperand(fp, kPackedArrayOffset));
1179 __ Str(xzr,
MemOperand(fp, WasmToJSInterpreterFrameConstants::kGCSPOffset));
1183 WasmToJSInterpreterFrameConstants::kGCScanSlotLimitOffset));
1187 shared_function_info,
1196 context,
FieldMemOperand(target_js_function, JSFunction::kContextOffset));
1197 __ Mov(
cp, context);
1201 Label receiver_undefined;
1202 Label calculate_js_function_arity;
1206 SharedFunctionInfo::kFlagsOffset));
1207 __ Tst(flags, Immediate(SharedFunctionInfo::IsNativeBit::kMask |
1208 SharedFunctionInfo::IsStrictBit::kMask));
1210 __ B(&receiver_undefined,
ne);
1212 __ B(&calculate_js_function_arity);
1214 __ bind(&receiver_undefined);
1215 __ LoadRoot(
receiver, RootIndex::kUndefinedValue);
1217 __ bind(&calculate_js_function_arity);
1223 Register valuetypes_array_ptr = signature;
1224 LoadFromSignature(masm, valuetypes_array_ptr, return_count, param_count);
1225 __ Str(param_count,
MemOperand(fp, kParamCountOffset));
1234 __ Mov(scratch, sp);
1237 WasmToJSInterpreterFrameConstants::kGCScanSlotLimitOffset));
1240 __ Push(callable,
cp);
1241 __ Add(array_size, param_count, Immediate(1));
1243 __ Add(scratch, array_size, Immediate(1));
1244 __ And(array_size, scratch, Immediate(-2));
1249 __ Sub(scratch, array_size, Immediate(1));
1254 __ Mov(param_index, xzr);
1263 __ Str(return_count,
MemOperand(fp, kReturnCountOffset));
1264 __ Str(valuetypes_array_ptr,
MemOperand(fp, kValueTypesArrayStartOffset));
1266 Label prepare_for_js_call;
1267 __ Cmp(param_count, 0);
1269 __ B(&prepare_for_js_call,
eq);
1273 __ Mov(current_param_slot_offset, Immediate(0));
1279 constexpr int kValueTypeSize =
sizeof(wasm::ValueType);
1280 static_assert(kValueTypeSize == 4);
1281 const int32_t kValueTypeSizeLog2 =
log2(kValueTypeSize);
1282 __ Add(valuetypes_array_ptr, valuetypes_array_ptr,
1283 Operand(return_count,
LSL, kValueTypeSizeLog2));
1284 DEFINE_REG_W(valuetype);
1293 Register param = target_js_function;
1295 Label loop_copy_param_ref, load_ref_param, set_and_move;
1297 __ bind(&loop_copy_param_ref);
1298 __ Ldr(valuetype,
MemOperand(valuetypes_array_ptr, 0));
1299 __ Tst(valuetype, Immediate(1));
1300 __ B(&load_ref_param,
ne);
1306 Label inc_param_32bit;
1308 __ B(&inc_param_32bit,
eq);
1310 __ B(&inc_param_32bit,
eq);
1312 Label inc_param_64bit;
1314 __ B(&inc_param_64bit,
eq);
1316 __ B(&inc_param_64bit,
eq);
1321 __ bind(&inc_param_32bit);
1322 __ Add(current_param_slot_offset, current_param_slot_offset,
1323 Immediate(
sizeof(int32_t)));
1324 __ B(&set_and_move);
1326 __ bind(&inc_param_64bit);
1327 __ Add(current_param_slot_offset, current_param_slot_offset,
1328 Immediate(
sizeof(int64_t)));
1329 __ B(&set_and_move);
1331 __ bind(&load_ref_param);
1336 __ Ldr(param,
MemOperand(packed_args, current_param_slot_offset));
1337 __ Add(current_param_slot_offset, current_param_slot_offset,
1340 __ bind(&set_and_move);
1341 __ Add(param_index, param_index, 1);
1344 __ Add(valuetypes_array_ptr, valuetypes_array_ptr,
1345 Immediate(kValueTypeSize));
1346 __ Cmp(param_index, param_count);
1347 __ B(&loop_copy_param_ref,
lt);
1351 __ Ldr(return_count,
MemOperand(fp, kReturnCountOffset));
1352 __ Ldr(valuetypes_array_ptr,
MemOperand(fp, kValueTypesArrayStartOffset));
1353 __ Add(valuetypes_array_ptr, valuetypes_array_ptr,
1354 Operand(return_count,
LSL, kValueTypeSizeLog2));
1355 __ Mov(current_param_slot_offset, xzr);
1356 __ Mov(param_index, xzr);
1361 Label loop_through_params;
1362 __ bind(&loop_through_params);
1364 __ Ldr(valuetype,
MemOperand(valuetypes_array_ptr, 0));
1371 Label param_conversion_done, check_ref_param, skip_ref_param, convert_param;
1373 __ B(&check_ref_param,
ne);
1376 __ Ldr(param.W(),
MemOperand(packed_args, current_param_slot_offset));
1383 __ Adds(wzr, param.W(), param.W());
1385 __ B(&convert_param,
vs);
1392 __ Add(param_index, param_index, 1);
1394 __ Add(current_param_slot_offset, current_param_slot_offset,
sizeof(int32_t));
1396 __ B(¶m_conversion_done);
1399 __ bind(&check_ref_param);
1400 __ Tst(valuetype, Immediate(1));
1401 __ B(&convert_param,
eq);
1403 __ bind(&skip_ref_param);
1404 __ Add(param_index, param_index, 1);
1405 __ Add(current_param_slot_offset, current_param_slot_offset,
1407 __ B(¶m_conversion_done);
1412 __ bind(&convert_param);
1420 __ Str(param_index,
MemOperand(fp, kParamIndexOffset));
1421 __ Str(valuetypes_array_ptr,
MemOperand(fp, kValueTypesArrayStartOffset));
1422 __ Str(current_param_slot_offset,
MemOperand(fp, kCurrentParamOffset));
1424 Label param_kWasmI32_not_smi;
1425 Label param_kWasmI64;
1426 Label param_kWasmF32;
1427 Label param_kWasmF64;
1428 Label finish_param_conversion;
1431 __ B(¶m_kWasmI32_not_smi,
eq);
1433 __ B(¶m_kWasmI64,
eq);
1435 __ B(¶m_kWasmF32,
eq);
1437 __ B(¶m_kWasmF64,
eq);
1443 __ bind(¶m_kWasmI32_not_smi);
1448 __ jmp(&finish_param_conversion);
1450 __ bind(¶m_kWasmI64);
1451 __ Ldr(param,
MemOperand(packed_args, current_param_slot_offset));
1454 __ jmp(&finish_param_conversion);
1456 __ bind(¶m_kWasmF32);
1457 __ Ldr(v0,
MemOperand(packed_args, current_param_slot_offset));
1461 __ jmp(&finish_param_conversion);
1463 __ bind(¶m_kWasmF64);
1464 __ Ldr(d0,
MemOperand(packed_args, current_param_slot_offset));
1470 __ bind(&finish_param_conversion);
1472 __ Ldr(current_param_slot_offset,
MemOperand(fp, kCurrentParamOffset));
1473 __ Add(current_param_slot_offset, current_param_slot_offset,
increment);
1474 __ Ldr(valuetypes_array_ptr,
MemOperand(fp, kValueTypesArrayStartOffset));
1475 __ Ldr(param_index,
MemOperand(fp, kParamIndexOffset));
1476 __ Ldr(packed_args,
MemOperand(fp, kPackedArrayOffset));
1477 __ Ldr(param_count,
MemOperand(fp, kParamCountOffset));
1479 __ Add(param_index, param_index, 1);
1485 __ bind(¶m_conversion_done);
1487 __ Add(valuetypes_array_ptr, valuetypes_array_ptr, Immediate(kValueTypeSize));
1488 __ Cmp(param_index, param_count);
1489 __ B(&loop_through_params,
lt);
1494 __ bind(&prepare_for_js_call);
1501 regs.ResetExcept(param, packed_args, valuetypes_array_ptr, context,
1502 return_count, valuetype, scratch);
1533 __ Mov(scratch, sp);
1536 WasmToJSInterpreterFrameConstants::kGCScanSlotLimitOffset));
1541 __ Ldr(return_count,
MemOperand(fp, kReturnCountOffset));
1542 __ Ldr(packed_args,
MemOperand(fp, kPackedArrayOffset));
1544 __ Ldr(valuetypes_array_ptr,
1548 __ Mov(result_index, xzr);
1550 __ Mov(current_result_offset, xzr);
1553 Label convert_return;
1556 Label loop_copy_return_refs;
1557 __ cmp(return_count, Immediate(1));
1558 __ B(&all_done,
lt);
1559 __ B(&convert_return,
eq);
1563 __ Mov(fixed_array, xzr);
1575 kCurrentParamOffset == kContextOffset + 0x10,
1576 "Expected two (tagged) slots between 'context' and 'current_param'.");
1582 WasmToJSInterpreterFrameConstants::kGCScanSlotLimitOffset));
1594 WasmToJSInterpreterFrameConstants::kGCScanSlotLimitOffset));
1596 __ Ldr(return_count,
MemOperand(fp, kReturnCountOffset));
1597 __ Ldr(packed_args,
MemOperand(fp, kPackedArrayOffset));
1599 __ Ldr(valuetypes_array_ptr,
1601 __ Mov(result_index, xzr);
1602 __ Mov(current_result_offset, xzr);
1604 __ Add(scratch, fixed_array,
1606 __ LoadTaggedField(return_reg,
1612 __ bind(&convert_return);
1615 __ Str(current_result_offset,
MemOperand(fp, kCurrentResultOffset));
1616 __ Str(result_index,
MemOperand(fp, kResultIndexOffset));
1617 __ Str(valuetypes_array_ptr,
MemOperand(fp, kValueTypesArrayStartOffset));
1622 __ Ldr(valuetype,
MemOperand(valuetypes_array_ptr, 0));
1624 Label return_kWasmI32;
1625 Label return_kWasmI32_not_smi;
1626 Label return_kWasmI64;
1627 Label return_kWasmF32;
1628 Label return_kWasmF64;
1629 Label return_kWasmRef;
1634 __ B(&return_kWasmI32,
eq);
1636 __ B(&return_kWasmI64,
eq);
1638 __ B(&return_kWasmF32,
eq);
1640 __ B(&return_kWasmF64,
eq);
1642 __ Tst(valuetype, Immediate(1));
1643 __ B(&return_kWasmRef,
ne);
1648 __ bind(&return_kWasmI32);
1649 __ JumpIfNotSmi(return_reg, &return_kWasmI32_not_smi);
1652 __ AssertZeroExtended(return_reg);
1653 __ Ldr(packed_args,
MemOperand(fp, kPackedArrayOffset));
1654 __ Str(return_reg.W(),
MemOperand(packed_args, current_result_offset));
1655 __ Add(current_result_offset, current_result_offset,
1656 Immediate(
sizeof(int32_t)));
1657 __ jmp(&return_done);
1659 __ bind(&return_kWasmI32_not_smi);
1662 __ AssertZeroExtended(return_reg);
1663 __ Ldr(packed_args,
MemOperand(fp, kPackedArrayOffset));
1664 __ Ldr(current_result_offset,
MemOperand(fp, kCurrentResultOffset));
1665 __ Str(return_reg.W(),
MemOperand(packed_args, current_result_offset));
1666 __ Add(current_result_offset, current_result_offset,
1667 Immediate(
sizeof(int32_t)));
1668 __ jmp(&return_done);
1670 __ bind(&return_kWasmI64);
1672 __ Ldr(packed_args,
MemOperand(fp, kPackedArrayOffset));
1673 __ Ldr(current_result_offset,
MemOperand(fp, kCurrentResultOffset));
1674 __ Str(return_reg,
MemOperand(packed_args, current_result_offset));
1675 __ Add(current_result_offset, current_result_offset,
1676 Immediate(
sizeof(int64_t)));
1677 __ jmp(&return_done);
1679 __ bind(&return_kWasmF32);
1682 __ Ldr(packed_args,
MemOperand(fp, kPackedArrayOffset));
1683 __ Ldr(current_result_offset,
MemOperand(fp, kCurrentResultOffset));
1685 __ Add(current_result_offset, current_result_offset,
1686 Immediate(
sizeof(
float)));
1687 __ jmp(&return_done);
1689 __ bind(&return_kWasmF64);
1692 __ Ldr(packed_args,
MemOperand(fp, kPackedArrayOffset));
1693 __ Ldr(current_result_offset,
MemOperand(fp, kCurrentResultOffset));
1695 __ Add(current_result_offset, current_result_offset,
1696 Immediate(
sizeof(
double)));
1697 __ jmp(&return_done);
1699 __ bind(&return_kWasmRef);
1700 __ Ldr(packed_args,
MemOperand(fp, kPackedArrayOffset));
1703 __ Add(current_result_offset, current_result_offset,
1704 Immediate(
sizeof(
double)));
1707 __ bind(&return_done);
1712 __ Ldr(valuetypes_array_ptr,
MemOperand(fp, kValueTypesArrayStartOffset));
1713 __ Add(valuetypes_array_ptr, valuetypes_array_ptr, Immediate(kValueTypeSize));
1714 __ Ldr(result_index,
MemOperand(fp, kResultIndexOffset));
1715 __ Add(result_index, result_index, Immediate(1));
1717 __ cmp(result_index, scratch);
1718 __ B(&loop_copy_return_refs,
ge);
1720 __ Add(scratch, fixed_array,
1722 __ LoadTaggedField(return_reg,
1724 __ jmp(&convert_return);
1733 __ bind(&loop_copy_return_refs);
1737 __ Ldr(return_count,
MemOperand(fp, kReturnCountOffset));
1738 __ cmp(return_count, Immediate(1));
1739 __ B(&all_done,
eq);
1741 Label copy_return_if_ref, copy_return_ref, done_copy_return_ref;
1742 __ Ldr(packed_args,
MemOperand(fp, kPackedArrayOffset));
1744 __ Ldr(valuetypes_array_ptr,
1746 __ Mov(result_index, xzr);
1747 __ Mov(current_result_offset, xzr);
1750 __ bind(©_return_if_ref);
1751 __ Ldr(valuetype,
MemOperand(valuetypes_array_ptr, 0));
1753 __ Tst(valuetype, Immediate(1));
1754 __ B(©_return_ref,
ne);
1756 Label inc_result_32bit;
1758 __ B(&inc_result_32bit,
eq);
1760 __ B(&inc_result_32bit,
eq);
1762 Label inc_result_64bit;
1764 __ B(&inc_result_64bit,
eq);
1766 __ B(&inc_result_64bit,
eq);
1771 __ bind(&inc_result_32bit);
1772 __ Add(current_result_offset, current_result_offset,
1773 Immediate(
sizeof(int32_t)));
1774 __ jmp(&done_copy_return_ref);
1776 __ bind(&inc_result_64bit);
1777 __ Add(current_result_offset, current_result_offset,
1778 Immediate(
sizeof(int64_t)));
1779 __ jmp(&done_copy_return_ref);
1781 __ bind(©_return_ref);
1782 __ Add(scratch, fixed_array,
1784 __ LoadTaggedField(return_reg,
1786 __ Str(return_reg,
MemOperand(packed_args, current_result_offset));
1787 __ Add(current_result_offset, current_result_offset,
1791 __ bind(&done_copy_return_ref);
1792 __ Add(valuetypes_array_ptr, valuetypes_array_ptr, Immediate(kValueTypeSize));
1793 __ Add(result_index, result_index, Immediate(1));
1794 __ cmp(result_index, return_count);
1795 __ B(©_return_if_ref,
lt);
1803 DEFINE_REG_W(scratch32);
1806 __ Mov(scratch32, Immediate(1));
1810 __ LeaveFrame(StackFrame::WASM_TO_JS);
1812 __ Mov(x0, Immediate(WasmToJSInterpreterFrameConstants::kSuccess));
RegisterAllocator * allocator_
std::vector< Register * > allocated_registers_
#define DEFINE_PINNED(Name, Reg)
#define BUILTIN_CODE(isolate, name)
static constexpr Builtin Call(ConvertReceiverMode=ConvertReceiverMode::kAny)
static ExternalReference Create(const SCTableReference &table_ref)
static constexpr uint32_t thread_in_wasm_flag_address_offset()
static constexpr MainThreadFlags kPointersToHereAreInterestingMask
static constexpr MainThreadFlags kPointersFromHereAreInterestingMask
static constexpr size_t kReturnCountOffset
static constexpr size_t kRepsOffset
static constexpr size_t kParameterCountOffset
static constexpr Tagged< Smi > zero()
static const int kNextOffset
static const int kSlotCount
static constexpr int SharedFunctionInfoOffsetInTaggedJSFunction()
static constexpr int ToTagged(int offset)
RegListBase< RegisterT > registers
void Add(RWDigits Z, Digits X, Digits Y)
int invoke(const char *params)
void And(LiftoffAssembler *lasm, Register dst, Register lhs, Register rhs)
void Sub(LiftoffAssembler *lasm, Register dst, Register lhs, Register rhs)
constexpr IndependentValueType kWasmF32
constexpr IndependentValueType kWasmI32
constexpr IndependentValueType kWasmS128
constexpr IndependentValueType kWasmF64
constexpr IndependentValueType kWasmI64
constexpr Register no_reg
constexpr Register kRootRegister
@ kUnknownIndirectPointerTag
RegListBase< Register > RegList
constexpr int kPCOnStackSize
constexpr Register kJavaScriptCallArgCountRegister
constexpr int kSystemPointerSizeLog2
constexpr int kFPOnStackSize
MemOperand FieldMemOperand(Register object, int offset)
constexpr int kSystemPointerSize
constexpr DoubleRegister kFPReturnRegister0
constexpr int kTaggedSizeLog2
constexpr Register kReturnRegister0
constexpr Register kWasmImplicitArgRegister
constexpr Register kContextRegister
constexpr bool SmiValuesAre32Bits()
constexpr Register kPtrComprCageBaseRegister
constexpr int kXRegSizeInBits
constexpr Register kJSFunctionRegister
constexpr Register padreg
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define OFFSET_OF_DATA_START(Type)