github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/engine/interpreter/operations.go (about)

     1  package interpreter
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"strings"
     7  )
     8  
     9  // unsignedInt represents unsigned 32-bit or 64-bit integers.
    10  type unsignedInt byte
    11  
    12  const (
    13  	unsignedInt32 unsignedInt = iota
    14  	unsignedInt64
    15  )
    16  
    17  // String implements fmt.Stringer.
    18  func (s unsignedInt) String() (ret string) {
    19  	switch s {
    20  	case unsignedInt32:
    21  		ret = "i32"
    22  	case unsignedInt64:
    23  		ret = "i64"
    24  	}
    25  	return
    26  }
    27  
    28  // signedInt represents signed or unsigned integers.
    29  type signedInt byte
    30  
    31  const (
    32  	signedInt32 signedInt = iota
    33  	signedInt64
    34  	signedUint32
    35  	signedUint64
    36  )
    37  
    38  // String implements fmt.Stringer.
    39  func (s signedInt) String() (ret string) {
    40  	switch s {
    41  	case signedUint32:
    42  		ret = "u32"
    43  	case signedUint64:
    44  		ret = "u64"
    45  	case signedInt32:
    46  		ret = "s32"
    47  	case signedInt64:
    48  		ret = "s64"
    49  	}
    50  	return
    51  }
    52  
    53  // float represents the scalar double or single precision floating points.
    54  type float byte
    55  
    56  const (
    57  	f32 float = iota
    58  	f64
    59  )
    60  
    61  // String implements fmt.Stringer.
    62  func (s float) String() (ret string) {
    63  	switch s {
    64  	case f32:
    65  		ret = "f32"
    66  	case f64:
    67  		ret = "f64"
    68  	}
    69  	return
    70  }
    71  
    72  // unsignedType is the union of unsignedInt, float and V128 vector type.
    73  type unsignedType byte
    74  
    75  const (
    76  	unsignedTypeI32 unsignedType = iota
    77  	unsignedTypeI64
    78  	unsignedTypeF32
    79  	unsignedTypeF64
    80  	unsignedTypeV128
    81  	unsignedTypeUnknown
    82  )
    83  
    84  // String implements fmt.Stringer.
    85  func (s unsignedType) String() (ret string) {
    86  	switch s {
    87  	case unsignedTypeI32:
    88  		ret = "i32"
    89  	case unsignedTypeI64:
    90  		ret = "i64"
    91  	case unsignedTypeF32:
    92  		ret = "f32"
    93  	case unsignedTypeF64:
    94  		ret = "f64"
    95  	case unsignedTypeV128:
    96  		ret = "v128"
    97  	case unsignedTypeUnknown:
    98  		ret = "unknown"
    99  	}
   100  	return
   101  }
   102  
   103  // signedType is the union of signedInt and float types.
   104  type signedType byte
   105  
   106  const (
   107  	signedTypeInt32 signedType = iota
   108  	signedTypeUint32
   109  	signedTypeInt64
   110  	signedTypeUint64
   111  	signedTypeFloat32
   112  	signedTypeFloat64
   113  )
   114  
   115  // String implements fmt.Stringer.
   116  func (s signedType) String() (ret string) {
   117  	switch s {
   118  	case signedTypeInt32:
   119  		ret = "s32"
   120  	case signedTypeUint32:
   121  		ret = "u32"
   122  	case signedTypeInt64:
   123  		ret = "s64"
   124  	case signedTypeUint64:
   125  		ret = "u64"
   126  	case signedTypeFloat32:
   127  		ret = "f32"
   128  	case signedTypeFloat64:
   129  		ret = "f64"
   130  	}
   131  	return
   132  }
   133  
   134  // operationKind is the Kind of each implementation of Operation interface.
   135  type operationKind uint16
   136  
   137  // String implements fmt.Stringer.
   138  func (o operationKind) String() (ret string) {
   139  	switch o {
   140  	case operationKindUnreachable:
   141  		ret = "Unreachable"
   142  	case operationKindLabel:
   143  		ret = "label"
   144  	case operationKindBr:
   145  		ret = "Br"
   146  	case operationKindBrIf:
   147  		ret = "BrIf"
   148  	case operationKindBrTable:
   149  		ret = "BrTable"
   150  	case operationKindCall:
   151  		ret = "Call"
   152  	case operationKindCallIndirect:
   153  		ret = "CallIndirect"
   154  	case operationKindDrop:
   155  		ret = "Drop"
   156  	case operationKindSelect:
   157  		ret = "Select"
   158  	case operationKindPick:
   159  		ret = "Pick"
   160  	case operationKindSet:
   161  		ret = "Swap"
   162  	case operationKindGlobalGet:
   163  		ret = "GlobalGet"
   164  	case operationKindGlobalSet:
   165  		ret = "GlobalSet"
   166  	case operationKindLoad:
   167  		ret = "Load"
   168  	case operationKindLoad8:
   169  		ret = "Load8"
   170  	case operationKindLoad16:
   171  		ret = "Load16"
   172  	case operationKindLoad32:
   173  		ret = "Load32"
   174  	case operationKindStore:
   175  		ret = "Store"
   176  	case operationKindStore8:
   177  		ret = "Store8"
   178  	case operationKindStore16:
   179  		ret = "Store16"
   180  	case operationKindStore32:
   181  		ret = "Store32"
   182  	case operationKindMemorySize:
   183  		ret = "MemorySize"
   184  	case operationKindMemoryGrow:
   185  		ret = "MemoryGrow"
   186  	case operationKindConstI32:
   187  		ret = "ConstI32"
   188  	case operationKindConstI64:
   189  		ret = "ConstI64"
   190  	case operationKindConstF32:
   191  		ret = "ConstF32"
   192  	case operationKindConstF64:
   193  		ret = "ConstF64"
   194  	case operationKindEq:
   195  		ret = "Eq"
   196  	case operationKindNe:
   197  		ret = "Ne"
   198  	case operationKindEqz:
   199  		ret = "Eqz"
   200  	case operationKindLt:
   201  		ret = "Lt"
   202  	case operationKindGt:
   203  		ret = "Gt"
   204  	case operationKindLe:
   205  		ret = "Le"
   206  	case operationKindGe:
   207  		ret = "Ge"
   208  	case operationKindAdd:
   209  		ret = "Add"
   210  	case operationKindSub:
   211  		ret = "Sub"
   212  	case operationKindMul:
   213  		ret = "Mul"
   214  	case operationKindClz:
   215  		ret = "Clz"
   216  	case operationKindCtz:
   217  		ret = "Ctz"
   218  	case operationKindPopcnt:
   219  		ret = "Popcnt"
   220  	case operationKindDiv:
   221  		ret = "Div"
   222  	case operationKindRem:
   223  		ret = "Rem"
   224  	case operationKindAnd:
   225  		ret = "And"
   226  	case operationKindOr:
   227  		ret = "Or"
   228  	case operationKindXor:
   229  		ret = "Xor"
   230  	case operationKindShl:
   231  		ret = "Shl"
   232  	case operationKindShr:
   233  		ret = "Shr"
   234  	case operationKindRotl:
   235  		ret = "Rotl"
   236  	case operationKindRotr:
   237  		ret = "Rotr"
   238  	case operationKindAbs:
   239  		ret = "Abs"
   240  	case operationKindNeg:
   241  		ret = "Neg"
   242  	case operationKindCeil:
   243  		ret = "Ceil"
   244  	case operationKindFloor:
   245  		ret = "Floor"
   246  	case operationKindTrunc:
   247  		ret = "Trunc"
   248  	case operationKindNearest:
   249  		ret = "Nearest"
   250  	case operationKindSqrt:
   251  		ret = "Sqrt"
   252  	case operationKindMin:
   253  		ret = "Min"
   254  	case operationKindMax:
   255  		ret = "Max"
   256  	case operationKindCopysign:
   257  		ret = "Copysign"
   258  	case operationKindI32WrapFromI64:
   259  		ret = "I32WrapFromI64"
   260  	case operationKindITruncFromF:
   261  		ret = "ITruncFromF"
   262  	case operationKindFConvertFromI:
   263  		ret = "FConvertFromI"
   264  	case operationKindF32DemoteFromF64:
   265  		ret = "F32DemoteFromF64"
   266  	case operationKindF64PromoteFromF32:
   267  		ret = "F64PromoteFromF32"
   268  	case operationKindI32ReinterpretFromF32:
   269  		ret = "I32ReinterpretFromF32"
   270  	case operationKindI64ReinterpretFromF64:
   271  		ret = "I64ReinterpretFromF64"
   272  	case operationKindF32ReinterpretFromI32:
   273  		ret = "F32ReinterpretFromI32"
   274  	case operationKindF64ReinterpretFromI64:
   275  		ret = "F64ReinterpretFromI64"
   276  	case operationKindExtend:
   277  		ret = "Extend"
   278  	case operationKindMemoryInit:
   279  		ret = "MemoryInit"
   280  	case operationKindDataDrop:
   281  		ret = "DataDrop"
   282  	case operationKindMemoryCopy:
   283  		ret = "MemoryCopy"
   284  	case operationKindMemoryFill:
   285  		ret = "MemoryFill"
   286  	case operationKindTableInit:
   287  		ret = "TableInit"
   288  	case operationKindElemDrop:
   289  		ret = "ElemDrop"
   290  	case operationKindTableCopy:
   291  		ret = "TableCopy"
   292  	case operationKindRefFunc:
   293  		ret = "RefFunc"
   294  	case operationKindTableGet:
   295  		ret = "TableGet"
   296  	case operationKindTableSet:
   297  		ret = "TableSet"
   298  	case operationKindTableSize:
   299  		ret = "TableSize"
   300  	case operationKindTableGrow:
   301  		ret = "TableGrow"
   302  	case operationKindTableFill:
   303  		ret = "TableFill"
   304  	case operationKindV128Const:
   305  		ret = "ConstV128"
   306  	case operationKindV128Add:
   307  		ret = "V128Add"
   308  	case operationKindV128Sub:
   309  		ret = "V128Sub"
   310  	case operationKindV128Load:
   311  		ret = "V128Load"
   312  	case operationKindV128LoadLane:
   313  		ret = "V128LoadLane"
   314  	case operationKindV128Store:
   315  		ret = "V128Store"
   316  	case operationKindV128StoreLane:
   317  		ret = "V128StoreLane"
   318  	case operationKindV128ExtractLane:
   319  		ret = "V128ExtractLane"
   320  	case operationKindV128ReplaceLane:
   321  		ret = "V128ReplaceLane"
   322  	case operationKindV128Splat:
   323  		ret = "V128Splat"
   324  	case operationKindV128Shuffle:
   325  		ret = "V128Shuffle"
   326  	case operationKindV128Swizzle:
   327  		ret = "V128Swizzle"
   328  	case operationKindV128AnyTrue:
   329  		ret = "V128AnyTrue"
   330  	case operationKindV128AllTrue:
   331  		ret = "V128AllTrue"
   332  	case operationKindV128And:
   333  		ret = "V128And"
   334  	case operationKindV128Not:
   335  		ret = "V128Not"
   336  	case operationKindV128Or:
   337  		ret = "V128Or"
   338  	case operationKindV128Xor:
   339  		ret = "V128Xor"
   340  	case operationKindV128Bitselect:
   341  		ret = "V128Bitselect"
   342  	case operationKindV128AndNot:
   343  		ret = "V128AndNot"
   344  	case operationKindV128BitMask:
   345  		ret = "V128BitMask"
   346  	case operationKindV128Shl:
   347  		ret = "V128Shl"
   348  	case operationKindV128Shr:
   349  		ret = "V128Shr"
   350  	case operationKindV128Cmp:
   351  		ret = "V128Cmp"
   352  	case operationKindSignExtend32From8:
   353  		ret = "SignExtend32From8"
   354  	case operationKindSignExtend32From16:
   355  		ret = "SignExtend32From16"
   356  	case operationKindSignExtend64From8:
   357  		ret = "SignExtend64From8"
   358  	case operationKindSignExtend64From16:
   359  		ret = "SignExtend64From16"
   360  	case operationKindSignExtend64From32:
   361  		ret = "SignExtend64From32"
   362  	case operationKindV128AddSat:
   363  		ret = "V128AddSat"
   364  	case operationKindV128SubSat:
   365  		ret = "V128SubSat"
   366  	case operationKindV128Mul:
   367  		ret = "V128Mul"
   368  	case operationKindV128Div:
   369  		ret = "V128Div"
   370  	case operationKindV128Neg:
   371  		ret = "V128Neg"
   372  	case operationKindV128Sqrt:
   373  		ret = "V128Sqrt"
   374  	case operationKindV128Abs:
   375  		ret = "V128Abs"
   376  	case operationKindV128Popcnt:
   377  		ret = "V128Popcnt"
   378  	case operationKindV128Min:
   379  		ret = "V128Min"
   380  	case operationKindV128Max:
   381  		ret = "V128Max"
   382  	case operationKindV128AvgrU:
   383  		ret = "V128AvgrU"
   384  	case operationKindV128Ceil:
   385  		ret = "V128Ceil"
   386  	case operationKindV128Floor:
   387  		ret = "V128Floor"
   388  	case operationKindV128Trunc:
   389  		ret = "V128Trunc"
   390  	case operationKindV128Nearest:
   391  		ret = "V128Nearest"
   392  	case operationKindV128Pmin:
   393  		ret = "V128Pmin"
   394  	case operationKindV128Pmax:
   395  		ret = "V128Pmax"
   396  	case operationKindV128Extend:
   397  		ret = "V128Extend"
   398  	case operationKindV128ExtMul:
   399  		ret = "V128ExtMul"
   400  	case operationKindV128Q15mulrSatS:
   401  		ret = "V128Q15mulrSatS"
   402  	case operationKindV128ExtAddPairwise:
   403  		ret = "V128ExtAddPairwise"
   404  	case operationKindV128FloatPromote:
   405  		ret = "V128FloatPromote"
   406  	case operationKindV128FloatDemote:
   407  		ret = "V128FloatDemote"
   408  	case operationKindV128FConvertFromI:
   409  		ret = "V128FConvertFromI"
   410  	case operationKindV128Dot:
   411  		ret = "V128Dot"
   412  	case operationKindV128Narrow:
   413  		ret = "V128Narrow"
   414  	case operationKindV128ITruncSatFromF:
   415  		ret = "V128ITruncSatFromF"
   416  	case operationKindBuiltinFunctionCheckExitCode:
   417  		ret = "BuiltinFunctionCheckExitCode"
   418  	case operationKindAtomicMemoryWait:
   419  		ret = "operationKindAtomicMemoryWait"
   420  	case operationKindAtomicMemoryNotify:
   421  		ret = "operationKindAtomicMemoryNotify"
   422  	case operationKindAtomicFence:
   423  		ret = "operationKindAtomicFence"
   424  	case operationKindAtomicLoad:
   425  		ret = "operationKindAtomicLoad"
   426  	case operationKindAtomicLoad8:
   427  		ret = "operationKindAtomicLoad8"
   428  	case operationKindAtomicLoad16:
   429  		ret = "operationKindAtomicLoad16"
   430  	case operationKindAtomicStore:
   431  		ret = "operationKindAtomicStore"
   432  	case operationKindAtomicStore8:
   433  		ret = "operationKindAtomicStore8"
   434  	case operationKindAtomicStore16:
   435  		ret = "operationKindAtomicStore16"
   436  	case operationKindAtomicRMW:
   437  		ret = "operationKindAtomicRMW"
   438  	case operationKindAtomicRMW8:
   439  		ret = "operationKindAtomicRMW8"
   440  	case operationKindAtomicRMW16:
   441  		ret = "operationKindAtomicRMW16"
   442  	case operationKindAtomicRMWCmpxchg:
   443  		ret = "operationKindAtomicRMWCmpxchg"
   444  	case operationKindAtomicRMW8Cmpxchg:
   445  		ret = "operationKindAtomicRMW8Cmpxchg"
   446  	case operationKindAtomicRMW16Cmpxchg:
   447  		ret = "operationKindAtomicRMW16Cmpxchg"
   448  	default:
   449  		panic(fmt.Errorf("unknown operation %d", o))
   450  	}
   451  	return
   452  }
   453  
   454  const (
   455  	// operationKindUnreachable is the Kind for NewOperationUnreachable.
   456  	operationKindUnreachable operationKind = iota
   457  	// operationKindLabel is the Kind for NewOperationLabel.
   458  	operationKindLabel
   459  	// operationKindBr is the Kind for NewOperationBr.
   460  	operationKindBr
   461  	// operationKindBrIf is the Kind for NewOperationBrIf.
   462  	operationKindBrIf
   463  	// operationKindBrTable is the Kind for NewOperationBrTable.
   464  	operationKindBrTable
   465  	// operationKindCall is the Kind for NewOperationCall.
   466  	operationKindCall
   467  	// operationKindCallIndirect is the Kind for NewOperationCallIndirect.
   468  	operationKindCallIndirect
   469  	// operationKindDrop is the Kind for NewOperationDrop.
   470  	operationKindDrop
   471  	// operationKindSelect is the Kind for NewOperationSelect.
   472  	operationKindSelect
   473  	// operationKindPick is the Kind for NewOperationPick.
   474  	operationKindPick
   475  	// operationKindSet is the Kind for NewOperationSet.
   476  	operationKindSet
   477  	// operationKindGlobalGet is the Kind for NewOperationGlobalGet.
   478  	operationKindGlobalGet
   479  	// operationKindGlobalSet is the Kind for NewOperationGlobalSet.
   480  	operationKindGlobalSet
   481  	// operationKindLoad is the Kind for NewOperationLoad.
   482  	operationKindLoad
   483  	// operationKindLoad8 is the Kind for NewOperationLoad8.
   484  	operationKindLoad8
   485  	// operationKindLoad16 is the Kind for NewOperationLoad16.
   486  	operationKindLoad16
   487  	// operationKindLoad32 is the Kind for NewOperationLoad32.
   488  	operationKindLoad32
   489  	// operationKindStore is the Kind for NewOperationStore.
   490  	operationKindStore
   491  	// operationKindStore8 is the Kind for NewOperationStore8.
   492  	operationKindStore8
   493  	// operationKindStore16 is the Kind for NewOperationStore16.
   494  	operationKindStore16
   495  	// operationKindStore32 is the Kind for NewOperationStore32.
   496  	operationKindStore32
   497  	// operationKindMemorySize is the Kind for NewOperationMemorySize.
   498  	operationKindMemorySize
   499  	// operationKindMemoryGrow is the Kind for NewOperationMemoryGrow.
   500  	operationKindMemoryGrow
   501  	// operationKindConstI32 is the Kind for NewOperationConstI32.
   502  	operationKindConstI32
   503  	// operationKindConstI64 is the Kind for NewOperationConstI64.
   504  	operationKindConstI64
   505  	// operationKindConstF32 is the Kind for NewOperationConstF32.
   506  	operationKindConstF32
   507  	// operationKindConstF64 is the Kind for NewOperationConstF64.
   508  	operationKindConstF64
   509  	// operationKindEq is the Kind for NewOperationEq.
   510  	operationKindEq
   511  	// operationKindNe is the Kind for NewOperationNe.
   512  	operationKindNe
   513  	// operationKindEqz is the Kind for NewOperationEqz.
   514  	operationKindEqz
   515  	// operationKindLt is the Kind for NewOperationLt.
   516  	operationKindLt
   517  	// operationKindGt is the Kind for NewOperationGt.
   518  	operationKindGt
   519  	// operationKindLe is the Kind for NewOperationLe.
   520  	operationKindLe
   521  	// operationKindGe is the Kind for NewOperationGe.
   522  	operationKindGe
   523  	// operationKindAdd is the Kind for NewOperationAdd.
   524  	operationKindAdd
   525  	// operationKindSub is the Kind for NewOperationSub.
   526  	operationKindSub
   527  	// operationKindMul is the Kind for NewOperationMul.
   528  	operationKindMul
   529  	// operationKindClz is the Kind for NewOperationClz.
   530  	operationKindClz
   531  	// operationKindCtz is the Kind for NewOperationCtz.
   532  	operationKindCtz
   533  	// operationKindPopcnt is the Kind for NewOperationPopcnt.
   534  	operationKindPopcnt
   535  	// operationKindDiv is the Kind for NewOperationDiv.
   536  	operationKindDiv
   537  	// operationKindRem is the Kind for NewOperationRem.
   538  	operationKindRem
   539  	// operationKindAnd is the Kind for NewOperationAnd.
   540  	operationKindAnd
   541  	// operationKindOr is the Kind for NewOperationOr.
   542  	operationKindOr
   543  	// operationKindXor is the Kind for NewOperationXor.
   544  	operationKindXor
   545  	// operationKindShl is the Kind for NewOperationShl.
   546  	operationKindShl
   547  	// operationKindShr is the Kind for NewOperationShr.
   548  	operationKindShr
   549  	// operationKindRotl is the Kind for NewOperationRotl.
   550  	operationKindRotl
   551  	// operationKindRotr is the Kind for NewOperationRotr.
   552  	operationKindRotr
   553  	// operationKindAbs is the Kind for NewOperationAbs.
   554  	operationKindAbs
   555  	// operationKindNeg is the Kind for NewOperationNeg.
   556  	operationKindNeg
   557  	// operationKindCeil is the Kind for NewOperationCeil.
   558  	operationKindCeil
   559  	// operationKindFloor is the Kind for NewOperationFloor.
   560  	operationKindFloor
   561  	// operationKindTrunc is the Kind for NewOperationTrunc.
   562  	operationKindTrunc
   563  	// operationKindNearest is the Kind for NewOperationNearest.
   564  	operationKindNearest
   565  	// operationKindSqrt is the Kind for NewOperationSqrt.
   566  	operationKindSqrt
   567  	// operationKindMin is the Kind for NewOperationMin.
   568  	operationKindMin
   569  	// operationKindMax is the Kind for NewOperationMax.
   570  	operationKindMax
   571  	// operationKindCopysign is the Kind for NewOperationCopysign.
   572  	operationKindCopysign
   573  	// operationKindI32WrapFromI64 is the Kind for NewOperationI32WrapFromI64.
   574  	operationKindI32WrapFromI64
   575  	// operationKindITruncFromF is the Kind for NewOperationITruncFromF.
   576  	operationKindITruncFromF
   577  	// operationKindFConvertFromI is the Kind for NewOperationFConvertFromI.
   578  	operationKindFConvertFromI
   579  	// operationKindF32DemoteFromF64 is the Kind for NewOperationF32DemoteFromF64.
   580  	operationKindF32DemoteFromF64
   581  	// operationKindF64PromoteFromF32 is the Kind for NewOperationF64PromoteFromF32.
   582  	operationKindF64PromoteFromF32
   583  	// operationKindI32ReinterpretFromF32 is the Kind for NewOperationI32ReinterpretFromF32.
   584  	operationKindI32ReinterpretFromF32
   585  	// operationKindI64ReinterpretFromF64 is the Kind for NewOperationI64ReinterpretFromF64.
   586  	operationKindI64ReinterpretFromF64
   587  	// operationKindF32ReinterpretFromI32 is the Kind for NewOperationF32ReinterpretFromI32.
   588  	operationKindF32ReinterpretFromI32
   589  	// operationKindF64ReinterpretFromI64 is the Kind for NewOperationF64ReinterpretFromI64.
   590  	operationKindF64ReinterpretFromI64
   591  	// operationKindExtend is the Kind for NewOperationExtend.
   592  	operationKindExtend
   593  	// operationKindSignExtend32From8 is the Kind for NewOperationSignExtend32From8.
   594  	operationKindSignExtend32From8
   595  	// operationKindSignExtend32From16 is the Kind for NewOperationSignExtend32From16.
   596  	operationKindSignExtend32From16
   597  	// operationKindSignExtend64From8 is the Kind for NewOperationSignExtend64From8.
   598  	operationKindSignExtend64From8
   599  	// operationKindSignExtend64From16 is the Kind for NewOperationSignExtend64From16.
   600  	operationKindSignExtend64From16
   601  	// operationKindSignExtend64From32 is the Kind for NewOperationSignExtend64From32.
   602  	operationKindSignExtend64From32
   603  	// operationKindMemoryInit is the Kind for NewOperationMemoryInit.
   604  	operationKindMemoryInit
   605  	// operationKindDataDrop is the Kind for NewOperationDataDrop.
   606  	operationKindDataDrop
   607  	// operationKindMemoryCopy is the Kind for NewOperationMemoryCopy.
   608  	operationKindMemoryCopy
   609  	// operationKindMemoryFill is the Kind for NewOperationMemoryFill.
   610  	operationKindMemoryFill
   611  	// operationKindTableInit is the Kind for NewOperationTableInit.
   612  	operationKindTableInit
   613  	// operationKindElemDrop is the Kind for NewOperationElemDrop.
   614  	operationKindElemDrop
   615  	// operationKindTableCopy is the Kind for NewOperationTableCopy.
   616  	operationKindTableCopy
   617  	// operationKindRefFunc is the Kind for NewOperationRefFunc.
   618  	operationKindRefFunc
   619  	// operationKindTableGet is the Kind for NewOperationTableGet.
   620  	operationKindTableGet
   621  	// operationKindTableSet is the Kind for NewOperationTableSet.
   622  	operationKindTableSet
   623  	// operationKindTableSize is the Kind for NewOperationTableSize.
   624  	operationKindTableSize
   625  	// operationKindTableGrow is the Kind for NewOperationTableGrow.
   626  	operationKindTableGrow
   627  	// operationKindTableFill is the Kind for NewOperationTableFill.
   628  	operationKindTableFill
   629  
   630  	// Vector value related instructions are prefixed by V128.
   631  
   632  	// operationKindV128Const is the Kind for NewOperationV128Const.
   633  	operationKindV128Const
   634  	// operationKindV128Add is the Kind for NewOperationV128Add.
   635  	operationKindV128Add
   636  	// operationKindV128Sub is the Kind for NewOperationV128Sub.
   637  	operationKindV128Sub
   638  	// operationKindV128Load is the Kind for NewOperationV128Load.
   639  	operationKindV128Load
   640  	// operationKindV128LoadLane is the Kind for NewOperationV128LoadLane.
   641  	operationKindV128LoadLane
   642  	// operationKindV128Store is the Kind for NewOperationV128Store.
   643  	operationKindV128Store
   644  	// operationKindV128StoreLane is the Kind for NewOperationV128StoreLane.
   645  	operationKindV128StoreLane
   646  	// operationKindV128ExtractLane is the Kind for NewOperationV128ExtractLane.
   647  	operationKindV128ExtractLane
   648  	// operationKindV128ReplaceLane is the Kind for NewOperationV128ReplaceLane.
   649  	operationKindV128ReplaceLane
   650  	// operationKindV128Splat is the Kind for NewOperationV128Splat.
   651  	operationKindV128Splat
   652  	// operationKindV128Shuffle is the Kind for NewOperationV128Shuffle.
   653  	operationKindV128Shuffle
   654  	// operationKindV128Swizzle is the Kind for NewOperationV128Swizzle.
   655  	operationKindV128Swizzle
   656  	// operationKindV128AnyTrue is the Kind for NewOperationV128AnyTrue.
   657  	operationKindV128AnyTrue
   658  	// operationKindV128AllTrue is the Kind for NewOperationV128AllTrue.
   659  	operationKindV128AllTrue
   660  	// operationKindV128BitMask is the Kind for NewOperationV128BitMask.
   661  	operationKindV128BitMask
   662  	// operationKindV128And is the Kind for NewOperationV128And.
   663  	operationKindV128And
   664  	// operationKindV128Not is the Kind for NewOperationV128Not.
   665  	operationKindV128Not
   666  	// operationKindV128Or is the Kind for NewOperationV128Or.
   667  	operationKindV128Or
   668  	// operationKindV128Xor is the Kind for NewOperationV128Xor.
   669  	operationKindV128Xor
   670  	// operationKindV128Bitselect is the Kind for NewOperationV128Bitselect.
   671  	operationKindV128Bitselect
   672  	// operationKindV128AndNot is the Kind for NewOperationV128AndNot.
   673  	operationKindV128AndNot
   674  	// operationKindV128Shl is the Kind for NewOperationV128Shl.
   675  	operationKindV128Shl
   676  	// operationKindV128Shr is the Kind for NewOperationV128Shr.
   677  	operationKindV128Shr
   678  	// operationKindV128Cmp is the Kind for NewOperationV128Cmp.
   679  	operationKindV128Cmp
   680  	// operationKindV128AddSat is the Kind for NewOperationV128AddSat.
   681  	operationKindV128AddSat
   682  	// operationKindV128SubSat is the Kind for NewOperationV128SubSat.
   683  	operationKindV128SubSat
   684  	// operationKindV128Mul is the Kind for NewOperationV128Mul.
   685  	operationKindV128Mul
   686  	// operationKindV128Div is the Kind for NewOperationV128Div.
   687  	operationKindV128Div
   688  	// operationKindV128Neg is the Kind for NewOperationV128Neg.
   689  	operationKindV128Neg
   690  	// operationKindV128Sqrt is the Kind for NewOperationV128Sqrt.
   691  	operationKindV128Sqrt
   692  	// operationKindV128Abs is the Kind for NewOperationV128Abs.
   693  	operationKindV128Abs
   694  	// operationKindV128Popcnt is the Kind for NewOperationV128Popcnt.
   695  	operationKindV128Popcnt
   696  	// operationKindV128Min is the Kind for NewOperationV128Min.
   697  	operationKindV128Min
   698  	// operationKindV128Max is the Kind for NewOperationV128Max.
   699  	operationKindV128Max
   700  	// operationKindV128AvgrU is the Kind for NewOperationV128AvgrU.
   701  	operationKindV128AvgrU
   702  	// operationKindV128Pmin is the Kind for NewOperationV128Pmin.
   703  	operationKindV128Pmin
   704  	// operationKindV128Pmax is the Kind for NewOperationV128Pmax.
   705  	operationKindV128Pmax
   706  	// operationKindV128Ceil is the Kind for NewOperationV128Ceil.
   707  	operationKindV128Ceil
   708  	// operationKindV128Floor is the Kind for NewOperationV128Floor.
   709  	operationKindV128Floor
   710  	// operationKindV128Trunc is the Kind for NewOperationV128Trunc.
   711  	operationKindV128Trunc
   712  	// operationKindV128Nearest is the Kind for NewOperationV128Nearest.
   713  	operationKindV128Nearest
   714  	// operationKindV128Extend is the Kind for NewOperationV128Extend.
   715  	operationKindV128Extend
   716  	// operationKindV128ExtMul is the Kind for NewOperationV128ExtMul.
   717  	operationKindV128ExtMul
   718  	// operationKindV128Q15mulrSatS is the Kind for NewOperationV128Q15mulrSatS.
   719  	operationKindV128Q15mulrSatS
   720  	// operationKindV128ExtAddPairwise is the Kind for NewOperationV128ExtAddPairwise.
   721  	operationKindV128ExtAddPairwise
   722  	// operationKindV128FloatPromote is the Kind for NewOperationV128FloatPromote.
   723  	operationKindV128FloatPromote
   724  	// operationKindV128FloatDemote is the Kind for NewOperationV128FloatDemote.
   725  	operationKindV128FloatDemote
   726  	// operationKindV128FConvertFromI is the Kind for NewOperationV128FConvertFromI.
   727  	operationKindV128FConvertFromI
   728  	// operationKindV128Dot is the Kind for NewOperationV128Dot.
   729  	operationKindV128Dot
   730  	// operationKindV128Narrow is the Kind for NewOperationV128Narrow.
   731  	operationKindV128Narrow
   732  	// operationKindV128ITruncSatFromF is the Kind for NewOperationV128ITruncSatFromF.
   733  	operationKindV128ITruncSatFromF
   734  
   735  	// operationKindBuiltinFunctionCheckExitCode is the Kind for NewOperationBuiltinFunctionCheckExitCode.
   736  	operationKindBuiltinFunctionCheckExitCode
   737  
   738  	// operationKindAtomicMemoryWait is the kind for NewOperationAtomicMemoryWait.
   739  	operationKindAtomicMemoryWait
   740  	// operationKindAtomicMemoryNotify is the kind for NewOperationAtomicMemoryNotify.
   741  	operationKindAtomicMemoryNotify
   742  	// operationKindAtomicFence is the kind for NewOperationAtomicFence.
   743  	operationKindAtomicFence
   744  	// operationKindAtomicLoad is the kind for NewOperationAtomicLoad.
   745  	operationKindAtomicLoad
   746  	// operationKindAtomicLoad8 is the kind for NewOperationAtomicLoad8.
   747  	operationKindAtomicLoad8
   748  	// operationKindAtomicLoad16 is the kind for NewOperationAtomicLoad16.
   749  	operationKindAtomicLoad16
   750  	// operationKindAtomicStore is the kind for NewOperationAtomicStore.
   751  	operationKindAtomicStore
   752  	// operationKindAtomicStore8 is the kind for NewOperationAtomicStore8.
   753  	operationKindAtomicStore8
   754  	// operationKindAtomicStore16 is the kind for NewOperationAtomicStore16.
   755  	operationKindAtomicStore16
   756  
   757  	// operationKindAtomicRMW is the kind for NewOperationAtomicRMW.
   758  	operationKindAtomicRMW
   759  	// operationKindAtomicRMW8 is the kind for NewOperationAtomicRMW8.
   760  	operationKindAtomicRMW8
   761  	// operationKindAtomicRMW16 is the kind for NewOperationAtomicRMW16.
   762  	operationKindAtomicRMW16
   763  
   764  	// operationKindAtomicRMWCmpxchg is the kind for NewOperationAtomicRMWCmpxchg.
   765  	operationKindAtomicRMWCmpxchg
   766  	// operationKindAtomicRMW8Cmpxchg is the kind for NewOperationAtomicRMW8Cmpxchg.
   767  	operationKindAtomicRMW8Cmpxchg
   768  	// operationKindAtomicRMW16Cmpxchg is the kind for NewOperationAtomicRMW16Cmpxchg.
   769  	operationKindAtomicRMW16Cmpxchg
   770  
   771  	// operationKindEnd is always placed at the bottom of this iota definition to be used in the test.
   772  	operationKindEnd
   773  )
   774  
   775  // NewOperationBuiltinFunctionCheckExitCode is a constructor for unionOperation with Kind operationKindBuiltinFunctionCheckExitCode.
   776  //
   777  // OperationBuiltinFunctionCheckExitCode corresponds to the instruction to check the api.Module is already closed due to
   778  // context.DeadlineExceeded, context.Canceled, or the explicit call of CloseWithExitCode on api.Module.
   779  func newOperationBuiltinFunctionCheckExitCode() unionOperation {
   780  	return unionOperation{Kind: operationKindBuiltinFunctionCheckExitCode}
   781  }
   782  
   783  // label is the unique identifier for each block in a single function in interpreterir
   784  // where "block" consists of multiple operations, and must End with branching operations
   785  // (e.g. operationKindBr or operationKindBrIf).
   786  type label uint64
   787  
   788  // Kind returns the labelKind encoded in this label.
   789  func (l label) Kind() labelKind {
   790  	return labelKind(uint32(l))
   791  }
   792  
   793  // FrameID returns the frame id encoded in this label.
   794  func (l label) FrameID() int {
   795  	return int(uint32(l >> 32))
   796  }
   797  
   798  // NewLabel is a constructor for a label.
   799  func newLabel(kind labelKind, frameID uint32) label {
   800  	return label(kind) | label(frameID)<<32
   801  }
   802  
   803  // String implements fmt.Stringer.
   804  func (l label) String() (ret string) {
   805  	frameID := l.FrameID()
   806  	switch l.Kind() {
   807  	case labelKindHeader:
   808  		ret = fmt.Sprintf(".L%d", frameID)
   809  	case labelKindElse:
   810  		ret = fmt.Sprintf(".L%d_else", frameID)
   811  	case labelKindContinuation:
   812  		ret = fmt.Sprintf(".L%d_cont", frameID)
   813  	case labelKindReturn:
   814  		return ".return"
   815  	}
   816  	return
   817  }
   818  
   819  func (l label) IsReturnTarget() bool {
   820  	return l.Kind() == labelKindReturn
   821  }
   822  
   823  // labelKind is the Kind of the label.
   824  type labelKind = byte
   825  
   826  const (
   827  	// labelKindHeader is the header for various blocks. For example, the "then" block of
   828  	// wasm.OpcodeIfName in Wasm has the label of this Kind.
   829  	labelKindHeader labelKind = iota
   830  	// labelKindElse is the Kind of label for "else" block of wasm.OpcodeIfName in Wasm.
   831  	labelKindElse
   832  	// labelKindContinuation is the Kind of label which is the continuation of blocks.
   833  	// For example, for wasm text like
   834  	// (func
   835  	//   ....
   836  	//   (if (local.get 0) (then (nop)) (else (nop)))
   837  	//   return
   838  	// )
   839  	// we have the continuation block (of if-block) corresponding to "return" opcode.
   840  	labelKindContinuation
   841  	labelKindReturn
   842  	labelKindNum
   843  )
   844  
   845  // unionOperation implements Operation and is the compilation (engine.lowerIR) result of a interpreterir.Operation.
   846  //
   847  // Not all operations result in a unionOperation, e.g. interpreterir.OperationI32ReinterpretFromF32, and some operations are
   848  // more complex than others, e.g. interpreterir.NewOperationBrTable.
   849  //
   850  // Note: This is a form of union type as it can store fields needed for any operation. Hence, most fields are opaque and
   851  // only relevant when in context of its kind.
   852  type unionOperation struct {
   853  	// Kind determines how to interpret the other fields in this struct.
   854  	Kind   operationKind
   855  	B1, B2 byte
   856  	B3     bool
   857  	U1, U2 uint64
   858  	U3     uint64
   859  	Us     []uint64
   860  }
   861  
   862  // String implements fmt.Stringer.
   863  func (o unionOperation) String() string {
   864  	switch o.Kind {
   865  	case operationKindUnreachable,
   866  		operationKindSelect,
   867  		operationKindMemorySize,
   868  		operationKindMemoryGrow,
   869  		operationKindI32WrapFromI64,
   870  		operationKindF32DemoteFromF64,
   871  		operationKindF64PromoteFromF32,
   872  		operationKindI32ReinterpretFromF32,
   873  		operationKindI64ReinterpretFromF64,
   874  		operationKindF32ReinterpretFromI32,
   875  		operationKindF64ReinterpretFromI64,
   876  		operationKindSignExtend32From8,
   877  		operationKindSignExtend32From16,
   878  		operationKindSignExtend64From8,
   879  		operationKindSignExtend64From16,
   880  		operationKindSignExtend64From32,
   881  		operationKindMemoryInit,
   882  		operationKindDataDrop,
   883  		operationKindMemoryCopy,
   884  		operationKindMemoryFill,
   885  		operationKindTableInit,
   886  		operationKindElemDrop,
   887  		operationKindTableCopy,
   888  		operationKindRefFunc,
   889  		operationKindTableGet,
   890  		operationKindTableSet,
   891  		operationKindTableSize,
   892  		operationKindTableGrow,
   893  		operationKindTableFill,
   894  		operationKindBuiltinFunctionCheckExitCode:
   895  		return o.Kind.String()
   896  
   897  	case operationKindCall,
   898  		operationKindGlobalGet,
   899  		operationKindGlobalSet:
   900  		return fmt.Sprintf("%s %d", o.Kind, o.B1)
   901  
   902  	case operationKindLabel:
   903  		return label(o.U1).String()
   904  
   905  	case operationKindBr:
   906  		return fmt.Sprintf("%s %s", o.Kind, label(o.U1).String())
   907  
   908  	case operationKindBrIf:
   909  		thenTarget := label(o.U1)
   910  		elseTarget := label(o.U2)
   911  		return fmt.Sprintf("%s %s, %s", o.Kind, thenTarget, elseTarget)
   912  
   913  	case operationKindBrTable:
   914  		var targets []string
   915  		var defaultLabel label
   916  		if len(o.Us) > 0 {
   917  			targets = make([]string, len(o.Us)-1)
   918  			for i, t := range o.Us[1:] {
   919  				targets[i] = label(t).String()
   920  			}
   921  			defaultLabel = label(o.Us[0])
   922  		}
   923  		return fmt.Sprintf("%s [%s] %s", o.Kind, strings.Join(targets, ","), defaultLabel)
   924  
   925  	case operationKindCallIndirect:
   926  		return fmt.Sprintf("%s: type=%d, table=%d", o.Kind, o.U1, o.U2)
   927  
   928  	case operationKindDrop:
   929  		start := int64(o.U1)
   930  		end := int64(o.U2)
   931  		return fmt.Sprintf("%s %d..%d", o.Kind, start, end)
   932  
   933  	case operationKindPick, operationKindSet:
   934  		return fmt.Sprintf("%s %d (is_vector=%v)", o.Kind, o.U1, o.B3)
   935  
   936  	case operationKindLoad, operationKindStore:
   937  		return fmt.Sprintf("%s.%s (align=%d, offset=%d)", unsignedType(o.B1), o.Kind, o.U1, o.U2)
   938  
   939  	case operationKindLoad8,
   940  		operationKindLoad16:
   941  		return fmt.Sprintf("%s.%s (align=%d, offset=%d)", signedType(o.B1), o.Kind, o.U1, o.U2)
   942  
   943  	case operationKindStore8,
   944  		operationKindStore16,
   945  		operationKindStore32:
   946  		return fmt.Sprintf("%s (align=%d, offset=%d)", o.Kind, o.U1, o.U2)
   947  
   948  	case operationKindLoad32:
   949  		var t string
   950  		if o.B1 == 1 {
   951  			t = "i64"
   952  		} else {
   953  			t = "u64"
   954  		}
   955  		return fmt.Sprintf("%s.%s (align=%d, offset=%d)", t, o.Kind, o.U1, o.U2)
   956  
   957  	case operationKindEq,
   958  		operationKindNe,
   959  		operationKindAdd,
   960  		operationKindSub,
   961  		operationKindMul:
   962  		return fmt.Sprintf("%s.%s", unsignedType(o.B1), o.Kind)
   963  
   964  	case operationKindEqz,
   965  		operationKindClz,
   966  		operationKindCtz,
   967  		operationKindPopcnt,
   968  		operationKindAnd,
   969  		operationKindOr,
   970  		operationKindXor,
   971  		operationKindShl,
   972  		operationKindRotl,
   973  		operationKindRotr:
   974  		return fmt.Sprintf("%s.%s", unsignedInt(o.B1), o.Kind)
   975  
   976  	case operationKindRem, operationKindShr:
   977  		return fmt.Sprintf("%s.%s", signedInt(o.B1), o.Kind)
   978  
   979  	case operationKindLt,
   980  		operationKindGt,
   981  		operationKindLe,
   982  		operationKindGe,
   983  		operationKindDiv:
   984  		return fmt.Sprintf("%s.%s", signedType(o.B1), o.Kind)
   985  
   986  	case operationKindAbs,
   987  		operationKindNeg,
   988  		operationKindCeil,
   989  		operationKindFloor,
   990  		operationKindTrunc,
   991  		operationKindNearest,
   992  		operationKindSqrt,
   993  		operationKindMin,
   994  		operationKindMax,
   995  		operationKindCopysign:
   996  		return fmt.Sprintf("%s.%s", float(o.B1), o.Kind)
   997  
   998  	case operationKindConstI32,
   999  		operationKindConstI64:
  1000  		return fmt.Sprintf("%s %#x", o.Kind, o.U1)
  1001  
  1002  	case operationKindConstF32:
  1003  		return fmt.Sprintf("%s %f", o.Kind, math.Float32frombits(uint32(o.U1)))
  1004  	case operationKindConstF64:
  1005  		return fmt.Sprintf("%s %f", o.Kind, math.Float64frombits(o.U1))
  1006  
  1007  	case operationKindITruncFromF:
  1008  		return fmt.Sprintf("%s.%s.%s (non_trapping=%v)", signedInt(o.B2), o.Kind, float(o.B1), o.B3)
  1009  	case operationKindFConvertFromI:
  1010  		return fmt.Sprintf("%s.%s.%s", float(o.B2), o.Kind, signedInt(o.B1))
  1011  	case operationKindExtend:
  1012  		var in, out string
  1013  		if o.B3 {
  1014  			in = "i32"
  1015  			out = "i64"
  1016  		} else {
  1017  			in = "u32"
  1018  			out = "u64"
  1019  		}
  1020  		return fmt.Sprintf("%s.%s.%s", out, o.Kind, in)
  1021  
  1022  	case operationKindV128Const:
  1023  		return fmt.Sprintf("%s [%#x, %#x]", o.Kind, o.U1, o.U2)
  1024  	case operationKindV128Add,
  1025  		operationKindV128Sub:
  1026  		return fmt.Sprintf("%s (shape=%s)", o.Kind, shapeName(o.B1))
  1027  	case operationKindV128Load,
  1028  		operationKindV128LoadLane,
  1029  		operationKindV128Store,
  1030  		operationKindV128StoreLane,
  1031  		operationKindV128ExtractLane,
  1032  		operationKindV128ReplaceLane,
  1033  		operationKindV128Splat,
  1034  		operationKindV128Shuffle,
  1035  		operationKindV128Swizzle,
  1036  		operationKindV128AnyTrue,
  1037  		operationKindV128AllTrue,
  1038  		operationKindV128BitMask,
  1039  		operationKindV128And,
  1040  		operationKindV128Not,
  1041  		operationKindV128Or,
  1042  		operationKindV128Xor,
  1043  		operationKindV128Bitselect,
  1044  		operationKindV128AndNot,
  1045  		operationKindV128Shl,
  1046  		operationKindV128Shr,
  1047  		operationKindV128Cmp,
  1048  		operationKindV128AddSat,
  1049  		operationKindV128SubSat,
  1050  		operationKindV128Mul,
  1051  		operationKindV128Div,
  1052  		operationKindV128Neg,
  1053  		operationKindV128Sqrt,
  1054  		operationKindV128Abs,
  1055  		operationKindV128Popcnt,
  1056  		operationKindV128Min,
  1057  		operationKindV128Max,
  1058  		operationKindV128AvgrU,
  1059  		operationKindV128Pmin,
  1060  		operationKindV128Pmax,
  1061  		operationKindV128Ceil,
  1062  		operationKindV128Floor,
  1063  		operationKindV128Trunc,
  1064  		operationKindV128Nearest,
  1065  		operationKindV128Extend,
  1066  		operationKindV128ExtMul,
  1067  		operationKindV128Q15mulrSatS,
  1068  		operationKindV128ExtAddPairwise,
  1069  		operationKindV128FloatPromote,
  1070  		operationKindV128FloatDemote,
  1071  		operationKindV128FConvertFromI,
  1072  		operationKindV128Dot,
  1073  		operationKindV128Narrow:
  1074  		return o.Kind.String()
  1075  
  1076  	case operationKindV128ITruncSatFromF:
  1077  		if o.B3 {
  1078  			return fmt.Sprintf("%s.%sS", o.Kind, shapeName(o.B1))
  1079  		} else {
  1080  			return fmt.Sprintf("%s.%sU", o.Kind, shapeName(o.B1))
  1081  		}
  1082  
  1083  	case operationKindAtomicMemoryWait,
  1084  		operationKindAtomicMemoryNotify,
  1085  		operationKindAtomicFence,
  1086  		operationKindAtomicLoad,
  1087  		operationKindAtomicLoad8,
  1088  		operationKindAtomicLoad16,
  1089  		operationKindAtomicStore,
  1090  		operationKindAtomicStore8,
  1091  		operationKindAtomicStore16,
  1092  		operationKindAtomicRMW,
  1093  		operationKindAtomicRMW8,
  1094  		operationKindAtomicRMW16,
  1095  		operationKindAtomicRMWCmpxchg,
  1096  		operationKindAtomicRMW8Cmpxchg,
  1097  		operationKindAtomicRMW16Cmpxchg:
  1098  		return o.Kind.String()
  1099  
  1100  	default:
  1101  		panic(fmt.Sprintf("TODO: %v", o.Kind))
  1102  	}
  1103  }
  1104  
  1105  // NewOperationUnreachable is a constructor for unionOperation with operationKindUnreachable
  1106  //
  1107  // This corresponds to wasm.OpcodeUnreachable.
  1108  //
  1109  // The engines are expected to exit the execution with wasmruntime.ErrRuntimeUnreachable error.
  1110  func newOperationUnreachable() unionOperation {
  1111  	return unionOperation{Kind: operationKindUnreachable}
  1112  }
  1113  
  1114  // NewOperationLabel is a constructor for unionOperation with operationKindLabel.
  1115  //
  1116  // This is used to inform the engines of the beginning of a label.
  1117  func newOperationLabel(label label) unionOperation {
  1118  	return unionOperation{Kind: operationKindLabel, U1: uint64(label)}
  1119  }
  1120  
  1121  // NewOperationBr is a constructor for unionOperation with operationKindBr.
  1122  //
  1123  // The engines are expected to branch into U1 label.
  1124  func newOperationBr(target label) unionOperation {
  1125  	return unionOperation{Kind: operationKindBr, U1: uint64(target)}
  1126  }
  1127  
  1128  // NewOperationBrIf is a constructor for unionOperation with operationKindBrIf.
  1129  //
  1130  // The engines are expected to pop a value and branch into U1 label if the value equals 1.
  1131  // Otherwise, the code branches into U2 label.
  1132  func newOperationBrIf(thenTarget, elseTarget label, thenDrop inclusiveRange) unionOperation {
  1133  	return unionOperation{
  1134  		Kind: operationKindBrIf,
  1135  		U1:   uint64(thenTarget),
  1136  		U2:   uint64(elseTarget),
  1137  		U3:   thenDrop.AsU64(),
  1138  	}
  1139  }
  1140  
  1141  // NewOperationBrTable is a constructor for unionOperation with operationKindBrTable.
  1142  //
  1143  // This corresponds to wasm.OpcodeBrTableName except that the label
  1144  // here means the interpreterir level, not the ones of Wasm.
  1145  //
  1146  // The engines are expected to do the br_table operation based on the default (Us[len(Us)-1], Us[len(Us)-2]) and
  1147  // targets (Us[:len(Us)-1], Rs[:len(Us)-1]). More precisely, this pops a value from the stack (called "index")
  1148  // and decides which branch we go into next based on the value.
  1149  //
  1150  // For example, assume we have operations like {default: L_DEFAULT, targets: [L0, L1, L2]}.
  1151  // If "index" >= len(defaults), then branch into the L_DEFAULT label.
  1152  // Otherwise, we enter label of targets[index].
  1153  func newOperationBrTable(targetLabelsAndRanges []uint64) unionOperation {
  1154  	return unionOperation{
  1155  		Kind: operationKindBrTable,
  1156  		Us:   targetLabelsAndRanges,
  1157  	}
  1158  }
  1159  
  1160  // NewOperationCall is a constructor for unionOperation with operationKindCall.
  1161  //
  1162  // This corresponds to wasm.OpcodeCallName, and engines are expected to
  1163  // enter into a function whose index equals OperationCall.FunctionIndex.
  1164  func newOperationCall(functionIndex uint32) unionOperation {
  1165  	return unionOperation{Kind: operationKindCall, U1: uint64(functionIndex)}
  1166  }
  1167  
  1168  // NewOperationCallIndirect implements Operation.
  1169  //
  1170  // This corresponds to wasm.OpcodeCallIndirectName, and engines are expected to
  1171  // consume the one value from the top of stack (called "offset"),
  1172  // and make a function call against the function whose function address equals
  1173  // Tables[OperationCallIndirect.TableIndex][offset].
  1174  //
  1175  // Note: This is called indirect function call in the sense that the target function is indirectly
  1176  // determined by the current state (top value) of the stack.
  1177  // Therefore, two checks are performed at runtime before entering the target function:
  1178  // 1) whether "offset" exceeds the length of table Tables[OperationCallIndirect.TableIndex].
  1179  // 2) whether the type of the function table[offset] matches the function type specified by OperationCallIndirect.TypeIndex.
  1180  func newOperationCallIndirect(typeIndex, tableIndex uint32) unionOperation {
  1181  	return unionOperation{Kind: operationKindCallIndirect, U1: uint64(typeIndex), U2: uint64(tableIndex)}
  1182  }
  1183  
  1184  // inclusiveRange is the range which spans across the value stack starting from the top to the bottom, and
  1185  // both boundary are included in the range.
  1186  type inclusiveRange struct {
  1187  	Start, End int32
  1188  }
  1189  
  1190  // AsU64 is be used to convert inclusiveRange to uint64 so that it can be stored in unionOperation.
  1191  func (i inclusiveRange) AsU64() uint64 {
  1192  	return uint64(uint32(i.Start))<<32 | uint64(uint32(i.End))
  1193  }
  1194  
  1195  // inclusiveRangeFromU64 retrieves inclusiveRange from the given uint64 which is stored in unionOperation.
  1196  func inclusiveRangeFromU64(v uint64) inclusiveRange {
  1197  	return inclusiveRange{
  1198  		Start: int32(uint32(v >> 32)),
  1199  		End:   int32(uint32(v)),
  1200  	}
  1201  }
  1202  
  1203  // nopinclusiveRange is inclusiveRange which corresponds to no-operation.
  1204  var nopinclusiveRange = inclusiveRange{Start: -1, End: -1}
  1205  
  1206  // NewOperationDrop is a constructor for unionOperation with operationKindDrop.
  1207  //
  1208  // The engines are expected to discard the values selected by NewOperationDrop.Depth which
  1209  // starts from the top of the stack to the bottom.
  1210  //
  1211  // depth spans across the uint64 value stack at runtime to be dropped by this operation.
  1212  func newOperationDrop(depth inclusiveRange) unionOperation {
  1213  	return unionOperation{Kind: operationKindDrop, U1: depth.AsU64()}
  1214  }
  1215  
  1216  // NewOperationSelect is a constructor for unionOperation with operationKindSelect.
  1217  //
  1218  // This corresponds to wasm.OpcodeSelect.
  1219  //
  1220  // The engines are expected to pop three values, say [..., x2, x1, c], then if the value "c" equals zero,
  1221  // "x1" is pushed back onto the stack and, otherwise "x2" is pushed back.
  1222  //
  1223  // isTargetVector true if the selection target value's type is wasm.ValueTypeV128.
  1224  func newOperationSelect(isTargetVector bool) unionOperation {
  1225  	return unionOperation{Kind: operationKindSelect, B3: isTargetVector}
  1226  }
  1227  
  1228  // NewOperationPick is a constructor for unionOperation with operationKindPick.
  1229  //
  1230  // The engines are expected to copy a value pointed by depth, and push the
  1231  // copied value onto the top of the stack.
  1232  //
  1233  // depth is the location of the pick target in the uint64 value stack at runtime.
  1234  // If isTargetVector=true, this points to the location of the lower 64-bits of the vector.
  1235  func newOperationPick(depth int, isTargetVector bool) unionOperation {
  1236  	return unionOperation{Kind: operationKindPick, U1: uint64(depth), B3: isTargetVector}
  1237  }
  1238  
  1239  // NewOperationSet is a constructor for unionOperation with operationKindSet.
  1240  //
  1241  // The engines are expected to set the top value of the stack to the location specified by
  1242  // depth.
  1243  //
  1244  // depth is the location of the set target in the uint64 value stack at runtime.
  1245  // If isTargetVector=true, this points the location of the lower 64-bits of the vector.
  1246  func newOperationSet(depth int, isTargetVector bool) unionOperation {
  1247  	return unionOperation{Kind: operationKindSet, U1: uint64(depth), B3: isTargetVector}
  1248  }
  1249  
  1250  // NewOperationGlobalGet is a constructor for unionOperation with operationKindGlobalGet.
  1251  //
  1252  // The engines are expected to read the global value specified by OperationGlobalGet.Index,
  1253  // and push the copy of the value onto the stack.
  1254  //
  1255  // See wasm.OpcodeGlobalGet.
  1256  func newOperationGlobalGet(index uint32) unionOperation {
  1257  	return unionOperation{Kind: operationKindGlobalGet, U1: uint64(index)}
  1258  }
  1259  
  1260  // NewOperationGlobalSet is a constructor for unionOperation with operationKindGlobalSet.
  1261  //
  1262  // The engines are expected to consume the value from the top of the stack,
  1263  // and write the value into the global specified by OperationGlobalSet.Index.
  1264  //
  1265  // See wasm.OpcodeGlobalSet.
  1266  func newOperationGlobalSet(index uint32) unionOperation {
  1267  	return unionOperation{Kind: operationKindGlobalSet, U1: uint64(index)}
  1268  }
  1269  
  1270  // memoryArg is the "memarg" to all memory instructions.
  1271  //
  1272  // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#memory-instructions%E2%91%A0
  1273  type memoryArg struct {
  1274  	// Alignment the expected alignment (expressed as the exponent of a power of 2). Default to the natural alignment.
  1275  	//
  1276  	// "Natural alignment" is defined here as the smallest power of two that can hold the size of the value type. Ex
  1277  	// wasm.ValueTypeI64 is encoded in 8 little-endian bytes. 2^3 = 8, so the natural alignment is three.
  1278  	Alignment uint32
  1279  
  1280  	// Offset is the address offset added to the instruction's dynamic address operand, yielding a 33-bit effective
  1281  	// address that is the zero-based index at which the memory is accessed. Default to zero.
  1282  	Offset uint32
  1283  }
  1284  
  1285  // NewOperationLoad is a constructor for unionOperation with operationKindLoad.
  1286  //
  1287  // This corresponds to wasm.OpcodeI32LoadName wasm.OpcodeI64LoadName wasm.OpcodeF32LoadName and wasm.OpcodeF64LoadName.
  1288  //
  1289  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1290  // otherwise load the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1291  func newOperationLoad(unsignedType unsignedType, arg memoryArg) unionOperation {
  1292  	return unionOperation{Kind: operationKindLoad, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1293  }
  1294  
  1295  // NewOperationLoad8 is a constructor for unionOperation with operationKindLoad8.
  1296  //
  1297  // This corresponds to wasm.OpcodeI32Load8SName wasm.OpcodeI32Load8UName wasm.OpcodeI64Load8SName wasm.OpcodeI64Load8UName.
  1298  //
  1299  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1300  // otherwise load the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1301  func newOperationLoad8(signedInt signedInt, arg memoryArg) unionOperation {
  1302  	return unionOperation{Kind: operationKindLoad8, B1: byte(signedInt), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1303  }
  1304  
  1305  // NewOperationLoad16 is a constructor for unionOperation with operationKindLoad16.
  1306  //
  1307  // This corresponds to wasm.OpcodeI32Load16SName wasm.OpcodeI32Load16UName wasm.OpcodeI64Load16SName wasm.OpcodeI64Load16UName.
  1308  //
  1309  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1310  // otherwise load the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1311  func newOperationLoad16(signedInt signedInt, arg memoryArg) unionOperation {
  1312  	return unionOperation{Kind: operationKindLoad16, B1: byte(signedInt), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1313  }
  1314  
  1315  // NewOperationLoad32 is a constructor for unionOperation with operationKindLoad32.
  1316  //
  1317  // This corresponds to wasm.OpcodeI64Load32SName wasm.OpcodeI64Load32UName.
  1318  //
  1319  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1320  // otherwise load the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1321  func newOperationLoad32(signed bool, arg memoryArg) unionOperation {
  1322  	sigB := byte(0)
  1323  	if signed {
  1324  		sigB = 1
  1325  	}
  1326  	return unionOperation{Kind: operationKindLoad32, B1: sigB, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1327  }
  1328  
  1329  // NewOperationStore is a constructor for unionOperation with operationKindStore.
  1330  //
  1331  // # This corresponds to wasm.OpcodeI32StoreName wasm.OpcodeI64StoreName wasm.OpcodeF32StoreName wasm.OpcodeF64StoreName
  1332  //
  1333  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1334  // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1335  func newOperationStore(unsignedType unsignedType, arg memoryArg) unionOperation {
  1336  	return unionOperation{Kind: operationKindStore, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1337  }
  1338  
  1339  // NewOperationStore8 is a constructor for unionOperation with operationKindStore8.
  1340  //
  1341  // # This corresponds to wasm.OpcodeI32Store8Name wasm.OpcodeI64Store8Name
  1342  //
  1343  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1344  // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1345  func newOperationStore8(arg memoryArg) unionOperation {
  1346  	return unionOperation{Kind: operationKindStore8, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1347  }
  1348  
  1349  // NewOperationStore16 is a constructor for unionOperation with operationKindStore16.
  1350  //
  1351  // # This corresponds to wasm.OpcodeI32Store16Name wasm.OpcodeI64Store16Name
  1352  //
  1353  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1354  // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1355  func newOperationStore16(arg memoryArg) unionOperation {
  1356  	return unionOperation{Kind: operationKindStore16, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1357  }
  1358  
  1359  // NewOperationStore32 is a constructor for unionOperation with operationKindStore32.
  1360  //
  1361  // # This corresponds to wasm.OpcodeI64Store32Name
  1362  //
  1363  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1364  // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1365  func newOperationStore32(arg memoryArg) unionOperation {
  1366  	return unionOperation{Kind: operationKindStore32, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1367  }
  1368  
  1369  // NewOperationMemorySize is a constructor for unionOperation with operationKindMemorySize.
  1370  //
  1371  // This corresponds to wasm.OpcodeMemorySize.
  1372  //
  1373  // The engines are expected to push the current page size of the memory onto the stack.
  1374  func newOperationMemorySize() unionOperation {
  1375  	return unionOperation{Kind: operationKindMemorySize}
  1376  }
  1377  
  1378  // NewOperationMemoryGrow is a constructor for unionOperation with operationKindMemoryGrow.
  1379  //
  1380  // This corresponds to wasm.OpcodeMemoryGrow.
  1381  //
  1382  // The engines are expected to pop one value from the top of the stack, then
  1383  // execute wasm.MemoryInstance Grow with the value, and push the previous
  1384  // page size of the memory onto the stack.
  1385  func newOperationMemoryGrow() unionOperation {
  1386  	return unionOperation{Kind: operationKindMemoryGrow}
  1387  }
  1388  
  1389  // NewOperationConstI32 is a constructor for unionOperation with OperationConstI32.
  1390  //
  1391  // This corresponds to wasm.OpcodeI32Const.
  1392  func newOperationConstI32(value uint32) unionOperation {
  1393  	return unionOperation{Kind: operationKindConstI32, U1: uint64(value)}
  1394  }
  1395  
  1396  // NewOperationConstI64 is a constructor for unionOperation with OperationConstI64.
  1397  //
  1398  // This corresponds to wasm.OpcodeI64Const.
  1399  func newOperationConstI64(value uint64) unionOperation {
  1400  	return unionOperation{Kind: operationKindConstI64, U1: value}
  1401  }
  1402  
  1403  // NewOperationConstF32 is a constructor for unionOperation with OperationConstF32.
  1404  //
  1405  // This corresponds to wasm.OpcodeF32Const.
  1406  func newOperationConstF32(value float32) unionOperation {
  1407  	return unionOperation{Kind: operationKindConstF32, U1: uint64(math.Float32bits(value))}
  1408  }
  1409  
  1410  // NewOperationConstF64 is a constructor for unionOperation with OperationConstF64.
  1411  //
  1412  // This corresponds to wasm.OpcodeF64Const.
  1413  func newOperationConstF64(value float64) unionOperation {
  1414  	return unionOperation{Kind: operationKindConstF64, U1: math.Float64bits(value)}
  1415  }
  1416  
  1417  // NewOperationEq is a constructor for unionOperation with operationKindEq.
  1418  //
  1419  // This corresponds to wasm.OpcodeI32EqName wasm.OpcodeI64EqName wasm.OpcodeF32EqName wasm.OpcodeF64EqName
  1420  func newOperationEq(b unsignedType) unionOperation {
  1421  	return unionOperation{Kind: operationKindEq, B1: byte(b)}
  1422  }
  1423  
  1424  // NewOperationNe is a constructor for unionOperation with operationKindNe.
  1425  //
  1426  // This corresponds to wasm.OpcodeI32NeName wasm.OpcodeI64NeName wasm.OpcodeF32NeName wasm.OpcodeF64NeName
  1427  func newOperationNe(b unsignedType) unionOperation {
  1428  	return unionOperation{Kind: operationKindNe, B1: byte(b)}
  1429  }
  1430  
  1431  // NewOperationEqz is a constructor for unionOperation with operationKindEqz.
  1432  //
  1433  // This corresponds to wasm.OpcodeI32EqzName wasm.OpcodeI64EqzName
  1434  func newOperationEqz(b unsignedInt) unionOperation {
  1435  	return unionOperation{Kind: operationKindEqz, B1: byte(b)}
  1436  }
  1437  
  1438  // NewOperationLt is a constructor for unionOperation with operationKindLt.
  1439  //
  1440  // This corresponds to wasm.OpcodeI32LtS wasm.OpcodeI32LtU wasm.OpcodeI64LtS wasm.OpcodeI64LtU wasm.OpcodeF32Lt wasm.OpcodeF64Lt
  1441  func newOperationLt(b signedType) unionOperation {
  1442  	return unionOperation{Kind: operationKindLt, B1: byte(b)}
  1443  }
  1444  
  1445  // NewOperationGt is a constructor for unionOperation with operationKindGt.
  1446  //
  1447  // This corresponds to wasm.OpcodeI32GtS wasm.OpcodeI32GtU wasm.OpcodeI64GtS wasm.OpcodeI64GtU wasm.OpcodeF32Gt wasm.OpcodeF64Gt
  1448  func newOperationGt(b signedType) unionOperation {
  1449  	return unionOperation{Kind: operationKindGt, B1: byte(b)}
  1450  }
  1451  
  1452  // NewOperationLe is a constructor for unionOperation with operationKindLe.
  1453  //
  1454  // This corresponds to wasm.OpcodeI32LeS wasm.OpcodeI32LeU wasm.OpcodeI64LeS wasm.OpcodeI64LeU wasm.OpcodeF32Le wasm.OpcodeF64Le
  1455  func newOperationLe(b signedType) unionOperation {
  1456  	return unionOperation{Kind: operationKindLe, B1: byte(b)}
  1457  }
  1458  
  1459  // NewOperationGe is a constructor for unionOperation with operationKindGe.
  1460  //
  1461  // This corresponds to wasm.OpcodeI32GeS wasm.OpcodeI32GeU wasm.OpcodeI64GeS wasm.OpcodeI64GeU wasm.OpcodeF32Ge wasm.OpcodeF64Ge
  1462  // NewOperationGe is the constructor for OperationGe
  1463  func newOperationGe(b signedType) unionOperation {
  1464  	return unionOperation{Kind: operationKindGe, B1: byte(b)}
  1465  }
  1466  
  1467  // NewOperationAdd is a constructor for unionOperation with operationKindAdd.
  1468  //
  1469  // This corresponds to wasm.OpcodeI32AddName wasm.OpcodeI64AddName wasm.OpcodeF32AddName wasm.OpcodeF64AddName.
  1470  func newOperationAdd(b unsignedType) unionOperation {
  1471  	return unionOperation{Kind: operationKindAdd, B1: byte(b)}
  1472  }
  1473  
  1474  // NewOperationSub is a constructor for unionOperation with operationKindSub.
  1475  //
  1476  // This corresponds to wasm.OpcodeI32SubName wasm.OpcodeI64SubName wasm.OpcodeF32SubName wasm.OpcodeF64SubName.
  1477  func newOperationSub(b unsignedType) unionOperation {
  1478  	return unionOperation{Kind: operationKindSub, B1: byte(b)}
  1479  }
  1480  
  1481  // NewOperationMul is a constructor for unionOperation with wperationKindMul.
  1482  //
  1483  // This corresponds to wasm.OpcodeI32MulName wasm.OpcodeI64MulName wasm.OpcodeF32MulName wasm.OpcodeF64MulName.
  1484  // NewOperationMul is the constructor for OperationMul
  1485  func newOperationMul(b unsignedType) unionOperation {
  1486  	return unionOperation{Kind: operationKindMul, B1: byte(b)}
  1487  }
  1488  
  1489  // NewOperationClz is a constructor for unionOperation with operationKindClz.
  1490  //
  1491  // This corresponds to wasm.OpcodeI32ClzName wasm.OpcodeI64ClzName.
  1492  //
  1493  // The engines are expected to count up the leading zeros in the
  1494  // current top of the stack, and push the count result.
  1495  // For example, stack of [..., 0x00_ff_ff_ff] results in [..., 8].
  1496  // See wasm.OpcodeI32Clz wasm.OpcodeI64Clz
  1497  func newOperationClz(b unsignedInt) unionOperation {
  1498  	return unionOperation{Kind: operationKindClz, B1: byte(b)}
  1499  }
  1500  
  1501  // NewOperationCtz is a constructor for unionOperation with operationKindCtz.
  1502  //
  1503  // This corresponds to wasm.OpcodeI32CtzName wasm.OpcodeI64CtzName.
  1504  //
  1505  // The engines are expected to count up the trailing zeros in the
  1506  // current top of the stack, and push the count result.
  1507  // For example, stack of [..., 0xff_ff_ff_00] results in [..., 8].
  1508  func newOperationCtz(b unsignedInt) unionOperation {
  1509  	return unionOperation{Kind: operationKindCtz, B1: byte(b)}
  1510  }
  1511  
  1512  // NewOperationPopcnt is a constructor for unionOperation with operationKindPopcnt.
  1513  //
  1514  // This corresponds to wasm.OpcodeI32PopcntName wasm.OpcodeI64PopcntName.
  1515  //
  1516  // The engines are expected to count up the number of set bits in the
  1517  // current top of the stack, and push the count result.
  1518  // For example, stack of [..., 0b00_00_00_11] results in [..., 2].
  1519  func newOperationPopcnt(b unsignedInt) unionOperation {
  1520  	return unionOperation{Kind: operationKindPopcnt, B1: byte(b)}
  1521  }
  1522  
  1523  // NewOperationDiv is a constructor for unionOperation with operationKindDiv.
  1524  //
  1525  // This corresponds to wasm.OpcodeI32DivS wasm.OpcodeI32DivU wasm.OpcodeI64DivS
  1526  //
  1527  //	wasm.OpcodeI64DivU wasm.OpcodeF32Div wasm.OpcodeF64Div.
  1528  func newOperationDiv(b signedType) unionOperation {
  1529  	return unionOperation{Kind: operationKindDiv, B1: byte(b)}
  1530  }
  1531  
  1532  // NewOperationRem is a constructor for unionOperation with operationKindRem.
  1533  //
  1534  // This corresponds to wasm.OpcodeI32RemS wasm.OpcodeI32RemU wasm.OpcodeI64RemS wasm.OpcodeI64RemU.
  1535  //
  1536  // The engines are expected to perform division on the top
  1537  // two values of integer type on the stack and puts the remainder of the result
  1538  // onto the stack. For example, stack [..., 10, 3] results in [..., 1] where
  1539  // the quotient is discarded.
  1540  // NewOperationRem is the constructor for OperationRem
  1541  func newOperationRem(b signedInt) unionOperation {
  1542  	return unionOperation{Kind: operationKindRem, B1: byte(b)}
  1543  }
  1544  
  1545  // NewOperationAnd is a constructor for unionOperation with operationKindAnd.
  1546  //
  1547  // # This corresponds to wasm.OpcodeI32AndName wasm.OpcodeI64AndName
  1548  //
  1549  // The engines are expected to perform "And" operation on
  1550  // top two values on the stack, and pushes the result.
  1551  func newOperationAnd(b unsignedInt) unionOperation {
  1552  	return unionOperation{Kind: operationKindAnd, B1: byte(b)}
  1553  }
  1554  
  1555  // NewOperationOr is a constructor for unionOperation with operationKindOr.
  1556  //
  1557  // # This corresponds to wasm.OpcodeI32OrName wasm.OpcodeI64OrName
  1558  //
  1559  // The engines are expected to perform "Or" operation on
  1560  // top two values on the stack, and pushes the result.
  1561  func newOperationOr(b unsignedInt) unionOperation {
  1562  	return unionOperation{Kind: operationKindOr, B1: byte(b)}
  1563  }
  1564  
  1565  // NewOperationXor is a constructor for unionOperation with operationKindXor.
  1566  //
  1567  // # This corresponds to wasm.OpcodeI32XorName wasm.OpcodeI64XorName
  1568  //
  1569  // The engines are expected to perform "Xor" operation on
  1570  // top two values on the stack, and pushes the result.
  1571  func newOperationXor(b unsignedInt) unionOperation {
  1572  	return unionOperation{Kind: operationKindXor, B1: byte(b)}
  1573  }
  1574  
  1575  // NewOperationShl is a constructor for unionOperation with operationKindShl.
  1576  //
  1577  // # This corresponds to wasm.OpcodeI32ShlName wasm.OpcodeI64ShlName
  1578  //
  1579  // The engines are expected to perform "Shl" operation on
  1580  // top two values on the stack, and pushes the result.
  1581  func newOperationShl(b unsignedInt) unionOperation {
  1582  	return unionOperation{Kind: operationKindShl, B1: byte(b)}
  1583  }
  1584  
  1585  // NewOperationShr is a constructor for unionOperation with operationKindShr.
  1586  //
  1587  // # This corresponds to wasm.OpcodeI32ShrSName wasm.OpcodeI32ShrUName wasm.OpcodeI64ShrSName wasm.OpcodeI64ShrUName
  1588  //
  1589  // If OperationShr.Type is signed integer, then, the engines are expected to perform arithmetic right shift on the two
  1590  // top values on the stack, otherwise do the logical right shift.
  1591  func newOperationShr(b signedInt) unionOperation {
  1592  	return unionOperation{Kind: operationKindShr, B1: byte(b)}
  1593  }
  1594  
  1595  // NewOperationRotl is a constructor for unionOperation with operationKindRotl.
  1596  //
  1597  // # This corresponds to wasm.OpcodeI32RotlName wasm.OpcodeI64RotlName
  1598  //
  1599  // The engines are expected to perform "Rotl" operation on
  1600  // top two values on the stack, and pushes the result.
  1601  func newOperationRotl(b unsignedInt) unionOperation {
  1602  	return unionOperation{Kind: operationKindRotl, B1: byte(b)}
  1603  }
  1604  
  1605  // NewOperationRotr is a constructor for unionOperation with operationKindRotr.
  1606  //
  1607  // # This corresponds to wasm.OpcodeI32RotrName wasm.OpcodeI64RotrName
  1608  //
  1609  // The engines are expected to perform "Rotr" operation on
  1610  // top two values on the stack, and pushes the result.
  1611  func newOperationRotr(b unsignedInt) unionOperation {
  1612  	return unionOperation{Kind: operationKindRotr, B1: byte(b)}
  1613  }
  1614  
  1615  // NewOperationAbs is a constructor for unionOperation with operationKindAbs.
  1616  //
  1617  // This corresponds to wasm.OpcodeF32Abs wasm.OpcodeF64Abs
  1618  func newOperationAbs(b float) unionOperation {
  1619  	return unionOperation{Kind: operationKindAbs, B1: byte(b)}
  1620  }
  1621  
  1622  // NewOperationNeg is a constructor for unionOperation with operationKindNeg.
  1623  //
  1624  // This corresponds to wasm.OpcodeF32Neg wasm.OpcodeF64Neg
  1625  func newOperationNeg(b float) unionOperation {
  1626  	return unionOperation{Kind: operationKindNeg, B1: byte(b)}
  1627  }
  1628  
  1629  // NewOperationCeil is a constructor for unionOperation with operationKindCeil.
  1630  //
  1631  // This corresponds to wasm.OpcodeF32CeilName wasm.OpcodeF64CeilName
  1632  func newOperationCeil(b float) unionOperation {
  1633  	return unionOperation{Kind: operationKindCeil, B1: byte(b)}
  1634  }
  1635  
  1636  // NewOperationFloor is a constructor for unionOperation with operationKindFloor.
  1637  //
  1638  // This corresponds to wasm.OpcodeF32FloorName wasm.OpcodeF64FloorName
  1639  func newOperationFloor(b float) unionOperation {
  1640  	return unionOperation{Kind: operationKindFloor, B1: byte(b)}
  1641  }
  1642  
  1643  // NewOperationTrunc is a constructor for unionOperation with operationKindTrunc.
  1644  //
  1645  // This corresponds to wasm.OpcodeF32TruncName wasm.OpcodeF64TruncName
  1646  func newOperationTrunc(b float) unionOperation {
  1647  	return unionOperation{Kind: operationKindTrunc, B1: byte(b)}
  1648  }
  1649  
  1650  // NewOperationNearest is a constructor for unionOperation with operationKindNearest.
  1651  //
  1652  // # This corresponds to wasm.OpcodeF32NearestName wasm.OpcodeF64NearestName
  1653  //
  1654  // Note: this is *not* equivalent to math.Round and instead has the same
  1655  // the semantics of LLVM's rint intrinsic. See https://llvm.org/docs/LangRef.html#llvm-rint-intrinsic.
  1656  // For example, math.Round(-4.5) produces -5 while we want to produce -4.
  1657  func newOperationNearest(b float) unionOperation {
  1658  	return unionOperation{Kind: operationKindNearest, B1: byte(b)}
  1659  }
  1660  
  1661  // NewOperationSqrt is a constructor for unionOperation with operationKindSqrt.
  1662  //
  1663  // This corresponds to wasm.OpcodeF32SqrtName wasm.OpcodeF64SqrtName
  1664  func newOperationSqrt(b float) unionOperation {
  1665  	return unionOperation{Kind: operationKindSqrt, B1: byte(b)}
  1666  }
  1667  
  1668  // NewOperationMin is a constructor for unionOperation with operationKindMin.
  1669  //
  1670  // # This corresponds to wasm.OpcodeF32MinName wasm.OpcodeF64MinName
  1671  //
  1672  // The engines are expected to pop two values from the stack, and push back the maximum of
  1673  // these two values onto the stack. For example, stack [..., 100.1, 1.9] results in [..., 1.9].
  1674  //
  1675  // Note: WebAssembly specifies that min/max must always return NaN if one of values is NaN,
  1676  // which is a different behavior different from math.Min.
  1677  func newOperationMin(b float) unionOperation {
  1678  	return unionOperation{Kind: operationKindMin, B1: byte(b)}
  1679  }
  1680  
  1681  // NewOperationMax is a constructor for unionOperation with operationKindMax.
  1682  //
  1683  // # This corresponds to wasm.OpcodeF32MaxName wasm.OpcodeF64MaxName
  1684  //
  1685  // The engines are expected to pop two values from the stack, and push back the maximum of
  1686  // these two values onto the stack. For example, stack [..., 100.1, 1.9] results in [..., 100.1].
  1687  //
  1688  // Note: WebAssembly specifies that min/max must always return NaN if one of values is NaN,
  1689  // which is a different behavior different from math.Max.
  1690  func newOperationMax(b float) unionOperation {
  1691  	return unionOperation{Kind: operationKindMax, B1: byte(b)}
  1692  }
  1693  
  1694  // NewOperationCopysign is a constructor for unionOperation with operationKindCopysign.
  1695  //
  1696  // # This corresponds to wasm.OpcodeF32CopysignName wasm.OpcodeF64CopysignName
  1697  //
  1698  // The engines are expected to pop two float values from the stack, and copy the signbit of
  1699  // the first-popped value to the last one.
  1700  // For example, stack [..., 1.213, -5.0] results in [..., -1.213].
  1701  func newOperationCopysign(b float) unionOperation {
  1702  	return unionOperation{Kind: operationKindCopysign, B1: byte(b)}
  1703  }
  1704  
  1705  // NewOperationI32WrapFromI64 is a constructor for unionOperation with operationKindI32WrapFromI64.
  1706  //
  1707  // This corresponds to wasm.OpcodeI32WrapI64 and equivalent to uint64(uint32(v)) in Go.
  1708  //
  1709  // The engines are expected to replace the 64-bit int on top of the stack
  1710  // with the corresponding 32-bit integer.
  1711  func newOperationI32WrapFromI64() unionOperation {
  1712  	return unionOperation{Kind: operationKindI32WrapFromI64}
  1713  }
  1714  
  1715  // NewOperationITruncFromF is a constructor for unionOperation with operationKindITruncFromF.
  1716  //
  1717  // This corresponds to
  1718  //
  1719  //	wasm.OpcodeI32TruncF32SName wasm.OpcodeI32TruncF32UName wasm.OpcodeI32TruncF64SName
  1720  //	wasm.OpcodeI32TruncF64UName wasm.OpcodeI64TruncF32SName wasm.OpcodeI64TruncF32UName wasm.OpcodeI64TruncF64SName
  1721  //	wasm.OpcodeI64TruncF64UName. wasm.OpcodeI32TruncSatF32SName wasm.OpcodeI32TruncSatF32UName
  1722  //	wasm.OpcodeI32TruncSatF64SName wasm.OpcodeI32TruncSatF64UName wasm.OpcodeI64TruncSatF32SName
  1723  //	wasm.OpcodeI64TruncSatF32UName wasm.OpcodeI64TruncSatF64SName wasm.OpcodeI64TruncSatF64UName
  1724  //
  1725  // See [1] and [2] for when we encounter undefined behavior in the WebAssembly specification if NewOperationITruncFromF.NonTrapping == false.
  1726  // To summarize, if the source float value is NaN or doesn't fit in the destination range of integers (incl. +=Inf),
  1727  // then the runtime behavior is undefined. In wazero, the engines are expected to exit the execution in these undefined cases with
  1728  // wasmruntime.ErrRuntimeInvalidConversionToInteger error.
  1729  //
  1730  // [1] https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#-hrefop-trunc-umathrmtruncmathsfu_m-n-z for unsigned integers.
  1731  // [2] https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#-hrefop-trunc-smathrmtruncmathsfs_m-n-z for signed integers.
  1732  //
  1733  // nonTrapping true if this conversion is "nontrapping" in the sense of the
  1734  // https://github.com/WebAssembly/spec/blob/ce4b6c4d47eb06098cc7ab2e81f24748da822f20/proposals/nontrapping-float-to-int-conversion/Overview.md
  1735  func newOperationITruncFromF(inputType float, outputType signedInt, nonTrapping bool) unionOperation {
  1736  	return unionOperation{
  1737  		Kind: operationKindITruncFromF,
  1738  		B1:   byte(inputType),
  1739  		B2:   byte(outputType),
  1740  		B3:   nonTrapping,
  1741  	}
  1742  }
  1743  
  1744  // NewOperationFConvertFromI is a constructor for unionOperation with operationKindFConvertFromI.
  1745  //
  1746  // This corresponds to
  1747  //
  1748  //	wasm.OpcodeF32ConvertI32SName wasm.OpcodeF32ConvertI32UName wasm.OpcodeF32ConvertI64SName wasm.OpcodeF32ConvertI64UName
  1749  //	wasm.OpcodeF64ConvertI32SName wasm.OpcodeF64ConvertI32UName wasm.OpcodeF64ConvertI64SName wasm.OpcodeF64ConvertI64UName
  1750  //
  1751  // and equivalent to float32(uint32(x)), float32(int32(x)), etc in Go.
  1752  func newOperationFConvertFromI(inputType signedInt, outputType float) unionOperation {
  1753  	return unionOperation{
  1754  		Kind: operationKindFConvertFromI,
  1755  		B1:   byte(inputType),
  1756  		B2:   byte(outputType),
  1757  	}
  1758  }
  1759  
  1760  // NewOperationF32DemoteFromF64 is a constructor for unionOperation with operationKindF32DemoteFromF64.
  1761  //
  1762  // This corresponds to wasm.OpcodeF32DemoteF64 and is equivalent float32(float64(v)).
  1763  func newOperationF32DemoteFromF64() unionOperation {
  1764  	return unionOperation{Kind: operationKindF32DemoteFromF64}
  1765  }
  1766  
  1767  // NewOperationF64PromoteFromF32 is a constructor for unionOperation with operationKindF64PromoteFromF32.
  1768  //
  1769  // This corresponds to wasm.OpcodeF64PromoteF32 and is equivalent float64(float32(v)).
  1770  func newOperationF64PromoteFromF32() unionOperation {
  1771  	return unionOperation{Kind: operationKindF64PromoteFromF32}
  1772  }
  1773  
  1774  // NewOperationI32ReinterpretFromF32 is a constructor for unionOperation with operationKindI32ReinterpretFromF32.
  1775  //
  1776  // This corresponds to wasm.OpcodeI32ReinterpretF32Name.
  1777  func newOperationI32ReinterpretFromF32() unionOperation {
  1778  	return unionOperation{Kind: operationKindI32ReinterpretFromF32}
  1779  }
  1780  
  1781  // NewOperationI64ReinterpretFromF64 is a constructor for unionOperation with operationKindI64ReinterpretFromF64.
  1782  //
  1783  // This corresponds to wasm.OpcodeI64ReinterpretF64Name.
  1784  func newOperationI64ReinterpretFromF64() unionOperation {
  1785  	return unionOperation{Kind: operationKindI64ReinterpretFromF64}
  1786  }
  1787  
  1788  // NewOperationF32ReinterpretFromI32 is a constructor for unionOperation with operationKindF32ReinterpretFromI32.
  1789  //
  1790  // This corresponds to wasm.OpcodeF32ReinterpretI32Name.
  1791  func newOperationF32ReinterpretFromI32() unionOperation {
  1792  	return unionOperation{Kind: operationKindF32ReinterpretFromI32}
  1793  }
  1794  
  1795  // NewOperationF64ReinterpretFromI64 is a constructor for unionOperation with operationKindF64ReinterpretFromI64.
  1796  //
  1797  // This corresponds to wasm.OpcodeF64ReinterpretI64Name.
  1798  func newOperationF64ReinterpretFromI64() unionOperation {
  1799  	return unionOperation{Kind: operationKindF64ReinterpretFromI64}
  1800  }
  1801  
  1802  // NewOperationExtend is a constructor for unionOperation with operationKindExtend.
  1803  //
  1804  // # This corresponds to wasm.OpcodeI64ExtendI32SName wasm.OpcodeI64ExtendI32UName
  1805  //
  1806  // The engines are expected to extend the 32-bit signed or unsigned int on top of the stack
  1807  // as a 64-bit integer of corresponding signedness. For unsigned case, this is just reinterpreting the
  1808  // underlying bit pattern as 64-bit integer. For signed case, this is sign-extension which preserves the
  1809  // original integer's sign.
  1810  func newOperationExtend(signed bool) unionOperation {
  1811  	op := unionOperation{Kind: operationKindExtend}
  1812  	if signed {
  1813  		op.B1 = 1
  1814  	}
  1815  	return op
  1816  }
  1817  
  1818  // NewOperationSignExtend32From8 is a constructor for unionOperation with operationKindSignExtend32From8.
  1819  //
  1820  // This corresponds to wasm.OpcodeI32Extend8SName.
  1821  //
  1822  // The engines are expected to sign-extend the first 8-bits of 32-bit in as signed 32-bit int.
  1823  func newOperationSignExtend32From8() unionOperation {
  1824  	return unionOperation{Kind: operationKindSignExtend32From8}
  1825  }
  1826  
  1827  // NewOperationSignExtend32From16 is a constructor for unionOperation with operationKindSignExtend32From16.
  1828  //
  1829  // This corresponds to wasm.OpcodeI32Extend16SName.
  1830  //
  1831  // The engines are expected to sign-extend the first 16-bits of 32-bit in as signed 32-bit int.
  1832  func newOperationSignExtend32From16() unionOperation {
  1833  	return unionOperation{Kind: operationKindSignExtend32From16}
  1834  }
  1835  
  1836  // NewOperationSignExtend64From8 is a constructor for unionOperation with operationKindSignExtend64From8.
  1837  //
  1838  // This corresponds to wasm.OpcodeI64Extend8SName.
  1839  //
  1840  // The engines are expected to sign-extend the first 8-bits of 64-bit in as signed 32-bit int.
  1841  func newOperationSignExtend64From8() unionOperation {
  1842  	return unionOperation{Kind: operationKindSignExtend64From8}
  1843  }
  1844  
  1845  // NewOperationSignExtend64From16 is a constructor for unionOperation with operationKindSignExtend64From16.
  1846  //
  1847  // This corresponds to wasm.OpcodeI64Extend16SName.
  1848  //
  1849  // The engines are expected to sign-extend the first 16-bits of 64-bit in as signed 32-bit int.
  1850  func newOperationSignExtend64From16() unionOperation {
  1851  	return unionOperation{Kind: operationKindSignExtend64From16}
  1852  }
  1853  
  1854  // NewOperationSignExtend64From32 is a constructor for unionOperation with operationKindSignExtend64From32.
  1855  //
  1856  // This corresponds to wasm.OpcodeI64Extend32SName.
  1857  //
  1858  // The engines are expected to sign-extend the first 32-bits of 64-bit in as signed 32-bit int.
  1859  func newOperationSignExtend64From32() unionOperation {
  1860  	return unionOperation{Kind: operationKindSignExtend64From32}
  1861  }
  1862  
  1863  // NewOperationMemoryInit is a constructor for unionOperation with operationKindMemoryInit.
  1864  //
  1865  // This corresponds to wasm.OpcodeMemoryInitName.
  1866  //
  1867  // dataIndex is the index of the data instance in ModuleInstance.DataInstances
  1868  // by which this operation instantiates a part of the memory.
  1869  func newOperationMemoryInit(dataIndex uint32) unionOperation {
  1870  	return unionOperation{Kind: operationKindMemoryInit, U1: uint64(dataIndex)}
  1871  }
  1872  
  1873  // NewOperationDataDrop implements Operation.
  1874  //
  1875  // This corresponds to wasm.OpcodeDataDropName.
  1876  //
  1877  // dataIndex is the index of the data instance in ModuleInstance.DataInstances
  1878  // which this operation drops.
  1879  func newOperationDataDrop(dataIndex uint32) unionOperation {
  1880  	return unionOperation{Kind: operationKindDataDrop, U1: uint64(dataIndex)}
  1881  }
  1882  
  1883  // NewOperationMemoryCopy is a consuctor for unionOperation with operationKindMemoryCopy.
  1884  //
  1885  // This corresponds to wasm.OpcodeMemoryCopyName.
  1886  func newOperationMemoryCopy() unionOperation {
  1887  	return unionOperation{Kind: operationKindMemoryCopy}
  1888  }
  1889  
  1890  // NewOperationMemoryFill is a consuctor for unionOperation with operationKindMemoryFill.
  1891  func newOperationMemoryFill() unionOperation {
  1892  	return unionOperation{Kind: operationKindMemoryFill}
  1893  }
  1894  
  1895  // NewOperationTableInit is a constructor for unionOperation with operationKindTableInit.
  1896  //
  1897  // This corresponds to wasm.OpcodeTableInitName.
  1898  //
  1899  // elemIndex is the index of the element by which this operation initializes a part of the table.
  1900  // tableIndex is the index of the table on which this operation initialize by the target element.
  1901  func newOperationTableInit(elemIndex, tableIndex uint32) unionOperation {
  1902  	return unionOperation{Kind: operationKindTableInit, U1: uint64(elemIndex), U2: uint64(tableIndex)}
  1903  }
  1904  
  1905  // NewOperationElemDrop is a constructor for unionOperation with operationKindElemDrop.
  1906  //
  1907  // This corresponds to wasm.OpcodeElemDropName.
  1908  //
  1909  // elemIndex is the index of the element which this operation drops.
  1910  func newOperationElemDrop(elemIndex uint32) unionOperation {
  1911  	return unionOperation{Kind: operationKindElemDrop, U1: uint64(elemIndex)}
  1912  }
  1913  
  1914  // NewOperationTableCopy implements Operation.
  1915  //
  1916  // This corresponds to wasm.OpcodeTableCopyName.
  1917  func newOperationTableCopy(srcTableIndex, dstTableIndex uint32) unionOperation {
  1918  	return unionOperation{Kind: operationKindTableCopy, U1: uint64(srcTableIndex), U2: uint64(dstTableIndex)}
  1919  }
  1920  
  1921  // NewOperationRefFunc constructor for unionOperation with operationKindRefFunc.
  1922  //
  1923  // This corresponds to wasm.OpcodeRefFuncName, and engines are expected to
  1924  // push the opaque pointer value of engine specific func for the given FunctionIndex.
  1925  //
  1926  // Note: in wazero, we express any reference types (funcref or externref) as opaque pointers which is uint64.
  1927  // Therefore, the engine implementations emit instructions to push the address of *function onto the stack.
  1928  func newOperationRefFunc(functionIndex uint32) unionOperation {
  1929  	return unionOperation{Kind: operationKindRefFunc, U1: uint64(functionIndex)}
  1930  }
  1931  
  1932  // NewOperationTableGet constructor for unionOperation with operationKindTableGet.
  1933  //
  1934  // This corresponds to wasm.OpcodeTableGetName.
  1935  func newOperationTableGet(tableIndex uint32) unionOperation {
  1936  	return unionOperation{Kind: operationKindTableGet, U1: uint64(tableIndex)}
  1937  }
  1938  
  1939  // NewOperationTableSet constructor for unionOperation with operationKindTableSet.
  1940  //
  1941  // This corresponds to wasm.OpcodeTableSetName.
  1942  func newOperationTableSet(tableIndex uint32) unionOperation {
  1943  	return unionOperation{Kind: operationKindTableSet, U1: uint64(tableIndex)}
  1944  }
  1945  
  1946  // NewOperationTableSize constructor for unionOperation with operationKindTableSize.
  1947  //
  1948  // This corresponds to wasm.OpcodeTableSizeName.
  1949  func newOperationTableSize(tableIndex uint32) unionOperation {
  1950  	return unionOperation{Kind: operationKindTableSize, U1: uint64(tableIndex)}
  1951  }
  1952  
  1953  // NewOperationTableGrow constructor for unionOperation with operationKindTableGrow.
  1954  //
  1955  // This corresponds to wasm.OpcodeTableGrowName.
  1956  func newOperationTableGrow(tableIndex uint32) unionOperation {
  1957  	return unionOperation{Kind: operationKindTableGrow, U1: uint64(tableIndex)}
  1958  }
  1959  
  1960  // NewOperationTableFill constructor for unionOperation with operationKindTableFill.
  1961  //
  1962  // This corresponds to wasm.OpcodeTableFillName.
  1963  func newOperationTableFill(tableIndex uint32) unionOperation {
  1964  	return unionOperation{Kind: operationKindTableFill, U1: uint64(tableIndex)}
  1965  }
  1966  
  1967  // NewOperationV128Const constructor for unionOperation with operationKindV128Const
  1968  func newOperationV128Const(lo, hi uint64) unionOperation {
  1969  	return unionOperation{Kind: operationKindV128Const, U1: lo, U2: hi}
  1970  }
  1971  
  1972  // shape corresponds to a shape of v128 values.
  1973  // https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-shape
  1974  type shape = byte
  1975  
  1976  const (
  1977  	shapeI8x16 shape = iota
  1978  	shapeI16x8
  1979  	shapeI32x4
  1980  	shapeI64x2
  1981  	shapeF32x4
  1982  	shapeF64x2
  1983  )
  1984  
  1985  func shapeName(s shape) (ret string) {
  1986  	switch s {
  1987  	case shapeI8x16:
  1988  		ret = "I8x16"
  1989  	case shapeI16x8:
  1990  		ret = "I16x8"
  1991  	case shapeI32x4:
  1992  		ret = "I32x4"
  1993  	case shapeI64x2:
  1994  		ret = "I64x2"
  1995  	case shapeF32x4:
  1996  		ret = "F32x4"
  1997  	case shapeF64x2:
  1998  		ret = "F64x2"
  1999  	}
  2000  	return
  2001  }
  2002  
  2003  // NewOperationV128Add constructor for unionOperation with operationKindV128Add.
  2004  //
  2005  // This corresponds to wasm.OpcodeVecI8x16AddName wasm.OpcodeVecI16x8AddName wasm.OpcodeVecI32x4AddName
  2006  //
  2007  //	wasm.OpcodeVecI64x2AddName wasm.OpcodeVecF32x4AddName wasm.OpcodeVecF64x2AddName
  2008  func newOperationV128Add(shape shape) unionOperation {
  2009  	return unionOperation{Kind: operationKindV128Add, B1: shape}
  2010  }
  2011  
  2012  // NewOperationV128Sub constructor for unionOperation with operationKindV128Sub.
  2013  //
  2014  // This corresponds to wasm.OpcodeVecI8x16SubName wasm.OpcodeVecI16x8SubName wasm.OpcodeVecI32x4SubName
  2015  //
  2016  //	wasm.OpcodeVecI64x2SubName wasm.OpcodeVecF32x4SubName wasm.OpcodeVecF64x2SubName
  2017  func newOperationV128Sub(shape shape) unionOperation {
  2018  	return unionOperation{Kind: operationKindV128Sub, B1: shape}
  2019  }
  2020  
  2021  // v128LoadType represents a type of wasm.OpcodeVecV128Load* instructions.
  2022  type v128LoadType = byte
  2023  
  2024  const (
  2025  	// v128LoadType128 corresponds to wasm.OpcodeVecV128LoadName.
  2026  	v128LoadType128 v128LoadType = iota
  2027  	// v128LoadType8x8s corresponds to wasm.OpcodeVecV128Load8x8SName.
  2028  	v128LoadType8x8s
  2029  	// v128LoadType8x8u corresponds to wasm.OpcodeVecV128Load8x8UName.
  2030  	v128LoadType8x8u
  2031  	// v128LoadType16x4s corresponds to wasm.OpcodeVecV128Load16x4SName
  2032  	v128LoadType16x4s
  2033  	// v128LoadType16x4u corresponds to wasm.OpcodeVecV128Load16x4UName
  2034  	v128LoadType16x4u
  2035  	// v128LoadType32x2s corresponds to wasm.OpcodeVecV128Load32x2SName
  2036  	v128LoadType32x2s
  2037  	// v128LoadType32x2u corresponds to wasm.OpcodeVecV128Load32x2UName
  2038  	v128LoadType32x2u
  2039  	// v128LoadType8Splat corresponds to wasm.OpcodeVecV128Load8SplatName
  2040  	v128LoadType8Splat
  2041  	// v128LoadType16Splat corresponds to wasm.OpcodeVecV128Load16SplatName
  2042  	v128LoadType16Splat
  2043  	// v128LoadType32Splat corresponds to wasm.OpcodeVecV128Load32SplatName
  2044  	v128LoadType32Splat
  2045  	// v128LoadType64Splat corresponds to wasm.OpcodeVecV128Load64SplatName
  2046  	v128LoadType64Splat
  2047  	// v128LoadType32zero corresponds to wasm.OpcodeVecV128Load32zeroName
  2048  	v128LoadType32zero
  2049  	// v128LoadType64zero corresponds to wasm.OpcodeVecV128Load64zeroName
  2050  	v128LoadType64zero
  2051  )
  2052  
  2053  // NewOperationV128Load is a constructor for unionOperation with operationKindV128Load.
  2054  //
  2055  // This corresponds to
  2056  //
  2057  //	wasm.OpcodeVecV128LoadName wasm.OpcodeVecV128Load8x8SName wasm.OpcodeVecV128Load8x8UName
  2058  //	wasm.OpcodeVecV128Load16x4SName wasm.OpcodeVecV128Load16x4UName wasm.OpcodeVecV128Load32x2SName
  2059  //	wasm.OpcodeVecV128Load32x2UName wasm.OpcodeVecV128Load8SplatName wasm.OpcodeVecV128Load16SplatName
  2060  //	wasm.OpcodeVecV128Load32SplatName wasm.OpcodeVecV128Load64SplatName wasm.OpcodeVecV128Load32zeroName
  2061  //	wasm.OpcodeVecV128Load64zeroName
  2062  func newOperationV128Load(loadType v128LoadType, arg memoryArg) unionOperation {
  2063  	return unionOperation{Kind: operationKindV128Load, B1: loadType, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2064  }
  2065  
  2066  // NewOperationV128LoadLane is a constructor for unionOperation with operationKindV128LoadLane.
  2067  //
  2068  // This corresponds to wasm.OpcodeVecV128Load8LaneName wasm.OpcodeVecV128Load16LaneName
  2069  //
  2070  //	wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName.
  2071  //
  2072  // laneIndex is >=0 && <(128/LaneSize).
  2073  // laneSize is either 8, 16, 32, or 64.
  2074  func newOperationV128LoadLane(laneIndex, laneSize byte, arg memoryArg) unionOperation {
  2075  	return unionOperation{Kind: operationKindV128LoadLane, B1: laneSize, B2: laneIndex, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2076  }
  2077  
  2078  // NewOperationV128Store is a constructor for unionOperation with operationKindV128Store.
  2079  //
  2080  // This corresponds to wasm.OpcodeVecV128Load8LaneName wasm.OpcodeVecV128Load16LaneName
  2081  //
  2082  //	wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName.
  2083  func newOperationV128Store(arg memoryArg) unionOperation {
  2084  	return unionOperation{
  2085  		Kind: operationKindV128Store,
  2086  		U1:   uint64(arg.Alignment),
  2087  		U2:   uint64(arg.Offset),
  2088  	}
  2089  }
  2090  
  2091  // NewOperationV128StoreLane implements Operation.
  2092  //
  2093  // This corresponds to wasm.OpcodeVecV128Load8LaneName wasm.OpcodeVecV128Load16LaneName
  2094  //
  2095  //	wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName.
  2096  //
  2097  // laneIndex is >=0 && <(128/LaneSize).
  2098  // laneSize is either 8, 16, 32, or 64.
  2099  func newOperationV128StoreLane(laneIndex byte, laneSize byte, arg memoryArg) unionOperation {
  2100  	return unionOperation{
  2101  		Kind: operationKindV128StoreLane,
  2102  		B1:   laneSize,
  2103  		B2:   laneIndex,
  2104  		U1:   uint64(arg.Alignment),
  2105  		U2:   uint64(arg.Offset),
  2106  	}
  2107  }
  2108  
  2109  // NewOperationV128ExtractLane is a constructor for unionOperation with operationKindV128ExtractLane.
  2110  //
  2111  // This corresponds to
  2112  //
  2113  //	wasm.OpcodeVecI8x16ExtractLaneSName wasm.OpcodeVecI8x16ExtractLaneUName
  2114  //	wasm.OpcodeVecI16x8ExtractLaneSName wasm.OpcodeVecI16x8ExtractLaneUName
  2115  //	wasm.OpcodeVecI32x4ExtractLaneName wasm.OpcodeVecI64x2ExtractLaneName
  2116  //	wasm.OpcodeVecF32x4ExtractLaneName wasm.OpcodeVecF64x2ExtractLaneName.
  2117  //
  2118  // laneIndex is >=0 && <M where shape = NxM.
  2119  // signed is used when shape is either i8x16 or i16x2 to specify whether to sign-extend or not.
  2120  func newOperationV128ExtractLane(laneIndex byte, signed bool, shape shape) unionOperation {
  2121  	return unionOperation{
  2122  		Kind: operationKindV128ExtractLane,
  2123  		B1:   shape,
  2124  		B2:   laneIndex,
  2125  		B3:   signed,
  2126  	}
  2127  }
  2128  
  2129  // NewOperationV128ReplaceLane is a constructor for unionOperation with operationKindV128ReplaceLane.
  2130  //
  2131  // This corresponds to
  2132  //
  2133  //	wasm.OpcodeVecI8x16ReplaceLaneName wasm.OpcodeVecI16x8ReplaceLaneName
  2134  //	wasm.OpcodeVecI32x4ReplaceLaneName wasm.OpcodeVecI64x2ReplaceLaneName
  2135  //	wasm.OpcodeVecF32x4ReplaceLaneName wasm.OpcodeVecF64x2ReplaceLaneName.
  2136  //
  2137  // laneIndex is >=0 && <M where shape = NxM.
  2138  func newOperationV128ReplaceLane(laneIndex byte, shape shape) unionOperation {
  2139  	return unionOperation{Kind: operationKindV128ReplaceLane, B1: shape, B2: laneIndex}
  2140  }
  2141  
  2142  // NewOperationV128Splat is a constructor for unionOperation with operationKindV128Splat.
  2143  //
  2144  // This corresponds to
  2145  //
  2146  //	wasm.OpcodeVecI8x16SplatName wasm.OpcodeVecI16x8SplatName
  2147  //	wasm.OpcodeVecI32x4SplatName wasm.OpcodeVecI64x2SplatName
  2148  //	wasm.OpcodeVecF32x4SplatName wasm.OpcodeVecF64x2SplatName.
  2149  func newOperationV128Splat(shape shape) unionOperation {
  2150  	return unionOperation{Kind: operationKindV128Splat, B1: shape}
  2151  }
  2152  
  2153  // NewOperationV128Shuffle is a constructor for unionOperation with operationKindV128Shuffle.
  2154  func newOperationV128Shuffle(lanes []uint64) unionOperation {
  2155  	return unionOperation{Kind: operationKindV128Shuffle, Us: lanes}
  2156  }
  2157  
  2158  // NewOperationV128Swizzle is a constructor for unionOperation with operationKindV128Swizzle.
  2159  //
  2160  // This corresponds to wasm.OpcodeVecI8x16SwizzleName.
  2161  func newOperationV128Swizzle() unionOperation {
  2162  	return unionOperation{Kind: operationKindV128Swizzle}
  2163  }
  2164  
  2165  // NewOperationV128AnyTrue is a constructor for unionOperation with operationKindV128AnyTrue.
  2166  //
  2167  // This corresponds to wasm.OpcodeVecV128AnyTrueName.
  2168  func newOperationV128AnyTrue() unionOperation {
  2169  	return unionOperation{Kind: operationKindV128AnyTrue}
  2170  }
  2171  
  2172  // NewOperationV128AllTrue is a constructor for unionOperation with operationKindV128AllTrue.
  2173  //
  2174  // This corresponds to
  2175  //
  2176  //	wasm.OpcodeVecI8x16AllTrueName wasm.OpcodeVecI16x8AllTrueName
  2177  //	wasm.OpcodeVecI32x4AllTrueName wasm.OpcodeVecI64x2AllTrueName.
  2178  func newOperationV128AllTrue(shape shape) unionOperation {
  2179  	return unionOperation{Kind: operationKindV128AllTrue, B1: shape}
  2180  }
  2181  
  2182  // NewOperationV128BitMask is a constructor for unionOperation with operationKindV128BitMask.
  2183  //
  2184  // This corresponds to
  2185  //
  2186  //	wasm.OpcodeVecI8x16BitMaskName wasm.OpcodeVecI16x8BitMaskName
  2187  //	wasm.OpcodeVecI32x4BitMaskName wasm.OpcodeVecI64x2BitMaskName.
  2188  func newOperationV128BitMask(shape shape) unionOperation {
  2189  	return unionOperation{Kind: operationKindV128BitMask, B1: shape}
  2190  }
  2191  
  2192  // NewOperationV128And is a constructor for unionOperation with operationKindV128And.
  2193  //
  2194  // This corresponds to wasm.OpcodeVecV128And.
  2195  func newOperationV128And() unionOperation {
  2196  	return unionOperation{Kind: operationKindV128And}
  2197  }
  2198  
  2199  // NewOperationV128Not is a constructor for unionOperation with operationKindV128Not.
  2200  //
  2201  // This corresponds to wasm.OpcodeVecV128Not.
  2202  func newOperationV128Not() unionOperation {
  2203  	return unionOperation{Kind: operationKindV128Not}
  2204  }
  2205  
  2206  // NewOperationV128Or is a constructor for unionOperation with operationKindV128Or.
  2207  //
  2208  // This corresponds to wasm.OpcodeVecV128Or.
  2209  func newOperationV128Or() unionOperation {
  2210  	return unionOperation{Kind: operationKindV128Or}
  2211  }
  2212  
  2213  // NewOperationV128Xor is a constructor for unionOperation with operationKindV128Xor.
  2214  //
  2215  // This corresponds to wasm.OpcodeVecV128Xor.
  2216  func newOperationV128Xor() unionOperation {
  2217  	return unionOperation{Kind: operationKindV128Xor}
  2218  }
  2219  
  2220  // NewOperationV128Bitselect is a constructor for unionOperation with operationKindV128Bitselect.
  2221  //
  2222  // This corresponds to wasm.OpcodeVecV128Bitselect.
  2223  func newOperationV128Bitselect() unionOperation {
  2224  	return unionOperation{Kind: operationKindV128Bitselect}
  2225  }
  2226  
  2227  // NewOperationV128AndNot is a constructor for unionOperation with operationKindV128AndNot.
  2228  //
  2229  // This corresponds to wasm.OpcodeVecV128AndNot.
  2230  func newOperationV128AndNot() unionOperation {
  2231  	return unionOperation{Kind: operationKindV128AndNot}
  2232  }
  2233  
  2234  // NewOperationV128Shl is a constructor for unionOperation with operationKindV128Shl.
  2235  //
  2236  // This corresponds to
  2237  //
  2238  //	wasm.OpcodeVecI8x16ShlName wasm.OpcodeVecI16x8ShlName
  2239  //	wasm.OpcodeVecI32x4ShlName wasm.OpcodeVecI64x2ShlName
  2240  func newOperationV128Shl(shape shape) unionOperation {
  2241  	return unionOperation{Kind: operationKindV128Shl, B1: shape}
  2242  }
  2243  
  2244  // NewOperationV128Shr is a constructor for unionOperation with operationKindV128Shr.
  2245  //
  2246  // This corresponds to
  2247  //
  2248  //	wasm.OpcodeVecI8x16ShrSName wasm.OpcodeVecI8x16ShrUName wasm.OpcodeVecI16x8ShrSName
  2249  //	wasm.OpcodeVecI16x8ShrUName wasm.OpcodeVecI32x4ShrSName wasm.OpcodeVecI32x4ShrUName.
  2250  //	wasm.OpcodeVecI64x2ShrSName wasm.OpcodeVecI64x2ShrUName.
  2251  func newOperationV128Shr(shape shape, signed bool) unionOperation {
  2252  	return unionOperation{Kind: operationKindV128Shr, B1: shape, B3: signed}
  2253  }
  2254  
  2255  // NewOperationV128Cmp is a constructor for unionOperation with operationKindV128Cmp.
  2256  //
  2257  // This corresponds to
  2258  //
  2259  //	wasm.OpcodeVecI8x16EqName, wasm.OpcodeVecI8x16NeName, wasm.OpcodeVecI8x16LtSName, wasm.OpcodeVecI8x16LtUName, wasm.OpcodeVecI8x16GtSName,
  2260  //	wasm.OpcodeVecI8x16GtUName, wasm.OpcodeVecI8x16LeSName, wasm.OpcodeVecI8x16LeUName, wasm.OpcodeVecI8x16GeSName, wasm.OpcodeVecI8x16GeUName,
  2261  //	wasm.OpcodeVecI16x8EqName, wasm.OpcodeVecI16x8NeName, wasm.OpcodeVecI16x8LtSName, wasm.OpcodeVecI16x8LtUName, wasm.OpcodeVecI16x8GtSName,
  2262  //	wasm.OpcodeVecI16x8GtUName, wasm.OpcodeVecI16x8LeSName, wasm.OpcodeVecI16x8LeUName, wasm.OpcodeVecI16x8GeSName, wasm.OpcodeVecI16x8GeUName,
  2263  //	wasm.OpcodeVecI32x4EqName, wasm.OpcodeVecI32x4NeName, wasm.OpcodeVecI32x4LtSName, wasm.OpcodeVecI32x4LtUName, wasm.OpcodeVecI32x4GtSName,
  2264  //	wasm.OpcodeVecI32x4GtUName, wasm.OpcodeVecI32x4LeSName, wasm.OpcodeVecI32x4LeUName, wasm.OpcodeVecI32x4GeSName, wasm.OpcodeVecI32x4GeUName,
  2265  //	wasm.OpcodeVecI64x2EqName, wasm.OpcodeVecI64x2NeName, wasm.OpcodeVecI64x2LtSName, wasm.OpcodeVecI64x2GtSName, wasm.OpcodeVecI64x2LeSName,
  2266  //	wasm.OpcodeVecI64x2GeSName, wasm.OpcodeVecF32x4EqName, wasm.OpcodeVecF32x4NeName, wasm.OpcodeVecF32x4LtName, wasm.OpcodeVecF32x4GtName,
  2267  //	wasm.OpcodeVecF32x4LeName, wasm.OpcodeVecF32x4GeName, wasm.OpcodeVecF64x2EqName, wasm.OpcodeVecF64x2NeName, wasm.OpcodeVecF64x2LtName,
  2268  //	wasm.OpcodeVecF64x2GtName, wasm.OpcodeVecF64x2LeName, wasm.OpcodeVecF64x2GeName
  2269  func newOperationV128Cmp(cmpType v128CmpType) unionOperation {
  2270  	return unionOperation{Kind: operationKindV128Cmp, B1: cmpType}
  2271  }
  2272  
  2273  // v128CmpType represents a type of vector comparison operation.
  2274  type v128CmpType = byte
  2275  
  2276  const (
  2277  	// v128CmpTypeI8x16Eq corresponds to wasm.OpcodeVecI8x16EqName.
  2278  	v128CmpTypeI8x16Eq v128CmpType = iota
  2279  	// v128CmpTypeI8x16Ne corresponds to wasm.OpcodeVecI8x16NeName.
  2280  	v128CmpTypeI8x16Ne
  2281  	// v128CmpTypeI8x16LtS corresponds to wasm.OpcodeVecI8x16LtSName.
  2282  	v128CmpTypeI8x16LtS
  2283  	// v128CmpTypeI8x16LtU corresponds to wasm.OpcodeVecI8x16LtUName.
  2284  	v128CmpTypeI8x16LtU
  2285  	// v128CmpTypeI8x16GtS corresponds to wasm.OpcodeVecI8x16GtSName.
  2286  	v128CmpTypeI8x16GtS
  2287  	// v128CmpTypeI8x16GtU corresponds to wasm.OpcodeVecI8x16GtUName.
  2288  	v128CmpTypeI8x16GtU
  2289  	// v128CmpTypeI8x16LeS corresponds to wasm.OpcodeVecI8x16LeSName.
  2290  	v128CmpTypeI8x16LeS
  2291  	// v128CmpTypeI8x16LeU corresponds to wasm.OpcodeVecI8x16LeUName.
  2292  	v128CmpTypeI8x16LeU
  2293  	// v128CmpTypeI8x16GeS corresponds to wasm.OpcodeVecI8x16GeSName.
  2294  	v128CmpTypeI8x16GeS
  2295  	// v128CmpTypeI8x16GeU corresponds to wasm.OpcodeVecI8x16GeUName.
  2296  	v128CmpTypeI8x16GeU
  2297  	// v128CmpTypeI16x8Eq corresponds to wasm.OpcodeVecI16x8EqName.
  2298  	v128CmpTypeI16x8Eq
  2299  	// v128CmpTypeI16x8Ne corresponds to wasm.OpcodeVecI16x8NeName.
  2300  	v128CmpTypeI16x8Ne
  2301  	// v128CmpTypeI16x8LtS corresponds to wasm.OpcodeVecI16x8LtSName.
  2302  	v128CmpTypeI16x8LtS
  2303  	// v128CmpTypeI16x8LtU corresponds to wasm.OpcodeVecI16x8LtUName.
  2304  	v128CmpTypeI16x8LtU
  2305  	// v128CmpTypeI16x8GtS corresponds to wasm.OpcodeVecI16x8GtSName.
  2306  	v128CmpTypeI16x8GtS
  2307  	// v128CmpTypeI16x8GtU corresponds to wasm.OpcodeVecI16x8GtUName.
  2308  	v128CmpTypeI16x8GtU
  2309  	// v128CmpTypeI16x8LeS corresponds to wasm.OpcodeVecI16x8LeSName.
  2310  	v128CmpTypeI16x8LeS
  2311  	// v128CmpTypeI16x8LeU corresponds to wasm.OpcodeVecI16x8LeUName.
  2312  	v128CmpTypeI16x8LeU
  2313  	// v128CmpTypeI16x8GeS corresponds to wasm.OpcodeVecI16x8GeSName.
  2314  	v128CmpTypeI16x8GeS
  2315  	// v128CmpTypeI16x8GeU corresponds to wasm.OpcodeVecI16x8GeUName.
  2316  	v128CmpTypeI16x8GeU
  2317  	// v128CmpTypeI32x4Eq corresponds to wasm.OpcodeVecI32x4EqName.
  2318  	v128CmpTypeI32x4Eq
  2319  	// v128CmpTypeI32x4Ne corresponds to wasm.OpcodeVecI32x4NeName.
  2320  	v128CmpTypeI32x4Ne
  2321  	// v128CmpTypeI32x4LtS corresponds to wasm.OpcodeVecI32x4LtSName.
  2322  	v128CmpTypeI32x4LtS
  2323  	// v128CmpTypeI32x4LtU corresponds to wasm.OpcodeVecI32x4LtUName.
  2324  	v128CmpTypeI32x4LtU
  2325  	// v128CmpTypeI32x4GtS corresponds to wasm.OpcodeVecI32x4GtSName.
  2326  	v128CmpTypeI32x4GtS
  2327  	// v128CmpTypeI32x4GtU corresponds to wasm.OpcodeVecI32x4GtUName.
  2328  	v128CmpTypeI32x4GtU
  2329  	// v128CmpTypeI32x4LeS corresponds to wasm.OpcodeVecI32x4LeSName.
  2330  	v128CmpTypeI32x4LeS
  2331  	// v128CmpTypeI32x4LeU corresponds to wasm.OpcodeVecI32x4LeUName.
  2332  	v128CmpTypeI32x4LeU
  2333  	// v128CmpTypeI32x4GeS corresponds to wasm.OpcodeVecI32x4GeSName.
  2334  	v128CmpTypeI32x4GeS
  2335  	// v128CmpTypeI32x4GeU corresponds to wasm.OpcodeVecI32x4GeUName.
  2336  	v128CmpTypeI32x4GeU
  2337  	// v128CmpTypeI64x2Eq corresponds to wasm.OpcodeVecI64x2EqName.
  2338  	v128CmpTypeI64x2Eq
  2339  	// v128CmpTypeI64x2Ne corresponds to wasm.OpcodeVecI64x2NeName.
  2340  	v128CmpTypeI64x2Ne
  2341  	// v128CmpTypeI64x2LtS corresponds to wasm.OpcodeVecI64x2LtSName.
  2342  	v128CmpTypeI64x2LtS
  2343  	// v128CmpTypeI64x2GtS corresponds to wasm.OpcodeVecI64x2GtSName.
  2344  	v128CmpTypeI64x2GtS
  2345  	// v128CmpTypeI64x2LeS corresponds to wasm.OpcodeVecI64x2LeSName.
  2346  	v128CmpTypeI64x2LeS
  2347  	// v128CmpTypeI64x2GeS corresponds to wasm.OpcodeVecI64x2GeSName.
  2348  	v128CmpTypeI64x2GeS
  2349  	// v128CmpTypeF32x4Eq corresponds to wasm.OpcodeVecF32x4EqName.
  2350  	v128CmpTypeF32x4Eq
  2351  	// v128CmpTypeF32x4Ne corresponds to wasm.OpcodeVecF32x4NeName.
  2352  	v128CmpTypeF32x4Ne
  2353  	// v128CmpTypeF32x4Lt corresponds to wasm.OpcodeVecF32x4LtName.
  2354  	v128CmpTypeF32x4Lt
  2355  	// v128CmpTypeF32x4Gt corresponds to wasm.OpcodeVecF32x4GtName.
  2356  	v128CmpTypeF32x4Gt
  2357  	// v128CmpTypeF32x4Le corresponds to wasm.OpcodeVecF32x4LeName.
  2358  	v128CmpTypeF32x4Le
  2359  	// v128CmpTypeF32x4Ge corresponds to wasm.OpcodeVecF32x4GeName.
  2360  	v128CmpTypeF32x4Ge
  2361  	// v128CmpTypeF64x2Eq corresponds to wasm.OpcodeVecF64x2EqName.
  2362  	v128CmpTypeF64x2Eq
  2363  	// v128CmpTypeF64x2Ne corresponds to wasm.OpcodeVecF64x2NeName.
  2364  	v128CmpTypeF64x2Ne
  2365  	// v128CmpTypeF64x2Lt corresponds to wasm.OpcodeVecF64x2LtName.
  2366  	v128CmpTypeF64x2Lt
  2367  	// v128CmpTypeF64x2Gt corresponds to wasm.OpcodeVecF64x2GtName.
  2368  	v128CmpTypeF64x2Gt
  2369  	// v128CmpTypeF64x2Le corresponds to wasm.OpcodeVecF64x2LeName.
  2370  	v128CmpTypeF64x2Le
  2371  	// v128CmpTypeF64x2Ge corresponds to wasm.OpcodeVecF64x2GeName.
  2372  	v128CmpTypeF64x2Ge
  2373  )
  2374  
  2375  // NewOperationV128AddSat is a constructor for unionOperation with operationKindV128AddSat.
  2376  //
  2377  // This corresponds to wasm.OpcodeVecI8x16AddSatUName wasm.OpcodeVecI8x16AddSatSName
  2378  //
  2379  //	wasm.OpcodeVecI16x8AddSatUName wasm.OpcodeVecI16x8AddSatSName
  2380  //
  2381  // shape is either shapeI8x16 or shapeI16x8.
  2382  func newOperationV128AddSat(shape shape, signed bool) unionOperation {
  2383  	return unionOperation{Kind: operationKindV128AddSat, B1: shape, B3: signed}
  2384  }
  2385  
  2386  // NewOperationV128SubSat is a constructor for unionOperation with operationKindV128SubSat.
  2387  //
  2388  // This corresponds to wasm.OpcodeVecI8x16SubSatUName wasm.OpcodeVecI8x16SubSatSName
  2389  //
  2390  //	wasm.OpcodeVecI16x8SubSatUName wasm.OpcodeVecI16x8SubSatSName
  2391  //
  2392  // shape is either shapeI8x16 or shapeI16x8.
  2393  func newOperationV128SubSat(shape shape, signed bool) unionOperation {
  2394  	return unionOperation{Kind: operationKindV128SubSat, B1: shape, B3: signed}
  2395  }
  2396  
  2397  // NewOperationV128Mul is a constructor for unionOperation with operationKindV128Mul
  2398  //
  2399  // This corresponds to wasm.OpcodeVecF32x4MulName wasm.OpcodeVecF64x2MulName
  2400  //
  2401  //		wasm.OpcodeVecI16x8MulName wasm.OpcodeVecI32x4MulName wasm.OpcodeVecI64x2MulName.
  2402  //	 shape is either shapeI16x8, shapeI32x4, shapeI64x2, shapeF32x4 or shapeF64x2.
  2403  func newOperationV128Mul(shape shape) unionOperation {
  2404  	return unionOperation{Kind: operationKindV128Mul, B1: shape}
  2405  }
  2406  
  2407  // NewOperationV128Div is a constructor for unionOperation with operationKindV128Div.
  2408  //
  2409  // This corresponds to wasm.OpcodeVecF32x4DivName wasm.OpcodeVecF64x2DivName.
  2410  // shape is either shapeF32x4 or shapeF64x2.
  2411  func newOperationV128Div(shape shape) unionOperation {
  2412  	return unionOperation{Kind: operationKindV128Div, B1: shape}
  2413  }
  2414  
  2415  // NewOperationV128Neg is a constructor for unionOperation with operationKindV128Neg.
  2416  //
  2417  // This corresponds to wasm.OpcodeVecI8x16NegName wasm.OpcodeVecI16x8NegName wasm.OpcodeVecI32x4NegName
  2418  //
  2419  //	wasm.OpcodeVecI64x2NegName wasm.OpcodeVecF32x4NegName wasm.OpcodeVecF64x2NegName.
  2420  func newOperationV128Neg(shape shape) unionOperation {
  2421  	return unionOperation{Kind: operationKindV128Neg, B1: shape}
  2422  }
  2423  
  2424  // NewOperationV128Sqrt is a constructor for unionOperation with 128operationKindV128Sqrt.
  2425  //
  2426  // shape is either shapeF32x4 or shapeF64x2.
  2427  // This corresponds to wasm.OpcodeVecF32x4SqrtName wasm.OpcodeVecF64x2SqrtName.
  2428  func newOperationV128Sqrt(shape shape) unionOperation {
  2429  	return unionOperation{Kind: operationKindV128Sqrt, B1: shape}
  2430  }
  2431  
  2432  // NewOperationV128Abs is a constructor for unionOperation with operationKindV128Abs.
  2433  //
  2434  // This corresponds to wasm.OpcodeVecI8x16AbsName wasm.OpcodeVecI16x8AbsName wasm.OpcodeVecI32x4AbsName
  2435  //
  2436  //	wasm.OpcodeVecI64x2AbsName wasm.OpcodeVecF32x4AbsName wasm.OpcodeVecF64x2AbsName.
  2437  func newOperationV128Abs(shape shape) unionOperation {
  2438  	return unionOperation{Kind: operationKindV128Abs, B1: shape}
  2439  }
  2440  
  2441  // NewOperationV128Popcnt is a constructor for unionOperation with operationKindV128Popcnt.
  2442  //
  2443  // This corresponds to wasm.OpcodeVecI8x16PopcntName.
  2444  func newOperationV128Popcnt(shape shape) unionOperation {
  2445  	return unionOperation{Kind: operationKindV128Popcnt, B1: shape}
  2446  }
  2447  
  2448  // NewOperationV128Min is a constructor for unionOperation with operationKindV128Min.
  2449  //
  2450  // This corresponds to
  2451  //
  2452  //	wasm.OpcodeVecI8x16MinSName wasm.OpcodeVecI8x16MinUName wasm.OpcodeVecI16x8MinSName wasm.OpcodeVecI16x8MinUName
  2453  //	wasm.OpcodeVecI32x4MinSName wasm.OpcodeVecI32x4MinUName wasm.OpcodeVecI16x8MinSName wasm.OpcodeVecI16x8MinUName
  2454  //	wasm.OpcodeVecF32x4MinName wasm.OpcodeVecF64x2MinName
  2455  func newOperationV128Min(shape shape, signed bool) unionOperation {
  2456  	return unionOperation{Kind: operationKindV128Min, B1: shape, B3: signed}
  2457  }
  2458  
  2459  // NewOperationV128Max is a constructor for unionOperation with operationKindV128Max.
  2460  //
  2461  // This corresponds to
  2462  //
  2463  //	wasm.OpcodeVecI8x16MaxSName wasm.OpcodeVecI8x16MaxUName wasm.OpcodeVecI16x8MaxSName wasm.OpcodeVecI16x8MaxUName
  2464  //	wasm.OpcodeVecI32x4MaxSName wasm.OpcodeVecI32x4MaxUName wasm.OpcodeVecI16x8MaxSName wasm.OpcodeVecI16x8MaxUName
  2465  //	wasm.OpcodeVecF32x4MaxName wasm.OpcodeVecF64x2MaxName.
  2466  func newOperationV128Max(shape shape, signed bool) unionOperation {
  2467  	return unionOperation{Kind: operationKindV128Max, B1: shape, B3: signed}
  2468  }
  2469  
  2470  // NewOperationV128AvgrU is a constructor for unionOperation with operationKindV128AvgrU.
  2471  //
  2472  // This corresponds to wasm.OpcodeVecI8x16AvgrUName.
  2473  func newOperationV128AvgrU(shape shape) unionOperation {
  2474  	return unionOperation{Kind: operationKindV128AvgrU, B1: shape}
  2475  }
  2476  
  2477  // NewOperationV128Pmin is a constructor for unionOperation with operationKindV128Pmin.
  2478  //
  2479  // This corresponds to wasm.OpcodeVecF32x4PminName wasm.OpcodeVecF64x2PminName.
  2480  func newOperationV128Pmin(shape shape) unionOperation {
  2481  	return unionOperation{Kind: operationKindV128Pmin, B1: shape}
  2482  }
  2483  
  2484  // NewOperationV128Pmax is a constructor for unionOperation with operationKindV128Pmax.
  2485  //
  2486  // This corresponds to wasm.OpcodeVecF32x4PmaxName wasm.OpcodeVecF64x2PmaxName.
  2487  func newOperationV128Pmax(shape shape) unionOperation {
  2488  	return unionOperation{Kind: operationKindV128Pmax, B1: shape}
  2489  }
  2490  
  2491  // NewOperationV128Ceil is a constructor for unionOperation with operationKindV128Ceil.
  2492  //
  2493  // This corresponds to wasm.OpcodeVecF32x4CeilName wasm.OpcodeVecF64x2CeilName
  2494  func newOperationV128Ceil(shape shape) unionOperation {
  2495  	return unionOperation{Kind: operationKindV128Ceil, B1: shape}
  2496  }
  2497  
  2498  // NewOperationV128Floor is a constructor for unionOperation with operationKindV128Floor.
  2499  //
  2500  // This corresponds to wasm.OpcodeVecF32x4FloorName wasm.OpcodeVecF64x2FloorName
  2501  func newOperationV128Floor(shape shape) unionOperation {
  2502  	return unionOperation{Kind: operationKindV128Floor, B1: shape}
  2503  }
  2504  
  2505  // NewOperationV128Trunc is a constructor for unionOperation with operationKindV128Trunc.
  2506  //
  2507  // This corresponds to wasm.OpcodeVecF32x4TruncName wasm.OpcodeVecF64x2TruncName
  2508  func newOperationV128Trunc(shape shape) unionOperation {
  2509  	return unionOperation{Kind: operationKindV128Trunc, B1: shape}
  2510  }
  2511  
  2512  // NewOperationV128Nearest is a constructor for unionOperation with operationKindV128Nearest.
  2513  //
  2514  // This corresponds to wasm.OpcodeVecF32x4NearestName wasm.OpcodeVecF64x2NearestName
  2515  func newOperationV128Nearest(shape shape) unionOperation {
  2516  	return unionOperation{Kind: operationKindV128Nearest, B1: shape}
  2517  }
  2518  
  2519  // NewOperationV128Extend is a constructor for unionOperation with operationKindV128Extend.
  2520  //
  2521  // This corresponds to
  2522  //
  2523  //	wasm.OpcodeVecI16x8ExtendLowI8x16SName wasm.OpcodeVecI16x8ExtendHighI8x16SName
  2524  //	wasm.OpcodeVecI16x8ExtendLowI8x16UName wasm.OpcodeVecI16x8ExtendHighI8x16UName
  2525  //	wasm.OpcodeVecI32x4ExtendLowI16x8SName wasm.OpcodeVecI32x4ExtendHighI16x8SName
  2526  //	wasm.OpcodeVecI32x4ExtendLowI16x8UName wasm.OpcodeVecI32x4ExtendHighI16x8UName
  2527  //	wasm.OpcodeVecI64x2ExtendLowI32x4SName wasm.OpcodeVecI64x2ExtendHighI32x4SName
  2528  //	wasm.OpcodeVecI64x2ExtendLowI32x4UName wasm.OpcodeVecI64x2ExtendHighI32x4UName
  2529  //
  2530  // originshape is the shape of the original lanes for extension which is
  2531  // either shapeI8x16, shapeI16x8, or shapeI32x4.
  2532  // useLow true if it uses the lower half of vector for extension.
  2533  func newOperationV128Extend(originshape shape, signed bool, useLow bool) unionOperation {
  2534  	op := unionOperation{Kind: operationKindV128Extend}
  2535  	op.B1 = originshape
  2536  	if signed {
  2537  		op.B2 = 1
  2538  	}
  2539  	op.B3 = useLow
  2540  	return op
  2541  }
  2542  
  2543  // NewOperationV128ExtMul is a constructor for unionOperation with operationKindV128ExtMul.
  2544  //
  2545  // This corresponds to
  2546  //
  2547  //		wasm.OpcodeVecI16x8ExtMulLowI8x16SName wasm.OpcodeVecI16x8ExtMulLowI8x16UName
  2548  //		wasm.OpcodeVecI16x8ExtMulHighI8x16SName wasm.OpcodeVecI16x8ExtMulHighI8x16UName
  2549  //	 wasm.OpcodeVecI32x4ExtMulLowI16x8SName wasm.OpcodeVecI32x4ExtMulLowI16x8UName
  2550  //		wasm.OpcodeVecI32x4ExtMulHighI16x8SName wasm.OpcodeVecI32x4ExtMulHighI16x8UName
  2551  //	 wasm.OpcodeVecI64x2ExtMulLowI32x4SName wasm.OpcodeVecI64x2ExtMulLowI32x4UName
  2552  //		wasm.OpcodeVecI64x2ExtMulHighI32x4SName wasm.OpcodeVecI64x2ExtMulHighI32x4UName.
  2553  //
  2554  // originshape is the shape of the original lanes for extension which is
  2555  // either shapeI8x16, shapeI16x8, or shapeI32x4.
  2556  // useLow true if it uses the lower half of vector for extension.
  2557  func newOperationV128ExtMul(originshape shape, signed bool, useLow bool) unionOperation {
  2558  	op := unionOperation{Kind: operationKindV128ExtMul}
  2559  	op.B1 = originshape
  2560  	if signed {
  2561  		op.B2 = 1
  2562  	}
  2563  	op.B3 = useLow
  2564  	return op
  2565  }
  2566  
  2567  // NewOperationV128Q15mulrSatS is a constructor for unionOperation with operationKindV128Q15mulrSatS.
  2568  //
  2569  // This corresponds to wasm.OpcodeVecI16x8Q15mulrSatSName
  2570  func newOperationV128Q15mulrSatS() unionOperation {
  2571  	return unionOperation{Kind: operationKindV128Q15mulrSatS}
  2572  }
  2573  
  2574  // NewOperationV128ExtAddPairwise is a constructor for unionOperation with operationKindV128ExtAddPairwise.
  2575  //
  2576  // This corresponds to
  2577  //
  2578  //	wasm.OpcodeVecI16x8ExtaddPairwiseI8x16SName wasm.OpcodeVecI16x8ExtaddPairwiseI8x16UName
  2579  //	wasm.OpcodeVecI32x4ExtaddPairwiseI16x8SName wasm.OpcodeVecI32x4ExtaddPairwiseI16x8UName.
  2580  //
  2581  // originshape is the shape of the original lanes for extension which is
  2582  // either shapeI8x16, or shapeI16x8.
  2583  func newOperationV128ExtAddPairwise(originshape shape, signed bool) unionOperation {
  2584  	return unionOperation{Kind: operationKindV128ExtAddPairwise, B1: originshape, B3: signed}
  2585  }
  2586  
  2587  // NewOperationV128FloatPromote is a constructor for unionOperation with NewOperationV128FloatPromote.
  2588  //
  2589  // This corresponds to wasm.OpcodeVecF64x2PromoteLowF32x4ZeroName
  2590  // This discards the higher 64-bit of a vector, and promotes two
  2591  // 32-bit floats in the lower 64-bit as two 64-bit floats.
  2592  func newOperationV128FloatPromote() unionOperation {
  2593  	return unionOperation{Kind: operationKindV128FloatPromote}
  2594  }
  2595  
  2596  // NewOperationV128FloatDemote is a constructor for unionOperation with NewOperationV128FloatDemote.
  2597  //
  2598  // This corresponds to wasm.OpcodeVecF32x4DemoteF64x2ZeroName.
  2599  func newOperationV128FloatDemote() unionOperation {
  2600  	return unionOperation{Kind: operationKindV128FloatDemote}
  2601  }
  2602  
  2603  // NewOperationV128FConvertFromI is a constructor for unionOperation with NewOperationV128FConvertFromI.
  2604  //
  2605  // This corresponds to
  2606  //
  2607  //	wasm.OpcodeVecF32x4ConvertI32x4SName wasm.OpcodeVecF32x4ConvertI32x4UName
  2608  //	wasm.OpcodeVecF64x2ConvertLowI32x4SName wasm.OpcodeVecF64x2ConvertLowI32x4UName.
  2609  //
  2610  // destinationshape is the shape of the destination lanes for conversion which is
  2611  // either shapeF32x4, or shapeF64x2.
  2612  func newOperationV128FConvertFromI(destinationshape shape, signed bool) unionOperation {
  2613  	return unionOperation{Kind: operationKindV128FConvertFromI, B1: destinationshape, B3: signed}
  2614  }
  2615  
  2616  // NewOperationV128Dot is a constructor for unionOperation with operationKindV128Dot.
  2617  //
  2618  // This corresponds to wasm.OpcodeVecI32x4DotI16x8SName
  2619  func newOperationV128Dot() unionOperation {
  2620  	return unionOperation{Kind: operationKindV128Dot}
  2621  }
  2622  
  2623  // NewOperationV128Narrow is a constructor for unionOperation with operationKindV128Narrow.
  2624  //
  2625  // This corresponds to
  2626  //
  2627  //	wasm.OpcodeVecI8x16NarrowI16x8SName wasm.OpcodeVecI8x16NarrowI16x8UName
  2628  //	wasm.OpcodeVecI16x8NarrowI32x4SName wasm.OpcodeVecI16x8NarrowI32x4UName.
  2629  //
  2630  // originshape is the shape of the original lanes for narrowing which is
  2631  // either shapeI16x8, or shapeI32x4.
  2632  func newOperationV128Narrow(originshape shape, signed bool) unionOperation {
  2633  	return unionOperation{Kind: operationKindV128Narrow, B1: originshape, B3: signed}
  2634  }
  2635  
  2636  // NewOperationV128ITruncSatFromF is a constructor for unionOperation with operationKindV128ITruncSatFromF.
  2637  //
  2638  // This corresponds to
  2639  //
  2640  //	wasm.OpcodeVecI32x4TruncSatF64x2UZeroName wasm.OpcodeVecI32x4TruncSatF64x2SZeroName
  2641  //	wasm.OpcodeVecI32x4TruncSatF32x4UName wasm.OpcodeVecI32x4TruncSatF32x4SName.
  2642  //
  2643  // originshape is the shape of the original lanes for truncation which is
  2644  // either shapeF32x4, or shapeF64x2.
  2645  func newOperationV128ITruncSatFromF(originshape shape, signed bool) unionOperation {
  2646  	return unionOperation{Kind: operationKindV128ITruncSatFromF, B1: originshape, B3: signed}
  2647  }
  2648  
  2649  // atomicArithmeticOp is the type for the operation kind of atomic arithmetic operations.
  2650  type atomicArithmeticOp byte
  2651  
  2652  const (
  2653  	// atomicArithmeticOpAdd is the kind for an add operation.
  2654  	atomicArithmeticOpAdd atomicArithmeticOp = iota
  2655  	// atomicArithmeticOpSub is the kind for a sub operation.
  2656  	atomicArithmeticOpSub
  2657  	// atomicArithmeticOpAnd is the kind for a bitwise and operation.
  2658  	atomicArithmeticOpAnd
  2659  	// atomicArithmeticOpOr is the kind for a bitwise or operation.
  2660  	atomicArithmeticOpOr
  2661  	// atomicArithmeticOpXor is the kind for a bitwise xor operation.
  2662  	atomicArithmeticOpXor
  2663  	// atomicArithmeticOpNop is the kind for a nop operation.
  2664  	atomicArithmeticOpNop
  2665  )
  2666  
  2667  // NewOperationAtomicMemoryWait is a constructor for unionOperation with operationKindAtomicMemoryWait.
  2668  //
  2669  // This corresponds to
  2670  //
  2671  //	wasm.OpcodeAtomicWait32Name wasm.OpcodeAtomicWait64Name
  2672  func newOperationAtomicMemoryWait(unsignedType unsignedType, arg memoryArg) unionOperation {
  2673  	return unionOperation{Kind: operationKindAtomicMemoryWait, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2674  }
  2675  
  2676  // NewOperationAtomicMemoryNotify is a constructor for unionOperation with operationKindAtomicMemoryNotify.
  2677  //
  2678  // This corresponds to
  2679  //
  2680  //	wasm.OpcodeAtomicNotifyName
  2681  func newOperationAtomicMemoryNotify(arg memoryArg) unionOperation {
  2682  	return unionOperation{Kind: operationKindAtomicMemoryNotify, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2683  }
  2684  
  2685  // NewOperationAtomicFence is a constructor for unionOperation with operationKindAtomicFence.
  2686  //
  2687  // This corresponds to
  2688  //
  2689  //	wasm.OpcodeAtomicFenceName
  2690  func newOperationAtomicFence() unionOperation {
  2691  	return unionOperation{Kind: operationKindAtomicFence}
  2692  }
  2693  
  2694  // NewOperationAtomicLoad is a constructor for unionOperation with operationKindAtomicLoad.
  2695  //
  2696  // This corresponds to
  2697  //
  2698  //	wasm.OpcodeAtomicI32LoadName wasm.OpcodeAtomicI64LoadName
  2699  func newOperationAtomicLoad(unsignedType unsignedType, arg memoryArg) unionOperation {
  2700  	return unionOperation{Kind: operationKindAtomicLoad, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2701  }
  2702  
  2703  // NewOperationAtomicLoad8 is a constructor for unionOperation with operationKindAtomicLoad8.
  2704  //
  2705  // This corresponds to
  2706  //
  2707  //	wasm.OpcodeAtomicI32Load8UName wasm.OpcodeAtomicI64Load8UName
  2708  func newOperationAtomicLoad8(unsignedType unsignedType, arg memoryArg) unionOperation {
  2709  	return unionOperation{Kind: operationKindAtomicLoad8, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2710  }
  2711  
  2712  // NewOperationAtomicLoad16 is a constructor for unionOperation with operationKindAtomicLoad16.
  2713  //
  2714  // This corresponds to
  2715  //
  2716  //	wasm.OpcodeAtomicI32Load16UName wasm.OpcodeAtomicI64Load16UName
  2717  func newOperationAtomicLoad16(unsignedType unsignedType, arg memoryArg) unionOperation {
  2718  	return unionOperation{Kind: operationKindAtomicLoad16, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2719  }
  2720  
  2721  // NewOperationAtomicStore is a constructor for unionOperation with operationKindAtomicStore.
  2722  //
  2723  // This corresponds to
  2724  //
  2725  //	wasm.OpcodeAtomicI32StoreName wasm.OpcodeAtomicI64StoreName
  2726  func newOperationAtomicStore(unsignedType unsignedType, arg memoryArg) unionOperation {
  2727  	return unionOperation{Kind: operationKindAtomicStore, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2728  }
  2729  
  2730  // NewOperationAtomicStore8 is a constructor for unionOperation with operationKindAtomicStore8.
  2731  //
  2732  // This corresponds to
  2733  //
  2734  //	wasm.OpcodeAtomicI32Store8UName wasm.OpcodeAtomicI64Store8UName
  2735  func newOperationAtomicStore8(unsignedType unsignedType, arg memoryArg) unionOperation {
  2736  	return unionOperation{Kind: operationKindAtomicStore8, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2737  }
  2738  
  2739  // NewOperationAtomicStore16 is a constructor for unionOperation with operationKindAtomicStore16.
  2740  //
  2741  // This corresponds to
  2742  //
  2743  //	wasm.OpcodeAtomicI32Store16UName wasm.OpcodeAtomicI64Store16UName
  2744  func newOperationAtomicStore16(unsignedType unsignedType, arg memoryArg) unionOperation {
  2745  	return unionOperation{Kind: operationKindAtomicStore16, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2746  }
  2747  
  2748  // NewOperationAtomicRMW is a constructor for unionOperation with operationKindAtomicRMW.
  2749  //
  2750  // This corresponds to
  2751  //
  2752  //	wasm.OpcodeAtomicI32RMWAddName wasm.OpcodeAtomicI64RmwAddName
  2753  //	wasm.OpcodeAtomicI32RMWSubName wasm.OpcodeAtomicI64RmwSubName
  2754  //	wasm.OpcodeAtomicI32RMWAndName wasm.OpcodeAtomicI64RmwAndName
  2755  //	wasm.OpcodeAtomicI32RMWOrName wasm.OpcodeAtomicI64RmwOrName
  2756  //	wasm.OpcodeAtomicI32RMWXorName wasm.OpcodeAtomicI64RmwXorName
  2757  func newOperationAtomicRMW(unsignedType unsignedType, arg memoryArg, op atomicArithmeticOp) unionOperation {
  2758  	return unionOperation{Kind: operationKindAtomicRMW, B1: byte(unsignedType), B2: byte(op), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2759  }
  2760  
  2761  // NewOperationAtomicRMW8 is a constructor for unionOperation with operationKindAtomicRMW8.
  2762  //
  2763  // This corresponds to
  2764  //
  2765  //	wasm.OpcodeAtomicI32RMW8AddUName wasm.OpcodeAtomicI64Rmw8AddUName
  2766  //	wasm.OpcodeAtomicI32RMW8SubUName wasm.OpcodeAtomicI64Rmw8SubUName
  2767  //	wasm.OpcodeAtomicI32RMW8AndUName wasm.OpcodeAtomicI64Rmw8AndUName
  2768  //	wasm.OpcodeAtomicI32RMW8OrUName wasm.OpcodeAtomicI64Rmw8OrUName
  2769  //	wasm.OpcodeAtomicI32RMW8XorUName wasm.OpcodeAtomicI64Rmw8XorUName
  2770  func newOperationAtomicRMW8(unsignedType unsignedType, arg memoryArg, op atomicArithmeticOp) unionOperation {
  2771  	return unionOperation{Kind: operationKindAtomicRMW8, B1: byte(unsignedType), B2: byte(op), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2772  }
  2773  
  2774  // NewOperationAtomicRMW16 is a constructor for unionOperation with operationKindAtomicRMW16.
  2775  //
  2776  // This corresponds to
  2777  //
  2778  //	wasm.OpcodeAtomicI32RMW16AddUName wasm.OpcodeAtomicI64Rmw16AddUName
  2779  //	wasm.OpcodeAtomicI32RMW16SubUName wasm.OpcodeAtomicI64Rmw16SubUName
  2780  //	wasm.OpcodeAtomicI32RMW16AndUName wasm.OpcodeAtomicI64Rmw16AndUName
  2781  //	wasm.OpcodeAtomicI32RMW16OrUName wasm.OpcodeAtomicI64Rmw16OrUName
  2782  //	wasm.OpcodeAtomicI32RMW16XorUName wasm.OpcodeAtomicI64Rmw16XorUName
  2783  func newOperationAtomicRMW16(unsignedType unsignedType, arg memoryArg, op atomicArithmeticOp) unionOperation {
  2784  	return unionOperation{Kind: operationKindAtomicRMW16, B1: byte(unsignedType), B2: byte(op), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2785  }
  2786  
  2787  // NewOperationAtomicRMWCmpxchg is a constructor for unionOperation with operationKindAtomicRMWCmpxchg.
  2788  //
  2789  // This corresponds to
  2790  //
  2791  //	wasm.OpcodeAtomicI32RMWCmpxchgName wasm.OpcodeAtomicI64RmwCmpxchgName
  2792  func newOperationAtomicRMWCmpxchg(unsignedType unsignedType, arg memoryArg) unionOperation {
  2793  	return unionOperation{Kind: operationKindAtomicRMWCmpxchg, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2794  }
  2795  
  2796  // NewOperationAtomicRMW8Cmpxchg is a constructor for unionOperation with operationKindAtomicRMW8Cmpxchg.
  2797  //
  2798  // This corresponds to
  2799  //
  2800  //	wasm.OpcodeAtomicI32RMW8CmpxchgUName wasm.OpcodeAtomicI64Rmw8CmpxchgUName
  2801  func newOperationAtomicRMW8Cmpxchg(unsignedType unsignedType, arg memoryArg) unionOperation {
  2802  	return unionOperation{Kind: operationKindAtomicRMW8Cmpxchg, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2803  }
  2804  
  2805  // NewOperationAtomicRMW16Cmpxchg is a constructor for unionOperation with operationKindAtomicRMW16Cmpxchg.
  2806  //
  2807  // This corresponds to
  2808  //
  2809  //	wasm.OpcodeAtomicI32RMW16CmpxchgUName wasm.OpcodeAtomicI64Rmw16CmpxchgUName
  2810  func newOperationAtomicRMW16Cmpxchg(unsignedType unsignedType, arg memoryArg) unionOperation {
  2811  	return unionOperation{Kind: operationKindAtomicRMW16Cmpxchg, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  2812  }