[wasm] Add remaining saturating conversions
Adds the remaining saturating float to int conversion opcodes. Bug: v8:7226 Change-Id: If84e564a7816eb4aedbc336f5c2e614da22bb10a Reviewed-on: https://chromium-review.googlesource.com/905472 Commit-Queue: Karl Schimpf <kschimpf@chromium.org> Reviewed-by: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#51157}
This commit is contained in:
parent
b7cf8ef868
commit
7f981c6c21
@ -785,16 +785,16 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input,
|
||||
op = m->SignExtendWord32ToInt64();
|
||||
break;
|
||||
case wasm::kExprI64SConvertF32:
|
||||
case wasm::kExprI64UConvertF32:
|
||||
case wasm::kExprI64SConvertF64:
|
||||
case wasm::kExprI64UConvertF64:
|
||||
case wasm::kExprI64SConvertSatF32:
|
||||
case wasm::kExprI64UConvertSatF32:
|
||||
case wasm::kExprI64SConvertSatF64:
|
||||
case wasm::kExprI64UConvertSatF64:
|
||||
return jsgraph()->machine()->Is32()
|
||||
? BuildCcallConvertFloat(input, position, opcode)
|
||||
: BuildIntConvertFloat(input, position, opcode);
|
||||
case wasm::kExprI64SConvertF64:
|
||||
return BuildI64SConvertF64(input, position);
|
||||
case wasm::kExprI64UConvertF32:
|
||||
return BuildI64UConvertF32(input, position);
|
||||
case wasm::kExprI64UConvertF64:
|
||||
return BuildI64UConvertF64(input, position);
|
||||
case wasm::kExprI32AsmjsLoadMem8S:
|
||||
return BuildAsmjsLoadMem(MachineType::Int8(), input);
|
||||
case wasm::kExprI32AsmjsLoadMem8U:
|
||||
@ -1395,8 +1395,15 @@ MachineType IntConvertType(wasm::WasmOpcode opcode) {
|
||||
case wasm::kExprI32UConvertSatF64:
|
||||
return MachineType::Uint32();
|
||||
case wasm::kExprI64SConvertF32:
|
||||
case wasm::kExprI64SConvertF64:
|
||||
case wasm::kExprI64SConvertSatF32:
|
||||
case wasm::kExprI64SConvertSatF64:
|
||||
return MachineType::Int64();
|
||||
case wasm::kExprI64UConvertF32:
|
||||
case wasm::kExprI64UConvertF64:
|
||||
case wasm::kExprI64UConvertSatF32:
|
||||
case wasm::kExprI64UConvertSatF64:
|
||||
return MachineType::Uint64();
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -1407,14 +1414,20 @@ MachineType FloatConvertType(wasm::WasmOpcode opcode) {
|
||||
case wasm::kExprI32SConvertF32:
|
||||
case wasm::kExprI32UConvertF32:
|
||||
case wasm::kExprI32SConvertSatF32:
|
||||
case wasm::kExprI32UConvertSatF32:
|
||||
case wasm::kExprI64SConvertF32:
|
||||
case wasm::kExprI64UConvertF32:
|
||||
case wasm::kExprI32UConvertSatF32:
|
||||
case wasm::kExprI64SConvertSatF32:
|
||||
case wasm::kExprI64UConvertSatF32:
|
||||
return MachineType::Float32();
|
||||
case wasm::kExprI32SConvertF64:
|
||||
case wasm::kExprI32UConvertF64:
|
||||
case wasm::kExprI64SConvertF64:
|
||||
case wasm::kExprI64UConvertF64:
|
||||
case wasm::kExprI32SConvertSatF64:
|
||||
case wasm::kExprI32UConvertSatF64:
|
||||
case wasm::kExprI64SConvertSatF64:
|
||||
case wasm::kExprI64UConvertSatF64:
|
||||
return MachineType::Float64();
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -1438,6 +1451,15 @@ const Operator* ConvertOp(WasmGraphBuilder* builder, wasm::WasmOpcode opcode) {
|
||||
case wasm::kExprI64SConvertF32:
|
||||
case wasm::kExprI64SConvertSatF32:
|
||||
return builder->jsgraph()->machine()->TryTruncateFloat32ToInt64();
|
||||
case wasm::kExprI64UConvertF32:
|
||||
case wasm::kExprI64UConvertSatF32:
|
||||
return builder->jsgraph()->machine()->TryTruncateFloat32ToUint64();
|
||||
case wasm::kExprI64SConvertF64:
|
||||
case wasm::kExprI64SConvertSatF64:
|
||||
return builder->jsgraph()->machine()->TryTruncateFloat64ToInt64();
|
||||
case wasm::kExprI64UConvertF64:
|
||||
case wasm::kExprI64UConvertSatF64:
|
||||
return builder->jsgraph()->machine()->TryTruncateFloat64ToUint64();
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -1469,12 +1491,18 @@ bool IsTrappingConvertOp(wasm::WasmOpcode opcode) {
|
||||
case wasm::kExprI32SConvertF64:
|
||||
case wasm::kExprI32UConvertF64:
|
||||
case wasm::kExprI64SConvertF32:
|
||||
case wasm::kExprI64UConvertF32:
|
||||
case wasm::kExprI64SConvertF64:
|
||||
case wasm::kExprI64UConvertF64:
|
||||
return true;
|
||||
case wasm::kExprI32SConvertSatF64:
|
||||
case wasm::kExprI32UConvertSatF64:
|
||||
case wasm::kExprI32SConvertSatF32:
|
||||
case wasm::kExprI32UConvertSatF32:
|
||||
case wasm::kExprI64SConvertSatF32:
|
||||
case wasm::kExprI64UConvertSatF32:
|
||||
case wasm::kExprI64SConvertSatF64:
|
||||
case wasm::kExprI64UConvertSatF64:
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -1890,93 +1918,6 @@ Node* WasmGraphBuilder::BuildIntToFloatConversionInstruction(
|
||||
return load;
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildI64UConvertF32(Node* input,
|
||||
wasm::WasmCodePosition position) {
|
||||
if (jsgraph()->machine()->Is32()) {
|
||||
return BuildFloatToIntConversionInstruction(
|
||||
input, ExternalReference::wasm_float32_to_uint64(jsgraph()->isolate()),
|
||||
MachineRepresentation::kFloat32, MachineType::Int64(), position);
|
||||
} else {
|
||||
Node* trunc = graph()->NewNode(
|
||||
jsgraph()->machine()->TryTruncateFloat32ToUint64(), input);
|
||||
Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc,
|
||||
graph()->start());
|
||||
Node* overflow = graph()->NewNode(jsgraph()->common()->Projection(1), trunc,
|
||||
graph()->start());
|
||||
ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildI64SConvertF64(Node* input,
|
||||
wasm::WasmCodePosition position) {
|
||||
if (jsgraph()->machine()->Is32()) {
|
||||
return BuildFloatToIntConversionInstruction(
|
||||
input, ExternalReference::wasm_float64_to_int64(jsgraph()->isolate()),
|
||||
MachineRepresentation::kFloat64, MachineType::Int64(), position);
|
||||
} else {
|
||||
Node* trunc = graph()->NewNode(
|
||||
jsgraph()->machine()->TryTruncateFloat64ToInt64(), input);
|
||||
Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc,
|
||||
graph()->start());
|
||||
Node* overflow = graph()->NewNode(jsgraph()->common()->Projection(1), trunc,
|
||||
graph()->start());
|
||||
ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::BuildI64UConvertF64(Node* input,
|
||||
wasm::WasmCodePosition position) {
|
||||
if (jsgraph()->machine()->Is32()) {
|
||||
return BuildFloatToIntConversionInstruction(
|
||||
input, ExternalReference::wasm_float64_to_uint64(jsgraph()->isolate()),
|
||||
MachineRepresentation::kFloat64, MachineType::Int64(), position);
|
||||
} else {
|
||||
Node* trunc = graph()->NewNode(
|
||||
jsgraph()->machine()->TryTruncateFloat64ToUint64(), input);
|
||||
Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc,
|
||||
graph()->start());
|
||||
Node* overflow = graph()->NewNode(jsgraph()->common()->Projection(1), trunc,
|
||||
graph()->start());
|
||||
ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(kschimpf) Remove this method once BuildI64UConvertF32,
|
||||
// BuildI64SConvertF64, and BuildI64UConvertF64 have been moved over to use
|
||||
// method BuildCcallConvertFloat() below.
|
||||
Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction(
|
||||
Node* input, ExternalReference ref,
|
||||
MachineRepresentation parameter_representation,
|
||||
const MachineType result_type, wasm::WasmCodePosition position) {
|
||||
Node* stack_slot_param = graph()->NewNode(
|
||||
jsgraph()->machine()->StackSlot(parameter_representation));
|
||||
Node* stack_slot_result = graph()->NewNode(
|
||||
jsgraph()->machine()->StackSlot(result_type.representation()));
|
||||
const Operator* store_op = jsgraph()->machine()->Store(
|
||||
StoreRepresentation(parameter_representation, kNoWriteBarrier));
|
||||
*effect_ =
|
||||
graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0),
|
||||
input, *effect_, *control_);
|
||||
MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2);
|
||||
sig_builder.AddReturn(MachineType::Int32());
|
||||
sig_builder.AddParam(MachineType::Pointer());
|
||||
sig_builder.AddParam(MachineType::Pointer());
|
||||
Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
|
||||
ZeroCheck32(wasm::kTrapFloatUnrepresentable,
|
||||
BuildCCall(sig_builder.Build(), function, stack_slot_param,
|
||||
stack_slot_result),
|
||||
position);
|
||||
const Operator* load_op = jsgraph()->machine()->Load(result_type);
|
||||
Node* load =
|
||||
graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0),
|
||||
*effect_, *control_);
|
||||
*effect_ = load;
|
||||
return load;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
ExternalReference convert_ccall_ref(WasmGraphBuilder* builder,
|
||||
@ -1986,6 +1927,18 @@ ExternalReference convert_ccall_ref(WasmGraphBuilder* builder,
|
||||
case wasm::kExprI64SConvertSatF32:
|
||||
return ExternalReference::wasm_float32_to_int64(
|
||||
builder->jsgraph()->isolate());
|
||||
case wasm::kExprI64UConvertF32:
|
||||
case wasm::kExprI64UConvertSatF32:
|
||||
return ExternalReference::wasm_float32_to_uint64(
|
||||
builder->jsgraph()->isolate());
|
||||
case wasm::kExprI64SConvertF64:
|
||||
case wasm::kExprI64SConvertSatF64:
|
||||
return ExternalReference::wasm_float64_to_int64(
|
||||
builder->jsgraph()->isolate());
|
||||
case wasm::kExprI64UConvertF64:
|
||||
case wasm::kExprI64UConvertSatF64:
|
||||
return ExternalReference::wasm_float64_to_uint64(
|
||||
builder->jsgraph()->isolate());
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -547,15 +547,8 @@ class WasmGraphBuilder {
|
||||
Node* BuildF64SConvertI64(Node* input);
|
||||
Node* BuildF64UConvertI64(Node* input);
|
||||
|
||||
Node* BuildFloatToIntConversionInstruction(
|
||||
Node* input, ExternalReference ref,
|
||||
MachineRepresentation parameter_representation,
|
||||
const MachineType result_type, wasm::WasmCodePosition position);
|
||||
Node* BuildCcallConvertFloat(Node* input, wasm::WasmCodePosition position,
|
||||
wasm::WasmOpcode opcode);
|
||||
Node* BuildI64UConvertF32(Node* input, wasm::WasmCodePosition position);
|
||||
Node* BuildI64SConvertF64(Node* input, wasm::WasmCodePosition position);
|
||||
Node* BuildI64UConvertF64(Node* input, wasm::WasmCodePosition position);
|
||||
|
||||
Node* BuildI32DivS(Node* left, Node* right, wasm::WasmCodePosition position);
|
||||
Node* BuildI32RemS(Node* left, Node* right, wasm::WasmCodePosition position);
|
||||
|
@ -496,6 +496,17 @@ int64_t ExecuteI64SConvertF64(double a, TrapReason* trap) {
|
||||
return output;
|
||||
}
|
||||
|
||||
int64_t ExecuteI64SConvertSatF64(double a) {
|
||||
TrapReason base_trap = kTrapCount;
|
||||
int64_t val = ExecuteI64SConvertF64(a, &base_trap);
|
||||
if (base_trap == kTrapCount) {
|
||||
return val;
|
||||
}
|
||||
return std::isnan(a) ? 0
|
||||
: (a < 0.0 ? std::numeric_limits<int64_t>::min()
|
||||
: std::numeric_limits<int64_t>::max());
|
||||
}
|
||||
|
||||
uint64_t ExecuteI64UConvertF32(float a, TrapReason* trap) {
|
||||
uint64_t output;
|
||||
if (!float32_to_uint64_wrapper(&a, &output)) {
|
||||
@ -504,6 +515,17 @@ uint64_t ExecuteI64UConvertF32(float a, TrapReason* trap) {
|
||||
return output;
|
||||
}
|
||||
|
||||
uint64_t ExecuteI64UConvertSatF32(float a) {
|
||||
TrapReason base_trap = kTrapCount;
|
||||
uint64_t val = ExecuteI64UConvertF32(a, &base_trap);
|
||||
if (base_trap == kTrapCount) {
|
||||
return val;
|
||||
}
|
||||
return std::isnan(a) ? 0
|
||||
: (a < 0.0 ? std::numeric_limits<uint64_t>::min()
|
||||
: std::numeric_limits<uint64_t>::max());
|
||||
}
|
||||
|
||||
uint64_t ExecuteI64UConvertF64(double a, TrapReason* trap) {
|
||||
uint64_t output;
|
||||
if (!float64_to_uint64_wrapper(&a, &output)) {
|
||||
@ -512,6 +534,17 @@ uint64_t ExecuteI64UConvertF64(double a, TrapReason* trap) {
|
||||
return output;
|
||||
}
|
||||
|
||||
uint64_t ExecuteI64UConvertSatF64(double a) {
|
||||
TrapReason base_trap = kTrapCount;
|
||||
int64_t val = ExecuteI64UConvertF64(a, &base_trap);
|
||||
if (base_trap == kTrapCount) {
|
||||
return val;
|
||||
}
|
||||
return std::isnan(a) ? 0
|
||||
: (a < 0.0 ? std::numeric_limits<uint64_t>::min()
|
||||
: std::numeric_limits<uint64_t>::max());
|
||||
}
|
||||
|
||||
inline int64_t ExecuteI64SConvertI32(int32_t a, TrapReason* trap) {
|
||||
return static_cast<int64_t>(a);
|
||||
}
|
||||
@ -1576,10 +1609,18 @@ class ThreadImpl {
|
||||
case kExprI32UConvertSatF64:
|
||||
Push(WasmValue(ExecuteConvertSaturate<uint32_t>(Pop().to<double>())));
|
||||
return true;
|
||||
case kExprI64SConvertSatF32: {
|
||||
case kExprI64SConvertSatF32:
|
||||
Push(WasmValue(ExecuteI64SConvertSatF32(Pop().to<float>())));
|
||||
return true;
|
||||
}
|
||||
case kExprI64UConvertSatF32:
|
||||
Push(WasmValue(ExecuteI64UConvertSatF32(Pop().to<float>())));
|
||||
return true;
|
||||
case kExprI64SConvertSatF64:
|
||||
Push(WasmValue(ExecuteI64SConvertSatF64(Pop().to<double>())));
|
||||
return true;
|
||||
case kExprI64UConvertSatF64:
|
||||
Push(WasmValue(ExecuteI64UConvertSatF64(Pop().to<double>())));
|
||||
return true;
|
||||
default:
|
||||
V8_Fatal(__FILE__, __LINE__, "Unknown or unimplemented opcode #%d:%s",
|
||||
code->start[pc], OpcodeName(code->start[pc]));
|
||||
|
@ -104,7 +104,8 @@ const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
|
||||
// TODO(kschimpf): Simplify after filling in other saturating operations.
|
||||
CASE_CONVERT_SAT_OP(Convert, I32, F32, "f32", "trunc")
|
||||
CASE_CONVERT_SAT_OP(Convert, I32, F64, "f64", "trunc")
|
||||
CASE_I64_OP(SConvertSatF32, "trunc_s::sat/f32")
|
||||
CASE_CONVERT_SAT_OP(Convert, I64, F32, "f32", "trunc")
|
||||
CASE_CONVERT_SAT_OP(Convert, I64, F64, "f64", "trunc")
|
||||
|
||||
CASE_CONVERT_OP(Convert, I64, I32, "i32", "extend")
|
||||
CASE_CONVERT_OP(Convert, F32, I32, "i32", "convert")
|
||||
|
@ -409,8 +409,10 @@ using WasmName = Vector<const char>;
|
||||
V(I32UConvertSatF32, 0xfc01, i_f) \
|
||||
V(I32SConvertSatF64, 0xfc02, i_d) \
|
||||
V(I32UConvertSatF64, 0xfc03, i_d) \
|
||||
V(I64SConvertSatF32, 0xfc04, l_f)
|
||||
// TODO(kschimpf): Add remaining numeric opcodes.
|
||||
V(I64SConvertSatF32, 0xfc04, l_f) \
|
||||
V(I64UConvertSatF32, 0xfc05, l_f) \
|
||||
V(I64SConvertSatF64, 0xfc06, l_d) \
|
||||
V(I64UConvertSatF64, 0xfc07, l_d)
|
||||
|
||||
#define FOREACH_ATOMIC_OPCODE(V) \
|
||||
V(I32AtomicLoad, 0xfe10, i_i) \
|
||||
|
@ -797,6 +797,27 @@ WASM_EXEC_TEST(I64SConvertF64) {
|
||||
}
|
||||
}
|
||||
|
||||
WASM_EXEC_TEST(I64SConvertSatF64) {
|
||||
EXPERIMENTAL_FLAG_SCOPE(sat_f2i_conversions);
|
||||
WasmRunner<int64_t, double> r(execution_mode);
|
||||
BUILD(r, WASM_I64_SCONVERT_SAT_F64(WASM_GET_LOCAL(0)));
|
||||
FOR_FLOAT64_INPUTS(i) {
|
||||
int64_t expected;
|
||||
if (*i < static_cast<double>(std::numeric_limits<int64_t>::max()) &&
|
||||
*i >= static_cast<double>(std::numeric_limits<int64_t>::min())) {
|
||||
expected = static_cast<int64_t>(*i);
|
||||
} else if (std::isnan(*i)) {
|
||||
expected = static_cast<int64_t>(0);
|
||||
} else if (*i < 0.0) {
|
||||
expected = std::numeric_limits<int64_t>::min();
|
||||
} else {
|
||||
expected = std::numeric_limits<int64_t>::max();
|
||||
}
|
||||
int64_t found = r.Call(*i);
|
||||
CHECK_EQ(expected, found);
|
||||
}
|
||||
}
|
||||
|
||||
WASM_EXEC_TEST(I64UConvertF32) {
|
||||
WasmRunner<uint64_t, float> r(execution_mode);
|
||||
BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0)));
|
||||
@ -811,6 +832,27 @@ WASM_EXEC_TEST(I64UConvertF32) {
|
||||
}
|
||||
}
|
||||
|
||||
WASM_EXEC_TEST(I64UConvertSatF32) {
|
||||
EXPERIMENTAL_FLAG_SCOPE(sat_f2i_conversions);
|
||||
WasmRunner<int64_t, float> r(execution_mode);
|
||||
BUILD(r, WASM_I64_UCONVERT_SAT_F32(WASM_GET_LOCAL(0)));
|
||||
FOR_FLOAT32_INPUTS(i) {
|
||||
uint64_t expected;
|
||||
if (*i < static_cast<float>(std::numeric_limits<uint64_t>::max()) &&
|
||||
*i > -1) {
|
||||
expected = static_cast<uint64_t>(*i);
|
||||
} else if (std::isnan(*i)) {
|
||||
expected = static_cast<uint64_t>(0);
|
||||
} else if (*i < 0.0) {
|
||||
expected = std::numeric_limits<uint64_t>::min();
|
||||
} else {
|
||||
expected = std::numeric_limits<uint64_t>::max();
|
||||
}
|
||||
uint64_t found = r.Call(*i);
|
||||
CHECK_EQ(expected, found);
|
||||
}
|
||||
}
|
||||
|
||||
WASM_EXEC_TEST(I64UConvertF64) {
|
||||
WasmRunner<uint64_t, double> r(execution_mode);
|
||||
BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0)));
|
||||
@ -825,6 +867,27 @@ WASM_EXEC_TEST(I64UConvertF64) {
|
||||
}
|
||||
}
|
||||
|
||||
WASM_EXEC_TEST(I64UConvertSatF64) {
|
||||
EXPERIMENTAL_FLAG_SCOPE(sat_f2i_conversions);
|
||||
WasmRunner<int64_t, double> r(execution_mode);
|
||||
BUILD(r, WASM_I64_UCONVERT_SAT_F64(WASM_GET_LOCAL(0)));
|
||||
FOR_FLOAT64_INPUTS(i) {
|
||||
int64_t expected;
|
||||
if (*i < static_cast<float>(std::numeric_limits<uint64_t>::max()) &&
|
||||
*i > -1) {
|
||||
expected = static_cast<uint64_t>(*i);
|
||||
} else if (std::isnan(*i)) {
|
||||
expected = static_cast<uint64_t>(0);
|
||||
} else if (*i < 0.0) {
|
||||
expected = std::numeric_limits<uint64_t>::min();
|
||||
} else {
|
||||
expected = std::numeric_limits<uint64_t>::max();
|
||||
}
|
||||
int64_t found = r.Call(*i);
|
||||
CHECK_EQ(expected, found);
|
||||
}
|
||||
}
|
||||
|
||||
WASM_EXEC_TEST(CallI64Parameter) {
|
||||
ValueType param_types[20];
|
||||
for (int i = 0; i < 20; i++) param_types[i] = kWasmI64;
|
||||
|
@ -565,6 +565,9 @@ inline WasmOpcode LoadStoreOpcodeOf(MachineType type, bool store) {
|
||||
#define WASM_I32_SCONVERT_SAT_F64(x) x, WASM_NUMERIC_OP(kExprI32SConvertSatF64)
|
||||
#define WASM_I32_UCONVERT_SAT_F64(x) x, WASM_NUMERIC_OP(kExprI32UConvertSatF64)
|
||||
#define WASM_I64_SCONVERT_SAT_F32(x) x, WASM_NUMERIC_OP(kExprI64SConvertSatF32)
|
||||
#define WASM_I64_UCONVERT_SAT_F32(x) x, WASM_NUMERIC_OP(kExprI64UConvertSatF32)
|
||||
#define WASM_I64_SCONVERT_SAT_F64(x) x, WASM_NUMERIC_OP(kExprI64SConvertSatF64)
|
||||
#define WASM_I64_UCONVERT_SAT_F64(x) x, WASM_NUMERIC_OP(kExprI64UConvertSatF64)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Memory Operations.
|
||||
|
Loading…
Reference in New Issue
Block a user