macro_rules! exec_op {
($executor:ident; binary_fallible $ty:ty, |$lhs:ident, $rhs:ident| $expr:expr) => {{
fn exec_binary_fallible(value_stack: &mut ValueStack) -> Result<(), Trap> {
let $rhs = <$ty>::stack_pop(value_stack);
let $lhs = <$ty>::stack_pop(value_stack);
<$ty>::stack_push(value_stack, $expr?)
}
exec_binary_fallible(&mut $executor.store.value_stack)?;
}};
($executor:ident; unary $from:ty => $to:ty, |$v:ident| $expr:expr) => {{
fn exec_unary(value_stack: &mut ValueStack) -> Result<(), Trap> {
let $v = <$from>::stack_pop(value_stack);
<$to>::stack_push(value_stack, $expr)
}
exec_unary(&mut $executor.store.value_stack)?;
}};
($executor:ident; binary $from:ty => $to:ty, |$lhs:ident, $rhs:ident| $expr:expr) => {{
exec_op!($executor; binary $from, $from => $to, |$lhs, $rhs| $expr)
}};
($executor:ident; binary $lhs_ty:ty, $rhs_ty:ty => $res:ty, |$lhs:ident, $rhs:ident| $expr:expr) => {{
fn exec_binary(value_stack: &mut ValueStack) -> Result<(), Trap> {
let $rhs = <$rhs_ty>::stack_pop(value_stack);
let $lhs = <$lhs_ty>::stack_pop(value_stack);
<$res>::stack_push(value_stack, $expr)
}
exec_binary(&mut $executor.store.value_stack)?;
}};
($executor:ident; ternary $from:ty => $to:ty, |$a:ident, $b:ident, $c:ident| $expr:expr) => {{
fn exec_ternary(value_stack: &mut ValueStack) -> Result<(), Trap> {
let $c = <$from>::stack_pop(value_stack);
let $b = <$from>::stack_pop(value_stack);
let $a = <$from>::stack_pop(value_stack);
<$to>::stack_push(value_stack, $expr)
}
exec_ternary(&mut $executor.store.value_stack)?;
}};
}
#[rustfmt::skip]
macro_rules! instruction_handlers {
($emit:ident) => {
$emit! { executor, instr_ptr, dispatch_next, dispatch_flow;
Unreachable => { return cold!(Err(Trap::Unreachable.into())); },
Drop32 => { _ = Value32::stack_pop(&mut executor.store.value_stack)},
Drop64 => { _ = Value64::stack_pop(&mut executor.store.value_stack)},
Drop128 => { _ = Value128::stack_pop(&mut executor.store.value_stack)},
Select32 => Value32::stack_select(&mut executor.store.value_stack),
Select64 => Value64::stack_select(&mut executor.store.value_stack),
Select128 => Value128::stack_select(&mut executor.store.value_stack),
SelectStore32(idx) => executor.exec_select_store::<Value32, 4>(idx.resolve(&executor.func.data))?,
SelectStore64(idx) => executor.exec_select_store::<Value64, 8>(idx.resolve(&executor.func.data))?,
SelectMulti(counts) => executor.store.value_stack.select_multi(*counts),
Call(v) => dispatch_flow!(executor.exec_call_direct(*v, instr_ptr + 1)?),
CallSelf => { executor.exec_call_self(instr_ptr + 1)?; dispatch_next!(0); },
CallIndirect(idx) => dispatch_flow!(executor.exec_call_indirect::<false>(*idx, instr_ptr + 1)?),
CallRef(ty) => dispatch_flow!(executor.exec_call_ref::<false>(*ty, instr_ptr + 1)?),
ReturnCall(v) => dispatch_flow!(executor.exec_return_call_direct(*v)?),
ReturnCallSelf => { executor.exec_return_call_self()?; dispatch_next!(0); },
ReturnCallIndirect(idx) => dispatch_flow!(executor.exec_call_indirect::<true>(*idx, instr_ptr + 1)?),
ReturnCallRef(ty) => dispatch_flow!(executor.exec_call_ref::<true>(*ty, instr_ptr + 1)?),
Throw(tag) => dispatch_flow!(executor.exec_throw(*tag, instr_ptr)?),
ThrowRef => dispatch_flow!(executor.exec_throw_ref(instr_ptr)?),
Jump(ip) => dispatch_next!(*ip as usize),
JumpIfZero32(ip) => if i32::stack_pop(&mut executor.store.value_stack) == 0 { dispatch_next!(*ip as usize) },
JumpIfNonZero32(ip) => if i32::stack_pop(&mut executor.store.value_stack) != 0 { dispatch_next!(*ip as usize) },
JumpIfZero64(ip) => if i64::stack_pop(&mut executor.store.value_stack) == 0 { dispatch_next!(*ip as usize) },
JumpIfNonZero64(ip) => if i64::stack_pop(&mut executor.store.value_stack) != 0 { dispatch_next!(*ip as usize) },
JumpIfRefNull(ip) => { let ip = *ip; if executor.exec_jump_if_ref::<true>() { dispatch_next!(ip as usize) } },
JumpIfRefNonNull(ip) => { let ip = *ip; if executor.exec_jump_if_ref::<false>() { dispatch_next!(ip as usize) } },
BrOnCast(idx) => if let Some(ip) = executor.exec_br_on_cast::<false>(*idx) { dispatch_next!(ip) },
BrOnCastFail(idx) => if let Some(ip) = executor.exec_br_on_cast::<true>(*idx) { dispatch_next!(ip) },
JumpIfLocalZero32(arg) => if executor.exec_jump_if_local::<Value32, true>(arg.local) { dispatch_next!(arg.target_ip as usize) },
JumpIfLocalNonZero32(arg) => if executor.exec_jump_if_local::<Value32, false>(arg.local) { dispatch_next!(arg.target_ip as usize) },
JumpIfLocalZero64(arg) => if executor.exec_jump_if_local::<Value64, true>(arg.local) { dispatch_next!(arg.target_ip as usize) },
JumpIfLocalNonZero64(arg) => if executor.exec_jump_if_local::<Value64, false>(arg.local) { dispatch_next!(arg.target_ip as usize) },
JumpCmpStackConst32(packed) => if let Some(ip) = executor.exec_jump_cmp_stack_const32(*packed) { dispatch_next!(ip) },
JumpCmpStackConst64(packed) => if let Some(ip) = executor.exec_jump_cmp_stack_const64(*packed) { dispatch_next!(ip) },
JumpCmpStackLocal32(packed) => if let Some(ip) = executor.exec_jump_cmp_stack_local32(*packed) { dispatch_next!(ip) },
JumpCmpStackLocal64(packed) => if let Some(ip) = executor.exec_jump_cmp_stack_local64(*packed) { dispatch_next!(ip) },
BinOpLocalConstJump32(packed) => if let Some(ip) = executor.exec_binop_local_const_jump(*packed) { dispatch_next!(ip) },
BinOpLocalConstJumpCmpLocal32(packed) => if let Some(ip) = executor.exec_binop_local_const_jump_cmp_local(*packed) { dispatch_next!(ip) },
BinOpStackConstTeeLocalJump32(packed) => if let Some(ip) = executor.exec_binop_stack_const_tee_local_jump(*packed)? { dispatch_next!(ip) },
BinOpGlobalConstJump32(packed) => if let Some(ip) = executor.exec_binop_global_const_jump(*packed) { dispatch_next!(ip) },
IncLocalJump32(idx) => if let Some(ip) = executor.exec_inc_local_jump(*idx) { dispatch_next!(ip) },
IncStackTeeLocalJump32(idx) => if let Some(ip) = executor.exec_inc_stack_tee_local_jump(*idx)? { dispatch_next!(ip) },
IncGlobalJump32(idx) => if let Some(ip) = executor.exec_inc_global_jump(*idx) { dispatch_next!(ip) },
IncLocalJumpCmpLocal32(packed) => if let Some(ip) = executor.exec_inc_local_jump_cmp_local(*packed) { dispatch_next!(ip) },
JumpCmpLocalConst32(packed) => if let Some(ip) = executor.exec_jump_cmp_local_const32(*packed) { dispatch_next!(ip) },
JumpCmpLocalConst64(packed) => if let Some(ip) = executor.exec_jump_cmp_local_const64(*packed) { dispatch_next!(ip) },
JumpCmpLocalLocal32(packed) => if let Some(ip) = executor.exec_jump_cmp_local_local32(*packed) { dispatch_next!(ip) },
JumpCmpLocalLocal64(packed) => if let Some(ip) = executor.exec_jump_cmp_local_local64(*packed) { dispatch_next!(ip) },
DropKeep32 { base, keep } => executor.store.value_stack.stack_32.truncate_keep((executor.cf.stack_base().s32 + u32::from(*base)) as usize, *keep as usize),
DropKeep64 { base, keep } => executor.store.value_stack.stack_64.truncate_keep((executor.cf.stack_base().s64 + u32::from(*base)) as usize, *keep as usize),
DropKeep128 { base, keep } => executor.store.value_stack.stack_128.truncate_keep((executor.cf.stack_base().s128 + u32::from(*base)) as usize, *keep as usize),
BranchTable(idx) => dispatch_next!(executor.exec_branch_table(*idx)),
Return => dispatch_flow!(executor.exec_return()),
ReturnVoid => dispatch_flow!(executor.exec_return_void()),
Return32 => dispatch_flow!(executor.exec_return_32()),
Return64 => dispatch_flow!(executor.exec_return_64()),
Return128 => dispatch_flow!(executor.exec_return_128()),
LocalGet32(local_index) => Value32::local_push(&mut executor.store.value_stack, &executor.cf, *local_index)?,
LocalGet64(local_index) => Value64::local_push(&mut executor.store.value_stack, &executor.cf, *local_index)?,
LocalGet128(local_index) => Value128::local_push(&mut executor.store.value_stack, &executor.cf, *local_index)?,
LocalSet32(local_index) => executor.exec_local_set_pop::<Value32>(*local_index),
LocalSet64(local_index) => executor.exec_local_set_pop::<Value64>(*local_index),
LocalSet128(local_index) => executor.exec_local_set_pop::<Value128>(*local_index),
LocalCopy32(from, to) => Value32::local_copy(&mut executor.store.value_stack, &executor.cf, *from, *to),
LocalCopy64(from, to) => Value64::local_copy(&mut executor.store.value_stack, &executor.cf, *from, *to),
LocalCopy128(from, to) => Value128::local_copy(&mut executor.store.value_stack, &executor.cf, *from, *to),
AddConst32(c) => { i32::stack_update(&mut executor.store.value_stack, |value| value.wrapping_add(*c)); },
AndConst32(c) => { i32::stack_update(&mut executor.store.value_stack, |value| value & *c); },
XorConst32(c) => { i32::stack_update(&mut executor.store.value_stack, |value| value ^ *c); },
ShrUConst32(c) => { u32::stack_update(&mut executor.store.value_stack, |value| value.wrapping_shr(*c as u32)); },
AddConst64(idx) => { let rhs = idx.resolve(&executor.func.data).value(); i64::stack_update(&mut executor.store.value_stack, |value| value.wrapping_add(rhs)); },
BinOpStackConst32(op, rhs) => { u32::stack_update(&mut executor.store.value_stack, |lhs| op.exec(lhs, *rhs as u32)); },
BinOpStackConst64(packed) => { let rhs = packed.index.resolve(&executor.func.data).value() as u64; u64::stack_update(&mut executor.store.value_stack, |lhs| packed.op.exec(lhs, rhs)); },
IncLocal32(arg) => { i32::local_update(&mut executor.store.value_stack, &executor.cf, arg.local, |value| value.wrapping_add(arg.value)); },
IncLocal64(packed) => { let rhs = packed.index.resolve(&executor.func.data).value(); i64::local_update(&mut executor.store.value_stack, &executor.cf, packed.op, |value| value.wrapping_add(rhs)); },
I32Add3 => exec_op!(executor; ternary i32 => i32, |a, b, c| a.wrapping_add(b).wrapping_add(c)),
I64Add3 => exec_op!(executor; ternary i64 => i64, |a, b, c| a.wrapping_add(b).wrapping_add(c)),
MulAccLocal32(acc) => executor.exec_mul_acc_local::<i32>(*acc, i32::wrapping_mul, i32::wrapping_add),
MulAccLocal64(acc) => executor.exec_mul_acc_local::<i64>(*acc, i64::wrapping_mul, i64::wrapping_add),
FMulAccLocal32(acc) => executor.exec_mul_acc_local::<f32>(*acc, #[inline(always)] |a, b| a * b, #[inline(always)] |a, b| a + b),
FMulAccLocal64(acc) => executor.exec_mul_acc_local::<f64>(*acc, #[inline(always)] |a, b| a * b, #[inline(always)] |a, b| a + b),
BinOpLocalLocal32(op, a, b) => executor.exec_binop_local_local::<Value32, true>(*a, *b, None, *op)?,
BinOpLocalLocal64(op, a, b) => executor.exec_binop_local_local::<Value64, true>(*a, *b, None, *op)?,
BinOpLocalLocal128(op, a, b) => executor.exec_binop_local_local::<Value128, true>(*a, *b, None, *op)?,
CmpLocalLocal32(op, a, b) => executor.exec_cmp_local_local::<i32>(*a, *b, *op)?,
CmpLocalLocal64(op, a, b) => executor.exec_cmp_local_local::<i64>(*a, *b, *op)?,
AddLocalLocalSet32(arg) => executor.exec_binop_local_local::<Value32, false>(arg.left, arg.right, Some(arg.dst), BinOp::IAdd)?,
AddLocalLocalTee32(arg) => executor.exec_binop_local_local::<Value32, true>(arg.left, arg.right, Some(arg.dst), BinOp::IAdd)?,
BinOpLocalLocalSet32(packed) => executor.exec_binop_local_local_indexed::<Value32, false>(packed.index, packed.op)?,
BinOpLocalLocalSet64(packed) => executor.exec_binop_local_local_indexed::<Value64, false>(packed.index, packed.op)?,
BinOpLocalLocalSet128(packed) => executor.exec_binop_local_local_indexed::<Value128, false>(packed.index, packed.op)?,
BinOpLocalLocalTee32(packed) => executor.exec_binop_local_local_indexed::<Value32, true>(packed.index, packed.op)?,
BinOpLocalLocalTee64(packed) => executor.exec_binop_local_local_indexed::<Value64, true>(packed.index, packed.op)?,
BinOpLocalLocalTee128(packed) => executor.exec_binop_local_local_indexed::<Value128, true>(packed.index, packed.op)?,
AddLocalConst32(arg) => executor.exec_binop_local_const::<Value32, true>(arg.local, arg.value as u32, None, BinOp::IAdd)?,
SubLocalConst32(arg) => executor.exec_binop_local_const::<Value32, true>(arg.local, arg.value as u32, None, BinOp::ISub)?,
MulLocalConst32(arg) => executor.exec_binop_local_const::<Value32, true>(arg.local, arg.value as u32, None, BinOp::IMul)?,
AndLocalConst32(arg) => executor.exec_binop_local_const::<Value32, true>(arg.local, arg.value as u32, None, BinOp::IAnd)?,
ShrULocalConst32(arg) => executor.exec_binop_local_const::<Value32, true>(arg.local, arg.value as u32, None, BinOp::IShrU)?,
BinOpLocalConst32(packed) => { let v = packed.index.resolve(&executor.func.data); executor.exec_binop_local_const::<Value32, true>(v.a(), v.b(), None, packed.op)?; },
BinOpLocalConst64(packed) => { let v = packed.index.resolve(&executor.func.data); executor.exec_binop_local_const::<Value64, true>(v.a(), v.b(), None, packed.op)?; },
BinOpLocalConst128(packed) => { let v = packed.index.resolve(&executor.func.data); let rhs = Value128(v.b().resolve(&executor.func.data).value()); executor.exec_binop_local_const::<Value128, true>(v.a(), rhs, None, packed.op)?; },
BinOpLocalConstSet32(packed) => { let v = packed.index.resolve(&executor.func.data); executor.exec_binop_local_const::<Value32, false>(v.a(), v.c(), Some(v.b()), packed.op)?; },
BinOpLocalConstTee32(packed) => { let v = packed.index.resolve(&executor.func.data); executor.exec_binop_local_const::<Value32, true>(v.a(), v.c(), Some(v.b()), packed.op)?; },
BinOpLocalConstSet64(packed) => { let v = packed.index.resolve(&executor.func.data); executor.exec_binop_local_const::<Value64, false>(v.a(), v.c(), Some(v.b()), packed.op)?; },
BinOpLocalConstTee64(packed) => { let v = packed.index.resolve(&executor.func.data); executor.exec_binop_local_const::<Value64, true>(v.a(), v.c(), Some(v.b()), packed.op)?; },
BinOpLocalConstSet128(packed) => { let v = packed.index.resolve(&executor.func.data); let rhs = Value128(v.c().resolve(&executor.func.data).value()); executor.exec_binop_local_const::<Value128, false>(v.a(), rhs, Some(v.b()), packed.op)?; },
BinOpLocalConstTee128(packed) => { let v = packed.index.resolve(&executor.func.data); let rhs = Value128(v.c().resolve(&executor.func.data).value()); executor.exec_binop_local_const::<Value128, true>(v.a(), rhs, Some(v.b()), packed.op)?; },
BinOpStackLocal32(op, local) => executor.exec_binop_stack_local::<Value32, true>(*local, None, *op)?,
BinOpStackLocalSet32(op, local, dst) => executor.exec_binop_stack_local::<Value32, false>(*local, Some(*dst), *op)?,
BinOpStackLocalTee32(op, local, dst) => executor.exec_binop_stack_local::<Value32, true>(*local, Some(*dst), *op)?,
BinOpStackLocal128(op, local) => executor.exec_binop_stack_local::<Value128, true>(*local, None, *op)?,
BinOpStackGlobal32(op, global_index) => executor.exec_binop_stack_global::<Value32>(*global_index, *op)?,
BinOpStackGlobal64(op, global_index) => executor.exec_binop_stack_global::<Value64>(*global_index, *op)?,
BinOpGlobalConst32(packed) => { let v = packed.index.resolve(&executor.func.data); executor.exec_binop_global_const::<Value32>(v.a(), v.b(), packed.op)?; },
BinOpGlobalConst64(packed) => { let v = packed.index.resolve(&executor.func.data); executor.exec_binop_global_const::<Value64>(v.a(), v.b(), packed.op)?; },
BinOpGlobalConst128(packed) => { let v = packed.index.resolve(&executor.func.data); let rhs = Value128(v.b().resolve(&executor.func.data).value()); executor.exec_binop_global_const::<Value128>(v.a(), rhs, packed.op)?; },
SetLocalConst32(arg) => i32::local_set(&mut executor.store.value_stack, &executor.cf, arg.local, arg.value),
SetLocalConst64(packed) => { let v = packed.index.resolve(&executor.func.data).value(); i64::local_set(&mut executor.store.value_stack, &executor.cf, packed.op, v); },
SetLocalConst128(packed) => Value128::local_set(&mut executor.store.value_stack, &executor.cf, packed.op, Value128(packed.index.resolve(&executor.func.data).value())),
IncMemoryLocal32(arg) => executor.exec_inc_memory_local::<i32, 4>(arg.memory_arg_idx, arg.local1, #[inline(always)] |v| v.wrapping_add(1))?,
IncMemoryLocal64(arg) => executor.exec_inc_memory_local::<i64, 8>(arg.memory_arg_idx, arg.local1, #[inline(always)] |v| v.wrapping_add(1))?,
StoreLocalLocal32(arg) => executor.exec_store_local_local::<u32, 4>(arg.memory_arg_idx, arg.local1, arg.local2)?,
StoreLocalLocal64(arg) => executor.exec_store_local_local::<i64, 8>(arg.memory_arg_idx, arg.local1, arg.local2)?,
StoreLocalLocal128(arg) => executor.exec_store_local_local::<Value128, 16>(arg.memory_arg_idx, arg.local1, arg.local2)?,
LoadLocal32(arg) => executor.exec_load_local::<i32, 4, _, false, false>(arg.memory_arg_idx, arg.local1, 0, identity)?,
LoadLocal64(arg) => executor.exec_load_local::<i64, 8, _, false, false>(arg.memory_arg_idx, arg.local1, 0, identity)?,
LoadLocal8S32(arg) => executor.exec_load_local::<i8, 1, _, false, false>(arg.memory_arg_idx, arg.local1, 0, i32::from)?,
LoadLocal8U32(arg) => executor.exec_load_local::<u8, 1, _, false, false>(arg.memory_arg_idx, arg.local1, 0, i32::from)?,
LoadLocal16S32(arg) => executor.exec_load_local::<i16, 2, _, false, false>(arg.memory_arg_idx, arg.local1, 0, i32::from)?,
LoadLocal16U32(arg) => executor.exec_load_local::<u16, 2, _, false, false>(arg.memory_arg_idx, arg.local1, 0, i32::from)?,
LoadLocalTee32(arg) => executor.exec_load_local::<i32, 4, _, true, true>(arg.memory_arg_idx, arg.local1, arg.local2, identity)?,
LoadLocalSet32(arg) => executor.exec_load_local::<i32, 4, _, true, false>(arg.memory_arg_idx, arg.local1, arg.local2, identity)?,
LoadLocalTee8S32(arg) => executor.exec_load_local::<i8, 1, _, true, true>(arg.memory_arg_idx, arg.local1, arg.local2, i32::from)?,
LoadLocalTee8U32(arg) => executor.exec_load_local::<u8, 1, _, true, true>(arg.memory_arg_idx, arg.local1, arg.local2, i32::from)?,
LoadLocalTee16S32(arg) => executor.exec_load_local::<i16, 2, _, true, true>(arg.memory_arg_idx, arg.local1, arg.local2, i32::from)?,
LoadLocalTee16U32(arg) => executor.exec_load_local::<u16, 2, _, true, true>(arg.memory_arg_idx, arg.local1, arg.local2, i32::from)?,
LoadLocalSet8S32(arg) => executor.exec_load_local::<i8, 1, _, true, false>(arg.memory_arg_idx, arg.local1, arg.local2, i32::from)?,
LoadLocalSet8U32(arg) => executor.exec_load_local::<u8, 1, _, true, false>(arg.memory_arg_idx, arg.local1, arg.local2, i32::from)?,
LoadLocalSet16S32(arg) => executor.exec_load_local::<i16, 2, _, true, false>(arg.memory_arg_idx, arg.local1, arg.local2, i32::from)?,
LoadLocalSet16U32(arg) => executor.exec_load_local::<u16, 2, _, true, false>(arg.memory_arg_idx, arg.local1, arg.local2, i32::from)?,
LoadLocalTee128(arg) => executor.exec_load_local::<Value128, 16, _, true, true>(arg.memory_arg_idx, arg.local1, arg.local2, identity)?,
LoadLocalSet128(arg) => executor.exec_load_local::<Value128, 16, _, true, false>(arg.memory_arg_idx, arg.local1, arg.local2, identity)?,
AndConstTee32(arg) => executor.exec_binop_const_tee::<Value32>(arg.value as u32, arg.local, BinOp::IAnd)?,
SubConstTee32(arg) => executor.exec_binop_const_tee::<Value32>(arg.value as u32, arg.local, BinOp::ISub)?,
AndConstTee64(packed) => executor.exec_binop_const_tee::<Value64>(packed.index.resolve(&executor.func.data).value() as u64, packed.op, BinOp::IAnd)?,
SubConstTee64(packed) => executor.exec_binop_const_tee::<Value64>(packed.index.resolve(&executor.func.data).value() as u64, packed.op, BinOp::ISub)?,
LocalTee32(local_index) => executor.exec_local_tee::<Value32>(*local_index),
LocalTee64(local_index) => executor.exec_local_tee::<Value64>(*local_index),
LocalTee128(local_index) => executor.exec_local_tee::<Value128>(*local_index),
GlobalGet32(global_index) => executor.exec_global_get::<Value32>(*global_index)?,
GlobalGet64(global_index) => executor.exec_global_get::<Value64>(*global_index)?,
GlobalGet128(global_index) => executor.exec_global_get::<Value128>(*global_index)?,
GlobalSet32(global_index) => executor.exec_global_set::<Value32>(*global_index),
GlobalSet64(global_index) => executor.exec_global_set::<Value64>(*global_index),
GlobalSet128(global_index) => executor.exec_global_set::<Value128>(*global_index),
GlobalTee32(global_index) => executor.exec_global_tee::<Value32>(*global_index),
GlobalTee64(global_index) => executor.exec_global_tee::<Value64>(*global_index),
GlobalTee128(global_index) => executor.exec_global_tee::<Value128>(*global_index),
Const32(val) => i32::stack_push(&mut executor.store.value_stack, *val)?,
Const64Imm(val) => i64::stack_push(&mut executor.store.value_stack, i64::from(*val))?,
Const64(idx) => i64::stack_push(&mut executor.store.value_stack, idx.resolve(&executor.func.data).value())?,
Const128Imm(val) => Value128::stack_push(&mut executor.store.value_stack, Value128(u128::from(*val).to_le_bytes()))?,
I64Eqz => exec_op!(executor; unary i64 => i32, |v| i32::from(v == 0)),
I32Eqz => exec_op!(executor; unary i32 => i32, |v| i32::from(v == 0)),
I32Eq => exec_op!(executor; binary i32 => i32, |a, b| i32::from(a == b)),
I64Eq => exec_op!(executor; binary i64 => i32, |a, b| i32::from(a == b)),
F32Eq => exec_op!(executor; binary f32 => i32, |a, b| i32::from(a == b)),
F64Eq => exec_op!(executor; binary f64 => i32, |a, b| i32::from(a == b)),
I32Ne => exec_op!(executor; binary i32 => i32, |a, b| i32::from(a != b)),
I64Ne => exec_op!(executor; binary i64 => i32, |a, b| i32::from(a != b)),
F32Ne => exec_op!(executor; binary f32 => i32, |a, b| i32::from(a != b)),
F64Ne => exec_op!(executor; binary f64 => i32, |a, b| i32::from(a != b)),
I32LtS => exec_op!(executor; binary i32 => i32, |a, b| i32::from(a < b)),
I64LtS => exec_op!(executor; binary i64 => i32, |a, b| i32::from(a < b)),
I32LtU => exec_op!(executor; binary u32 => i32, |a, b| i32::from(a < b)),
I64LtU => exec_op!(executor; binary u64 => i32, |a, b| i32::from(a < b)),
F32Lt => exec_op!(executor; binary f32 => i32, |a, b| i32::from(a < b)),
F64Lt => exec_op!(executor; binary f64 => i32, |a, b| i32::from(a < b)),
I32LeS => exec_op!(executor; binary i32 => i32, |a, b| i32::from(a <= b)),
I64LeS => exec_op!(executor; binary i64 => i32, |a, b| i32::from(a <= b)),
I32LeU => exec_op!(executor; binary u32 => i32, |a, b| i32::from(a <= b)),
I64LeU => exec_op!(executor; binary u64 => i32, |a, b| i32::from(a <= b)),
F32Le => exec_op!(executor; binary f32 => i32, |a, b| i32::from(a <= b)),
F64Le => exec_op!(executor; binary f64 => i32, |a, b| i32::from(a <= b)),
I32GeS => exec_op!(executor; binary i32 => i32, |a, b| i32::from(a >= b)),
I64GeS => exec_op!(executor; binary i64 => i32, |a, b| i32::from(a >= b)),
I32GeU => exec_op!(executor; binary u32 => i32, |a, b| i32::from(a >= b)),
I64GeU => exec_op!(executor; binary u64 => i32, |a, b| i32::from(a >= b)),
F32Ge => exec_op!(executor; binary f32 => i32, |a, b| i32::from(a >= b)),
F64Ge => exec_op!(executor; binary f64 => i32, |a, b| i32::from(a >= b)),
I32GtS => exec_op!(executor; binary i32 => i32, |a, b| i32::from(a > b)),
I64GtS => exec_op!(executor; binary i64 => i32, |a, b| i32::from(a > b)),
I32GtU => exec_op!(executor; binary u32 => i32, |a, b| i32::from(a > b)),
I64GtU => exec_op!(executor; binary u64 => i32, |a, b| i32::from(a > b)),
F32Gt => exec_op!(executor; binary f32 => i32, |a, b| i32::from(a > b)),
F64Gt => exec_op!(executor; binary f64 => i32, |a, b| i32::from(a > b)),
I32Add => exec_op!(executor; binary i32 => i32, |a, b| a.wrapping_add(b)),
I64Add => exec_op!(executor; binary i64 => i64, |a, b| a.wrapping_add(b)),
F32Add => exec_op!(executor; binary f32 => f32, |a, b| a + b),
F64Add => exec_op!(executor; binary f64 => f64, |a, b| a + b),
I32Sub => exec_op!(executor; binary i32 => i32, |a, b| a.wrapping_sub(b)),
I64Sub => exec_op!(executor; binary i64 => i64, |a, b| a.wrapping_sub(b)),
F32Sub => exec_op!(executor; binary f32 => f32, |a, b| a - b),
F64Sub => exec_op!(executor; binary f64 => f64, |a, b| a - b),
F32Div => exec_op!(executor; binary f32 => f32, |a, b| a / b),
F64Div => exec_op!(executor; binary f64 => f64, |a, b| a / b),
I32Mul => exec_op!(executor; binary i32 => i32, |a, b| a.wrapping_mul(b)),
I64Mul => exec_op!(executor; binary i64 => i64, |a, b| a.wrapping_mul(b)),
F32Mul => exec_op!(executor; binary f32 => f32, |a, b| a * b),
F64Mul => exec_op!(executor; binary f64 => f64, |a, b| a * b),
I32DivS => exec_op!(executor; binary_fallible i32, |a, b| a.tw_checked_div(b)),
I64DivS => exec_op!(executor; binary_fallible i64, |a, b| a.tw_checked_div(b)),
I32DivU => exec_op!(executor; binary_fallible u32, |a, b| a.checked_div(b).ok_or(Trap::DivisionByZero)),
I64DivU => exec_op!(executor; binary_fallible u64, |a, b| a.checked_div(b).ok_or(Trap::DivisionByZero)),
I32RemS => exec_op!(executor; binary_fallible i32, |a, b| a.tw_checked_wrapping_rem(b)),
I64RemS => exec_op!(executor; binary_fallible i64, |a, b| a.tw_checked_wrapping_rem(b)),
I32RemU => exec_op!(executor; binary_fallible u32, |a, b| a.tw_checked_wrapping_rem(b)),
I64RemU => exec_op!(executor; binary_fallible u64, |a, b| a.tw_checked_wrapping_rem(b)),
I32And => exec_op!(executor; binary i32 => i32, |a, b| a & b),
I64And => exec_op!(executor; binary i64 => i64, |a, b| a & b),
I32Or => exec_op!(executor; binary i32 => i32, |a, b| a | b),
I64Or => exec_op!(executor; binary i64 => i64, |a, b| a | b),
I32Xor => exec_op!(executor; binary i32 => i32, |a, b| a ^ b),
I64Xor => exec_op!(executor; binary i64 => i64, |a, b| a ^ b),
I32Shl => exec_op!(executor; binary i32 => i32, |a, b| a.wrapping_shl(b as u32)),
I64Shl => exec_op!(executor; binary i64 => i64, |a, b| a.wrapping_shl(b as u32)),
I32ShrS => exec_op!(executor; binary i32 => i32, |a, b| a.wrapping_shr(b as u32)),
I64ShrS => exec_op!(executor; binary i64 => i64, |a, b| a.wrapping_shr(b as u32)),
I32ShrU => exec_op!(executor; binary u32 => u32, |a, b| a.wrapping_shr(b)),
I64ShrU => exec_op!(executor; binary u64 => u64, |a, b| a.wrapping_shr(b as u32)),
I32Rotl => exec_op!(executor; binary i32 => i32, |a, b| a.rotate_left(b as u32)),
I64Rotl => exec_op!(executor; binary i64 => i64, |a, b| a.rotate_left(b as u32)),
I32Rotr => exec_op!(executor; binary i32 => i32, |a, b| a.rotate_right(b as u32)),
I64Rotr => exec_op!(executor; binary i64 => i64, |a, b| a.rotate_right(b as u32)),
I64Add128 => executor.exec_i64_add128()?,
I64Sub128 => executor.exec_i64_sub128()?,
I64MulWideS => executor.exec_i64_mul_wide_s()?,
I64MulWideU => executor.exec_i64_mul_wide_u()?,
I32Clz => exec_op!(executor; unary i32 => i32, |v| v.leading_zeros() as i32),
I64Clz => exec_op!(executor; unary i64 => i64, |v| i64::from(v.leading_zeros())),
I32Ctz => exec_op!(executor; unary i32 => i32, |v| v.trailing_zeros() as i32),
I64Ctz => exec_op!(executor; unary i64 => i64, |v| i64::from(v.trailing_zeros())),
I32Popcnt => exec_op!(executor; unary i32 => i32, |v| v.count_ones() as i32),
I64Popcnt => exec_op!(executor; unary i64 => i64, |v| i64::from(v.count_ones())),
RefFunc(func_idx) => ValueRef::stack_push(&mut executor.store.value_stack, ValueRef::from_category_addr(executor.module.resolve_func_addr(*func_idx)))?,
RefNull(_) => ValueRef::stack_push(&mut executor.store.value_stack, ValueRef::NULL)?,
RefIsNull => executor.exec_ref_is_null()?,
RefAsNonNull => executor.exec_ref_as_non_null()?,
RefI31 => exec_op!(executor; unary i32 => ValueRef, |v| ValueRef::from_i31(v)),
I31GetS => executor.exec_i31_get(true)?,
I31GetU => executor.exec_i31_get(false)?,
RefEq => exec_op!(executor; binary ValueRef => i32, |a, b| i32::from(a == b)),
RefTest(ty) => executor.exec_ref_test(*ty)?,
RefCast(ty) => executor.exec_ref_cast(*ty)?,
StructNew(ty) => executor.exec_struct_new(*ty, false)?,
StructNewDefault(ty) => executor.exec_struct_new(*ty, true)?,
StructGet(idx) => executor.exec_struct_get(*idx, None)?,
StructGetS(idx) => executor.exec_struct_get(*idx, Some(true))?,
StructGetU(idx) => executor.exec_struct_get(*idx, Some(false))?,
StructSet(idx) => executor.exec_struct_set(*idx)?,
ArrayNew(ty) => executor.exec_array_new(*ty, false)?,
ArrayNewDefault(ty) => executor.exec_array_new(*ty, true)?,
ArrayNewFixed(idx) => executor.exec_array_new_fixed(*idx)?,
ArrayNewData(idx) => executor.exec_array_new_data(*idx)?,
ArrayNewElem(idx) => executor.exec_array_new_elem(*idx)?,
ArrayGet(ty) => executor.exec_array_get(*ty, None)?,
ArrayGetS(ty) => executor.exec_array_get(*ty, Some(true))?,
ArrayGetU(ty) => executor.exec_array_get(*ty, Some(false))?,
ArraySet(ty) => executor.exec_array_set(*ty)?,
ArrayLen => executor.exec_array_len()?,
ArrayFill(ty) => executor.exec_array_fill(*ty)?,
ArrayCopy(idx) => executor.exec_array_copy(*idx)?,
ArrayInitData(idx) => executor.exec_array_init_data(*idx)?,
ArrayInitElem(idx) => executor.exec_array_init_elem(*idx)?,
MemorySize(addr) => executor.exec_memory_size(*addr)?,
MemoryGrow(addr) => executor.exec_memory_grow(*addr)?,
MemoryCopy(idx) => executor.exec_memory_copy(*idx)?,
MemoryFill(addr) => executor.exec_memory_fill(*addr)?,
MemoryFillConst(idx) => executor.exec_memory_fill_const(*idx)?,
MemoryInit(idx) => executor.exec_memory_init(*idx)?,
DataDrop(data_index) => executor.store.state.get_data_mut(executor.module.resolve_data_addr(*data_index)).drop(),
ElemDrop(elem_index) => executor.store.state.get_elem_mut(executor.module.resolve_elem_addr(*elem_index)).drop(),
TableGet(table_idx) => executor.exec_table_get(*table_idx)?,
TableSet(table_idx) => executor.exec_table_set(*table_idx)?,
TableSize(table_idx) => executor.exec_table_size(*table_idx)?,
TableInit(idx) => executor.exec_table_init(*idx)?,
TableGrow(table_idx) => executor.exec_table_grow(*table_idx)?,
TableFill(table_idx) => executor.exec_table_fill(*table_idx)?,
TableCopy(idx) => executor.exec_table_copy(*idx)?,
I32Store(idx) => executor.exec_mem_store::<i32, i32, 4>(idx.resolve(&executor.func.data), identity)?,
I64Store(idx) => executor.exec_mem_store::<i64, i64, 8>(idx.resolve(&executor.func.data), identity)?,
F32Store(idx) => executor.exec_mem_store::<f32, f32, 4>(idx.resolve(&executor.func.data), identity)?,
F64Store(idx) => executor.exec_mem_store::<f64, f64, 8>(idx.resolve(&executor.func.data), identity)?,
FMaStoreF32(m) => executor.exec_fma_store::<f32, 4>(*m)?,
FMaStoreF64(m) => executor.exec_fma_store::<f64, 8>(*m)?,
I32Store8(idx) => executor.exec_mem_store::<i32, i8, 1>(idx.resolve(&executor.func.data), #[inline(always)] |v| v as i8)?,
I32Store16(idx) => executor.exec_mem_store::<i32, i16, 2>(idx.resolve(&executor.func.data), #[inline(always)] |v| v as i16)?,
I64Store8(idx) => executor.exec_mem_store::<i64, i8, 1>(idx.resolve(&executor.func.data), #[inline(always)] |v| v as i8)?,
I64Store16(idx) => executor.exec_mem_store::<i64, i16, 2>(idx.resolve(&executor.func.data), #[inline(always)] |v| v as i16)?,
I64Store32(idx) => executor.exec_mem_store::<i64, i32, 4>(idx.resolve(&executor.func.data), #[inline(always)] |v| v as i32)?,
I32Load(idx) => executor.exec_mem_load::<i32, 4, _>(idx.resolve(&executor.func.data), identity)?,
I64Load(idx) => executor.exec_mem_load::<i64, 8, _>(idx.resolve(&executor.func.data), identity)?,
F32Load(idx) => executor.exec_mem_load::<f32, 4, _>(idx.resolve(&executor.func.data), identity)?,
F64Load(idx) => executor.exec_mem_load::<f64, 8, _>(idx.resolve(&executor.func.data), identity)?,
I32Load8S(idx) => executor.exec_mem_load::<i8, 1, _>(idx.resolve(&executor.func.data), i32::from)?,
I32Load8U(idx) => executor.exec_mem_load::<u8, 1, _>(idx.resolve(&executor.func.data), i32::from)?,
I32Load16S(idx) => executor.exec_mem_load::<i16, 2, _>(idx.resolve(&executor.func.data), i32::from)?,
I32Load16U(idx) => executor.exec_mem_load::<u16, 2, _>(idx.resolve(&executor.func.data), i32::from)?,
I64Load8S(idx) => executor.exec_mem_load::<i8, 1, _>(idx.resolve(&executor.func.data), i64::from)?,
I64Load8U(idx) => executor.exec_mem_load::<u8, 1, _>(idx.resolve(&executor.func.data), i64::from)?,
I64Load16S(idx) => executor.exec_mem_load::<i16, 2, _>(idx.resolve(&executor.func.data), i64::from)?,
I64Load16U(idx) => executor.exec_mem_load::<u16, 2, _>(idx.resolve(&executor.func.data), i64::from)?,
I64Load32S(idx) => executor.exec_mem_load::<i32, 4, _>(idx.resolve(&executor.func.data), i64::from)?,
I64Load32U(idx) => executor.exec_mem_load::<u32, 4, _>(idx.resolve(&executor.func.data), i64::from)?,
F32ConvertI32S => exec_op!(executor; unary i32 => f32, |v| v as f32),
F32ConvertI64S => exec_op!(executor; unary i64 => f32, |v| v as f32),
F64ConvertI32S => exec_op!(executor; unary i32 => f64, |v| f64::from(v)),
F64ConvertI64S => exec_op!(executor; unary i64 => f64, |v| v as f64),
F32ConvertI32U => exec_op!(executor; unary u32 => f32, |v| v as f32),
F32ConvertI64U => exec_op!(executor; unary u64 => f32, |v| v as f32),
F64ConvertI32U => exec_op!(executor; unary u32 => f64, |v| f64::from(v)),
F64ConvertI64U => exec_op!(executor; unary u64 => f64, |v| v as f64),
I32Extend8S => exec_op!(executor; unary i32 => i32, |v| i32::from(v as i8)),
I32Extend16S => exec_op!(executor; unary i32 => i32, |v| i32::from(v as i16)),
I64Extend8S => exec_op!(executor; unary i64 => i64, |v| i64::from(v as i8)),
I64Extend16S => exec_op!(executor; unary i64 => i64, |v| i64::from(v as i16)),
I64Extend32S => exec_op!(executor; unary i64 => i64, |v| i64::from(v as i32)),
I64ExtendI32U => exec_op!(executor; unary u32 => i64, |v| i64::from(v)),
I64ExtendI32S => exec_op!(executor; unary i32 => i64, |v| i64::from(v)),
I32WrapI64 => exec_op!(executor; unary i64 => i32, |v| v as i32),
F32DemoteF64 => exec_op!(executor; unary f64 => f32, |v| v as f32),
F64PromoteF32 => exec_op!(executor; unary f32 => f64, |v| f64::from(v)),
F32Abs => exec_op!(executor; unary f32 => f32, |v| v.abs()),
F64Abs => exec_op!(executor; unary f64 => f64, |v| v.abs()),
F32Neg => exec_op!(executor; unary f32 => f32, |v| -v),
F64Neg => exec_op!(executor; unary f64 => f64, |v| -v),
F32Ceil => exec_op!(executor; unary f32 => f32, |v| v.ceil()),
F64Ceil => exec_op!(executor; unary f64 => f64, |v| v.ceil()),
F32Floor => exec_op!(executor; unary f32 => f32, |v| v.floor()),
F64Floor => exec_op!(executor; unary f64 => f64, |v| v.floor()),
F32Trunc => exec_op!(executor; unary f32 => f32, |v| v.trunc()),
F64Trunc => exec_op!(executor; unary f64 => f64, |v| v.trunc()),
F32Nearest => exec_op!(executor; unary f32 => f32, |v| v.tw_nearest()),
F64Nearest => exec_op!(executor; unary f64 => f64, |v| v.tw_nearest()),
F32Sqrt => exec_op!(executor; unary f32 => f32, |v| v.sqrt()),
F64Sqrt => exec_op!(executor; unary f64 => f64, |v| v.sqrt()),
F32Min => exec_op!(executor; binary f32 => f32, |a, b| a.tw_minimum(b)),
F64Min => exec_op!(executor; binary f64 => f64, |a, b| a.tw_minimum(b)),
F32Max => exec_op!(executor; binary f32 => f32, |a, b| a.tw_maximum(b)),
F64Max => exec_op!(executor; binary f64 => f64, |a, b| a.tw_maximum(b)),
F32Copysign => exec_op!(executor; binary f32 => f32, |a, b| a.copysign(b)),
F64Copysign => exec_op!(executor; binary f64 => f64, |a, b| a.copysign(b)),
I32TruncF32S => checked_conv_float!(f32, i32, executor),
I32TruncF64S => checked_conv_float!(f64, i32, executor),
I32TruncF32U => checked_conv_float!(f32, u32, i32, executor),
I32TruncF64U => checked_conv_float!(f64, u32, i32, executor),
I64TruncF32S => checked_conv_float!(f32, i64, executor),
I64TruncF64S => checked_conv_float!(f64, i64, executor),
I64TruncF32U => checked_conv_float!(f32, u64, i64, executor),
I64TruncF64U => checked_conv_float!(f64, u64, i64, executor),
I32TruncSatF32S => exec_op!(executor; unary f32 => i32, |v| v.trunc() as i32),
I32TruncSatF32U => exec_op!(executor; unary f32 => u32, |v| v.trunc() as u32),
I32TruncSatF64S => exec_op!(executor; unary f64 => i32, |v| v.trunc() as i32),
I32TruncSatF64U => exec_op!(executor; unary f64 => u32, |v| v.trunc() as u32),
I64TruncSatF32S => exec_op!(executor; unary f32 => i64, |v| v.trunc() as i64),
I64TruncSatF32U => exec_op!(executor; unary f32 => u64, |v| v.trunc() as u64),
I64TruncSatF64S => exec_op!(executor; unary f64 => i64, |v| v.trunc() as i64),
I64TruncSatF64U => exec_op!(executor; unary f64 => u64, |v| v.trunc() as u64),
V128Not => exec_op!(executor; unary Value128 => Value128, |v| v.v128_not()),
V128And => exec_op!(executor; binary Value128 => Value128, |a, b| a.v128_and(b)),
V128AndNot => exec_op!(executor; binary Value128 => Value128, |a, b| a.v128_andnot(b)),
V128Or => exec_op!(executor; binary Value128 => Value128, |a, b| a.v128_or(b)),
V128Xor => exec_op!(executor; binary Value128 => Value128, |a, b| a.v128_xor(b)),
V128Bitselect => exec_op!(executor; ternary Value128 => Value128, |a, b, c| Value128::v128_bitselect(a, b, c)),
V128AnyTrue => exec_op!(executor; unary Value128 => i32, |v| v.v128_any_true() as i32),
I8x16Swizzle => exec_op!(executor; binary Value128 => Value128, |a, s| a.i8x16_swizzle(s)),
I8x16RelaxedSwizzle => exec_op!(executor; binary Value128 => Value128, |a, s| a.i8x16_relaxed_swizzle(s)),
V128Load(idx) => executor.exec_mem_load::<Value128, 16, _>(idx.resolve(&executor.func.data), identity)?,
V128Load8x8S(idx) => executor.exec_mem_load::<u64, 8, Value128>(idx.resolve(&executor.func.data), |v| Value128::v128_load8x8_s(v.to_le_bytes()))?,
V128Load8x8U(idx) => executor.exec_mem_load::<u64, 8, Value128>(idx.resolve(&executor.func.data), |v| Value128::v128_load8x8_u(v.to_le_bytes()))?,
V128Load16x4S(idx) => executor.exec_mem_load::<u64, 8, Value128>(idx.resolve(&executor.func.data), |v| Value128::v128_load16x4_s(v.to_le_bytes()))?,
V128Load16x4U(idx) => executor.exec_mem_load::<u64, 8, Value128>(idx.resolve(&executor.func.data), |v| Value128::v128_load16x4_u(v.to_le_bytes()))?,
V128Load32x2S(idx) => executor.exec_mem_load::<u64, 8, Value128>(idx.resolve(&executor.func.data), |v| Value128::v128_load32x2_s(v.to_le_bytes()))?,
V128Load32x2U(idx) => executor.exec_mem_load::<u64, 8, Value128>(idx.resolve(&executor.func.data), |v| Value128::v128_load32x2_u(v.to_le_bytes()))?,
V128Load8Splat(idx) => executor.exec_mem_load::<i8, 1, Value128>(idx.resolve(&executor.func.data), Value128::splat_i8)?,
V128Load16Splat(idx) => executor.exec_mem_load::<i16, 2, Value128>(idx.resolve(&executor.func.data), Value128::splat_i16)?,
V128Load32Splat(idx) => executor.exec_mem_load::<i32, 4, Value128>(idx.resolve(&executor.func.data), Value128::splat_i32)?,
V128Load64Splat(idx) => executor.exec_mem_load::<i64, 8, Value128>(idx.resolve(&executor.func.data), Value128::splat_i64)?,
V128Store(idx) => executor.exec_mem_store::<Value128, Value128, 16>(idx.resolve(&executor.func.data), identity)?,
V128Store8Lane(arg) => executor.exec_mem_store_lane::<i8, 1>(*arg)?,
V128Store16Lane(arg) => executor.exec_mem_store_lane::<i16, 2>(*arg)?,
V128Store32Lane(arg) => executor.exec_mem_store_lane::<i32, 4>(*arg)?,
V128Store64Lane(arg) => executor.exec_mem_store_lane::<i64, 8>(*arg)?,
V128Load32Zero(idx) => executor.exec_mem_load::<i32, 4, Value128>(idx.resolve(&executor.func.data), |v| Value128::from_i32x4([v, 0, 0, 0]))?,
V128Load64Zero(idx) => executor.exec_mem_load::<i64, 8, Value128>(idx.resolve(&executor.func.data), |v| Value128::from_i64x2([v, 0]))?,
Const128(arg) => Value128::stack_push(&mut executor.store.value_stack, Value128(arg.resolve(&executor.func.data).value()))?,
I8x16ExtractLaneS(lane) => executor.exec_simd_extract_lane::<i32>(*lane, |v, lane| v.extract_lane_i8(lane) as i32)?,
I8x16ExtractLaneU(lane) => executor.exec_simd_extract_lane::<i32>(*lane, |v, lane| v.extract_lane_u8(lane) as i32)?,
I16x8ExtractLaneS(lane) => executor.exec_simd_extract_lane::<i32>(*lane, |v, lane| v.extract_lane_i16(lane) as i32)?,
I16x8ExtractLaneU(lane) => executor.exec_simd_extract_lane::<i32>(*lane, |v, lane| v.extract_lane_u16(lane) as i32)?,
I32x4ExtractLane(lane) => executor.exec_simd_extract_lane::<i32>(*lane, Value128::extract_lane_i32)?,
I64x2ExtractLane(lane) => executor.exec_simd_extract_lane::<i64>(*lane, Value128::extract_lane_i64)?,
F32x4ExtractLane(lane) => executor.exec_simd_extract_lane::<f32>(*lane, Value128::extract_lane_f32)?,
F64x2ExtractLane(lane) => executor.exec_simd_extract_lane::<f64>(*lane, Value128::extract_lane_f64)?,
V128Load8Lane(arg) => executor.exec_mem_load_lane::<i8, 1>(*arg)?,
V128Load16Lane(arg) => executor.exec_mem_load_lane::<i16, 2>(*arg)?,
V128Load32Lane(arg) => executor.exec_mem_load_lane::<i32, 4>(*arg)?,
V128Load64Lane(arg) => executor.exec_mem_load_lane::<i64, 8>(*arg)?,
I8x16ReplaceLane(lane) => executor.exec_simd_replace_lane::<i32>(*lane, |value, vector, lane| vector.i8x16_replace_lane(lane, value as i8))?,
I16x8ReplaceLane(lane) => executor.exec_simd_replace_lane::<i32>(*lane, |value, vector, lane| vector.i16x8_replace_lane(lane, value as i16))?,
I32x4ReplaceLane(lane) => executor.exec_simd_replace_lane::<i32>(*lane, |value, vector, lane| vector.i32x4_replace_lane(lane, value))?,
I64x2ReplaceLane(lane) => executor.exec_simd_replace_lane::<i64>(*lane, |value, vector, lane| vector.i64x2_replace_lane(lane, value))?,
F32x4ReplaceLane(lane) => executor.exec_simd_replace_lane::<f32>(*lane, |value, vector, lane| vector.f32x4_replace_lane(lane, value))?,
F64x2ReplaceLane(lane) => executor.exec_simd_replace_lane::<f64>(*lane, |value, vector, lane| vector.f64x2_replace_lane(lane, value))?,
I8x16Splat => exec_op!(executor; unary i32 => Value128, |v| Value128::splat_i8(v as i8)),
I16x8Splat => exec_op!(executor; unary i32 => Value128, |v| Value128::splat_i16(v as i16)),
I32x4Splat => exec_op!(executor; unary i32 => Value128, |v| Value128::splat_i32(v)),
I64x2Splat => exec_op!(executor; unary i64 => Value128, |v| Value128::splat_i64(v)),
F32x4Splat => exec_op!(executor; unary f32 => Value128, |v| Value128::splat_f32(v)),
F64x2Splat => exec_op!(executor; unary f64 => Value128, |v| Value128::splat_f64(v)),
I8x16Eq => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_eq(b)),
I16x8Eq => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_eq(b)),
I32x4Eq => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_eq(b)),
I64x2Eq => exec_op!(executor; binary Value128 => Value128, |a, b| a.i64x2_eq(b)),
F32x4Eq => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_eq(b)),
F64x2Eq => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_eq(b)),
I8x16Ne => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_ne(b)),
I16x8Ne => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_ne(b)),
I32x4Ne => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_ne(b)),
I64x2Ne => exec_op!(executor; binary Value128 => Value128, |a, b| a.i64x2_ne(b)),
F32x4Ne => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_ne(b)),
F64x2Ne => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_ne(b)),
I8x16LtS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_lt_s(b)),
I16x8LtS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_lt_s(b)),
I32x4LtS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_lt_s(b)),
I64x2LtS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i64x2_lt_s(b)),
I8x16LtU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_lt_u(b)),
I16x8LtU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_lt_u(b)),
I32x4LtU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_lt_u(b)),
F32x4Lt => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_lt(b)),
F64x2Lt => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_lt(b)),
F32x4Gt => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_gt(b)),
F64x2Gt => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_gt(b)),
I8x16GtS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_gt_s(b)),
I16x8GtS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_gt_s(b)),
I32x4GtS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_gt_s(b)),
I64x2GtS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i64x2_gt_s(b)),
I64x2LeS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i64x2_le_s(b)),
F32x4Le => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_le(b)),
F64x2Le => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_le(b)),
I8x16GtU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_gt_u(b)),
I16x8GtU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_gt_u(b)),
I32x4GtU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_gt_u(b)),
F32x4Ge => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_ge(b)),
F64x2Ge => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_ge(b)),
I8x16LeS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_le_s(b)),
I16x8LeS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_le_s(b)),
I32x4LeS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_le_s(b)),
I8x16LeU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_le_u(b)),
I16x8LeU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_le_u(b)),
I32x4LeU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_le_u(b)),
I8x16GeS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_ge_s(b)),
I16x8GeS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_ge_s(b)),
I32x4GeS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_ge_s(b)),
I64x2GeS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i64x2_ge_s(b)),
I8x16GeU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_ge_u(b)),
I16x8GeU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_ge_u(b)),
I32x4GeU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_ge_u(b)),
I8x16Abs => exec_op!(executor; unary Value128 => Value128, |a| a.i8x16_abs()),
I16x8Abs => exec_op!(executor; unary Value128 => Value128, |a| a.i16x8_abs()),
I32x4Abs => exec_op!(executor; unary Value128 => Value128, |a| a.i32x4_abs()),
I64x2Abs => exec_op!(executor; unary Value128 => Value128, |a| a.i64x2_abs()),
I8x16Neg => exec_op!(executor; unary Value128 => Value128, |a| a.i8x16_neg()),
I16x8Neg => exec_op!(executor; unary Value128 => Value128, |a| a.i16x8_neg()),
I32x4Neg => exec_op!(executor; unary Value128 => Value128, |a| a.i32x4_neg()),
I64x2Neg => exec_op!(executor; unary Value128 => Value128, |a| a.i64x2_neg()),
I8x16AllTrue => exec_op!(executor; unary Value128 => i32, |v| v.i8x16_all_true() as i32),
I16x8AllTrue => exec_op!(executor; unary Value128 => i32, |v| v.i16x8_all_true() as i32),
I32x4AllTrue => exec_op!(executor; unary Value128 => i32, |v| v.i32x4_all_true() as i32),
I64x2AllTrue => exec_op!(executor; unary Value128 => i32, |v| v.i64x2_all_true() as i32),
I8x16Bitmask => exec_op!(executor; unary Value128 => i32, |v| v.i8x16_bitmask() as i32),
I16x8Bitmask => exec_op!(executor; unary Value128 => i32, |v| v.i16x8_bitmask() as i32),
I32x4Bitmask => exec_op!(executor; unary Value128 => i32, |v| v.i32x4_bitmask() as i32),
I64x2Bitmask => exec_op!(executor; unary Value128 => i32, |v| v.i64x2_bitmask() as i32),
I8x16Shl => exec_op!(executor; binary i32, Value128 => Value128, |a, b| b.i8x16_shl(a as u32)),
I16x8Shl => exec_op!(executor; binary i32, Value128 => Value128, |a, b| b.i16x8_shl(a as u32)),
I32x4Shl => exec_op!(executor; binary i32, Value128 => Value128, |a, b| b.i32x4_shl(a as u32)),
I64x2Shl => exec_op!(executor; binary i32, Value128 => Value128, |a, b| b.i64x2_shl(a as u32)),
I8x16ShrS => exec_op!(executor; binary i32, Value128 => Value128, |a, b| b.i8x16_shr_s(a as u32)),
I16x8ShrS => exec_op!(executor; binary i32, Value128 => Value128, |a, b| b.i16x8_shr_s(a as u32)),
I32x4ShrS => exec_op!(executor; binary i32, Value128 => Value128, |a, b| b.i32x4_shr_s(a as u32)),
I64x2ShrS => exec_op!(executor; binary i32, Value128 => Value128, |a, b| b.i64x2_shr_s(a as u32)),
I8x16ShrU => exec_op!(executor; binary i32, Value128 => Value128, |a, b| b.i8x16_shr_u(a as u32)),
I16x8ShrU => exec_op!(executor; binary i32, Value128 => Value128, |a, b| b.i16x8_shr_u(a as u32)),
I32x4ShrU => exec_op!(executor; binary i32, Value128 => Value128, |a, b| b.i32x4_shr_u(a as u32)),
I64x2ShrU => exec_op!(executor; binary i32, Value128 => Value128, |a, b| b.i64x2_shr_u(a as u32)),
I8x16Add => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_add(b)),
I16x8Add => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_add(b)),
I32x4Add => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_add(b)),
I64x2Add => exec_op!(executor; binary Value128 => Value128, |a, b| a.i64x2_add(b)),
I8x16Sub => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_sub(b)),
I16x8Sub => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_sub(b)),
I32x4Sub => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_sub(b)),
I64x2Sub => exec_op!(executor; binary Value128 => Value128, |a, b| a.i64x2_sub(b)),
I8x16MinS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_min_s(b)),
I16x8MinS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_min_s(b)),
I32x4MinS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_min_s(b)),
I8x16MinU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_min_u(b)),
I16x8MinU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_min_u(b)),
I32x4MinU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_min_u(b)),
I8x16MaxS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_max_s(b)),
I16x8MaxS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_max_s(b)),
I32x4MaxS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_max_s(b)),
I8x16MaxU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_max_u(b)),
I16x8MaxU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_max_u(b)),
I32x4MaxU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_max_u(b)),
I64x2Mul => exec_op!(executor; binary Value128 => Value128, |a, b| a.i64x2_mul(b)),
I16x8Mul => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_mul(b)),
I32x4Mul => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_mul(b)),
I8x16NarrowI16x8S => exec_op!(executor; binary Value128 => Value128, |a, b| Value128::i8x16_narrow_i16x8_s(a, b)),
I8x16NarrowI16x8U => exec_op!(executor; binary Value128 => Value128, |a, b| Value128::i8x16_narrow_i16x8_u(a, b)),
I16x8NarrowI32x4S => exec_op!(executor; binary Value128 => Value128, |a, b| Value128::i16x8_narrow_i32x4_s(a, b)),
I16x8NarrowI32x4U => exec_op!(executor; binary Value128 => Value128, |a, b| Value128::i16x8_narrow_i32x4_u(a, b)),
I8x16AddSatS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_add_sat_s(b)),
I16x8AddSatS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_add_sat_s(b)),
I8x16AddSatU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_add_sat_u(b)),
I16x8AddSatU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_add_sat_u(b)),
I8x16SubSatS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_sub_sat_s(b)),
I16x8SubSatS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_sub_sat_s(b)),
I8x16SubSatU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_sub_sat_u(b)),
I16x8SubSatU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_sub_sat_u(b)),
I8x16AvgrU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i8x16_avgr_u(b)),
I16x8AvgrU => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_avgr_u(b)),
I16x8ExtAddPairwiseI8x16S => exec_op!(executor; unary Value128 => Value128, |a| a.i16x8_extadd_pairwise_i8x16_s()),
I16x8ExtAddPairwiseI8x16U => exec_op!(executor; unary Value128 => Value128, |a| a.i16x8_extadd_pairwise_i8x16_u()),
I32x4ExtAddPairwiseI16x8S => exec_op!(executor; unary Value128 => Value128, |a| a.i32x4_extadd_pairwise_i16x8_s()),
I32x4ExtAddPairwiseI16x8U => exec_op!(executor; unary Value128 => Value128, |a| a.i32x4_extadd_pairwise_i16x8_u()),
I16x8ExtMulLowI8x16S => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_extmul_low_i8x16_s(b)),
I16x8ExtMulLowI8x16U => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_extmul_low_i8x16_u(b)),
I16x8ExtMulHighI8x16S => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_extmul_high_i8x16_s(b)),
I16x8ExtMulHighI8x16U => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_extmul_high_i8x16_u(b)),
I32x4ExtMulLowI16x8S => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_extmul_low_i16x8_s(b)),
I32x4ExtMulLowI16x8U => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_extmul_low_i16x8_u(b)),
I32x4ExtMulHighI16x8S => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_extmul_high_i16x8_s(b)),
I32x4ExtMulHighI16x8U => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_extmul_high_i16x8_u(b)),
I64x2ExtMulLowI32x4S => exec_op!(executor; binary Value128 => Value128, |a, b| a.i64x2_extmul_low_i32x4_s(b)),
I64x2ExtMulLowI32x4U => exec_op!(executor; binary Value128 => Value128, |a, b| a.i64x2_extmul_low_i32x4_u(b)),
I64x2ExtMulHighI32x4S => exec_op!(executor; binary Value128 => Value128, |a, b| a.i64x2_extmul_high_i32x4_s(b)),
I64x2ExtMulHighI32x4U => exec_op!(executor; binary Value128 => Value128, |a, b| a.i64x2_extmul_high_i32x4_u(b)),
I16x8ExtendLowI8x16S => exec_op!(executor; unary Value128 => Value128, |a| a.i16x8_extend_low_i8x16_s()),
I16x8ExtendLowI8x16U => exec_op!(executor; unary Value128 => Value128, |a| a.i16x8_extend_low_i8x16_u()),
I16x8ExtendHighI8x16S => exec_op!(executor; unary Value128 => Value128, |a| a.i16x8_extend_high_i8x16_s()),
I16x8ExtendHighI8x16U => exec_op!(executor; unary Value128 => Value128, |a| a.i16x8_extend_high_i8x16_u()),
I32x4ExtendLowI16x8S => exec_op!(executor; unary Value128 => Value128, |a| a.i32x4_extend_low_i16x8_s()),
I32x4ExtendLowI16x8U => exec_op!(executor; unary Value128 => Value128, |a| a.i32x4_extend_low_i16x8_u()),
I32x4ExtendHighI16x8S => exec_op!(executor; unary Value128 => Value128, |a| a.i32x4_extend_high_i16x8_s()),
I32x4ExtendHighI16x8U => exec_op!(executor; unary Value128 => Value128, |a| a.i32x4_extend_high_i16x8_u()),
I64x2ExtendLowI32x4S => exec_op!(executor; unary Value128 => Value128, |a| a.i64x2_extend_low_i32x4_s()),
I64x2ExtendLowI32x4U => exec_op!(executor; unary Value128 => Value128, |a| a.i64x2_extend_low_i32x4_u()),
I64x2ExtendHighI32x4S => exec_op!(executor; unary Value128 => Value128, |a| a.i64x2_extend_high_i32x4_s()),
I64x2ExtendHighI32x4U => exec_op!(executor; unary Value128 => Value128, |a| a.i64x2_extend_high_i32x4_u()),
I8x16Popcnt => exec_op!(executor; unary Value128 => Value128, |v| v.i8x16_popcnt()),
I8x16Shuffle(idx) => executor.exec_simd_shuffle(Value128(idx.resolve(&executor.func.data).value()))?,
I16x8Q15MulrSatS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_q15mulr_sat_s(b)),
I32x4DotI16x8S => exec_op!(executor; binary Value128 => Value128, |a, b| a.i32x4_dot_i16x8_s(b)),
I8x16RelaxedLaneselect => exec_op!(executor; ternary Value128 => Value128, |a, b, c| Value128::i8x16_relaxed_laneselect(a, b, c)),
I16x8RelaxedLaneselect => exec_op!(executor; ternary Value128 => Value128, |a, b, c| Value128::i16x8_relaxed_laneselect(a, b, c)),
I32x4RelaxedLaneselect => exec_op!(executor; ternary Value128 => Value128, |a, b, c| Value128::i32x4_relaxed_laneselect(a, b, c)),
I64x2RelaxedLaneselect => exec_op!(executor; ternary Value128 => Value128, |a, b, c| Value128::i64x2_relaxed_laneselect(a, b, c)),
I16x8RelaxedQ15mulrS => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_relaxed_q15mulr_s(b)),
I16x8RelaxedDotI8x16I7x16S => exec_op!(executor; binary Value128 => Value128, |a, b| a.i16x8_relaxed_dot_i8x16_i7x16_s(b)),
I32x4RelaxedDotI8x16I7x16AddS => exec_op!(executor; ternary Value128 => Value128, |a, b, c| a.i32x4_relaxed_dot_i8x16_i7x16_add_s(b, c)),
F32x4Ceil => exec_op!(executor; unary Value128 => Value128, |v| v.f32x4_ceil()),
F64x2Ceil => exec_op!(executor; unary Value128 => Value128, |v| v.f64x2_ceil()),
F32x4Floor => exec_op!(executor; unary Value128 => Value128, |v| v.f32x4_floor()),
F64x2Floor => exec_op!(executor; unary Value128 => Value128, |v| v.f64x2_floor()),
F32x4Trunc => exec_op!(executor; unary Value128 => Value128, |v| v.f32x4_trunc()),
F64x2Trunc => exec_op!(executor; unary Value128 => Value128, |v| v.f64x2_trunc()),
F32x4Nearest => exec_op!(executor; unary Value128 => Value128, |v| v.f32x4_nearest()),
F64x2Nearest => exec_op!(executor; unary Value128 => Value128, |v| v.f64x2_nearest()),
F32x4Abs => exec_op!(executor; unary Value128 => Value128, |v| v.f32x4_abs()),
F64x2Abs => exec_op!(executor; unary Value128 => Value128, |v| v.f64x2_abs()),
F32x4Neg => exec_op!(executor; unary Value128 => Value128, |v| v.f32x4_neg()),
F64x2Neg => exec_op!(executor; unary Value128 => Value128, |v| v.f64x2_neg()),
F32x4Sqrt => exec_op!(executor; unary Value128 => Value128, |v| v.f32x4_sqrt()),
F64x2Sqrt => exec_op!(executor; unary Value128 => Value128, |v| v.f64x2_sqrt()),
F32x4Add => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_add(b)),
F64x2Add => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_add(b)),
F32x4Sub => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_sub(b)),
F64x2Sub => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_sub(b)),
F32x4Mul => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_mul(b)),
F64x2Mul => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_mul(b)),
F32x4Div => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_div(b)),
F64x2Div => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_div(b)),
F32x4Min => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_min(b)),
F64x2Min => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_min(b)),
F32x4Max => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_max(b)),
F64x2Max => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_max(b)),
F32x4PMin => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_pmin(b)),
F32x4PMax => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_pmax(b)),
F64x2PMin => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_pmin(b)),
F64x2PMax => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_pmax(b)),
F32x4RelaxedMadd => exec_op!(executor; ternary Value128 => Value128, |a, b, c| a.f32x4_relaxed_madd(b, c)),
F32x4RelaxedNmadd => exec_op!(executor; ternary Value128 => Value128, |a, b, c| a.f32x4_relaxed_nmadd(b, c)),
F64x2RelaxedMadd => exec_op!(executor; ternary Value128 => Value128, |a, b, c| a.f64x2_relaxed_madd(b, c)),
F64x2RelaxedNmadd => exec_op!(executor; ternary Value128 => Value128, |a, b, c| a.f64x2_relaxed_nmadd(b, c)),
F32x4RelaxedMin => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_relaxed_min(b)),
F32x4RelaxedMax => exec_op!(executor; binary Value128 => Value128, |a, b| a.f32x4_relaxed_max(b)),
F64x2RelaxedMin => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_relaxed_min(b)),
F64x2RelaxedMax => exec_op!(executor; binary Value128 => Value128, |a, b| a.f64x2_relaxed_max(b)),
I32x4TruncSatF32x4S => exec_op!(executor; unary Value128 => Value128, |v| v.i32x4_trunc_sat_f32x4_s()),
I32x4TruncSatF32x4U => exec_op!(executor; unary Value128 => Value128, |v| v.i32x4_trunc_sat_f32x4_u()),
F32x4ConvertI32x4S => exec_op!(executor; unary Value128 => Value128, |v| v.f32x4_convert_i32x4_s()),
F32x4ConvertI32x4U => exec_op!(executor; unary Value128 => Value128, |v| v.f32x4_convert_i32x4_u()),
F64x2ConvertLowI32x4S => exec_op!(executor; unary Value128 => Value128, |v| v.f64x2_convert_low_i32x4_s()),
F64x2ConvertLowI32x4U => exec_op!(executor; unary Value128 => Value128, |v| v.f64x2_convert_low_i32x4_u()),
F32x4DemoteF64x2Zero => exec_op!(executor; unary Value128 => Value128, |v| v.f32x4_demote_f64x2_zero()),
F64x2PromoteLowF32x4 => exec_op!(executor; unary Value128 => Value128, |v| v.f64x2_promote_low_f32x4()),
I32x4TruncSatF64x2SZero => exec_op!(executor; unary Value128 => Value128, |v| v.i32x4_trunc_sat_f64x2_s_zero()),
I32x4TruncSatF64x2UZero => exec_op!(executor; unary Value128 => Value128, |v| v.i32x4_trunc_sat_f64x2_u_zero()),
I32x4RelaxedTruncF32x4S => exec_op!(executor; unary Value128 => Value128, |v| v.i32x4_relaxed_trunc_f32x4_s()),
I32x4RelaxedTruncF32x4U => exec_op!(executor; unary Value128 => Value128, |v| v.i32x4_relaxed_trunc_f32x4_u()),
I32x4RelaxedTruncF64x2SZero => exec_op!(executor; unary Value128 => Value128, |v| v.i32x4_relaxed_trunc_f64x2_s_zero()),
I32x4RelaxedTruncF64x2UZero => exec_op!(executor; unary Value128 => Value128, |v| v.i32x4_relaxed_trunc_f64x2_u_zero()),
}
};
}