Commit 607414e9 authored by evih's avatar evih Committed by Commit Bot

[wasm] Use js-to-wasm generic wrapper for f32 and f64 return

Currently, the generic wrapper is used for i32 and i64 params and 0 or 1
i32, i64, f32, f64 return value.

Bug: v8:10701
Change-Id: I610172995457354879afd3c9c2c6c2d55c2b700f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2414219Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Eva Herencsárová <evih@google.com>
Cr-Commit-Position: refs/heads/master@{#70090}
parent 98db2c84
...@@ -3589,8 +3589,6 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) { ...@@ -3589,8 +3589,6 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
kFrameMarkerOffset - kNumSpillSlots * kSystemPointerSize; kFrameMarkerOffset - kNumSpillSlots * kSystemPointerSize;
__ leaq(rsp, MemOperand(rbp, kLastSpillOffset)); __ leaq(rsp, MemOperand(rbp, kLastSpillOffset));
__ movq(param_count, MemOperand(rbp, kParamCountOffset));
// Unset thread_in_wasm_flag. // Unset thread_in_wasm_flag.
thread_in_wasm_flag_addr = r8; thread_in_wasm_flag_addr = r8;
__ movq( __ movq(
...@@ -3616,6 +3614,7 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) { ...@@ -3616,6 +3614,7 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
Label return_done; Label return_done;
__ bind(&return_done); __ bind(&return_done);
__ movq(param_count, MemOperand(rbp, kParamCountOffset));
// ------------------------------------------- // -------------------------------------------
// Deconstrunct the stack frame. // Deconstrunct the stack frame.
...@@ -3690,6 +3689,10 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) { ...@@ -3690,6 +3689,10 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
// Return conversions. // Return conversions.
// ------------------------------------------- // -------------------------------------------
__ bind(&convert_return); __ bind(&convert_return);
// We have to make sure that the kGCScanSlotCount is set correctly when we
// call the builtins for conversion. For these builtins it's the same as for
// the Wasm call, that is, kGCScanSlotCount = 0, so we don't have to reset it.
// We don't need the JS context for these builtin calls.
__ movq(valuetypes_array_ptr, MemOperand(rbp, kValueTypesArrayStartOffset)); __ movq(valuetypes_array_ptr, MemOperand(rbp, kValueTypesArrayStartOffset));
// The first valuetype of the array is the return's valuetype. // The first valuetype of the array is the return's valuetype.
...@@ -3698,6 +3701,8 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) { ...@@ -3698,6 +3701,8 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
Label return_kWasmI32; Label return_kWasmI32;
Label return_kWasmI64; Label return_kWasmI64;
Label return_kWasmF32;
Label return_kWasmF64;
__ cmpq(valuetype, Immediate(wasm::kWasmI32.raw_bit_field())); __ cmpq(valuetype, Immediate(wasm::kWasmI32.raw_bit_field()));
__ j(equal, &return_kWasmI32); __ j(equal, &return_kWasmI32);
...@@ -3705,14 +3710,13 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) { ...@@ -3705,14 +3710,13 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
__ cmpq(valuetype, Immediate(wasm::kWasmI64.raw_bit_field())); __ cmpq(valuetype, Immediate(wasm::kWasmI64.raw_bit_field()));
__ j(equal, &return_kWasmI64); __ j(equal, &return_kWasmI64);
__ int3(); __ cmpq(valuetype, Immediate(wasm::kWasmF32.raw_bit_field()));
__ j(equal, &return_kWasmF32);
__ bind(&return_kWasmI64); __ cmpq(valuetype, Immediate(wasm::kWasmF64.raw_bit_field()));
// We don't need the JS context for this builtin call. __ j(equal, &return_kWasmF64);
__ Call(BUILTIN_CODE(masm->isolate(), I64ToBigInt), RelocInfo::CODE_TARGET);
// We will need the parameter_count later. __ int3();
__ movq(param_count, MemOperand(rbp, kParamCountOffset));
__ jmp(&return_done);
__ bind(&return_kWasmI32); __ bind(&return_kWasmI32);
Label to_heapnumber; Label to_heapnumber;
...@@ -3732,17 +3736,29 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) { ...@@ -3732,17 +3736,29 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
} }
__ jmp(&return_done); __ jmp(&return_done);
// Handle the conversion of the return value to HeapNumber when it cannot be a // Handle the conversion of the I32 return value to HeapNumber when it cannot
// smi. // be a smi.
__ bind(&to_heapnumber); __ bind(&to_heapnumber);
// We have to make sure that the kGCScanSlotCount is set correctly. For this
// builtin it's the same as for the Wasm call = 0, so we don't have to reset
// it.
// We don't need the JS context for this builtin call.
__ Call(BUILTIN_CODE(masm->isolate(), WasmInt32ToHeapNumber), __ Call(BUILTIN_CODE(masm->isolate(), WasmInt32ToHeapNumber),
RelocInfo::CODE_TARGET); RelocInfo::CODE_TARGET);
// We will need the parameter_count later. __ jmp(&return_done);
__ movq(param_count, MemOperand(rbp, kParamCountOffset));
__ bind(&return_kWasmI64);
__ Call(BUILTIN_CODE(masm->isolate(), I64ToBigInt), RelocInfo::CODE_TARGET);
__ jmp(&return_done);
__ bind(&return_kWasmF32);
// The builtin expects the value to be in xmm0.
__ Movss(xmm0, xmm1);
__ Call(BUILTIN_CODE(masm->isolate(), WasmFloat32ToNumber),
RelocInfo::CODE_TARGET);
__ jmp(&return_done);
__ bind(&return_kWasmF64);
// The builtin expects the value to be in xmm0.
__ Movsd(xmm0, xmm1);
__ Call(BUILTIN_CODE(masm->isolate(), WasmFloat64ToNumber),
RelocInfo::CODE_TARGET);
__ jmp(&return_done); __ jmp(&return_done);
} }
......
...@@ -274,7 +274,9 @@ bool UseGenericWrapper(const FunctionSig* sig) { ...@@ -274,7 +274,9 @@ bool UseGenericWrapper(const FunctionSig* sig) {
} }
if (sig->returns().size() == 1 && if (sig->returns().size() == 1 &&
sig->GetReturn(0).kind() != ValueType::kI32 && sig->GetReturn(0).kind() != ValueType::kI32 &&
sig->GetReturn(0).kind() != ValueType::kI64) { sig->GetReturn(0).kind() != ValueType::kI64 &&
sig->GetReturn(0).kind() != ValueType::kF32 &&
sig->GetReturn(0).kind() != ValueType::kF64) {
return false; return false;
} }
for (ValueType type : sig->parameters()) { for (ValueType type : sig->parameters()) {
......
...@@ -388,3 +388,44 @@ let kSig_v_liilliiil = makeSig([kWasmI64, kWasmI32, kWasmI32, kWasmI64, ...@@ -388,3 +388,44 @@ let kSig_v_liilliiil = makeSig([kWasmI64, kWasmI32, kWasmI32, kWasmI64,
let instance = builder.instantiate({ mod: { func: import_func } }); let instance = builder.instantiate({ mod: { func: import_func } });
assertEquals(10000000000n, instance.exports.main()); assertEquals(10000000000n, instance.exports.main());
})(); })();
(function testGenericWrapper1F32Return() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_index = builder.addType(kSig_f_v);
let func_index = builder.addImport("mod", "func", sig_index);
builder.addFunction("main", sig_index)
.addBody([
kExprCallFunction, func_index
])
.exportFunc();
function import_func() {
gc();
return 0.5;
}
let instance = builder.instantiate({ mod: { func: import_func } });
assertEquals(0.5, instance.exports.main());
})();
(function testGenericWrapper1F64Return() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
let sig_index = builder.addType(kSig_d_v);
let func_index = builder.addImport("mod", "func", sig_index);
builder.addFunction("main", sig_index)
.addBody([
kExprCallFunction, func_index
])
.exportFunc();
function import_func() {
gc();
return 0.25;
}
let instance = builder.instantiate({ mod: { func: import_func } });
assertEquals(0.25, instance.exports.main());
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment