package interpreter

import (
	
	
	
	
	
	
	
	
	

	
	
	
	
	
	
	
	
	
)

// callStackCeiling is the maximum WebAssembly call frame stack height. This allows wazero to raise
// wasm.ErrCallStackOverflow instead of overflowing the Go runtime.
//
// The default value should suffice for most use cases. Those wishing to change this can via `go build -ldflags`.
var callStackCeiling = 2000

type compiledFunctionWithCount struct {
	funcs    []compiledFunction
	refCount int
}

// engine is an interpreter implementation of wasm.Engine
type engine struct {
	enabledFeatures   api.CoreFeatures
	compiledFunctions map[wasm.ModuleID]*compiledFunctionWithCount // guarded by mutex.
	mux               sync.Mutex
}

func ( context.Context,  api.CoreFeatures,  filecache.Cache) wasm.Engine {
	return &engine{
		enabledFeatures:   ,
		compiledFunctions: map[wasm.ModuleID]*compiledFunctionWithCount{},
	}
}

// Close implements the same method as documented on wasm.Engine.
func ( *engine) () ( error) {
	.mux.Lock()
	defer .mux.Unlock()
	clear(.compiledFunctions)
	return
}

// CompiledModuleCount implements the same method as documented on wasm.Engine.
func ( *engine) () uint32 {
	.mux.Lock()
	defer .mux.Unlock()
	return uint32(len(.compiledFunctions))
}

// DeleteCompiledModule implements the same method as documented on wasm.Engine.
func ( *engine) ( *wasm.Module) {
	.deleteCompiledFunctions()
}

func ( *engine) ( *wasm.Module) {
	.mux.Lock()
	defer .mux.Unlock()
	,  := .compiledFunctions[.ID]
	if ! {
		return
	}
	.refCount--
	if .refCount > 0 {
		return
	}
	delete(.compiledFunctions, .ID)
}

func ( *engine) ( *wasm.Module,  []compiledFunction) {
	.mux.Lock()
	defer .mux.Unlock()
	if ,  := .compiledFunctions[.ID];  {
		.refCount++
		return
	}
	.compiledFunctions[.ID] = &compiledFunctionWithCount{funcs: , refCount: 1}
}

func ( *engine) ( *wasm.Module,  bool) ( []compiledFunction,  bool) {
	.mux.Lock()
	defer .mux.Unlock()
	,  := .compiledFunctions[.ID]
	if  {
		 = .funcs
		if  {
			.refCount++
		}
	}
	return
}

// moduleEngine implements wasm.ModuleEngine
type moduleEngine struct {
	// codes are the compiled functions in a module instances.
	// The index is module instance-scoped.
	functions []function

	// parentEngine holds *engine from which this module engine is created from.
	parentEngine *engine
}

// GetGlobalValue implements the same method as documented on wasm.ModuleEngine.
func ( *moduleEngine) (wasm.Index) (,  uint64) {
	panic("BUG: GetGlobalValue should never be called on interpreter mode")
}

// SetGlobalValue implements the same method as documented on wasm.ModuleEngine.
func ( *moduleEngine) ( wasm.Index, ,  uint64) {
	panic("BUG: SetGlobalValue should never be called on interpreter mode")
}

// OwnsGlobals implements the same method as documented on wasm.ModuleEngine.
func ( *moduleEngine) () bool { return false }

// MemoryGrown implements wasm.ModuleEngine.
func ( *moduleEngine) () {}

// callEngine holds context per moduleEngine.Call, and shared across all the
// function calls originating from the same moduleEngine.Call execution.
//
// This implements api.Function.
type callEngine struct {
	internalapi.WazeroOnlyType

	// stack contains the operands.
	// Note that all the values are represented as uint64.
	stack []uint64

	// frames are the function call stack.
	frames []*callFrame

	// f is the initial function for this call engine.
	f *function

	// stackiterator for Listeners to walk frames and stack.
	stackIterator stackIterator
}

func ( *moduleEngine) ( *function) *callEngine {
	return &callEngine{f: }
}

func ( *callEngine) ( uint64) {
	.stack = append(.stack, )
}

func ( *callEngine) ( []uint64) {
	.stack = append(.stack, ...)
}

func ( *callEngine) () ( uint64) {
	// No need to check stack bound
	// as we can assume that all the operations
	// are valid thanks to validateFunction
	// at module validation phase
	// and interpreterir translation
	// before compilation.
	 := len(.stack) - 1
	 = .stack[]
	.stack = .stack[:]
	return
}

func ( *callEngine) ( []uint64) {
	 := len(.stack) - len()
	copy(, .stack[:])
	.stack = .stack[:]
}

// peekValues peeks api.ValueType values from the stack and returns them.
func ( *callEngine) ( int) []uint64 {
	if  == 0 {
		return nil
	}
	 := len(.stack)
	return .stack[- : ]
}

func ( *callEngine) ( uint64) {
	 := inclusiveRangeFromU64()
	if .Start == -1 {
		return
	} else if .Start == 0 {
		.stack = .stack[:int32(len(.stack))-1-.End]
	} else {
		 := .stack[:int32(len(.stack))-1-.End]
		 = append(, .stack[int32(len(.stack))-.Start:]...)
		.stack = 
	}
}

func ( *callEngine) ( *callFrame) {
	if callStackCeiling <= len(.frames) {
		panic(wasmruntime.ErrRuntimeStackOverflow)
	}
	.frames = append(.frames, )
}

func ( *callEngine) () ( *callFrame) {
	// No need to check stack bound as we can assume that all the operations are valid thanks to validateFunction at
	// module validation phase and interpreterir translation before compilation.
	 := len(.frames) - 1
	 = .frames[]
	.frames = .frames[:]
	return
}

type callFrame struct {
	// pc is the program counter representing the current position in code.body.
	pc uint64
	// f is the compiled function used in this function frame.
	f *function
	// base index in the frame of this function, used to detect the count of
	// values on the stack.
	base int
}

type compiledFunction struct {
	source              *wasm.Module
	body                []unionOperation
	listener            experimental.FunctionListener
	offsetsInWasmBinary []uint64
	hostFn              interface{}
	ensureTermination   bool
	index               wasm.Index
}

type function struct {
	funcType       *wasm.FunctionType
	moduleInstance *wasm.ModuleInstance
	typeID         wasm.FunctionTypeID
	parent         *compiledFunction
}

// functionFromUintptr resurrects the original *function from the given uintptr
// which comes from either funcref table or OpcodeRefFunc instruction.
func functionFromUintptr( uintptr) *function {
	// Wraps ptrs as the double pointer in order to avoid the unsafe access as detected by race detector.
	//
	// For example, if we have (*function)(unsafe.Pointer(ptr)) instead, then the race detector's "checkptr"
	// subroutine wanrs as "checkptr: pointer arithmetic result points to invalid allocation"
	// https://github.com/golang/go/blob/go1.24.0/src/runtime/checkptr.go#L69
	var  *uintptr = &
	return *(**function)(unsafe.Pointer())
}

type snapshot struct {
	stack  []uint64
	frames []*callFrame
	pc     uint64

	ret []uint64

	ce *callEngine
}

// Snapshot implements the same method as documented on experimental.Snapshotter.
func ( *callEngine) () experimental.Snapshot {
	return &snapshot{
		stack:  slices.Clone(.stack),
		frames: slices.Clone(.frames),
		ce:     ,
	}
}

// Restore implements the same method as documented on experimental.Snapshot.
func ( *snapshot) ( []uint64) {
	.ret = 
	panic()
}

func ( *snapshot) () {
	 := .ce

	.stack = .stack
	.frames = .frames
	.frames[len(.frames)-1].pc = .pc

	copy(.stack[len(.stack)-len(.ret):], .ret)
}

// Error implements the same method on error.
func ( *snapshot) () string {
	return "unhandled snapshot restore, this generally indicates restore was called from a different " +
		"exported function invocation than snapshot"
}

// stackIterator implements experimental.StackIterator.
type stackIterator struct {
	stack   []uint64
	frames  []*callFrame
	started bool
	fn      *function
	pc      uint64
}

func ( *stackIterator) ( []uint64,  []*callFrame,  *function) {
	.fn = 
	.pc = 0
	.stack = 
	.frames = 
	.started = false
}

func ( *stackIterator) () {
	.stack = nil
	.frames = nil
	.started = false
	.fn = nil
}

// Next implements the same method as documented on experimental.StackIterator.
func ( *stackIterator) () bool {
	if !.started {
		.started = true
		return true
	}

	if len(.frames) == 0 {
		return false
	}

	 := .frames[len(.frames)-1]
	.stack = .stack[:.base]
	.fn = .f
	.pc = .pc
	.frames = .frames[:len(.frames)-1]
	return true
}

// Function implements the same method as documented on
// experimental.StackIterator.
func ( *stackIterator) () experimental.InternalFunction {
	return internalFunction{.fn}
}

// ProgramCounter implements the same method as documented on
// experimental.StackIterator.
func ( *stackIterator) () experimental.ProgramCounter {
	return experimental.ProgramCounter(.pc)
}

// internalFunction implements experimental.InternalFunction.
type internalFunction struct{ *function }

// Definition implements the same method as documented on
// experimental.InternalFunction.
func ( internalFunction) () api.FunctionDefinition {
	return .definition()
}

// SourceOffsetForPC implements the same method as documented on
// experimental.InternalFunction.
func ( internalFunction) ( experimental.ProgramCounter) uint64 {
	 := .parent.offsetsInWasmBinary
	if uint64() < uint64(len()) {
		return []
	}
	return 0
}

// interpreter mode doesn't maintain call frames in the stack, so pass the zero size to the IR.
const callFrameStackSize = 0

// CompileModule implements the same method as documented on wasm.Engine.
func ( *engine) ( context.Context,  *wasm.Module,  []experimental.FunctionListener,  bool) error {
	if ,  := .getCompiledFunctions(, true);  { // cache hit!
		return nil
	}

	 := make([]compiledFunction, len(.FunctionSection))
	,  := newCompiler(.enabledFeatures, callFrameStackSize, , )
	if  != nil {
		return 
	}
	 := .ImportFunctionCount
	for  := range .CodeSection {
		var  experimental.FunctionListener
		if  < len() {
			 = []
		}

		 := &[]
		// If this is the host function, there's nothing to do as the runtime representation of
		// host function in interpreter is its Go function itself as opposed to Wasm functions,
		// which need to be compiled down to
		if  := &.CodeSection[]; .GoFunc != nil {
			.hostFn = .GoFunc
		} else {
			,  := .Next()
			if  != nil {
				return 
			}
			 = .lowerIR(, )
			if  != nil {
				 := .FunctionDefinition(uint32() + .ImportFunctionCount)
				return fmt.Errorf("failed to lower func[%s] to interpreterir: %w", .DebugName(), )
			}
		}
		.source = 
		.ensureTermination = 
		.listener = 
		.index =  + uint32()
	}
	.addCompiledFunctions(, )
	return nil
}

// NewModuleEngine implements the same method as documented on wasm.Engine.
func ( *engine) ( *wasm.Module,  *wasm.ModuleInstance) (wasm.ModuleEngine, error) {
	 := &moduleEngine{
		parentEngine: ,
		functions:    make([]function, len(.FunctionSection)+int(.ImportFunctionCount)),
	}

	,  := .getCompiledFunctions(, false)
	if ! {
		return nil, errors.New("source module must be compiled before instantiation")
	}

	for  := range  {
		 := &[]
		 :=  + int(.ImportFunctionCount)
		 := .FunctionSection[]
		.functions[] = function{
			moduleInstance: ,
			typeID:         .TypeIDs[],
			funcType:       &.TypeSection[],
			parent:         ,
		}
	}
	return , nil
}

// lowerIR lowers the interpreterir operations to engine friendly struct.
func ( *engine) ( *compilationResult,  *compiledFunction) error {
	// Copy the body from the result.
	.body = slices.Clone(.Operations)
	// Also copy the offsets if necessary.
	if  := .IROperationSourceOffsetsInWasmBinary; len() > 0 {
		.offsetsInWasmBinary = slices.Clone()
	}

	 := [labelKindNum][]uint64{}

	// First, we iterate all labels, and resolve the address.
	for  := range .body {
		 := &.body[]
		switch .Kind {
		case operationKindLabel:
			 := label(.U1)
			 := uint64()

			,  := .Kind(), .FrameID()
			 := [.Kind()]
			// Expand the slice if necessary.
			if  :=  - len() + 1;  > 0 {
				 = append(, make([]uint64, )...)
			}
			[] = 
			[] = 
		}
	}

	// Then resolve the label as the index to the body.
	for  := range .body {
		 := &.body[]
		switch .Kind {
		case operationKindBr:
			.setLabelAddress(&.U1, label(.U1), )
		case operationKindBrIf:
			.setLabelAddress(&.U1, label(.U1), )
			.setLabelAddress(&.U2, label(.U2), )
		case operationKindBrTable:
			for  := 0;  < len(.Us);  += 2 {
				 := .Us[]
				.setLabelAddress(&.Us[], label(), )
			}
		case operationKindTailCallReturnCallIndirect:
			.setLabelAddress(&.Us[1], label(.Us[1]), )
		}
	}
	return nil
}

func ( *engine) ( *uint64,  label,  [labelKindNum][]uint64) {
	if .IsReturnTarget() {
		// Jmp to the end of the possible binary.
		* = math.MaxUint64
	} else {
		* = [.Kind()][.FrameID()]
	}
}

// ResolveImportedFunction implements wasm.ModuleEngine.
func ( *moduleEngine) (, ,  wasm.Index,  wasm.ModuleEngine) {
	 := .(*moduleEngine)
	.functions[] = .functions[]
}

// ResolveImportedMemory implements wasm.ModuleEngine.
func ( *moduleEngine) (wasm.ModuleEngine) {}

// DoneInstantiation implements wasm.ModuleEngine.
func ( *moduleEngine) () {}

// FunctionInstanceReference implements the same method as documented on wasm.ModuleEngine.
func ( *moduleEngine) ( wasm.Index) wasm.Reference {
	return uintptr(unsafe.Pointer(&.functions[]))
}

// NewFunction implements the same method as documented on wasm.ModuleEngine.
func ( *moduleEngine) ( wasm.Index) ( api.Function) {
	// Note: The input parameters are pre-validated, so a compiled function is only absent on close. Updates to
	// code on close aren't locked, neither is this read.
	 := &.functions[]
	return .newCallEngine()
}

// LookupFunction implements the same method as documented on wasm.ModuleEngine.
func ( *moduleEngine) ( *wasm.TableInstance,  wasm.FunctionTypeID,  wasm.Index) (*wasm.ModuleInstance, wasm.Index) {
	if  >= uint32(len(.References)) {
		panic(wasmruntime.ErrRuntimeInvalidTableAccess)
	}
	 := .References[]
	if  == 0 {
		panic(wasmruntime.ErrRuntimeInvalidTableAccess)
	}

	 := functionFromUintptr()
	if .typeID !=  {
		panic(wasmruntime.ErrRuntimeIndirectCallTypeMismatch)
	}
	return .moduleInstance, .parent.index
}

// Definition implements the same method as documented on api.Function.
func ( *callEngine) () api.FunctionDefinition {
	return .f.definition()
}

func ( *function) () api.FunctionDefinition {
	 := .parent
	return .source.FunctionDefinition(.index)
}

// Call implements the same method as documented on api.Function.
func ( *callEngine) ( context.Context,  ...uint64) ( []uint64,  error) {
	 := .f.funcType
	if  := .ParamNumInUint64;  != len() {
		return nil, fmt.Errorf("expected %d params, but passed %d", , len())
	}
	return .call(, , nil)
}

// CallWithStack implements the same method as documented on api.Function.
func ( *callEngine) ( context.Context,  []uint64) error {
	, ,  := wasm.SplitCallStack(.f.funcType, )
	if  != nil {
		return 
	}
	_,  = .call(, , )
	return 
}

func ( *callEngine) ( context.Context, ,  []uint64) ( []uint64,  error) {
	 := .f.moduleInstance
	if .f.parent.ensureTermination {
		select {
		case <-.Done():
			// If the provided context is already done, close the call context
			// and return the error.
			.CloseWithCtxErr()
			return nil, .FailIfClosed()
		default:
		}
	}

	if .Value(expctxkeys.EnableSnapshotterKey{}) != nil {
		 = context.WithValue(, expctxkeys.SnapshotterKey{}, )
	}

	defer func() {
		// If the module closed during the call, and the call didn't err for another reason, set an ExitError.
		if  == nil {
			 = .FailIfClosed()
		}
		// TODO: ^^ Will not fail if the function was imported from a closed module.

		if  := recover();  != nil {
			 = .recoverOnCall(, , )
		}
	}()

	.pushValues()

	if .f.parent.ensureTermination {
		 := .CloseModuleOnCanceledOrTimeout()
		defer ()
	}

	.callFunction(, , .f)

	// This returns a safe copy of the results, instead of a slice view. If we
	// returned a re-slice, the caller could accidentally or purposefully
	// corrupt the stack of subsequent calls.
	 := .f.funcType
	if  == nil && .ResultNumInUint64 > 0 {
		 = make([]uint64, .ResultNumInUint64)
	}
	.popValues()
	return , nil
}

// functionListenerInvocation captures arguments needed to perform function
// listener invocations when unwinding the call stack.
type functionListenerInvocation struct {
	experimental.FunctionListener
	def api.FunctionDefinition
}

// recoverOnCall takes the recovered value `recoverOnCall`, and wraps it
// with the call frame stack traces. Also, reset the state of callEngine
// so that it can be used for the subsequent calls.
func ( *callEngine) ( context.Context,  *wasm.ModuleInstance,  interface{}) ( error) {
	if ,  := .(*snapshot);  {
		// A snapshot that wasn't handled was created by a different call engine possibly from a nested wasm invocation,
		// let it propagate up to be handled by the caller.
		panic()
	}

	 := wasmdebug.NewErrorBuilder()
	 := len(.frames)
	 := make([]functionListenerInvocation, 0, 16)

	if  > wasmdebug.MaxFrames {
		 = wasmdebug.MaxFrames
	}
	for  := 0;  < ; ++ {
		 := .popFrame()
		 := .f
		 := .definition()
		var  []string
		if  := .f.parent; .body != nil && len(.offsetsInWasmBinary) > 0 {
			 = .source.DWARFLines.Line(.offsetsInWasmBinary[.pc])
		}
		.AddFrame(.DebugName(), .ParamTypes(), .ResultTypes(), )
		if .parent.listener != nil {
			 = append(, functionListenerInvocation{
				FunctionListener: .parent.listener,
				def:              .definition(),
			})
		}
	}

	 = .FromRecovered()
	for  := range  {
		[].Abort(, , [].def, )
	}

	// Allows the reuse of CallEngine.
	.stack, .frames = .stack[:0], .frames[:0]
	return
}

func ( *callEngine) ( context.Context,  *wasm.ModuleInstance,  *function) {
	if .parent.hostFn != nil {
		.callGoFuncWithStack(, , )
	} else if  := .parent.listener;  != nil {
		.callNativeFuncWithListener(, , , )
	} else {
		.callNativeFunc(, , )
	}
}

func ( *callEngine) ( context.Context,  *wasm.ModuleInstance,  *function,  []uint64) {
	 := .funcType
	 := .parent.listener
	if  != nil {
		 := [:.ParamNumInUint64]
		.stackIterator.reset(.stack, .frames, )
		.Before(, , .definition(), , &.stackIterator)
		.stackIterator.clear()
	}
	 := &callFrame{f: , base: len(.stack)}
	.pushFrame()

	 := .parent.hostFn
	switch fn := .(type) {
	case api.GoModuleFunction:
		.Call(, , )
	case api.GoFunction:
		.Call(, )
	}

	.popFrame()
	if  != nil {
		// TODO: This doesn't get the error due to use of panic to propagate them.
		 := [:.ResultNumInUint64]
		.After(, , .definition(), )
	}
}

func ( *callEngine) ( context.Context,  *wasm.ModuleInstance,  *function) {
	 := &callFrame{f: , base: len(.stack)}
	 := .moduleInstance
	 := .Engine.(*moduleEngine).functions
	 := .MemoryInstance
	 := .Globals
	 := .Tables
	 := .TypeIDs
	 := .DataInstances
	 := .ElementInstances
	.pushFrame()
	 := .f.parent.body
	 := uint64(len())
	for .pc <  {
		 := &[.pc]
		// TODO: add description of each operation/case
		// on, for example, how many args are used,
		// how the stack is modified, etc.
		switch .Kind {
		case operationKindBuiltinFunctionCheckExitCode:
			if  := .FailIfClosed();  != nil {
				panic()
			}
			.pc++
		case operationKindUnreachable:
			panic(wasmruntime.ErrRuntimeUnreachable)
		case operationKindBr:
			.pc = .U1
		case operationKindBrIf:
			if .popValue() > 0 {
				.drop(.U3)
				.pc = .U1
			} else {
				.pc = .U2
			}
		case operationKindBrTable:
			 := .popValue()
			 := uint64(len(.Us))/2 - 1
			if  >  {
				 = 
			}
			 *= 2
			.drop(.Us[+1])
			.pc = .Us[]
		case operationKindCall:
			func() {
				if .Value(expctxkeys.EnableSnapshotterKey{}) != nil {
					defer func() {
						if  := recover();  != nil {
							if ,  := .(*snapshot);  && .ce ==  {
								.doRestore()
								 = .frames[len(.frames)-1]
								 = .f.parent.body
								 = uint64(len())
							} else {
								panic()
							}
						}
					}()
				}
				.callFunction(, .moduleInstance, &[.U1])
			}()
			.pc++
		case operationKindCallIndirect:
			 := .popValue()
			 := [.U2]
			 := .functionForOffset(, , [.U1])

			.callFunction(, .moduleInstance, )
			.pc++
		case operationKindDrop:
			.drop(.U1)
			.pc++
		case operationKindSelect:
			 := .popValue()
			if .B3 { // Target is vector.
				,  := .popValue(), .popValue()
				if  == 0 {
					_, _ = .popValue(), .popValue() // discard the x1's lo and hi bits.
					.pushValue()
					.pushValue()
				}
			} else {
				 := .popValue()
				if  == 0 {
					_ = .popValue()
					.pushValue()
				}
			}
			.pc++
		case operationKindPick:
			 := len(.stack) - 1 - int(.U1)
			.pushValue(.stack[])
			if .B3 { // V128 value target.
				.pushValue(.stack[+1])
			}
			.pc++
		case operationKindSet:
			if .B3 { // V128 value target.
				 := len(.stack) - 1 - int(.U1)
				 :=  + 1
				,  := .popValue(), .popValue()
				.stack[], .stack[] = , 
			} else {
				 := len(.stack) - 1 - int(.U1)
				.stack[] = .popValue()
			}
			.pc++
		case operationKindGlobalGet:
			 := [.U1]
			.pushValue(.Val)
			if .Type.ValType == wasm.ValueTypeV128 {
				.pushValue(.ValHi)
			}
			.pc++
		case operationKindGlobalSet:
			 := [.U1]
			if .Type.ValType == wasm.ValueTypeV128 {
				.ValHi = .popValue()
			}
			.Val = .popValue()
			.pc++
		case operationKindLoad:
			 := .popMemoryOffset()
			switch unsignedType(.B1) {
			case unsignedTypeI32, unsignedTypeF32:
				if ,  := .ReadUint32Le(); ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				} else {
					.pushValue(uint64())
				}
			case unsignedTypeI64, unsignedTypeF64:
				if ,  := .ReadUint64Le(); ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				} else {
					.pushValue()
				}
			}
			.pc++
		case operationKindLoad8:
			,  := .ReadByte(.popMemoryOffset())
			if ! {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}

			switch signedInt(.B1) {
			case signedInt32:
				.pushValue(uint64(uint32(int8())))
			case signedInt64:
				.pushValue(uint64(int8()))
			case signedUint32, signedUint64:
				.pushValue(uint64())
			}
			.pc++
		case operationKindLoad16:

			,  := .ReadUint16Le(.popMemoryOffset())
			if ! {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}

			switch signedInt(.B1) {
			case signedInt32:
				.pushValue(uint64(uint32(int16())))
			case signedInt64:
				.pushValue(uint64(int16()))
			case signedUint32, signedUint64:
				.pushValue(uint64())
			}
			.pc++
		case operationKindLoad32:
			,  := .ReadUint32Le(.popMemoryOffset())
			if ! {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}

			if .B1 == 1 { // Signed
				.pushValue(uint64(int32()))
			} else {
				.pushValue(uint64())
			}
			.pc++
		case operationKindStore:
			 := .popValue()
			 := .popMemoryOffset()
			switch unsignedType(.B1) {
			case unsignedTypeI32, unsignedTypeF32:
				if !.WriteUint32Le(, uint32()) {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
			case unsignedTypeI64, unsignedTypeF64:
				if !.WriteUint64Le(, ) {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
			}
			.pc++
		case operationKindStore8:
			 := byte(.popValue())
			 := .popMemoryOffset()
			if !.WriteByte(, ) {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			.pc++
		case operationKindStore16:
			 := uint16(.popValue())
			 := .popMemoryOffset()
			if !.WriteUint16Le(, ) {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			.pc++
		case operationKindStore32:
			 := uint32(.popValue())
			 := .popMemoryOffset()
			if !.WriteUint32Le(, ) {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			.pc++
		case operationKindMemorySize:
			.pushValue(uint64(.Pages()))
			.pc++
		case operationKindMemoryGrow:
			 := .popValue()
			if ,  := .Grow(uint32()); ! {
				.pushValue(uint64(0xffffffff)) // = -1 in signed 32-bit integer.
			} else {
				.pushValue(uint64())
			}
			.pc++
		case operationKindConstI32, operationKindConstI64,
			operationKindConstF32, operationKindConstF64:
			.pushValue(.U1)
			.pc++
		case operationKindEq:
			var  bool
			switch unsignedType(.B1) {
			case unsignedTypeI32:
				,  := .popValue(), .popValue()
				 = uint32() == uint32()
			case unsignedTypeI64:
				,  := .popValue(), .popValue()
				 =  == 
			case unsignedTypeF32:
				,  := .popValue(), .popValue()
				 = math.Float32frombits(uint32()) == math.Float32frombits(uint32())
			case unsignedTypeF64:
				,  := .popValue(), .popValue()
				 = math.Float64frombits() == math.Float64frombits()
			}
			if  {
				.pushValue(1)
			} else {
				.pushValue(0)
			}
			.pc++
		case operationKindNe:
			var  bool
			switch unsignedType(.B1) {
			case unsignedTypeI32, unsignedTypeI64:
				,  := .popValue(), .popValue()
				 =  != 
			case unsignedTypeF32:
				,  := .popValue(), .popValue()
				 = math.Float32frombits(uint32()) != math.Float32frombits(uint32())
			case unsignedTypeF64:
				,  := .popValue(), .popValue()
				 = math.Float64frombits() != math.Float64frombits()
			}
			if  {
				.pushValue(1)
			} else {
				.pushValue(0)
			}
			.pc++
		case operationKindEqz:
			if .popValue() == 0 {
				.pushValue(1)
			} else {
				.pushValue(0)
			}
			.pc++
		case operationKindLt:
			 := .popValue()
			 := .popValue()
			var  bool
			switch signedType(.B1) {
			case signedTypeInt32:
				 = int32() < int32()
			case signedTypeInt64:
				 = int64() < int64()
			case signedTypeUint32, signedTypeUint64:
				 =  < 
			case signedTypeFloat32:
				 = math.Float32frombits(uint32()) < math.Float32frombits(uint32())
			case signedTypeFloat64:
				 = math.Float64frombits() < math.Float64frombits()
			}
			if  {
				.pushValue(1)
			} else {
				.pushValue(0)
			}
			.pc++
		case operationKindGt:
			 := .popValue()
			 := .popValue()
			var  bool
			switch signedType(.B1) {
			case signedTypeInt32:
				 = int32() > int32()
			case signedTypeInt64:
				 = int64() > int64()
			case signedTypeUint32, signedTypeUint64:
				 =  > 
			case signedTypeFloat32:
				 = math.Float32frombits(uint32()) > math.Float32frombits(uint32())
			case signedTypeFloat64:
				 = math.Float64frombits() > math.Float64frombits()
			}
			if  {
				.pushValue(1)
			} else {
				.pushValue(0)
			}
			.pc++
		case operationKindLe:
			 := .popValue()
			 := .popValue()
			var  bool
			switch signedType(.B1) {
			case signedTypeInt32:
				 = int32() <= int32()
			case signedTypeInt64:
				 = int64() <= int64()
			case signedTypeUint32, signedTypeUint64:
				 =  <= 
			case signedTypeFloat32:
				 = math.Float32frombits(uint32()) <= math.Float32frombits(uint32())
			case signedTypeFloat64:
				 = math.Float64frombits() <= math.Float64frombits()
			}
			if  {
				.pushValue(1)
			} else {
				.pushValue(0)
			}
			.pc++
		case operationKindGe:
			 := .popValue()
			 := .popValue()
			var  bool
			switch signedType(.B1) {
			case signedTypeInt32:
				 = int32() >= int32()
			case signedTypeInt64:
				 = int64() >= int64()
			case signedTypeUint32, signedTypeUint64:
				 =  >= 
			case signedTypeFloat32:
				 = math.Float32frombits(uint32()) >= math.Float32frombits(uint32())
			case signedTypeFloat64:
				 = math.Float64frombits() >= math.Float64frombits()
			}
			if  {
				.pushValue(1)
			} else {
				.pushValue(0)
			}
			.pc++
		case operationKindAdd:
			 := .popValue()
			 := .popValue()
			switch unsignedType(.B1) {
			case unsignedTypeI32:
				 := uint32() + uint32()
				.pushValue(uint64())
			case unsignedTypeI64:
				.pushValue( + )
			case unsignedTypeF32:
				.pushValue(addFloat32bits(uint32(), uint32()))
			case unsignedTypeF64:
				 := math.Float64frombits() + math.Float64frombits()
				.pushValue(math.Float64bits())
			}
			.pc++
		case operationKindSub:
			 := .popValue()
			 := .popValue()
			switch unsignedType(.B1) {
			case unsignedTypeI32:
				.pushValue(uint64(uint32() - uint32()))
			case unsignedTypeI64:
				.pushValue( - )
			case unsignedTypeF32:
				.pushValue(subFloat32bits(uint32(), uint32()))
			case unsignedTypeF64:
				 := math.Float64frombits() - math.Float64frombits()
				.pushValue(math.Float64bits())
			}
			.pc++
		case operationKindMul:
			 := .popValue()
			 := .popValue()
			switch unsignedType(.B1) {
			case unsignedTypeI32:
				.pushValue(uint64(uint32() * uint32()))
			case unsignedTypeI64:
				.pushValue( * )
			case unsignedTypeF32:
				.pushValue(mulFloat32bits(uint32(), uint32()))
			case unsignedTypeF64:
				 := math.Float64frombits() * math.Float64frombits()
				.pushValue(math.Float64bits())
			}
			.pc++
		case operationKindClz:
			 := .popValue()
			if .B1 == 0 {
				// unsignedInt32
				.pushValue(uint64(bits.LeadingZeros32(uint32())))
			} else {
				// unsignedInt64
				.pushValue(uint64(bits.LeadingZeros64()))
			}
			.pc++
		case operationKindCtz:
			 := .popValue()
			if .B1 == 0 {
				// unsignedInt32
				.pushValue(uint64(bits.TrailingZeros32(uint32())))
			} else {
				// unsignedInt64
				.pushValue(uint64(bits.TrailingZeros64()))
			}
			.pc++
		case operationKindPopcnt:
			 := .popValue()
			if .B1 == 0 {
				// unsignedInt32
				.pushValue(uint64(bits.OnesCount32(uint32())))
			} else {
				// unsignedInt64
				.pushValue(uint64(bits.OnesCount64()))
			}
			.pc++
		case operationKindDiv:
			// If an integer, check we won't divide by zero.
			 := signedType(.B1)
			,  := .popValue(), .popValue()
			switch  {
			case signedTypeFloat32, signedTypeFloat64: // not integers
			default:
				if  == 0 {
					panic(wasmruntime.ErrRuntimeIntegerDivideByZero)
				}
			}

			switch  {
			case signedTypeInt32:
				 := int32()
				 := int32()
				if  == math.MinInt32 &&  == -1 {
					panic(wasmruntime.ErrRuntimeIntegerOverflow)
				}
				.pushValue(uint64(uint32( / )))
			case signedTypeInt64:
				 := int64()
				 := int64()
				if  == math.MinInt64 &&  == -1 {
					panic(wasmruntime.ErrRuntimeIntegerOverflow)
				}
				.pushValue(uint64( / ))
			case signedTypeUint32:
				 := uint32()
				 := uint32()
				.pushValue(uint64( / ))
			case signedTypeUint64:
				 := 
				 := 
				.pushValue( / )
			case signedTypeFloat32:
				.pushValue(divFloat32bits(uint32(), uint32()))
			case signedTypeFloat64:
				.pushValue(math.Float64bits(math.Float64frombits() / math.Float64frombits()))
			}
			.pc++
		case operationKindRem:
			,  := .popValue(), .popValue()
			if  == 0 {
				panic(wasmruntime.ErrRuntimeIntegerDivideByZero)
			}
			switch signedInt(.B1) {
			case signedInt32:
				 := int32()
				 := int32()
				.pushValue(uint64(uint32( % )))
			case signedInt64:
				 := int64()
				 := int64()
				.pushValue(uint64( % ))
			case signedUint32:
				 := uint32()
				 := uint32()
				.pushValue(uint64( % ))
			case signedUint64:
				 := 
				 := 
				.pushValue( % )
			}
			.pc++
		case operationKindAnd:
			 := .popValue()
			 := .popValue()
			if .B1 == 0 {
				// unsignedInt32
				.pushValue(uint64(uint32() & uint32()))
			} else {
				// unsignedInt64
				.pushValue(uint64( & ))
			}
			.pc++
		case operationKindOr:
			 := .popValue()
			 := .popValue()
			if .B1 == 0 {
				// unsignedInt32
				.pushValue(uint64(uint32() | uint32()))
			} else {
				// unsignedInt64
				.pushValue(uint64( | ))
			}
			.pc++
		case operationKindXor:
			 := .popValue()
			 := .popValue()
			if .B1 == 0 {
				// unsignedInt32
				.pushValue(uint64(uint32() ^ uint32()))
			} else {
				// unsignedInt64
				.pushValue(uint64( ^ ))
			}
			.pc++
		case operationKindShl:
			 := .popValue()
			 := .popValue()
			if .B1 == 0 {
				// unsignedInt32
				.pushValue(uint64(uint32() << (uint32() % 32)))
			} else {
				// unsignedInt64
				.pushValue( << ( % 64))
			}
			.pc++
		case operationKindShr:
			 := .popValue()
			 := .popValue()
			switch signedInt(.B1) {
			case signedInt32:
				.pushValue(uint64(uint32(int32() >> (uint32() % 32))))
			case signedInt64:
				.pushValue(uint64(int64() >> ( % 64)))
			case signedUint32:
				.pushValue(uint64(uint32() >> (uint32() % 32)))
			case signedUint64:
				.pushValue( >> ( % 64))
			}
			.pc++
		case operationKindRotl:
			 := .popValue()
			 := .popValue()
			if .B1 == 0 {
				// unsignedInt32
				.pushValue(uint64(bits.RotateLeft32(uint32(), int())))
			} else {
				// unsignedInt64
				.pushValue(uint64(bits.RotateLeft64(, int())))
			}
			.pc++
		case operationKindRotr:
			 := .popValue()
			 := .popValue()
			if .B1 == 0 {
				// unsignedInt32
				.pushValue(uint64(bits.RotateLeft32(uint32(), -int())))
			} else {
				// unsignedInt64
				.pushValue(uint64(bits.RotateLeft64(, -int())))
			}
			.pc++
		case operationKindAbs:
			if .B1 == 0 {
				// float32
				const  uint32 = 1 << 31
				.pushValue(uint64(uint32(.popValue()) &^ ))
			} else {
				// float64
				const  uint64 = 1 << 63
				.pushValue(.popValue() &^ )
			}
			.pc++
		case operationKindNeg:
			if .B1 == 0 {
				// float32
				 := -math.Float32frombits(uint32(.popValue()))
				.pushValue(uint64(math.Float32bits()))
			} else {
				// float64
				 := -math.Float64frombits(.popValue())
				.pushValue(math.Float64bits())
			}
			.pc++
		case operationKindCeil:
			if .B1 == 0 {
				// float32
				 := moremath.WasmCompatCeilF32(math.Float32frombits(uint32(.popValue())))
				.pushValue(uint64(math.Float32bits()))
			} else {
				// float64
				 := moremath.WasmCompatCeilF64(math.Float64frombits(.popValue()))
				.pushValue(math.Float64bits())
			}
			.pc++
		case operationKindFloor:
			if .B1 == 0 {
				// float32
				 := moremath.WasmCompatFloorF32(math.Float32frombits(uint32(.popValue())))
				.pushValue(uint64(math.Float32bits()))
			} else {
				// float64
				 := moremath.WasmCompatFloorF64(math.Float64frombits(.popValue()))
				.pushValue(math.Float64bits())
			}
			.pc++
		case operationKindTrunc:
			if .B1 == 0 {
				// float32
				 := moremath.WasmCompatTruncF32(math.Float32frombits(uint32(.popValue())))
				.pushValue(uint64(math.Float32bits()))
			} else {
				// float64
				 := moremath.WasmCompatTruncF64(math.Float64frombits(.popValue()))
				.pushValue(math.Float64bits())
			}
			.pc++
		case operationKindNearest:
			if .B1 == 0 {
				// float32
				 := math.Float32frombits(uint32(.popValue()))
				.pushValue(uint64(math.Float32bits(moremath.WasmCompatNearestF32())))
			} else {
				// float64
				 := math.Float64frombits(.popValue())
				.pushValue(math.Float64bits(moremath.WasmCompatNearestF64()))
			}
			.pc++
		case operationKindSqrt:
			if .B1 == 0 {
				// float32
				 := math.Sqrt(float64(math.Float32frombits(uint32(.popValue()))))
				.pushValue(uint64(math.Float32bits(float32())))
			} else {
				// float64
				 := math.Sqrt(math.Float64frombits(.popValue()))
				.pushValue(math.Float64bits())
			}
			.pc++
		case operationKindMin:
			if .B1 == 0 {
				// float32
				.pushValue(wasmCompatMin32bits(uint32(.popValue()), uint32(.popValue())))
			} else {
				 := math.Float64frombits(.popValue())
				 := math.Float64frombits(.popValue())
				.pushValue(math.Float64bits(moremath.WasmCompatMin64(, )))
			}
			.pc++
		case operationKindMax:
			if .B1 == 0 {
				.pushValue(wasmCompatMax32bits(uint32(.popValue()), uint32(.popValue())))
			} else {
				// float64
				 := math.Float64frombits(.popValue())
				 := math.Float64frombits(.popValue())
				.pushValue(math.Float64bits(moremath.WasmCompatMax64(, )))
			}
			.pc++
		case operationKindCopysign:
			if .B1 == 0 {
				// float32
				 := uint32(.popValue())
				 := uint32(.popValue())
				const  = 1 << 31
				.pushValue(uint64(&^ | &))
			} else {
				// float64
				 := .popValue()
				 := .popValue()
				const  = 1 << 63
				.pushValue(&^ | &)
			}
			.pc++
		case operationKindI32WrapFromI64:
			.pushValue(uint64(uint32(.popValue())))
			.pc++
		case operationKindITruncFromF:
			if .B1 == 0 {
				// float32
				switch signedInt(.B2) {
				case signedInt32:
					 := math.Trunc(float64(math.Float32frombits(uint32(.popValue()))))
					if math.IsNaN() { // NaN cannot be compared with themselves, so we have to use IsNaN
						if .B3 {
							// non-trapping conversion must cast nan to zero.
							 = 0
						} else {
							panic(wasmruntime.ErrRuntimeInvalidConversionToInteger)
						}
					} else if  < math.MinInt32 ||  > math.MaxInt32 {
						if .B3 {
							// non-trapping conversion must "saturate" the value for overflowing sources.
							if  < 0 {
								 = math.MinInt32
							} else {
								 = math.MaxInt32
							}
						} else {
							panic(wasmruntime.ErrRuntimeIntegerOverflow)
						}
					}
					.pushValue(uint64(uint32(int32())))
				case signedInt64:
					 := math.Trunc(float64(math.Float32frombits(uint32(.popValue()))))
					 := int64()
					if math.IsNaN() { // NaN cannot be compared with themselves, so we have to use IsNaN
						if .B3 {
							// non-trapping conversion must cast nan to zero.
							 = 0
						} else {
							panic(wasmruntime.ErrRuntimeInvalidConversionToInteger)
						}
					} else if  < math.MinInt64 ||  >= math.MaxInt64 {
						// Note: math.MaxInt64 is rounded up to math.MaxInt64+1 in 64-bit float representation,
						// and that's why we use '>=' not '>' to check overflow.
						if .B3 {
							// non-trapping conversion must "saturate" the value for overflowing sources.
							if  < 0 {
								 = math.MinInt64
							} else {
								 = math.MaxInt64
							}
						} else {
							panic(wasmruntime.ErrRuntimeIntegerOverflow)
						}
					}
					.pushValue(uint64())
				case signedUint32:
					 := math.Trunc(float64(math.Float32frombits(uint32(.popValue()))))
					if math.IsNaN() { // NaN cannot be compared with themselves, so we have to use IsNaN
						if .B3 {
							// non-trapping conversion must cast nan to zero.
							 = 0
						} else {
							panic(wasmruntime.ErrRuntimeInvalidConversionToInteger)
						}
					} else if  < 0 ||  > math.MaxUint32 {
						if .B3 {
							// non-trapping conversion must "saturate" the value for overflowing source.
							if  < 0 {
								 = 0
							} else {
								 = math.MaxUint32
							}
						} else {
							panic(wasmruntime.ErrRuntimeIntegerOverflow)
						}
					}
					.pushValue(uint64(uint32()))
				case signedUint64:
					 := math.Trunc(float64(math.Float32frombits(uint32(.popValue()))))
					 := uint64()
					if math.IsNaN() { // NaN cannot be compared with themselves, so we have to use IsNaN
						if .B3 {
							// non-trapping conversion must cast nan to zero.
							 = 0
						} else {
							panic(wasmruntime.ErrRuntimeInvalidConversionToInteger)
						}
					} else if  < 0 ||  >= math.MaxUint64 {
						// Note: math.MaxUint64 is rounded up to math.MaxUint64+1 in 64-bit float representation,
						// and that's why we use '>=' not '>' to check overflow.
						if .B3 {
							// non-trapping conversion must "saturate" the value for overflowing source.
							if  < 0 {
								 = 0
							} else {
								 = math.MaxUint64
							}
						} else {
							panic(wasmruntime.ErrRuntimeIntegerOverflow)
						}
					}
					.pushValue()
				}
			} else {
				// float64
				switch signedInt(.B2) {
				case signedInt32:
					 := math.Trunc(math.Float64frombits(.popValue()))
					if math.IsNaN() { // NaN cannot be compared with themselves, so we have to use IsNaN
						if .B3 {
							// non-trapping conversion must cast nan to zero.
							 = 0
						} else {
							panic(wasmruntime.ErrRuntimeInvalidConversionToInteger)
						}
					} else if  < math.MinInt32 ||  > math.MaxInt32 {
						if .B3 {
							// non-trapping conversion must "saturate" the value for overflowing source.
							if  < 0 {
								 = math.MinInt32
							} else {
								 = math.MaxInt32
							}
						} else {
							panic(wasmruntime.ErrRuntimeIntegerOverflow)
						}
					}
					.pushValue(uint64(uint32(int32())))
				case signedInt64:
					 := math.Trunc(math.Float64frombits(.popValue()))
					 := int64()
					if math.IsNaN() { // NaN cannot be compared with themselves, so we have to use IsNaN
						if .B3 {
							// non-trapping conversion must cast nan to zero.
							 = 0
						} else {
							panic(wasmruntime.ErrRuntimeInvalidConversionToInteger)
						}
					} else if  < math.MinInt64 ||  >= math.MaxInt64 {
						// Note: math.MaxInt64 is rounded up to math.MaxInt64+1 in 64-bit float representation,
						// and that's why we use '>=' not '>' to check overflow.
						if .B3 {
							// non-trapping conversion must "saturate" the value for overflowing source.
							if  < 0 {
								 = math.MinInt64
							} else {
								 = math.MaxInt64
							}
						} else {
							panic(wasmruntime.ErrRuntimeIntegerOverflow)
						}
					}
					.pushValue(uint64())
				case signedUint32:
					 := math.Trunc(math.Float64frombits(.popValue()))
					if math.IsNaN() { // NaN cannot be compared with themselves, so we have to use IsNaN
						if .B3 {
							// non-trapping conversion must cast nan to zero.
							 = 0
						} else {
							panic(wasmruntime.ErrRuntimeInvalidConversionToInteger)
						}
					} else if  < 0 ||  > math.MaxUint32 {
						if .B3 {
							// non-trapping conversion must "saturate" the value for overflowing source.
							if  < 0 {
								 = 0
							} else {
								 = math.MaxUint32
							}
						} else {
							panic(wasmruntime.ErrRuntimeIntegerOverflow)
						}
					}
					.pushValue(uint64(uint32()))
				case signedUint64:
					 := math.Trunc(math.Float64frombits(.popValue()))
					 := uint64()
					if math.IsNaN() { // NaN cannot be compared with themselves, so we have to use IsNaN
						if .B3 {
							// non-trapping conversion must cast nan to zero.
							 = 0
						} else {
							panic(wasmruntime.ErrRuntimeInvalidConversionToInteger)
						}
					} else if  < 0 ||  >= math.MaxUint64 {
						// Note: math.MaxUint64 is rounded up to math.MaxUint64+1 in 64-bit float representation,
						// and that's why we use '>=' not '>' to check overflow.
						if .B3 {
							// non-trapping conversion must "saturate" the value for overflowing source.
							if  < 0 {
								 = 0
							} else {
								 = math.MaxUint64
							}
						} else {
							panic(wasmruntime.ErrRuntimeIntegerOverflow)
						}
					}
					.pushValue()
				}
			}
			.pc++
		case operationKindFConvertFromI:
			switch signedInt(.B1) {
			case signedInt32:
				if .B2 == 0 {
					// float32
					 := float32(int32(.popValue()))
					.pushValue(uint64(math.Float32bits()))
				} else {
					// float64
					 := float64(int32(.popValue()))
					.pushValue(math.Float64bits())
				}
			case signedInt64:
				if .B2 == 0 {
					// float32
					 := float32(int64(.popValue()))
					.pushValue(uint64(math.Float32bits()))
				} else {
					// float64
					 := float64(int64(.popValue()))
					.pushValue(math.Float64bits())
				}
			case signedUint32:
				if .B2 == 0 {
					// float32
					 := float32(uint32(.popValue()))
					.pushValue(uint64(math.Float32bits()))
				} else {
					// float64
					 := float64(uint32(.popValue()))
					.pushValue(math.Float64bits())
				}
			case signedUint64:
				if .B2 == 0 {
					// float32
					 := float32(.popValue())
					.pushValue(uint64(math.Float32bits()))
				} else {
					// float64
					 := float64(.popValue())
					.pushValue(math.Float64bits())
				}
			}
			.pc++
		case operationKindF32DemoteFromF64:
			 := float32(math.Float64frombits(.popValue()))
			.pushValue(uint64(math.Float32bits()))
			.pc++
		case operationKindF64PromoteFromF32:
			 := float64(math.Float32frombits(uint32(.popValue())))
			.pushValue(math.Float64bits())
			.pc++
		case operationKindExtend:
			if .B1 == 1 {
				// Signed.
				 := int64(int32(.popValue()))
				.pushValue(uint64())
			} else {
				 := uint64(uint32(.popValue()))
				.pushValue()
			}
			.pc++
		case operationKindSignExtend32From8:
			 := uint32(int8(.popValue()))
			.pushValue(uint64())
			.pc++
		case operationKindSignExtend32From16:
			 := uint32(int16(.popValue()))
			.pushValue(uint64())
			.pc++
		case operationKindSignExtend64From8:
			 := int64(int8(.popValue()))
			.pushValue(uint64())
			.pc++
		case operationKindSignExtend64From16:
			 := int64(int16(.popValue()))
			.pushValue(uint64())
			.pc++
		case operationKindSignExtend64From32:
			 := int64(int32(.popValue()))
			.pushValue(uint64())
			.pc++
		case operationKindMemoryInit:
			 := [.U1]
			 := .popValue()
			 := .popValue()
			 := .popValue()
			if + > uint64(len()) ||
				+ > uint64(len(.Buffer)) {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			} else if  != 0 {
				copy(.Buffer[:+], [:])
			}
			.pc++
		case operationKindDataDrop:
			[.U1] = nil
			.pc++
		case operationKindMemoryCopy:
			 := uint64(len(.Buffer))
			 := .popValue()
			 := .popValue()
			 := .popValue()
			if + >  || + >  {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			} else if  != 0 {
				copy(.Buffer[:],
					.Buffer[:+])
			}
			.pc++
		case operationKindMemoryFill:
			 := .popValue()
			 := byte(.popValue())
			 := .popValue()
			if + > uint64(len(.Buffer)) {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			} else if  != 0 {
				// Uses the copy trick for faster filling the buffer with the value.
				// https://github.com/golang/go/blob/go1.24.0/src/bytes/bytes.go#L664-L673
				 := .Buffer[ : +]
				if  == 0 {
					clear()
				} else {
					[0] = 
					for  := 1;  < len(); {
						 := min(, 8192)
						 += copy([:], [:])
					}
				}
			}
			.pc++
		case operationKindTableInit:
			 := [.U1]
			 := .popValue()
			 := .popValue()
			 := .popValue()
			 := [.U2]
			if + > uint64(len()) ||
				+ > uint64(len(.References)) {
				panic(wasmruntime.ErrRuntimeInvalidTableAccess)
			} else if  != 0 {
				copy(.References[:+], [:])
			}
			.pc++
		case operationKindElemDrop:
			[.U1] = nil
			.pc++
		case operationKindTableCopy:
			,  := [.U1].References, [.U2].References
			 := .popValue()
			 := .popValue()
			 := .popValue()
			if + > uint64(len()) || + > uint64(len()) {
				panic(wasmruntime.ErrRuntimeInvalidTableAccess)
			} else if  != 0 {
				copy([:], [:+])
			}
			.pc++
		case operationKindRefFunc:
			.pushValue(uint64(uintptr(unsafe.Pointer(&[.U1]))))
			.pc++
		case operationKindTableGet:
			 := [.U1]

			 := .popValue()
			if  >= uint64(len(.References)) {
				panic(wasmruntime.ErrRuntimeInvalidTableAccess)
			}

			.pushValue(uint64(.References[]))
			.pc++
		case operationKindTableSet:
			 := [.U1]
			 := .popValue()

			 := .popValue()
			if  >= uint64(len(.References)) {
				panic(wasmruntime.ErrRuntimeInvalidTableAccess)
			}

			.References[] = uintptr() // externrefs are opaque uint64.
			.pc++
		case operationKindTableSize:
			 := [.U1]
			.pushValue(uint64(len(.References)))
			.pc++
		case operationKindTableGrow:
			 := [.U1]
			,  := .popValue(), .popValue()
			 := .Grow(uint32(), uintptr())
			.pushValue(uint64())
			.pc++
		case operationKindTableFill:
			 := [.U1]
			 := .popValue()
			 := uintptr(.popValue())
			 := .popValue()
			if + > uint64(len(.References)) {
				panic(wasmruntime.ErrRuntimeInvalidTableAccess)
			} else if  > 0 {
				// Uses the copy trick for faster filling the region with the value.
				// https://github.com/golang/go/blob/go1.24.0/src/slices/slices.go#L514-L517
				 := .References[ : +]
				[0] = 
				for  := 1;  < len();  *= 2 {
					copy([:], [:])
				}
			}
			.pc++
		case operationKindV128Const:
			,  := .U1, .U2
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Add:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			switch .B1 {
			case shapeI8x16:
				.pushValue(
					uint64(uint8(>>8)+uint8(>>8))<<8 | uint64(uint8()+uint8()) |
						uint64(uint8(>>24)+uint8(>>24))<<24 | uint64(uint8(>>16)+uint8(>>16))<<16 |
						uint64(uint8(>>40)+uint8(>>40))<<40 | uint64(uint8(>>32)+uint8(>>32))<<32 |
						uint64(uint8(>>56)+uint8(>>56))<<56 | uint64(uint8(>>48)+uint8(>>48))<<48,
				)
				.pushValue(
					uint64(uint8(>>8)+uint8(>>8))<<8 | uint64(uint8()+uint8()) |
						uint64(uint8(>>24)+uint8(>>24))<<24 | uint64(uint8(>>16)+uint8(>>16))<<16 |
						uint64(uint8(>>40)+uint8(>>40))<<40 | uint64(uint8(>>32)+uint8(>>32))<<32 |
						uint64(uint8(>>56)+uint8(>>56))<<56 | uint64(uint8(>>48)+uint8(>>48))<<48,
				)
			case shapeI16x8:
				.pushValue(
					uint64(uint16(>>16+>>16))<<16 | uint64(uint16()+uint16()) |
						uint64(uint16(>>48+>>48))<<48 | uint64(uint16(>>32+>>32))<<32,
				)
				.pushValue(
					uint64(uint16(>>16)+uint16(>>16))<<16 | uint64(uint16()+uint16()) |
						uint64(uint16(>>48)+uint16(>>48))<<48 | uint64(uint16(>>32)+uint16(>>32))<<32,
				)
			case shapeI32x4:
				.pushValue(uint64(uint32(>>32)+uint32(>>32))<<32 | uint64(uint32()+uint32()))
				.pushValue(uint64(uint32(>>32)+uint32(>>32))<<32 | uint64(uint32()+uint32()))
			case shapeI64x2:
				.pushValue( + )
				.pushValue( + )
			case shapeF32x4:
				.pushValue(
					addFloat32bits(uint32(), uint32()) | addFloat32bits(uint32(>>32), uint32(>>32))<<32,
				)
				.pushValue(
					addFloat32bits(uint32(), uint32()) | addFloat32bits(uint32(>>32), uint32(>>32))<<32,
				)
			case shapeF64x2:
				.pushValue(math.Float64bits(math.Float64frombits() + math.Float64frombits()))
				.pushValue(math.Float64bits(math.Float64frombits() + math.Float64frombits()))
			}
			.pc++
		case operationKindV128Sub:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			switch .B1 {
			case shapeI8x16:
				.pushValue(
					uint64(uint8(>>8)-uint8(>>8))<<8 | uint64(uint8()-uint8()) |
						uint64(uint8(>>24)-uint8(>>24))<<24 | uint64(uint8(>>16)-uint8(>>16))<<16 |
						uint64(uint8(>>40)-uint8(>>40))<<40 | uint64(uint8(>>32)-uint8(>>32))<<32 |
						uint64(uint8(>>56)-uint8(>>56))<<56 | uint64(uint8(>>48)-uint8(>>48))<<48,
				)
				.pushValue(
					uint64(uint8(>>8)-uint8(>>8))<<8 | uint64(uint8()-uint8()) |
						uint64(uint8(>>24)-uint8(>>24))<<24 | uint64(uint8(>>16)-uint8(>>16))<<16 |
						uint64(uint8(>>40)-uint8(>>40))<<40 | uint64(uint8(>>32)-uint8(>>32))<<32 |
						uint64(uint8(>>56)-uint8(>>56))<<56 | uint64(uint8(>>48)-uint8(>>48))<<48,
				)
			case shapeI16x8:
				.pushValue(
					uint64(uint16(>>16)-uint16(>>16))<<16 | uint64(uint16()-uint16()) |
						uint64(uint16(>>48)-uint16(>>48))<<48 | uint64(uint16(>>32)-uint16(>>32))<<32,
				)
				.pushValue(
					uint64(uint16(>>16)-uint16(>>16))<<16 | uint64(uint16()-uint16()) |
						uint64(uint16(>>48)-uint16(>>48))<<48 | uint64(uint16(>>32)-uint16(>>32))<<32,
				)
			case shapeI32x4:
				.pushValue(uint64(uint32(>>32->>32))<<32 | uint64(uint32()-uint32()))
				.pushValue(uint64(uint32(>>32->>32))<<32 | uint64(uint32()-uint32()))
			case shapeI64x2:
				.pushValue( - )
				.pushValue( - )
			case shapeF32x4:
				.pushValue(
					subFloat32bits(uint32(), uint32()) | subFloat32bits(uint32(>>32), uint32(>>32))<<32,
				)
				.pushValue(
					subFloat32bits(uint32(), uint32()) | subFloat32bits(uint32(>>32), uint32(>>32))<<32,
				)
			case shapeF64x2:
				.pushValue(math.Float64bits(math.Float64frombits() - math.Float64frombits()))
				.pushValue(math.Float64bits(math.Float64frombits() - math.Float64frombits()))
			}
			.pc++
		case operationKindV128Load:
			 := .popMemoryOffset()
			switch .B1 {
			case v128LoadType128:
				,  := .ReadUint64Le()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue()
				,  := .ReadUint64Le( + 8)
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue()
			case v128LoadType8x8s:
				,  := .Read(, 8)
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue(
					uint64(uint16(int8([3])))<<48 | uint64(uint16(int8([2])))<<32 | uint64(uint16(int8([1])))<<16 | uint64(uint16(int8([0]))),
				)
				.pushValue(
					uint64(uint16(int8([7])))<<48 | uint64(uint16(int8([6])))<<32 | uint64(uint16(int8([5])))<<16 | uint64(uint16(int8([4]))),
				)
			case v128LoadType8x8u:
				,  := .Read(, 8)
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue(
					uint64([3])<<48 | uint64([2])<<32 | uint64([1])<<16 | uint64([0]),
				)
				.pushValue(
					uint64([7])<<48 | uint64([6])<<32 | uint64([5])<<16 | uint64([4]),
				)
			case v128LoadType16x4s:
				,  := .Read(, 8)
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue(
					uint64(int16(binary.LittleEndian.Uint16([2:])))<<32 |
						uint64(uint32(int16(binary.LittleEndian.Uint16()))),
				)
				.pushValue(
					uint64(uint32(int16(binary.LittleEndian.Uint16([6:]))))<<32 |
						uint64(uint32(int16(binary.LittleEndian.Uint16([4:])))),
				)
			case v128LoadType16x4u:
				,  := .Read(, 8)
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue(
					uint64(binary.LittleEndian.Uint16([2:]))<<32 | uint64(binary.LittleEndian.Uint16()),
				)
				.pushValue(
					uint64(binary.LittleEndian.Uint16([6:]))<<32 | uint64(binary.LittleEndian.Uint16([4:])),
				)
			case v128LoadType32x2s:
				,  := .Read(, 8)
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue(uint64(int32(binary.LittleEndian.Uint32())))
				.pushValue(uint64(int32(binary.LittleEndian.Uint32([4:]))))
			case v128LoadType32x2u:
				,  := .Read(, 8)
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue(uint64(binary.LittleEndian.Uint32()))
				.pushValue(uint64(binary.LittleEndian.Uint32([4:])))
			case v128LoadType8Splat:
				,  := .ReadByte()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				 := uint64()<<56 | uint64()<<48 | uint64()<<40 | uint64()<<32 |
					uint64()<<24 | uint64()<<16 | uint64()<<8 | uint64()
				.pushValue()
				.pushValue()
			case v128LoadType16Splat:
				,  := .ReadUint16Le()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				 := uint64()<<48 | uint64()<<32 | uint64()<<16 | uint64()
				.pushValue()
				.pushValue()
			case v128LoadType32Splat:
				,  := .ReadUint32Le()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				 := uint64()<<32 | uint64()
				.pushValue()
				.pushValue()
			case v128LoadType64Splat:
				,  := .ReadUint64Le()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue()
				.pushValue()
			case v128LoadType32zero:
				,  := .ReadUint32Le()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue(uint64())
				.pushValue(0)
			case v128LoadType64zero:
				,  := .ReadUint64Le()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue()
				.pushValue(0)
			}
			.pc++
		case operationKindV128LoadLane:
			,  := .popValue(), .popValue()
			 := .popMemoryOffset()
			switch .B1 {
			case 8:
				,  := .ReadByte()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				if .B2 < 8 {
					 := .B2 << 3
					 = ( & ^(0xff << )) | uint64()<<
				} else {
					 := (.B2 - 8) << 3
					 = ( & ^(0xff << )) | uint64()<<
				}
			case 16:
				,  := .ReadUint16Le()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				if .B2 < 4 {
					 := .B2 << 4
					 = ( & ^(0xff_ff << )) | uint64()<<
				} else {
					 := (.B2 - 4) << 4
					 = ( & ^(0xff_ff << )) | uint64()<<
				}
			case 32:
				,  := .ReadUint32Le()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				if .B2 < 2 {
					 := .B2 << 5
					 = ( & ^(0xff_ff_ff_ff << )) | uint64()<<
				} else {
					 := (.B2 - 2) << 5
					 = ( & ^(0xff_ff_ff_ff << )) | uint64()<<
				}
			case 64:
				,  := .ReadUint64Le()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				if .B2 == 0 {
					 = 
				} else {
					 = 
				}
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Store:
			,  := .popValue(), .popValue()
			 := .popMemoryOffset()
			// Write the upper bytes first to trigger an early error if the memory access is out of bounds.
			// Otherwise, the lower bytes might be written to memory, but the upper bytes might not.
			if uint64()+8 > math.MaxUint32 {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			if  := .WriteUint64Le(+8, ); ! {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			if  := .WriteUint64Le(, ); ! {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			.pc++
		case operationKindV128StoreLane:
			,  := .popValue(), .popValue()
			 := .popMemoryOffset()
			var  bool
			switch .B1 {
			case 8:
				if .B2 < 8 {
					 = .WriteByte(, byte(>>(.B2*8)))
				} else {
					 = .WriteByte(, byte(>>((.B2-8)*8)))
				}
			case 16:
				if .B2 < 4 {
					 = .WriteUint16Le(, uint16(>>(.B2*16)))
				} else {
					 = .WriteUint16Le(, uint16(>>((.B2-4)*16)))
				}
			case 32:
				if .B2 < 2 {
					 = .WriteUint32Le(, uint32(>>(.B2*32)))
				} else {
					 = .WriteUint32Le(, uint32(>>((.B2-2)*32)))
				}
			case 64:
				if .B2 == 0 {
					 = .WriteUint64Le(, )
				} else {
					 = .WriteUint64Le(, )
				}
			}
			if ! {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			.pc++
		case operationKindV128ReplaceLane:
			 := .popValue()
			,  := .popValue(), .popValue()
			switch .B1 {
			case shapeI8x16:
				if .B2 < 8 {
					 := .B2 << 3
					 = ( & ^(0xff << )) | uint64(byte())<<
				} else {
					 := (.B2 - 8) << 3
					 = ( & ^(0xff << )) | uint64(byte())<<
				}
			case shapeI16x8:
				if .B2 < 4 {
					 := .B2 << 4
					 = ( & ^(0xff_ff << )) | uint64(uint16())<<
				} else {
					 := (.B2 - 4) << 4
					 = ( & ^(0xff_ff << )) | uint64(uint16())<<
				}
			case shapeI32x4, shapeF32x4:
				if .B2 < 2 {
					 := .B2 << 5
					 = ( & ^(0xff_ff_ff_ff << )) | uint64(uint32())<<
				} else {
					 := (.B2 - 2) << 5
					 = ( & ^(0xff_ff_ff_ff << )) | uint64(uint32())<<
				}
			case shapeI64x2, shapeF64x2:
				if .B2 == 0 {
					 = 
				} else {
					 = 
				}
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128ExtractLane:
			,  := .popValue(), .popValue()
			var  uint64
			switch .B1 {
			case shapeI8x16:
				var  byte
				if .B2 < 8 {
					 = byte( >> (.B2 * 8))
				} else {
					 = byte( >> ((.B2 - 8) * 8))
				}
				if .B3 {
					// sign-extend.
					 = uint64(uint32(int8()))
				} else {
					 = uint64()
				}
			case shapeI16x8:
				var  uint16
				if .B2 < 4 {
					 = uint16( >> (.B2 * 16))
				} else {
					 = uint16( >> ((.B2 - 4) * 16))
				}
				if .B3 {
					// sign-extend.
					 = uint64(uint32(int16()))
				} else {
					 = uint64()
				}
			case shapeI32x4, shapeF32x4:
				if .B2 < 2 {
					 = uint64(uint32( >> (.B2 * 32)))
				} else {
					 = uint64(uint32( >> ((.B2 - 2) * 32)))
				}
			case shapeI64x2, shapeF64x2:
				if .B2 == 0 {
					 = 
				} else {
					 = 
				}
			}
			.pushValue()
			.pc++
		case operationKindV128Splat:
			 := .popValue()
			var ,  uint64
			switch .B1 {
			case shapeI8x16:
				 := uint64(byte())<<56 | uint64(byte())<<48 | uint64(byte())<<40 | uint64(byte())<<32 |
					uint64(byte())<<24 | uint64(byte())<<16 | uint64(byte())<<8 | uint64(byte())
				,  = , 
			case shapeI16x8:
				 := uint64(uint16())<<48 | uint64(uint16())<<32 | uint64(uint16())<<16 | uint64(uint16())
				,  = , 
			case shapeI32x4, shapeF32x4:
				 := uint64(uint32())<<32 | uint64(uint32())
				,  = , 
			case shapeI64x2, shapeF64x2:
				,  = , 
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Swizzle:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			var  [16]byte
			for  := 0;  < 16; ++ {
				var  byte
				if  < 8 {
					 = byte( >> ( * 8))
				} else {
					 = byte( >> (( - 8) * 8))
				}
				if  < 8 {
					[] = byte( >> ( * 8))
				} else if  < 16 {
					[] = byte( >> (( - 8) * 8))
				}
			}
			.pushValue(binary.LittleEndian.Uint64([:8]))
			.pushValue(binary.LittleEndian.Uint64([8:]))
			.pc++
		case operationKindV128Shuffle:
			, , ,  := .popValue(), .popValue(), .popValue(), .popValue()
			var  [16]byte
			for ,  := range .Us {
				if  < 8 {
					[] = byte( >> ( * 8))
				} else if  < 16 {
					[] = byte( >> (( - 8) * 8))
				} else if  < 24 {
					[] = byte( >> (( - 16) * 8))
				} else if  < 32 {
					[] = byte( >> (( - 24) * 8))
				}
			}
			.pushValue(binary.LittleEndian.Uint64([:8]))
			.pushValue(binary.LittleEndian.Uint64([8:]))
			.pc++
		case operationKindV128AnyTrue:
			,  := .popValue(), .popValue()
			if  != 0 ||  != 0 {
				.pushValue(1)
			} else {
				.pushValue(0)
			}
			.pc++
		case operationKindV128AllTrue:
			,  := .popValue(), .popValue()
			var  bool
			switch .B1 {
			case shapeI8x16:
				 = (uint8() != 0) && (uint8(>>8) != 0) && (uint8(>>16) != 0) && (uint8(>>24) != 0) &&
					(uint8(>>32) != 0) && (uint8(>>40) != 0) && (uint8(>>48) != 0) && (uint8(>>56) != 0) &&
					(uint8() != 0) && (uint8(>>8) != 0) && (uint8(>>16) != 0) && (uint8(>>24) != 0) &&
					(uint8(>>32) != 0) && (uint8(>>40) != 0) && (uint8(>>48) != 0) && (uint8(>>56) != 0)
			case shapeI16x8:
				 = (uint16() != 0) && (uint16(>>16) != 0) && (uint16(>>32) != 0) && (uint16(>>48) != 0) &&
					(uint16() != 0) && (uint16(>>16) != 0) && (uint16(>>32) != 0) && (uint16(>>48) != 0)
			case shapeI32x4:
				 = (uint32() != 0) && (uint32(>>32) != 0) &&
					(uint32() != 0) && (uint32(>>32) != 0)
			case shapeI64x2:
				 = ( != 0) &&
					( != 0)
			}
			if  {
				.pushValue(1)
			} else {
				.pushValue(0)
			}
			.pc++
		case operationKindV128BitMask:
			// https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/simd/SIMD.md#bitmask-extraction
			,  := .popValue(), .popValue()
			var  uint64
			switch .B1 {
			case shapeI8x16:
				for  := 0;  < 8; ++ {
					if int8(>>(*8)) < 0 {
						 |= 1 << 
					}
				}
				for  := 0;  < 8; ++ {
					if int8(>>(*8)) < 0 {
						 |= 1 << ( + 8)
					}
				}
			case shapeI16x8:
				for  := 0;  < 4; ++ {
					if int16(>>(*16)) < 0 {
						 |= 1 << 
					}
				}
				for  := 0;  < 4; ++ {
					if int16(>>(*16)) < 0 {
						 |= 1 << ( + 4)
					}
				}
			case shapeI32x4:
				for  := 0;  < 2; ++ {
					if int32(>>(*32)) < 0 {
						 |= 1 << 
					}
				}
				for  := 0;  < 2; ++ {
					if int32(>>(*32)) < 0 {
						 |= 1 << ( + 2)
					}
				}
			case shapeI64x2:
				if int64() < 0 {
					 |= 0b01
				}
				if int() < 0 {
					 |= 0b10
				}
			}
			.pushValue()
			.pc++
		case operationKindV128And:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			.pushValue( & )
			.pushValue( & )
			.pc++
		case operationKindV128Not:
			,  := .popValue(), .popValue()
			.pushValue(^)
			.pushValue(^)
			.pc++
		case operationKindV128Or:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			.pushValue( | )
			.pushValue( | )
			.pc++
		case operationKindV128Xor:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			.pushValue( ^ )
			.pushValue( ^ )
			.pc++
		case operationKindV128Bitselect:
			// https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/simd/SIMD.md#bitwise-select
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			// v128.or(v128.and(v1, c), v128.and(v2, v128.not(c)))
			.pushValue(( & ) | ( & (^)))
			.pushValue(( & ) | ( & (^)))
			.pc++
		case operationKindV128AndNot:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			.pushValue( & (^))
			.pushValue( & (^))
			.pc++
		case operationKindV128Shl:
			 := .popValue()
			,  := .popValue(), .popValue()
			switch .B1 {
			case shapeI8x16:
				 =  % 8
				 = uint64(uint8(<<)) |
					uint64(uint8((>>8)<<))<<8 |
					uint64(uint8((>>16)<<))<<16 |
					uint64(uint8((>>24)<<))<<24 |
					uint64(uint8((>>32)<<))<<32 |
					uint64(uint8((>>40)<<))<<40 |
					uint64(uint8((>>48)<<))<<48 |
					uint64(uint8((>>56)<<))<<56
				 = uint64(uint8(<<)) |
					uint64(uint8((>>8)<<))<<8 |
					uint64(uint8((>>16)<<))<<16 |
					uint64(uint8((>>24)<<))<<24 |
					uint64(uint8((>>32)<<))<<32 |
					uint64(uint8((>>40)<<))<<40 |
					uint64(uint8((>>48)<<))<<48 |
					uint64(uint8((>>56)<<))<<56
			case shapeI16x8:
				 =  % 16
				 = uint64(uint16(<<)) |
					uint64(uint16((>>16)<<))<<16 |
					uint64(uint16((>>32)<<))<<32 |
					uint64(uint16((>>48)<<))<<48
				 = uint64(uint16(<<)) |
					uint64(uint16((>>16)<<))<<16 |
					uint64(uint16((>>32)<<))<<32 |
					uint64(uint16((>>48)<<))<<48
			case shapeI32x4:
				 =  % 32
				 = uint64(uint32(<<)) | uint64(uint32((>>32)<<))<<32
				 = uint64(uint32(<<)) | uint64(uint32((>>32)<<))<<32
			case shapeI64x2:
				 =  % 64
				 =  << 
				 =  << 
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Shr:
			 := .popValue()
			,  := .popValue(), .popValue()
			switch .B1 {
			case shapeI8x16:
				 =  % 8
				if .B3 { // signed
					 = uint64(uint8(int8()>>)) |
						uint64(uint8(int8(>>8)>>))<<8 |
						uint64(uint8(int8(>>16)>>))<<16 |
						uint64(uint8(int8(>>24)>>))<<24 |
						uint64(uint8(int8(>>32)>>))<<32 |
						uint64(uint8(int8(>>40)>>))<<40 |
						uint64(uint8(int8(>>48)>>))<<48 |
						uint64(uint8(int8(>>56)>>))<<56
					 = uint64(uint8(int8()>>)) |
						uint64(uint8(int8(>>8)>>))<<8 |
						uint64(uint8(int8(>>16)>>))<<16 |
						uint64(uint8(int8(>>24)>>))<<24 |
						uint64(uint8(int8(>>32)>>))<<32 |
						uint64(uint8(int8(>>40)>>))<<40 |
						uint64(uint8(int8(>>48)>>))<<48 |
						uint64(uint8(int8(>>56)>>))<<56
				} else {
					 = uint64(uint8()>>) |
						uint64(uint8(>>8)>>)<<8 |
						uint64(uint8(>>16)>>)<<16 |
						uint64(uint8(>>24)>>)<<24 |
						uint64(uint8(>>32)>>)<<32 |
						uint64(uint8(>>40)>>)<<40 |
						uint64(uint8(>>48)>>)<<48 |
						uint64(uint8(>>56)>>)<<56
					 = uint64(uint8()>>) |
						uint64(uint8(>>8)>>)<<8 |
						uint64(uint8(>>16)>>)<<16 |
						uint64(uint8(>>24)>>)<<24 |
						uint64(uint8(>>32)>>)<<32 |
						uint64(uint8(>>40)>>)<<40 |
						uint64(uint8(>>48)>>)<<48 |
						uint64(uint8(>>56)>>)<<56
				}
			case shapeI16x8:
				 =  % 16
				if .B3 { // signed
					 = uint64(uint16(int16()>>)) |
						uint64(uint16(int16(>>16)>>))<<16 |
						uint64(uint16(int16(>>32)>>))<<32 |
						uint64(uint16(int16(>>48)>>))<<48
					 = uint64(uint16(int16()>>)) |
						uint64(uint16(int16(>>16)>>))<<16 |
						uint64(uint16(int16(>>32)>>))<<32 |
						uint64(uint16(int16(>>48)>>))<<48
				} else {
					 = uint64(uint16()>>) |
						uint64(uint16(>>16)>>)<<16 |
						uint64(uint16(>>32)>>)<<32 |
						uint64(uint16(>>48)>>)<<48
					 = uint64(uint16()>>) |
						uint64(uint16(>>16)>>)<<16 |
						uint64(uint16(>>32)>>)<<32 |
						uint64(uint16(>>48)>>)<<48
				}
			case shapeI32x4:
				 =  % 32
				if .B3 {
					 = uint64(uint32(int32()>>)) | uint64(uint32(int32(>>32)>>))<<32
					 = uint64(uint32(int32()>>)) | uint64(uint32(int32(>>32)>>))<<32
				} else {
					 = uint64(uint32()>>) | uint64(uint32(>>32)>>)<<32
					 = uint64(uint32()>>) | uint64(uint32(>>32)>>)<<32
				}
			case shapeI64x2:
				 =  % 64
				if .B3 { // signed
					 = uint64(int64() >> )
					 = uint64(int64() >> )
				} else {
					 =  >> 
					 =  >> 
				}

			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Cmp:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			var  []bool
			switch .B1 {
			case v128CmpTypeI8x16Eq:
				 = []bool{
					byte(>>0) == byte(>>0), byte(>>8) == byte(>>8),
					byte(>>16) == byte(>>16), byte(>>24) == byte(>>24),
					byte(>>32) == byte(>>32), byte(>>40) == byte(>>40),
					byte(>>48) == byte(>>48), byte(>>56) == byte(>>56),
					byte(>>0) == byte(>>0), byte(>>8) == byte(>>8),
					byte(>>16) == byte(>>16), byte(>>24) == byte(>>24),
					byte(>>32) == byte(>>32), byte(>>40) == byte(>>40),
					byte(>>48) == byte(>>48), byte(>>56) == byte(>>56),
				}
			case v128CmpTypeI8x16Ne:
				 = []bool{
					byte(>>0) != byte(>>0), byte(>>8) != byte(>>8),
					byte(>>16) != byte(>>16), byte(>>24) != byte(>>24),
					byte(>>32) != byte(>>32), byte(>>40) != byte(>>40),
					byte(>>48) != byte(>>48), byte(>>56) != byte(>>56),
					byte(>>0) != byte(>>0), byte(>>8) != byte(>>8),
					byte(>>16) != byte(>>16), byte(>>24) != byte(>>24),
					byte(>>32) != byte(>>32), byte(>>40) != byte(>>40),
					byte(>>48) != byte(>>48), byte(>>56) != byte(>>56),
				}
			case v128CmpTypeI8x16LtS:
				 = []bool{
					int8(>>0) < int8(>>0), int8(>>8) < int8(>>8),
					int8(>>16) < int8(>>16), int8(>>24) < int8(>>24),
					int8(>>32) < int8(>>32), int8(>>40) < int8(>>40),
					int8(>>48) < int8(>>48), int8(>>56) < int8(>>56),
					int8(>>0) < int8(>>0), int8(>>8) < int8(>>8),
					int8(>>16) < int8(>>16), int8(>>24) < int8(>>24),
					int8(>>32) < int8(>>32), int8(>>40) < int8(>>40),
					int8(>>48) < int8(>>48), int8(>>56) < int8(>>56),
				}
			case v128CmpTypeI8x16LtU:
				 = []bool{
					byte(>>0) < byte(>>0), byte(>>8) < byte(>>8),
					byte(>>16) < byte(>>16), byte(>>24) < byte(>>24),
					byte(>>32) < byte(>>32), byte(>>40) < byte(>>40),
					byte(>>48) < byte(>>48), byte(>>56) < byte(>>56),
					byte(>>0) < byte(>>0), byte(>>8) < byte(>>8),
					byte(>>16) < byte(>>16), byte(>>24) < byte(>>24),
					byte(>>32) < byte(>>32), byte(>>40) < byte(>>40),
					byte(>>48) < byte(>>48), byte(>>56) < byte(>>56),
				}
			case v128CmpTypeI8x16GtS:
				 = []bool{
					int8(>>0) > int8(>>0), int8(>>8) > int8(>>8),
					int8(>>16) > int8(>>16), int8(>>24) > int8(>>24),
					int8(>>32) > int8(>>32), int8(>>40) > int8(>>40),
					int8(>>48) > int8(>>48), int8(>>56) > int8(>>56),
					int8(>>0) > int8(>>0), int8(>>8) > int8(>>8),
					int8(>>16) > int8(>>16), int8(>>24) > int8(>>24),
					int8(>>32) > int8(>>32), int8(>>40) > int8(>>40),
					int8(>>48) > int8(>>48), int8(>>56) > int8(>>56),
				}
			case v128CmpTypeI8x16GtU:
				 = []bool{
					byte(>>0) > byte(>>0), byte(>>8) > byte(>>8),
					byte(>>16) > byte(>>16), byte(>>24) > byte(>>24),
					byte(>>32) > byte(>>32), byte(>>40) > byte(>>40),
					byte(>>48) > byte(>>48), byte(>>56) > byte(>>56),
					byte(>>0) > byte(>>0), byte(>>8) > byte(>>8),
					byte(>>16) > byte(>>16), byte(>>24) > byte(>>24),
					byte(>>32) > byte(>>32), byte(>>40) > byte(>>40),
					byte(>>48) > byte(>>48), byte(>>56) > byte(>>56),
				}
			case v128CmpTypeI8x16LeS:
				 = []bool{
					int8(>>0) <= int8(>>0), int8(>>8) <= int8(>>8),
					int8(>>16) <= int8(>>16), int8(>>24) <= int8(>>24),
					int8(>>32) <= int8(>>32), int8(>>40) <= int8(>>40),
					int8(>>48) <= int8(>>48), int8(>>56) <= int8(>>56),
					int8(>>0) <= int8(>>0), int8(>>8) <= int8(>>8),
					int8(>>16) <= int8(>>16), int8(>>24) <= int8(>>24),
					int8(>>32) <= int8(>>32), int8(>>40) <= int8(>>40),
					int8(>>48) <= int8(>>48), int8(>>56) <= int8(>>56),
				}
			case v128CmpTypeI8x16LeU:
				 = []bool{
					byte(>>0) <= byte(>>0), byte(>>8) <= byte(>>8),
					byte(>>16) <= byte(>>16), byte(>>24) <= byte(>>24),
					byte(>>32) <= byte(>>32), byte(>>40) <= byte(>>40),
					byte(>>48) <= byte(>>48), byte(>>56) <= byte(>>56),
					byte(>>0) <= byte(>>0), byte(>>8) <= byte(>>8),
					byte(>>16) <= byte(>>16), byte(>>24) <= byte(>>24),
					byte(>>32) <= byte(>>32), byte(>>40) <= byte(>>40),
					byte(>>48) <= byte(>>48), byte(>>56) <= byte(>>56),
				}
			case v128CmpTypeI8x16GeS:
				 = []bool{
					int8(>>0) >= int8(>>0), int8(>>8) >= int8(>>8),
					int8(>>16) >= int8(>>16), int8(>>24) >= int8(>>24),
					int8(>>32) >= int8(>>32), int8(>>40) >= int8(>>40),
					int8(>>48) >= int8(>>48), int8(>>56) >= int8(>>56),
					int8(>>0) >= int8(>>0), int8(>>8) >= int8(>>8),
					int8(>>16) >= int8(>>16), int8(>>24) >= int8(>>24),
					int8(>>32) >= int8(>>32), int8(>>40) >= int8(>>40),
					int8(>>48) >= int8(>>48), int8(>>56) >= int8(>>56),
				}
			case v128CmpTypeI8x16GeU:
				 = []bool{
					byte(>>0) >= byte(>>0), byte(>>8) >= byte(>>8),
					byte(>>16) >= byte(>>16), byte(>>24) >= byte(>>24),
					byte(>>32) >= byte(>>32), byte(>>40) >= byte(>>40),
					byte(>>48) >= byte(>>48), byte(>>56) >= byte(>>56),
					byte(>>0) >= byte(>>0), byte(>>8) >= byte(>>8),
					byte(>>16) >= byte(>>16), byte(>>24) >= byte(>>24),
					byte(>>32) >= byte(>>32), byte(>>40) >= byte(>>40),
					byte(>>48) >= byte(>>48), byte(>>56) >= byte(>>56),
				}
			case v128CmpTypeI16x8Eq:
				 = []bool{
					uint16(>>0) == uint16(>>0), uint16(>>16) == uint16(>>16),
					uint16(>>32) == uint16(>>32), uint16(>>48) == uint16(>>48),
					uint16(>>0) == uint16(>>0), uint16(>>16) == uint16(>>16),
					uint16(>>32) == uint16(>>32), uint16(>>48) == uint16(>>48),
				}
			case v128CmpTypeI16x8Ne:
				 = []bool{
					uint16(>>0) != uint16(>>0), uint16(>>16) != uint16(>>16),
					uint16(>>32) != uint16(>>32), uint16(>>48) != uint16(>>48),
					uint16(>>0) != uint16(>>0), uint16(>>16) != uint16(>>16),
					uint16(>>32) != uint16(>>32), uint16(>>48) != uint16(>>48),
				}
			case v128CmpTypeI16x8LtS:
				 = []bool{
					int16(>>0) < int16(>>0), int16(>>16) < int16(>>16),
					int16(>>32) < int16(>>32), int16(>>48) < int16(>>48),
					int16(>>0) < int16(>>0), int16(>>16) < int16(>>16),
					int16(>>32) < int16(>>32), int16(>>48) < int16(>>48),
				}
			case v128CmpTypeI16x8LtU:
				 = []bool{
					uint16(>>0) < uint16(>>0), uint16(>>16) < uint16(>>16),
					uint16(>>32) < uint16(>>32), uint16(>>48) < uint16(>>48),
					uint16(>>0) < uint16(>>0), uint16(>>16) < uint16(>>16),
					uint16(>>32) < uint16(>>32), uint16(>>48) < uint16(>>48),
				}
			case v128CmpTypeI16x8GtS:
				 = []bool{
					int16(>>0) > int16(>>0), int16(>>16) > int16(>>16),
					int16(>>32) > int16(>>32), int16(>>48) > int16(>>48),
					int16(>>0) > int16(>>0), int16(>>16) > int16(>>16),
					int16(>>32) > int16(>>32), int16(>>48) > int16(>>48),
				}
			case v128CmpTypeI16x8GtU:
				 = []bool{
					uint16(>>0) > uint16(>>0), uint16(>>16) > uint16(>>16),
					uint16(>>32) > uint16(>>32), uint16(>>48) > uint16(>>48),
					uint16(>>0) > uint16(>>0), uint16(>>16) > uint16(>>16),
					uint16(>>32) > uint16(>>32), uint16(>>48) > uint16(>>48),
				}
			case v128CmpTypeI16x8LeS:
				 = []bool{
					int16(>>0) <= int16(>>0), int16(>>16) <= int16(>>16),
					int16(>>32) <= int16(>>32), int16(>>48) <= int16(>>48),
					int16(>>0) <= int16(>>0), int16(>>16) <= int16(>>16),
					int16(>>32) <= int16(>>32), int16(>>48) <= int16(>>48),
				}
			case v128CmpTypeI16x8LeU:
				 = []bool{
					uint16(>>0) <= uint16(>>0), uint16(>>16) <= uint16(>>16),
					uint16(>>32) <= uint16(>>32), uint16(>>48) <= uint16(>>48),
					uint16(>>0) <= uint16(>>0), uint16(>>16) <= uint16(>>16),
					uint16(>>32) <= uint16(>>32), uint16(>>48) <= uint16(>>48),
				}
			case v128CmpTypeI16x8GeS:
				 = []bool{
					int16(>>0) >= int16(>>0), int16(>>16) >= int16(>>16),
					int16(>>32) >= int16(>>32), int16(>>48) >= int16(>>48),
					int16(>>0) >= int16(>>0), int16(>>16) >= int16(>>16),
					int16(>>32) >= int16(>>32), int16(>>48) >= int16(>>48),
				}
			case v128CmpTypeI16x8GeU:
				 = []bool{
					uint16(>>0) >= uint16(>>0), uint16(>>16) >= uint16(>>16),
					uint16(>>32) >= uint16(>>32), uint16(>>48) >= uint16(>>48),
					uint16(>>0) >= uint16(>>0), uint16(>>16) >= uint16(>>16),
					uint16(>>32) >= uint16(>>32), uint16(>>48) >= uint16(>>48),
				}
			case v128CmpTypeI32x4Eq:
				 = []bool{
					uint32(>>0) == uint32(>>0), uint32(>>32) == uint32(>>32),
					uint32(>>0) == uint32(>>0), uint32(>>32) == uint32(>>32),
				}
			case v128CmpTypeI32x4Ne:
				 = []bool{
					uint32(>>0) != uint32(>>0), uint32(>>32) != uint32(>>32),
					uint32(>>0) != uint32(>>0), uint32(>>32) != uint32(>>32),
				}
			case v128CmpTypeI32x4LtS:
				 = []bool{
					int32(>>0) < int32(>>0), int32(>>32) < int32(>>32),
					int32(>>0) < int32(>>0), int32(>>32) < int32(>>32),
				}
			case v128CmpTypeI32x4LtU:
				 = []bool{
					uint32(>>0) < uint32(>>0), uint32(>>32) < uint32(>>32),
					uint32(>>0) < uint32(>>0), uint32(>>32) < uint32(>>32),
				}
			case v128CmpTypeI32x4GtS:
				 = []bool{
					int32(>>0) > int32(>>0), int32(>>32) > int32(>>32),
					int32(>>0) > int32(>>0), int32(>>32) > int32(>>32),
				}
			case v128CmpTypeI32x4GtU:
				 = []bool{
					uint32(>>0) > uint32(>>0), uint32(>>32) > uint32(>>32),
					uint32(>>0) > uint32(>>0), uint32(>>32) > uint32(>>32),
				}
			case v128CmpTypeI32x4LeS:
				 = []bool{
					int32(>>0) <= int32(>>0), int32(>>32) <= int32(>>32),
					int32(>>0) <= int32(>>0), int32(>>32) <= int32(>>32),
				}
			case v128CmpTypeI32x4LeU:
				 = []bool{
					uint32(>>0) <= uint32(>>0), uint32(>>32) <= uint32(>>32),
					uint32(>>0) <= uint32(>>0), uint32(>>32) <= uint32(>>32),
				}
			case v128CmpTypeI32x4GeS:
				 = []bool{
					int32(>>0) >= int32(>>0), int32(>>32) >= int32(>>32),
					int32(>>0) >= int32(>>0), int32(>>32) >= int32(>>32),
				}
			case v128CmpTypeI32x4GeU:
				 = []bool{
					uint32(>>0) >= uint32(>>0), uint32(>>32) >= uint32(>>32),
					uint32(>>0) >= uint32(>>0), uint32(>>32) >= uint32(>>32),
				}
			case v128CmpTypeI64x2Eq:
				 = []bool{ == ,  == }
			case v128CmpTypeI64x2Ne:
				 = []bool{ != ,  != }
			case v128CmpTypeI64x2LtS:
				 = []bool{int64() < int64(), int64() < int64()}
			case v128CmpTypeI64x2GtS:
				 = []bool{int64() > int64(), int64() > int64()}
			case v128CmpTypeI64x2LeS:
				 = []bool{int64() <= int64(), int64() <= int64()}
			case v128CmpTypeI64x2GeS:
				 = []bool{int64() >= int64(), int64() >= int64()}
			case v128CmpTypeF32x4Eq:
				 = []bool{
					math.Float32frombits(uint32(>>0)) == math.Float32frombits(uint32(>>0)),
					math.Float32frombits(uint32(>>32)) == math.Float32frombits(uint32(>>32)),
					math.Float32frombits(uint32(>>0)) == math.Float32frombits(uint32(>>0)),
					math.Float32frombits(uint32(>>32)) == math.Float32frombits(uint32(>>32)),
				}
			case v128CmpTypeF32x4Ne:
				 = []bool{
					math.Float32frombits(uint32(>>0)) != math.Float32frombits(uint32(>>0)),
					math.Float32frombits(uint32(>>32)) != math.Float32frombits(uint32(>>32)),
					math.Float32frombits(uint32(>>0)) != math.Float32frombits(uint32(>>0)),
					math.Float32frombits(uint32(>>32)) != math.Float32frombits(uint32(>>32)),
				}
			case v128CmpTypeF32x4Lt:
				 = []bool{
					math.Float32frombits(uint32(>>0)) < math.Float32frombits(uint32(>>0)),
					math.Float32frombits(uint32(>>32)) < math.Float32frombits(uint32(>>32)),
					math.Float32frombits(uint32(>>0)) < math.Float32frombits(uint32(>>0)),
					math.Float32frombits(uint32(>>32)) < math.Float32frombits(uint32(>>32)),
				}
			case v128CmpTypeF32x4Gt:
				 = []bool{
					math.Float32frombits(uint32(>>0)) > math.Float32frombits(uint32(>>0)),
					math.Float32frombits(uint32(>>32)) > math.Float32frombits(uint32(>>32)),
					math.Float32frombits(uint32(>>0)) > math.Float32frombits(uint32(>>0)),
					math.Float32frombits(uint32(>>32)) > math.Float32frombits(uint32(>>32)),
				}
			case v128CmpTypeF32x4Le:
				 = []bool{
					math.Float32frombits(uint32(>>0)) <= math.Float32frombits(uint32(>>0)),
					math.Float32frombits(uint32(>>32)) <= math.Float32frombits(uint32(>>32)),
					math.Float32frombits(uint32(>>0)) <= math.Float32frombits(uint32(>>0)),
					math.Float32frombits(uint32(>>32)) <= math.Float32frombits(uint32(>>32)),
				}
			case v128CmpTypeF32x4Ge:
				 = []bool{
					math.Float32frombits(uint32(>>0)) >= math.Float32frombits(uint32(>>0)),
					math.Float32frombits(uint32(>>32)) >= math.Float32frombits(uint32(>>32)),
					math.Float32frombits(uint32(>>0)) >= math.Float32frombits(uint32(>>0)),
					math.Float32frombits(uint32(>>32)) >= math.Float32frombits(uint32(>>32)),
				}
			case v128CmpTypeF64x2Eq:
				 = []bool{
					math.Float64frombits() == math.Float64frombits(),
					math.Float64frombits() == math.Float64frombits(),
				}
			case v128CmpTypeF64x2Ne:
				 = []bool{
					math.Float64frombits() != math.Float64frombits(),
					math.Float64frombits() != math.Float64frombits(),
				}
			case v128CmpTypeF64x2Lt:
				 = []bool{
					math.Float64frombits() < math.Float64frombits(),
					math.Float64frombits() < math.Float64frombits(),
				}
			case v128CmpTypeF64x2Gt:
				 = []bool{
					math.Float64frombits() > math.Float64frombits(),
					math.Float64frombits() > math.Float64frombits(),
				}
			case v128CmpTypeF64x2Le:
				 = []bool{
					math.Float64frombits() <= math.Float64frombits(),
					math.Float64frombits() <= math.Float64frombits(),
				}
			case v128CmpTypeF64x2Ge:
				 = []bool{
					math.Float64frombits() >= math.Float64frombits(),
					math.Float64frombits() >= math.Float64frombits(),
				}
			}

			var ,  uint64
			 := len()
			switch  {
			case 16:
				for ,  := range  {
					if  {
						if  < 8 {
							 |= 0xff << ( * 8)
						} else {
							 |= 0xff << (( - 8) * 8)
						}
					}
				}
			case 8:
				for ,  := range  {
					if  {
						if  < 4 {
							 |= 0xffff << ( * 16)
						} else {
							 |= 0xffff << (( - 4) * 16)
						}
					}
				}
			case 4:
				for ,  := range  {
					if  {
						if  < 2 {
							 |= 0xffff_ffff << ( * 32)
						} else {
							 |= 0xffff_ffff << (( - 2) * 32)
						}
					}
				}
			case 2:
				if [0] {
					 = ^uint64(0)
				}
				if [1] {
					 = ^uint64(0)
				}
			}

			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128AddSat:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()

			var ,  uint64

			// Lane-wise addition while saturating the overflowing values.
			// https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/simd/SIMD.md#saturating-integer-addition
			switch .B1 {
			case shapeI8x16:
				for  := 0;  < 16; ++ {
					var ,  byte
					if  < 8 {
						,  = byte(>>(*8)), byte(>>(*8))
					} else {
						,  = byte(>>((-8)*8)), byte(>>((-8)*8))
					}

					var  uint64
					if .B3 { // signed
						if  := int64(int8()) + int64(int8());  < math.MinInt8 {
							 = uint64(byte(0x80))
						} else if  > math.MaxInt8 {
							 = uint64(byte(0x7f))
						} else {
							 = uint64(byte(int8()))
						}
					} else {
						if  := int64() + int64();  < 0 {
							 = uint64(byte(0))
						} else if  > math.MaxUint8 {
							 = uint64(byte(0xff))
						} else {
							 = uint64(byte())
						}
					}

					if  < 8 { // first 8 lanes are on lower 64bits.
						 |=  << ( * 8)
					} else {
						 |=  << (( - 8) * 8)
					}
				}
			case shapeI16x8:
				for  := 0;  < 8; ++ {
					var ,  uint16
					if  < 4 {
						,  = uint16(>>(*16)), uint16(>>(*16))
					} else {
						,  = uint16(>>((-4)*16)), uint16(>>((-4)*16))
					}

					var  uint64
					if .B3 { // signed
						if  := int64(int16()) + int64(int16());  < math.MinInt16 {
							 = uint64(uint16(0x8000))
						} else if  > math.MaxInt16 {
							 = uint64(uint16(0x7fff))
						} else {
							 = uint64(uint16(int16()))
						}
					} else {
						if  := int64() + int64();  < 0 {
							 = uint64(uint16(0))
						} else if  > math.MaxUint16 {
							 = uint64(uint16(0xffff))
						} else {
							 = uint64(uint16())
						}
					}

					if  < 4 { // first 4 lanes are on lower 64bits.
						 |=  << ( * 16)
					} else {
						 |=  << (( - 4) * 16)
					}
				}
			}

			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128SubSat:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()

			var ,  uint64

			// Lane-wise subtraction while saturating the overflowing values.
			// https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/simd/SIMD.md#saturating-integer-subtraction
			switch .B1 {
			case shapeI8x16:
				for  := 0;  < 16; ++ {
					var ,  byte
					if  < 8 {
						,  = byte(>>(*8)), byte(>>(*8))
					} else {
						,  = byte(>>((-8)*8)), byte(>>((-8)*8))
					}

					var  uint64
					if .B3 { // signed
						if  := int64(int8()) - int64(int8());  < math.MinInt8 {
							 = uint64(byte(0x80))
						} else if  > math.MaxInt8 {
							 = uint64(byte(0x7f))
						} else {
							 = uint64(byte(int8()))
						}
					} else {
						if  := int64() - int64();  < 0 {
							 = uint64(byte(0))
						} else if  > math.MaxUint8 {
							 = uint64(byte(0xff))
						} else {
							 = uint64(byte())
						}
					}

					if  < 8 {
						 |=  << ( * 8)
					} else {
						 |=  << (( - 8) * 8)
					}
				}
			case shapeI16x8:
				for  := 0;  < 8; ++ {
					var ,  uint16
					if  < 4 {
						,  = uint16(>>(*16)), uint16(>>(*16))
					} else {
						,  = uint16(>>((-4)*16)), uint16(>>((-4)*16))
					}

					var  uint64
					if .B3 { // signed
						if  := int64(int16()) - int64(int16());  < math.MinInt16 {
							 = uint64(uint16(0x8000))
						} else if  > math.MaxInt16 {
							 = uint64(uint16(0x7fff))
						} else {
							 = uint64(uint16(int16()))
						}
					} else {
						if  := int64() - int64();  < 0 {
							 = uint64(uint16(0))
						} else if  > math.MaxUint16 {
							 = uint64(uint16(0xffff))
						} else {
							 = uint64(uint16())
						}
					}

					if  < 4 {
						 |=  << ( * 16)
					} else {
						 |=  << (( - 4) * 16)
					}
				}
			}

			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Mul:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			var ,  uint64
			switch .B1 {
			case shapeI16x8:
				 = uint64(uint16()*uint16()) | (uint64(uint16(>>16)*uint16(>>16)) << 16) |
					(uint64(uint16(>>32)*uint16(>>32)) << 32) | (uint64(uint16(>>48)*uint16(>>48)) << 48)
				 = uint64(uint16()*uint16()) | (uint64(uint16(>>16)*uint16(>>16)) << 16) |
					(uint64(uint16(>>32)*uint16(>>32)) << 32) | (uint64(uint16(>>48)*uint16(>>48)) << 48)
			case shapeI32x4:
				 = uint64(uint32()*uint32()) | (uint64(uint32(>>32)*uint32(>>32)) << 32)
				 = uint64(uint32()*uint32()) | (uint64(uint32(>>32)*uint32(>>32)) << 32)
			case shapeI64x2:
				 =  * 
				 =  * 
			case shapeF32x4:
				 = mulFloat32bits(uint32(), uint32()) | mulFloat32bits(uint32(>>32), uint32(>>32))<<32
				 = mulFloat32bits(uint32(), uint32()) | mulFloat32bits(uint32(>>32), uint32(>>32))<<32
			case shapeF64x2:
				 = math.Float64bits(math.Float64frombits() * math.Float64frombits())
				 = math.Float64bits(math.Float64frombits() * math.Float64frombits())
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Div:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			var ,  uint64
			if .B1 == shapeF64x2 {
				 = math.Float64bits(math.Float64frombits() / math.Float64frombits())
				 = math.Float64bits(math.Float64frombits() / math.Float64frombits())
			} else {
				 = divFloat32bits(uint32(), uint32()) | divFloat32bits(uint32(>>32), uint32(>>32))<<32
				 = divFloat32bits(uint32(), uint32()) | divFloat32bits(uint32(>>32), uint32(>>32))<<32
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Neg:
			,  := .popValue(), .popValue()
			switch .B1 {
			case shapeI8x16:
				 = uint64(-byte()) | (uint64(-byte(>>8)) << 8) |
					(uint64(-byte(>>16)) << 16) | (uint64(-byte(>>24)) << 24) |
					(uint64(-byte(>>32)) << 32) | (uint64(-byte(>>40)) << 40) |
					(uint64(-byte(>>48)) << 48) | (uint64(-byte(>>56)) << 56)
				 = uint64(-byte()) | (uint64(-byte(>>8)) << 8) |
					(uint64(-byte(>>16)) << 16) | (uint64(-byte(>>24)) << 24) |
					(uint64(-byte(>>32)) << 32) | (uint64(-byte(>>40)) << 40) |
					(uint64(-byte(>>48)) << 48) | (uint64(-byte(>>56)) << 56)
			case shapeI16x8:
				 = uint64(-uint16()) | (uint64(-uint16(>>16)) << 16) |
					(uint64(-uint16(>>32)) << 32) | (uint64(-uint16(>>48)) << 48)
				 = uint64(-uint16()) | (uint64(-uint16(>>16)) << 16) |
					(uint64(-uint16(>>32)) << 32) | (uint64(-uint16(>>48)) << 48)
			case shapeI32x4:
				 = uint64(-uint32()) | (uint64(-uint32(>>32)) << 32)
				 = uint64(-uint32()) | (uint64(-uint32(>>32)) << 32)
			case shapeI64x2:
				 = -
				 = -
			case shapeF32x4:
				 = uint64(math.Float32bits(-math.Float32frombits(uint32()))) |
					(uint64(math.Float32bits(-math.Float32frombits(uint32(>>32)))) << 32)
				 = uint64(math.Float32bits(-math.Float32frombits(uint32()))) |
					(uint64(math.Float32bits(-math.Float32frombits(uint32(>>32)))) << 32)
			case shapeF64x2:
				 = math.Float64bits(-math.Float64frombits())
				 = math.Float64bits(-math.Float64frombits())
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Sqrt:
			,  := .popValue(), .popValue()
			if .B1 == shapeF64x2 {
				 = math.Float64bits(math.Sqrt(math.Float64frombits()))
				 = math.Float64bits(math.Sqrt(math.Float64frombits()))
			} else {
				 = uint64(math.Float32bits(float32(math.Sqrt(float64(math.Float32frombits(uint32())))))) |
					(uint64(math.Float32bits(float32(math.Sqrt(float64(math.Float32frombits(uint32(>>32))))))) << 32)
				 = uint64(math.Float32bits(float32(math.Sqrt(float64(math.Float32frombits(uint32())))))) |
					(uint64(math.Float32bits(float32(math.Sqrt(float64(math.Float32frombits(uint32(>>32))))))) << 32)
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Abs:
			,  := .popValue(), .popValue()
			switch .B1 {
			case shapeI8x16:
				 = uint64(i8Abs(byte())) | (uint64(i8Abs(byte(>>8))) << 8) |
					(uint64(i8Abs(byte(>>16))) << 16) | (uint64(i8Abs(byte(>>24))) << 24) |
					(uint64(i8Abs(byte(>>32))) << 32) | (uint64(i8Abs(byte(>>40))) << 40) |
					(uint64(i8Abs(byte(>>48))) << 48) | (uint64(i8Abs(byte(>>56))) << 56)
				 = uint64(i8Abs(byte())) | (uint64(i8Abs(byte(>>8))) << 8) |
					(uint64(i8Abs(byte(>>16))) << 16) | (uint64(i8Abs(byte(>>24))) << 24) |
					(uint64(i8Abs(byte(>>32))) << 32) | (uint64(i8Abs(byte(>>40))) << 40) |
					(uint64(i8Abs(byte(>>48))) << 48) | (uint64(i8Abs(byte(>>56))) << 56)
			case shapeI16x8:
				 = uint64(i16Abs(uint16())) | (uint64(i16Abs(uint16(>>16))) << 16) |
					(uint64(i16Abs(uint16(>>32))) << 32) | (uint64(i16Abs(uint16(>>48))) << 48)
				 = uint64(i16Abs(uint16())) | (uint64(i16Abs(uint16(>>16))) << 16) |
					(uint64(i16Abs(uint16(>>32))) << 32) | (uint64(i16Abs(uint16(>>48))) << 48)
			case shapeI32x4:
				 = uint64(i32Abs(uint32())) | (uint64(i32Abs(uint32(>>32))) << 32)
				 = uint64(i32Abs(uint32())) | (uint64(i32Abs(uint32(>>32))) << 32)
			case shapeI64x2:
				if int64() < 0 {
					 = -
				}
				if int64() < 0 {
					 = -
				}
			case shapeF32x4:
				 =  &^ (1<<31 | 1<<63)
				 =  &^ (1<<31 | 1<<63)
			case shapeF64x2:
				 =  &^ (1 << 63)
				 =  &^ (1 << 63)
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Popcnt:
			,  := .popValue(), .popValue()
			var ,  uint64
			for  := 0;  < 16; ++ {
				var  byte
				if  < 8 {
					 = byte( >> ( * 8))
				} else {
					 = byte( >> (( - 8) * 8))
				}

				var  uint64
				for  := 0;  < 8; ++ {
					if (>>)&0b1 != 0 {
						++
					}
				}

				if  < 8 {
					 |=  << ( * 8)
				} else {
					 |=  << (( - 8) * 8)
				}
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Min:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			var ,  uint64
			switch .B1 {
			case shapeI8x16:
				if .B3 { // signed
					 = uint64(i8MinS(uint8(>>8), uint8(>>8)))<<8 | uint64(i8MinS(uint8(), uint8())) |
						uint64(i8MinS(uint8(>>24), uint8(>>24)))<<24 | uint64(i8MinS(uint8(>>16), uint8(>>16)))<<16 |
						uint64(i8MinS(uint8(>>40), uint8(>>40)))<<40 | uint64(i8MinS(uint8(>>32), uint8(>>32)))<<32 |
						uint64(i8MinS(uint8(>>56), uint8(>>56)))<<56 | uint64(i8MinS(uint8(>>48), uint8(>>48)))<<48
					 = uint64(i8MinS(uint8(>>8), uint8(>>8)))<<8 | uint64(i8MinS(uint8(), uint8())) |
						uint64(i8MinS(uint8(>>24), uint8(>>24)))<<24 | uint64(i8MinS(uint8(>>16), uint8(>>16)))<<16 |
						uint64(i8MinS(uint8(>>40), uint8(>>40)))<<40 | uint64(i8MinS(uint8(>>32), uint8(>>32)))<<32 |
						uint64(i8MinS(uint8(>>56), uint8(>>56)))<<56 | uint64(i8MinS(uint8(>>48), uint8(>>48)))<<48
				} else {
					 = uint64(i8MinU(uint8(>>8), uint8(>>8)))<<8 | uint64(i8MinU(uint8(), uint8())) |
						uint64(i8MinU(uint8(>>24), uint8(>>24)))<<24 | uint64(i8MinU(uint8(>>16), uint8(>>16)))<<16 |
						uint64(i8MinU(uint8(>>40), uint8(>>40)))<<40 | uint64(i8MinU(uint8(>>32), uint8(>>32)))<<32 |
						uint64(i8MinU(uint8(>>56), uint8(>>56)))<<56 | uint64(i8MinU(uint8(>>48), uint8(>>48)))<<48
					 = uint64(i8MinU(uint8(>>8), uint8(>>8)))<<8 | uint64(i8MinU(uint8(), uint8())) |
						uint64(i8MinU(uint8(>>24), uint8(>>24)))<<24 | uint64(i8MinU(uint8(>>16), uint8(>>16)))<<16 |
						uint64(i8MinU(uint8(>>40), uint8(>>40)))<<40 | uint64(i8MinU(uint8(>>32), uint8(>>32)))<<32 |
						uint64(i8MinU(uint8(>>56), uint8(>>56)))<<56 | uint64(i8MinU(uint8(>>48), uint8(>>48)))<<48
				}
			case shapeI16x8:
				if .B3 { // signed
					 = uint64(i16MinS(uint16(), uint16())) |
						uint64(i16MinS(uint16(>>16), uint16(>>16)))<<16 |
						uint64(i16MinS(uint16(>>32), uint16(>>32)))<<32 |
						uint64(i16MinS(uint16(>>48), uint16(>>48)))<<48
					 = uint64(i16MinS(uint16(), uint16())) |
						uint64(i16MinS(uint16(>>16), uint16(>>16)))<<16 |
						uint64(i16MinS(uint16(>>32), uint16(>>32)))<<32 |
						uint64(i16MinS(uint16(>>48), uint16(>>48)))<<48
				} else {
					 = uint64(i16MinU(uint16(), uint16())) |
						uint64(i16MinU(uint16(>>16), uint16(>>16)))<<16 |
						uint64(i16MinU(uint16(>>32), uint16(>>32)))<<32 |
						uint64(i16MinU(uint16(>>48), uint16(>>48)))<<48
					 = uint64(i16MinU(uint16(), uint16())) |
						uint64(i16MinU(uint16(>>16), uint16(>>16)))<<16 |
						uint64(i16MinU(uint16(>>32), uint16(>>32)))<<32 |
						uint64(i16MinU(uint16(>>48), uint16(>>48)))<<48
				}
			case shapeI32x4:
				if .B3 { // signed
					 = uint64(i32MinS(uint32(), uint32())) |
						uint64(i32MinS(uint32(>>32), uint32(>>32)))<<32
					 = uint64(i32MinS(uint32(), uint32())) |
						uint64(i32MinS(uint32(>>32), uint32(>>32)))<<32
				} else {
					 = uint64(i32MinU(uint32(), uint32())) |
						uint64(i32MinU(uint32(>>32), uint32(>>32)))<<32
					 = uint64(i32MinU(uint32(), uint32())) |
						uint64(i32MinU(uint32(>>32), uint32(>>32)))<<32
				}
			case shapeF32x4:
				 = wasmCompatMin32bits(uint32(), uint32()) |
					wasmCompatMin32bits(uint32(>>32), uint32(>>32))<<32
				 = wasmCompatMin32bits(uint32(), uint32()) |
					wasmCompatMin32bits(uint32(>>32), uint32(>>32))<<32
			case shapeF64x2:
				 = math.Float64bits(moremath.WasmCompatMin64(
					math.Float64frombits(),
					math.Float64frombits(),
				))
				 = math.Float64bits(moremath.WasmCompatMin64(
					math.Float64frombits(),
					math.Float64frombits(),
				))
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Max:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			var ,  uint64
			switch .B1 {
			case shapeI8x16:
				if .B3 { // signed
					 = uint64(i8MaxS(uint8(>>8), uint8(>>8)))<<8 | uint64(i8MaxS(uint8(), uint8())) |
						uint64(i8MaxS(uint8(>>24), uint8(>>24)))<<24 | uint64(i8MaxS(uint8(>>16), uint8(>>16)))<<16 |
						uint64(i8MaxS(uint8(>>40), uint8(>>40)))<<40 | uint64(i8MaxS(uint8(>>32), uint8(>>32)))<<32 |
						uint64(i8MaxS(uint8(>>56), uint8(>>56)))<<56 | uint64(i8MaxS(uint8(>>48), uint8(>>48)))<<48
					 = uint64(i8MaxS(uint8(>>8), uint8(>>8)))<<8 | uint64(i8MaxS(uint8(), uint8())) |
						uint64(i8MaxS(uint8(>>24), uint8(>>24)))<<24 | uint64(i8MaxS(uint8(>>16), uint8(>>16)))<<16 |
						uint64(i8MaxS(uint8(>>40), uint8(>>40)))<<40 | uint64(i8MaxS(uint8(>>32), uint8(>>32)))<<32 |
						uint64(i8MaxS(uint8(>>56), uint8(>>56)))<<56 | uint64(i8MaxS(uint8(>>48), uint8(>>48)))<<48
				} else {
					 = uint64(i8MaxU(uint8(>>8), uint8(>>8)))<<8 | uint64(i8MaxU(uint8(), uint8())) |
						uint64(i8MaxU(uint8(>>24), uint8(>>24)))<<24 | uint64(i8MaxU(uint8(>>16), uint8(>>16)))<<16 |
						uint64(i8MaxU(uint8(>>40), uint8(>>40)))<<40 | uint64(i8MaxU(uint8(>>32), uint8(>>32)))<<32 |
						uint64(i8MaxU(uint8(>>56), uint8(>>56)))<<56 | uint64(i8MaxU(uint8(>>48), uint8(>>48)))<<48
					 = uint64(i8MaxU(uint8(>>8), uint8(>>8)))<<8 | uint64(i8MaxU(uint8(), uint8())) |
						uint64(i8MaxU(uint8(>>24), uint8(>>24)))<<24 | uint64(i8MaxU(uint8(>>16), uint8(>>16)))<<16 |
						uint64(i8MaxU(uint8(>>40), uint8(>>40)))<<40 | uint64(i8MaxU(uint8(>>32), uint8(>>32)))<<32 |
						uint64(i8MaxU(uint8(>>56), uint8(>>56)))<<56 | uint64(i8MaxU(uint8(>>48), uint8(>>48)))<<48
				}
			case shapeI16x8:
				if .B3 { // signed
					 = uint64(i16MaxS(uint16(), uint16())) |
						uint64(i16MaxS(uint16(>>16), uint16(>>16)))<<16 |
						uint64(i16MaxS(uint16(>>32), uint16(>>32)))<<32 |
						uint64(i16MaxS(uint16(>>48), uint16(>>48)))<<48
					 = uint64(i16MaxS(uint16(), uint16())) |
						uint64(i16MaxS(uint16(>>16), uint16(>>16)))<<16 |
						uint64(i16MaxS(uint16(>>32), uint16(>>32)))<<32 |
						uint64(i16MaxS(uint16(>>48), uint16(>>48)))<<48
				} else {
					 = uint64(i16MaxU(uint16(), uint16())) |
						uint64(i16MaxU(uint16(>>16), uint16(>>16)))<<16 |
						uint64(i16MaxU(uint16(>>32), uint16(>>32)))<<32 |
						uint64(i16MaxU(uint16(>>48), uint16(>>48)))<<48
					 = uint64(i16MaxU(uint16(), uint16())) |
						uint64(i16MaxU(uint16(>>16), uint16(>>16)))<<16 |
						uint64(i16MaxU(uint16(>>32), uint16(>>32)))<<32 |
						uint64(i16MaxU(uint16(>>48), uint16(>>48)))<<48
				}
			case shapeI32x4:
				if .B3 { // signed
					 = uint64(i32MaxS(uint32(), uint32())) |
						uint64(i32MaxS(uint32(>>32), uint32(>>32)))<<32
					 = uint64(i32MaxS(uint32(), uint32())) |
						uint64(i32MaxS(uint32(>>32), uint32(>>32)))<<32
				} else {
					 = uint64(i32MaxU(uint32(), uint32())) |
						uint64(i32MaxU(uint32(>>32), uint32(>>32)))<<32
					 = uint64(i32MaxU(uint32(), uint32())) |
						uint64(i32MaxU(uint32(>>32), uint32(>>32)))<<32
				}
			case shapeF32x4:
				 = wasmCompatMax32bits(uint32(), uint32()) |
					wasmCompatMax32bits(uint32(>>32), uint32(>>32))<<32
				 = wasmCompatMax32bits(uint32(), uint32()) |
					wasmCompatMax32bits(uint32(>>32), uint32(>>32))<<32
			case shapeF64x2:
				 = math.Float64bits(moremath.WasmCompatMax64(
					math.Float64frombits(),
					math.Float64frombits(),
				))
				 = math.Float64bits(moremath.WasmCompatMax64(
					math.Float64frombits(),
					math.Float64frombits(),
				))
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128AvgrU:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			var ,  uint64
			switch .B1 {
			case shapeI8x16:
				 = uint64(i8RoundingAverage(uint8(>>8), uint8(>>8)))<<8 | uint64(i8RoundingAverage(uint8(), uint8())) |
					uint64(i8RoundingAverage(uint8(>>24), uint8(>>24)))<<24 | uint64(i8RoundingAverage(uint8(>>16), uint8(>>16)))<<16 |
					uint64(i8RoundingAverage(uint8(>>40), uint8(>>40)))<<40 | uint64(i8RoundingAverage(uint8(>>32), uint8(>>32)))<<32 |
					uint64(i8RoundingAverage(uint8(>>56), uint8(>>56)))<<56 | uint64(i8RoundingAverage(uint8(>>48), uint8(>>48)))<<48
				 = uint64(i8RoundingAverage(uint8(>>8), uint8(>>8)))<<8 | uint64(i8RoundingAverage(uint8(), uint8())) |
					uint64(i8RoundingAverage(uint8(>>24), uint8(>>24)))<<24 | uint64(i8RoundingAverage(uint8(>>16), uint8(>>16)))<<16 |
					uint64(i8RoundingAverage(uint8(>>40), uint8(>>40)))<<40 | uint64(i8RoundingAverage(uint8(>>32), uint8(>>32)))<<32 |
					uint64(i8RoundingAverage(uint8(>>56), uint8(>>56)))<<56 | uint64(i8RoundingAverage(uint8(>>48), uint8(>>48)))<<48
			case shapeI16x8:
				 = uint64(i16RoundingAverage(uint16(), uint16())) |
					uint64(i16RoundingAverage(uint16(>>16), uint16(>>16)))<<16 |
					uint64(i16RoundingAverage(uint16(>>32), uint16(>>32)))<<32 |
					uint64(i16RoundingAverage(uint16(>>48), uint16(>>48)))<<48
				 = uint64(i16RoundingAverage(uint16(), uint16())) |
					uint64(i16RoundingAverage(uint16(>>16), uint16(>>16)))<<16 |
					uint64(i16RoundingAverage(uint16(>>32), uint16(>>32)))<<32 |
					uint64(i16RoundingAverage(uint16(>>48), uint16(>>48)))<<48
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Pmin:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			var ,  uint64
			if .B1 == shapeF32x4 {
				if flt32(math.Float32frombits(uint32()), math.Float32frombits(uint32())) {
					 =  & 0x00000000_ffffffff
				} else {
					 =  & 0x00000000_ffffffff
				}
				if flt32(math.Float32frombits(uint32(>>32)), math.Float32frombits(uint32(>>32))) {
					 |=  & 0xffffffff_00000000
				} else {
					 |=  & 0xffffffff_00000000
				}
				if flt32(math.Float32frombits(uint32()), math.Float32frombits(uint32())) {
					 =  & 0x00000000_ffffffff
				} else {
					 =  & 0x00000000_ffffffff
				}
				if flt32(math.Float32frombits(uint32(>>32)), math.Float32frombits(uint32(>>32))) {
					 |=  & 0xffffffff_00000000
				} else {
					 |=  & 0xffffffff_00000000
				}
			} else {
				if flt64(math.Float64frombits(), math.Float64frombits()) {
					 = 
				} else {
					 = 
				}
				if flt64(math.Float64frombits(), math.Float64frombits()) {
					 = 
				} else {
					 = 
				}
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Pmax:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			var ,  uint64
			if .B1 == shapeF32x4 {
				if flt32(math.Float32frombits(uint32()), math.Float32frombits(uint32())) {
					 =  & 0x00000000_ffffffff
				} else {
					 =  & 0x00000000_ffffffff
				}
				if flt32(math.Float32frombits(uint32(>>32)), math.Float32frombits(uint32(>>32))) {
					 |=  & 0xffffffff_00000000
				} else {
					 |=  & 0xffffffff_00000000
				}
				if flt32(math.Float32frombits(uint32()), math.Float32frombits(uint32())) {
					 =  & 0x00000000_ffffffff
				} else {
					 =  & 0x00000000_ffffffff
				}
				if flt32(math.Float32frombits(uint32(>>32)), math.Float32frombits(uint32(>>32))) {
					 |=  & 0xffffffff_00000000
				} else {
					 |=  & 0xffffffff_00000000
				}
			} else {
				if flt64(math.Float64frombits(), math.Float64frombits()) {
					 = 
				} else {
					 = 
				}
				if flt64(math.Float64frombits(), math.Float64frombits()) {
					 = 
				} else {
					 = 
				}
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Ceil:
			,  := .popValue(), .popValue()
			if .B1 == shapeF32x4 {
				 = uint64(math.Float32bits(moremath.WasmCompatCeilF32(math.Float32frombits(uint32())))) |
					(uint64(math.Float32bits(moremath.WasmCompatCeilF32(math.Float32frombits(uint32(>>32))))) << 32)
				 = uint64(math.Float32bits(moremath.WasmCompatCeilF32(math.Float32frombits(uint32())))) |
					(uint64(math.Float32bits(moremath.WasmCompatCeilF32(math.Float32frombits(uint32(>>32))))) << 32)
			} else {
				 = math.Float64bits(moremath.WasmCompatCeilF64(math.Float64frombits()))
				 = math.Float64bits(moremath.WasmCompatCeilF64(math.Float64frombits()))
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Floor:
			,  := .popValue(), .popValue()
			if .B1 == shapeF32x4 {
				 = uint64(math.Float32bits(moremath.WasmCompatFloorF32(math.Float32frombits(uint32())))) |
					(uint64(math.Float32bits(moremath.WasmCompatFloorF32(math.Float32frombits(uint32(>>32))))) << 32)
				 = uint64(math.Float32bits(moremath.WasmCompatFloorF32(math.Float32frombits(uint32())))) |
					(uint64(math.Float32bits(moremath.WasmCompatFloorF32(math.Float32frombits(uint32(>>32))))) << 32)
			} else {
				 = math.Float64bits(moremath.WasmCompatFloorF64(math.Float64frombits()))
				 = math.Float64bits(moremath.WasmCompatFloorF64(math.Float64frombits()))
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Trunc:
			,  := .popValue(), .popValue()
			if .B1 == shapeF32x4 {
				 = uint64(math.Float32bits(moremath.WasmCompatTruncF32(math.Float32frombits(uint32())))) |
					(uint64(math.Float32bits(moremath.WasmCompatTruncF32(math.Float32frombits(uint32(>>32))))) << 32)
				 = uint64(math.Float32bits(moremath.WasmCompatTruncF32(math.Float32frombits(uint32())))) |
					(uint64(math.Float32bits(moremath.WasmCompatTruncF32(math.Float32frombits(uint32(>>32))))) << 32)
			} else {
				 = math.Float64bits(moremath.WasmCompatTruncF64(math.Float64frombits()))
				 = math.Float64bits(moremath.WasmCompatTruncF64(math.Float64frombits()))
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Nearest:
			,  := .popValue(), .popValue()
			if .B1 == shapeF32x4 {
				 = uint64(math.Float32bits(moremath.WasmCompatNearestF32(math.Float32frombits(uint32())))) |
					(uint64(math.Float32bits(moremath.WasmCompatNearestF32(math.Float32frombits(uint32(>>32))))) << 32)
				 = uint64(math.Float32bits(moremath.WasmCompatNearestF32(math.Float32frombits(uint32())))) |
					(uint64(math.Float32bits(moremath.WasmCompatNearestF32(math.Float32frombits(uint32(>>32))))) << 32)
			} else {
				 = math.Float64bits(moremath.WasmCompatNearestF64(math.Float64frombits()))
				 = math.Float64bits(moremath.WasmCompatNearestF64(math.Float64frombits()))
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Extend:
			,  := .popValue(), .popValue()
			var  uint64
			if .B3 { // use lower 64 bits
				 = 
			} else {
				 = 
			}

			 := .B2 == 1

			var ,  uint64
			switch .B1 {
			case shapeI8x16:
				for  := 0;  < 8; ++ {
					 := byte( >> ( * 8))

					var  uint16
					if  {
						 = uint16(int8())
					} else {
						 = uint16()
					}

					if  < 4 {
						 |= uint64() << ( * 16)
					} else {
						 |= uint64() << (( - 4) * 16)
					}
				}
			case shapeI16x8:
				for  := 0;  < 4; ++ {
					 := uint16( >> ( * 16))

					var  uint32
					if  {
						 = uint32(int16())
					} else {
						 = uint32()
					}

					if  < 2 {
						 |= uint64() << ( * 32)
					} else {
						 |= uint64() << (( - 2) * 32)
					}
				}
			case shapeI32x4:
				 := uint32()
				 := uint32( >> 32)
				if  {
					 = uint64(int32())
					 = uint64(int32())
				} else {
					 = uint64()
					 = uint64()
				}
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128ExtMul:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			var ,  uint64
			if .B3 { // use lower 64 bits
				,  = , 
			} else {
				,  = , 
			}

			 := .B2 == 1

			var ,  uint64
			switch .B1 {
			case shapeI8x16:
				for  := 0;  < 8; ++ {
					,  := byte(>>(*8)), byte(>>(*8))

					var  uint16
					if  {
						 = uint16(int16(int8()) * int16(int8()))
					} else {
						 = uint16() * uint16()
					}

					if  < 4 {
						 |= uint64() << ( * 16)
					} else {
						 |= uint64() << (( - 4) * 16)
					}
				}
			case shapeI16x8:
				for  := 0;  < 4; ++ {
					,  := uint16(>>(*16)), uint16(>>(*16))

					var  uint32
					if  {
						 = uint32(int32(int16()) * int32(int16()))
					} else {
						 = uint32() * uint32()
					}

					if  < 2 {
						 |= uint64() << ( * 32)
					} else {
						 |= uint64() << (( - 2) * 32)
					}
				}
			case shapeI32x4:
				,  := uint32(), uint32()
				,  := uint32(>>32), uint32(>>32)
				if  {
					 = uint64(int64(int32()) * int64(int32()))
					 = uint64(int64(int32()) * int64(int32()))
				} else {
					 = uint64() * uint64()
					 = uint64() * uint64()
				}
			}

			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Q15mulrSatS:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			var ,  uint64
			for  := 0;  < 8; ++ {
				var ,  int16
				if  < 4 {
					,  = int16(uint16(>>(*16))), int16(uint16(>>(*16)))
				} else {
					,  = int16(uint16(>>((-4)*16))), int16(uint16(>>((-4)*16)))
				}

				var  uint64
				// https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/simd/SIMD.md#saturating-integer-q-format-rounding-multiplication
				if  := ((int32() * int32()) + 0x4000) >> 15;  < math.MinInt16 {
					 = uint64(uint16(0x8000))
				} else if  > math.MaxInt16 {
					 = uint64(uint16(0x7fff))
				} else {
					 = uint64(uint16(int16()))
				}

				if  < 4 {
					 |=  << ( * 16)
				} else {
					 |=  << (( - 4) * 16)
				}
			}

			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128ExtAddPairwise:
			,  := .popValue(), .popValue()

			 := .B3

			var ,  uint64
			switch .B1 {
			case shapeI8x16:
				for  := 0;  < 8; ++ {
					var ,  byte
					if  < 4 {
						,  = byte(>>((*2)*8)), byte(>>((*2+1)*8))
					} else {
						,  = byte(>>(((-4)*2)*8)), byte(>>(((-4)*2+1)*8))
					}

					var  uint16
					if  {
						 = uint16(int16(int8()) + int16(int8()))
					} else {
						 = uint16() + uint16()
					}

					if  < 4 {
						 |= uint64() << ( * 16)
					} else {
						 |= uint64() << (( - 4) * 16)
					}
				}
			case shapeI16x8:
				for  := 0;  < 4; ++ {
					var ,  uint16
					if  < 2 {
						,  = uint16(>>((*2)*16)), uint16(>>((*2+1)*16))
					} else {
						,  = uint16(>>(((-2)*2)*16)), uint16(>>(((-2)*2+1)*16))
					}

					var  uint32
					if  {
						 = uint32(int32(int16()) + int32(int16()))
					} else {
						 = uint32() + uint32()
					}

					if  < 2 {
						 |= uint64() << ( * 32)
					} else {
						 |= uint64() << (( - 2) * 32)
					}
				}
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128FloatPromote:
			,  := .popValue(), .popValue()
			.pushValue(math.Float64bits(float64(math.Float32frombits(uint32()))))
			.pushValue(math.Float64bits(float64(math.Float32frombits(uint32( >> 32)))))
			.pc++
		case operationKindV128FloatDemote:
			,  := .popValue(), .popValue()
			.pushValue(
				uint64(math.Float32bits(float32(math.Float64frombits()))) |
					(uint64(math.Float32bits(float32(math.Float64frombits()))) << 32),
			)
			.pushValue(0)
			.pc++
		case operationKindV128FConvertFromI:
			,  := .popValue(), .popValue()
			, , ,  := uint32(), uint32(>>32), uint32(), uint32(>>32)
			 := .B3

			var ,  uint64
			switch .B1 { // Destination shape.
			case shapeF32x4: // f32x4 from signed/unsigned i32x4
				if  {
					 = uint64(math.Float32bits(float32(int32()))) |
						(uint64(math.Float32bits(float32(int32()))) << 32)
					 = uint64(math.Float32bits(float32(int32()))) |
						(uint64(math.Float32bits(float32(int32()))) << 32)
				} else {
					 = uint64(math.Float32bits(float32())) |
						(uint64(math.Float32bits(float32())) << 32)
					 = uint64(math.Float32bits(float32())) |
						(uint64(math.Float32bits(float32())) << 32)
				}
			case shapeF64x2: // f64x2 from signed/unsigned i32x4
				if  {
					,  = math.Float64bits(float64(int32())), math.Float64bits(float64(int32()))
				} else {
					,  = math.Float64bits(float64()), math.Float64bits(float64())
				}
			}

			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Narrow:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			 := .B3

			var ,  uint64
			switch .B1 {
			case shapeI16x8: // signed/unsigned i16x8 to i8x16
				for  := 0;  < 8; ++ {
					var  uint16
					if  < 4 {
						 = uint16( >> ( * 16))
					} else {
						 = uint16( >> (( - 4) * 16))
					}

					var  byte
					if  {
						if  := int16();  > math.MaxInt8 {
							 = math.MaxInt8
						} else if  < math.MinInt8 {
							 = math.MinInt8
							 = byte()
						} else {
							 = byte()
						}
					} else {
						if  := int16();  > math.MaxUint8 {
							 = math.MaxUint8
						} else if  < 0 {
							 = 0
						} else {
							 = byte()
						}
					}
					 |= uint64() << ( * 8)
				}
				for  := 0;  < 8; ++ {
					var  uint16
					if  < 4 {
						 = uint16( >> ( * 16))
					} else {
						 = uint16( >> (( - 4) * 16))
					}

					var  byte
					if  {
						if  := int16();  > math.MaxInt8 {
							 = math.MaxInt8
						} else if  < math.MinInt8 {
							 = math.MinInt8
							 = byte()
						} else {
							 = byte()
						}
					} else {
						if  := int16();  > math.MaxUint8 {
							 = math.MaxUint8
						} else if  < 0 {
							 = 0
						} else {
							 = byte()
						}
					}
					 |= uint64() << ( * 8)
				}
			case shapeI32x4: // signed/unsigned i32x4 to i16x8
				for  := 0;  < 4; ++ {
					var  uint32
					if  < 2 {
						 = uint32( >> ( * 32))
					} else {
						 = uint32( >> (( - 2) * 32))
					}

					var  uint16
					if  {
						if  := int32();  > math.MaxInt16 {
							 = math.MaxInt16
						} else if  < math.MinInt16 {
							 = math.MinInt16
							 = uint16()
						} else {
							 = uint16()
						}
					} else {
						if  := int32();  > math.MaxUint16 {
							 = math.MaxUint16
						} else if  < 0 {
							 = 0
						} else {
							 = uint16()
						}
					}
					 |= uint64() << ( * 16)
				}

				for  := 0;  < 4; ++ {
					var  uint32
					if  < 2 {
						 = uint32( >> ( * 32))
					} else {
						 = uint32( >> (( - 2) * 32))
					}

					var  uint16
					if  {
						if  := int32();  > math.MaxInt16 {
							 = math.MaxInt16
						} else if  < math.MinInt16 {
							 = math.MinInt16
							 = uint16()
						} else {
							 = uint16()
						}
					} else {
						if  := int32();  > math.MaxUint16 {
							 = math.MaxUint16
						} else if  < 0 {
							 = 0
						} else {
							 = uint16()
						}
					}
					 |= uint64() << ( * 16)
				}
			}
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128Dot:
			,  := .popValue(), .popValue()
			,  := .popValue(), .popValue()
			,  := v128Dot(, , , )
			.pushValue()
			.pushValue()
			.pc++
		case operationKindV128ITruncSatFromF:
			,  := .popValue(), .popValue()
			 := .B3
			var ,  uint64

			switch .B1 {
			case shapeF32x4: // f32x4 to i32x4
				for ,  := range [4]float64{
					math.Trunc(float64(math.Float32frombits(uint32()))),
					math.Trunc(float64(math.Float32frombits(uint32( >> 32)))),
					math.Trunc(float64(math.Float32frombits(uint32()))),
					math.Trunc(float64(math.Float32frombits(uint32( >> 32)))),
				} {

					var  uint32
					if math.IsNaN() {
						 = 0
					} else if  {
						if  < math.MinInt32 {
							 = math.MinInt32
						} else if  > math.MaxInt32 {
							 = math.MaxInt32
						}
						 = uint32(int32())
					} else {
						if  < 0 {
							 = 0
						} else if  > math.MaxUint32 {
							 = math.MaxUint32
						}
						 = uint32()
					}

					if  < 2 {
						 |= uint64() << ( * 32)
					} else {
						 |= uint64() << (( - 2) * 32)
					}
				}

			case shapeF64x2: // f64x2 to i32x4
				for ,  := range [2]float64{
					math.Trunc(math.Float64frombits()),
					math.Trunc(math.Float64frombits()),
				} {
					var  uint32
					if math.IsNaN() {
						 = 0
					} else if  {
						if  < math.MinInt32 {
							 = math.MinInt32
						} else if  > math.MaxInt32 {
							 = math.MaxInt32
						}
						 = uint32(int32())
					} else {
						if  < 0 {
							 = 0
						} else if  > math.MaxUint32 {
							 = math.MaxUint32
						}
						 = uint32()
					}

					 |= uint64() << ( * 32)
				}
			}

			.pushValue()
			.pushValue()
			.pc++
		case operationKindAtomicMemoryWait:
			 := int64(.popValue())
			 := .popValue()
			 := .popMemoryOffset()
			// Runtime instead of validation error because the spec intends to allow binaries to include
			// such instructions as long as they are not executed.
			if !.Shared {
				panic(wasmruntime.ErrRuntimeExpectedSharedMemory)
			}

			switch unsignedType(.B1) {
			case unsignedTypeI32:
				if %4 != 0 {
					panic(wasmruntime.ErrRuntimeUnalignedAtomic)
				}
				if int() > len(.Buffer)-4 {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue(.Wait32(, uint32(), , func( *wasm.MemoryInstance,  uint32) uint32 {
					.Mux.Lock()
					defer .Mux.Unlock()
					,  := .ReadUint32Le()
					return 
				}))
			case unsignedTypeI64:
				if %8 != 0 {
					panic(wasmruntime.ErrRuntimeUnalignedAtomic)
				}
				if int() > len(.Buffer)-8 {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue(.Wait64(, , , func( *wasm.MemoryInstance,  uint32) uint64 {
					.Mux.Lock()
					defer .Mux.Unlock()
					,  := .ReadUint64Le()
					return 
				}))
			}
			.pc++
		case operationKindAtomicMemoryNotify:
			 := .popValue()
			 := .popMemoryOffset()
			if %4 != 0 {
				panic(wasmruntime.ErrRuntimeUnalignedAtomic)
			}
			// Just a bounds check
			if  >= .Size() {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			 := .Notify(, uint32())
			.pushValue(uint64())
			.pc++
		case operationKindAtomicFence:
			// Memory not required for fence only
			if  != nil {
				// An empty critical section can be used as a synchronization primitive, which is what
				// fence is. Probably, there are no spectests or defined behavior to confirm this yet.
				.Mux.Lock()
				.Mux.Unlock() //nolint:staticcheck
			}
			.pc++
		case operationKindAtomicLoad:
			 := .popMemoryOffset()
			switch unsignedType(.B1) {
			case unsignedTypeI32:
				if %4 != 0 {
					panic(wasmruntime.ErrRuntimeUnalignedAtomic)
				}
				.Mux.Lock()
				,  := .ReadUint32Le()
				.Mux.Unlock()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue(uint64())
			case unsignedTypeI64:
				if %8 != 0 {
					panic(wasmruntime.ErrRuntimeUnalignedAtomic)
				}
				.Mux.Lock()
				,  := .ReadUint64Le()
				.Mux.Unlock()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				.pushValue()
			}
			.pc++
		case operationKindAtomicLoad8:
			 := .popMemoryOffset()
			.Mux.Lock()
			,  := .ReadByte()
			.Mux.Unlock()
			if ! {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			.pushValue(uint64())
			.pc++
		case operationKindAtomicLoad16:
			 := .popMemoryOffset()
			if %2 != 0 {
				panic(wasmruntime.ErrRuntimeUnalignedAtomic)
			}
			.Mux.Lock()
			,  := .ReadUint16Le()
			.Mux.Unlock()
			if ! {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			.pushValue(uint64())
			.pc++
		case operationKindAtomicStore:
			 := .popValue()
			 := .popMemoryOffset()
			switch unsignedType(.B1) {
			case unsignedTypeI32:
				if %4 != 0 {
					panic(wasmruntime.ErrRuntimeUnalignedAtomic)
				}
				.Mux.Lock()
				 := .WriteUint32Le(, uint32())
				.Mux.Unlock()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
			case unsignedTypeI64:
				if %8 != 0 {
					panic(wasmruntime.ErrRuntimeUnalignedAtomic)
				}
				.Mux.Lock()
				 := .WriteUint64Le(, )
				.Mux.Unlock()
				if ! {
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
			}
			.pc++
		case operationKindAtomicStore8:
			 := byte(.popValue())
			 := .popMemoryOffset()
			.Mux.Lock()
			 := .WriteByte(, )
			.Mux.Unlock()
			if ! {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			.pc++
		case operationKindAtomicStore16:
			 := uint16(.popValue())
			 := .popMemoryOffset()
			if %2 != 0 {
				panic(wasmruntime.ErrRuntimeUnalignedAtomic)
			}
			.Mux.Lock()
			 := .WriteUint16Le(, )
			.Mux.Unlock()
			if ! {
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			.pc++
		case operationKindAtomicRMW:
			 := .popValue()
			 := .popMemoryOffset()
			switch unsignedType(.B1) {
			case unsignedTypeI32:
				if %4 != 0 {
					panic(wasmruntime.ErrRuntimeUnalignedAtomic)
				}
				.Mux.Lock()
				,  := .ReadUint32Le()
				if ! {
					.Mux.Unlock()
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				var  uint32
				switch atomicArithmeticOp(.B2) {
				case atomicArithmeticOpAdd:
					 =  + uint32()
				case atomicArithmeticOpSub:
					 =  - uint32()
				case atomicArithmeticOpAnd:
					 =  & uint32()
				case atomicArithmeticOpOr:
					 =  | uint32()
				case atomicArithmeticOpXor:
					 =  ^ uint32()
				case atomicArithmeticOpNop:
					 = uint32()
				}
				.WriteUint32Le(, )
				.Mux.Unlock()
				.pushValue(uint64())
			case unsignedTypeI64:
				if %8 != 0 {
					panic(wasmruntime.ErrRuntimeUnalignedAtomic)
				}
				.Mux.Lock()
				,  := .ReadUint64Le()
				if ! {
					.Mux.Unlock()
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				var  uint64
				switch atomicArithmeticOp(.B2) {
				case atomicArithmeticOpAdd:
					 =  + 
				case atomicArithmeticOpSub:
					 =  - 
				case atomicArithmeticOpAnd:
					 =  & 
				case atomicArithmeticOpOr:
					 =  | 
				case atomicArithmeticOpXor:
					 =  ^ 
				case atomicArithmeticOpNop:
					 = 
				}
				.WriteUint64Le(, )
				.Mux.Unlock()
				.pushValue()
			}
			.pc++
		case operationKindAtomicRMW8:
			 := .popValue()
			 := .popMemoryOffset()
			.Mux.Lock()
			,  := .ReadByte()
			if ! {
				.Mux.Unlock()
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			 := byte()
			var  byte
			switch atomicArithmeticOp(.B2) {
			case atomicArithmeticOpAdd:
				 =  + 
			case atomicArithmeticOpSub:
				 =  - 
			case atomicArithmeticOpAnd:
				 =  & 
			case atomicArithmeticOpOr:
				 =  | 
			case atomicArithmeticOpXor:
				 =  ^ 
			case atomicArithmeticOpNop:
				 = 
			}
			.WriteByte(, )
			.Mux.Unlock()
			.pushValue(uint64())
			.pc++
		case operationKindAtomicRMW16:
			 := .popValue()
			 := .popMemoryOffset()
			if %2 != 0 {
				panic(wasmruntime.ErrRuntimeUnalignedAtomic)
			}
			.Mux.Lock()
			,  := .ReadUint16Le()
			if ! {
				.Mux.Unlock()
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			 := uint16()
			var  uint16
			switch atomicArithmeticOp(.B2) {
			case atomicArithmeticOpAdd:
				 =  + 
			case atomicArithmeticOpSub:
				 =  - 
			case atomicArithmeticOpAnd:
				 =  & 
			case atomicArithmeticOpOr:
				 =  | 
			case atomicArithmeticOpXor:
				 =  ^ 
			case atomicArithmeticOpNop:
				 = 
			}
			.WriteUint16Le(, )
			.Mux.Unlock()
			.pushValue(uint64())
			.pc++
		case operationKindAtomicRMWCmpxchg:
			 := .popValue()
			 := .popValue()
			 := .popMemoryOffset()
			switch unsignedType(.B1) {
			case unsignedTypeI32:
				if %4 != 0 {
					panic(wasmruntime.ErrRuntimeUnalignedAtomic)
				}
				.Mux.Lock()
				,  := .ReadUint32Le()
				if ! {
					.Mux.Unlock()
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				if  == uint32() {
					.WriteUint32Le(, uint32())
				}
				.Mux.Unlock()
				.pushValue(uint64())
			case unsignedTypeI64:
				if %8 != 0 {
					panic(wasmruntime.ErrRuntimeUnalignedAtomic)
				}
				.Mux.Lock()
				,  := .ReadUint64Le()
				if ! {
					.Mux.Unlock()
					panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
				}
				if  ==  {
					.WriteUint64Le(, )
				}
				.Mux.Unlock()
				.pushValue()
			}
			.pc++
		case operationKindAtomicRMW8Cmpxchg:
			 := byte(.popValue())
			 := byte(.popValue())
			 := .popMemoryOffset()
			.Mux.Lock()
			,  := .ReadByte()
			if ! {
				.Mux.Unlock()
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			if  ==  {
				.WriteByte(, )
			}
			.Mux.Unlock()
			.pushValue(uint64())
			.pc++
		case operationKindAtomicRMW16Cmpxchg:
			 := uint16(.popValue())
			 := uint16(.popValue())
			 := .popMemoryOffset()
			if %2 != 0 {
				panic(wasmruntime.ErrRuntimeUnalignedAtomic)
			}
			.Mux.Lock()
			,  := .ReadUint16Le()
			if ! {
				.Mux.Unlock()
				panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
			}
			if  ==  {
				.WriteUint16Le(, )
			}
			.Mux.Unlock()
			.pushValue(uint64())
			.pc++
		case operationKindTailCallReturnCall:
			 := &[.U1]
			.dropForTailCall(, )
			,  = .resetPc(, )

		case operationKindTailCallReturnCallIndirect:
			 := .popValue()
			 := [.U2]
			 := .functionForOffset(, , [.U1])

			// We are allowing proper tail calls only across functions that belong to the same
			// module; for indirect calls, we have to enforce it at run-time.
			// For details, see internal/engine/RATIONALE.md
			if .moduleInstance != .moduleInstance {
				// Revert to a normal call.
				.callFunction(, .moduleInstance, )
				// Return
				.drop(.Us[0])
				// Jump to the function frame (return)
				.pc = .Us[1]
				continue
			}

			.dropForTailCall(, )
			,  = .resetPc(, )

		default:
			.pc++
		}
	}
	.popFrame()
}

func ( *callEngine) ( *callFrame,  *function) {
	 := .base - .f.funcType.ParamNumInUint64
	 := .funcType.ParamNumInUint64
	.stack = append(.stack[:], .stack[len(.stack)-:]...)
}

func ( *callEngine) ( *callFrame,  *function) ( []unionOperation,  uint64) {
	// The compiler is currently allowing proper tail call only across functions
	// that belong to the same module; thus, we can overwrite the frame in-place.
	// For details, see internal/engine/RATIONALE.md
	.f = 
	.base = len(.stack)
	.pc = 0
	 = .f.parent.body
	 = uint64(len())
	return , 
}

func ( *callEngine) ( *wasm.TableInstance,  uint64,  wasm.FunctionTypeID) *function {
	if  >= uint64(len(.References)) {
		panic(wasmruntime.ErrRuntimeInvalidTableAccess)
	}
	 := .References[]
	if  == 0 {
		panic(wasmruntime.ErrRuntimeInvalidTableAccess)
	}

	 := functionFromUintptr()
	if .typeID !=  {
		panic(wasmruntime.ErrRuntimeIndirectCallTypeMismatch)
	}
	return 
}

func wasmCompatMax32bits(,  uint32) uint64 {
	return uint64(math.Float32bits(moremath.WasmCompatMax32(
		math.Float32frombits(),
		math.Float32frombits(),
	)))
}

func wasmCompatMin32bits(,  uint32) uint64 {
	return uint64(math.Float32bits(moremath.WasmCompatMin32(
		math.Float32frombits(),
		math.Float32frombits(),
	)))
}

func addFloat32bits(,  uint32) uint64 {
	return uint64(math.Float32bits(math.Float32frombits() + math.Float32frombits()))
}

func subFloat32bits(,  uint32) uint64 {
	return uint64(math.Float32bits(math.Float32frombits() - math.Float32frombits()))
}

func mulFloat32bits(,  uint32) uint64 {
	return uint64(math.Float32bits(math.Float32frombits() * math.Float32frombits()))
}

func divFloat32bits(,  uint32) uint64 {
	return uint64(math.Float32bits(math.Float32frombits() / math.Float32frombits()))
}

// https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/exec/numerics.html#xref-exec-numerics-op-flt-mathrm-flt-n-z-1-z-2
func flt32(,  float32) bool {
	if  !=  ||  !=  {
		return false
	} else if  ==  {
		return false
	} else if math.IsInf(float64(), 1) {
		return false
	} else if math.IsInf(float64(), -1) {
		return true
	} else if math.IsInf(float64(), 1) {
		return true
	} else if math.IsInf(float64(), -1) {
		return false
	}
	return  < 
}

// https://www.w3.org/TR/2022/WD-wasm-core-2-20220419/exec/numerics.html#xref-exec-numerics-op-flt-mathrm-flt-n-z-1-z-2
func flt64(,  float64) bool {
	if  !=  ||  !=  {
		return false
	} else if  ==  {
		return false
	} else if math.IsInf(, 1) {
		return false
	} else if math.IsInf(, -1) {
		return true
	} else if math.IsInf(, 1) {
		return true
	} else if math.IsInf(, -1) {
		return false
	}
	return  < 
}

func i8RoundingAverage(,  byte) byte {
	// https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/simd/SIMD.md#lane-wise-integer-rounding-average
	return byte((uint16() + uint16() + uint16(1)) / 2)
}

func i16RoundingAverage(,  uint16) uint16 {
	// https://github.com/WebAssembly/spec/blob/wg-2.0.draft1/proposals/simd/SIMD.md#lane-wise-integer-rounding-average
	return uint16((uint32() + uint32() + 1) / 2)
}

func i8Abs( byte) byte {
	if  := int8();  < 0 {
		return byte(-)
	} else {
		return byte()
	}
}

func i8MaxU(,  byte) byte {
	if  <  {
		return 
	} else {
		return 
	}
}

func i8MinU(,  byte) byte {
	if  >  {
		return 
	} else {
		return 
	}
}

func i8MaxS(,  byte) byte {
	if int8() < int8() {
		return 
	} else {
		return 
	}
}

func i8MinS(,  byte) byte {
	if int8() > int8() {
		return 
	} else {
		return 
	}
}

func i16MaxU(,  uint16) uint16 {
	if  <  {
		return 
	} else {
		return 
	}
}

func i16MinU(,  uint16) uint16 {
	if  >  {
		return 
	} else {
		return 
	}
}

func i16MaxS(,  uint16) uint16 {
	if int16() < int16() {
		return 
	} else {
		return 
	}
}

func i16MinS(,  uint16) uint16 {
	if int16() > int16() {
		return 
	} else {
		return 
	}
}

func i32MaxU(,  uint32) uint32 {
	if  <  {
		return 
	} else {
		return 
	}
}

func i32MinU(,  uint32) uint32 {
	if  >  {
		return 
	} else {
		return 
	}
}

func i32MaxS(,  uint32) uint32 {
	if int32() < int32() {
		return 
	} else {
		return 
	}
}

func i32MinS(,  uint32) uint32 {
	if int32() > int32() {
		return 
	} else {
		return 
	}
}

func i16Abs( uint16) uint16 {
	if  := int16();  < 0 {
		return uint16(-)
	} else {
		return uint16()
	}
}

func i32Abs( uint32) uint32 {
	if  := int32();  < 0 {
		return uint32(-)
	} else {
		return uint32()
	}
}

func ( *callEngine) ( context.Context,  *wasm.ModuleInstance,  *function,  experimental.FunctionListener) context.Context {
	,  := .definition(), .funcType

	.stackIterator.reset(.stack, .frames, )
	.Before(, , , .peekValues(.ParamNumInUint64), &.stackIterator)
	.stackIterator.clear()
	.callNativeFunc(, , )
	.After(, , , .peekValues(.ResultNumInUint64))
	return 
}

// popMemoryOffset takes a memory offset off the stack for use in load and store instructions.
// As the top of stack value is 64-bit, this ensures it is in range before returning it.
func ( *callEngine) ( *unionOperation) uint32 {
	 := .U2 + .popValue()
	if  > math.MaxUint32 {
		panic(wasmruntime.ErrRuntimeOutOfBoundsMemoryAccess)
	}
	return uint32()
}

func ( *callEngine) ( context.Context,  *wasm.ModuleInstance,  *function) {
	 := .funcType
	 := .ParamNumInUint64
	 := .ResultNumInUint64
	 := 

	// In the interpreter engine, ce.stack may only have capacity to store
	// parameters. Grow when there are more results than parameters.
	if  :=  - ;  > 0 {
		.stack = append(.stack, make([]uint64, )...)
		 += 
	}

	// Pass the stack elements to the go function.
	 := .stack[len(.stack)-:]
	.callGoFunc(, , , )

	// Shrink the stack when there were more parameters than results.
	if  :=  - ;  > 0 {
		.stack = .stack[0 : len(.stack)-]
	}
}

// v128Dot performs a dot product of two 64-bit vectors.
// Note: for some reason (which I suspect is due to a bug in Go compiler's regalloc),
// inlining this function causes a bug which happens **only when** we run with -race AND arm64 AND Go 1.22.
func v128Dot(, , ,  uint64) (uint64, uint64) {
	 := int32(int16(>>0)) * int32(int16(>>0))
	 := int32(int16(>>16)) * int32(int16(>>16))
	 := int32(int16(>>32)) * int32(int16(>>32))
	 := int32(int16(>>48)) * int32(int16(>>48))
	 := int32(int16(>>0)) * int32(int16(>>0))
	 := int32(int16(>>16)) * int32(int16(>>16))
	 := int32(int16(>>32)) * int32(int16(>>32))
	 := int32(int16(>>48)) * int32(int16(>>48))
	return uint64(uint32(+)) | (uint64(uint32(+)) << 32), uint64(uint32(+)) | (uint64(uint32(+)) << 32)
}