...

Source file src/github.com/tetratelabs/wazero/internal/wazeroir/operations.go

Documentation: github.com/tetratelabs/wazero/internal/wazeroir

     1  package wazeroir
     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  	Float32 Float = iota
    58  	Float64
    59  )
    60  
    61  // String implements fmt.Stringer.
    62  func (s Float) String() (ret string) {
    63  	switch s {
    64  	case Float32:
    65  		ret = "f32"
    66  	case Float64:
    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  	default:
   419  		panic(fmt.Errorf("unknown operation %d", o))
   420  	}
   421  	return
   422  }
   423  
   424  const (
   425  	// OperationKindUnreachable is the Kind for NewOperationUnreachable.
   426  	OperationKindUnreachable OperationKind = iota
   427  	// OperationKindLabel is the Kind for NewOperationLabel.
   428  	OperationKindLabel
   429  	// OperationKindBr is the Kind for NewOperationBr.
   430  	OperationKindBr
   431  	// OperationKindBrIf is the Kind for NewOperationBrIf.
   432  	OperationKindBrIf
   433  	// OperationKindBrTable is the Kind for NewOperationBrTable.
   434  	OperationKindBrTable
   435  	// OperationKindCall is the Kind for NewOperationCall.
   436  	OperationKindCall
   437  	// OperationKindCallIndirect is the Kind for NewOperationCallIndirect.
   438  	OperationKindCallIndirect
   439  	// OperationKindDrop is the Kind for NewOperationDrop.
   440  	OperationKindDrop
   441  	// OperationKindSelect is the Kind for NewOperationSelect.
   442  	OperationKindSelect
   443  	// OperationKindPick is the Kind for NewOperationPick.
   444  	OperationKindPick
   445  	// OperationKindSet is the Kind for NewOperationSet.
   446  	OperationKindSet
   447  	// OperationKindGlobalGet is the Kind for NewOperationGlobalGet.
   448  	OperationKindGlobalGet
   449  	// OperationKindGlobalSet is the Kind for NewOperationGlobalSet.
   450  	OperationKindGlobalSet
   451  	// OperationKindLoad is the Kind for NewOperationLoad.
   452  	OperationKindLoad
   453  	// OperationKindLoad8 is the Kind for NewOperationLoad8.
   454  	OperationKindLoad8
   455  	// OperationKindLoad16 is the Kind for NewOperationLoad16.
   456  	OperationKindLoad16
   457  	// OperationKindLoad32 is the Kind for NewOperationLoad32.
   458  	OperationKindLoad32
   459  	// OperationKindStore is the Kind for NewOperationStore.
   460  	OperationKindStore
   461  	// OperationKindStore8 is the Kind for NewOperationStore8.
   462  	OperationKindStore8
   463  	// OperationKindStore16 is the Kind for NewOperationStore16.
   464  	OperationKindStore16
   465  	// OperationKindStore32 is the Kind for NewOperationStore32.
   466  	OperationKindStore32
   467  	// OperationKindMemorySize is the Kind for NewOperationMemorySize.
   468  	OperationKindMemorySize
   469  	// OperationKindMemoryGrow is the Kind for NewOperationMemoryGrow.
   470  	OperationKindMemoryGrow
   471  	// OperationKindConstI32 is the Kind for NewOperationConstI32.
   472  	OperationKindConstI32
   473  	// OperationKindConstI64 is the Kind for NewOperationConstI64.
   474  	OperationKindConstI64
   475  	// OperationKindConstF32 is the Kind for NewOperationConstF32.
   476  	OperationKindConstF32
   477  	// OperationKindConstF64 is the Kind for NewOperationConstF64.
   478  	OperationKindConstF64
   479  	// OperationKindEq is the Kind for NewOperationEq.
   480  	OperationKindEq
   481  	// OperationKindNe is the Kind for NewOperationNe.
   482  	OperationKindNe
   483  	// OperationKindEqz is the Kind for NewOperationEqz.
   484  	OperationKindEqz
   485  	// OperationKindLt is the Kind for NewOperationLt.
   486  	OperationKindLt
   487  	// OperationKindGt is the Kind for NewOperationGt.
   488  	OperationKindGt
   489  	// OperationKindLe is the Kind for NewOperationLe.
   490  	OperationKindLe
   491  	// OperationKindGe is the Kind for NewOperationGe.
   492  	OperationKindGe
   493  	// OperationKindAdd is the Kind for NewOperationAdd.
   494  	OperationKindAdd
   495  	// OperationKindSub is the Kind for NewOperationSub.
   496  	OperationKindSub
   497  	// OperationKindMul is the Kind for NewOperationMul.
   498  	OperationKindMul
   499  	// OperationKindClz is the Kind for NewOperationClz.
   500  	OperationKindClz
   501  	// OperationKindCtz is the Kind for NewOperationCtz.
   502  	OperationKindCtz
   503  	// OperationKindPopcnt is the Kind for NewOperationPopcnt.
   504  	OperationKindPopcnt
   505  	// OperationKindDiv is the Kind for NewOperationDiv.
   506  	OperationKindDiv
   507  	// OperationKindRem is the Kind for NewOperationRem.
   508  	OperationKindRem
   509  	// OperationKindAnd is the Kind for NewOperationAnd.
   510  	OperationKindAnd
   511  	// OperationKindOr is the Kind for NewOperationOr.
   512  	OperationKindOr
   513  	// OperationKindXor is the Kind for NewOperationXor.
   514  	OperationKindXor
   515  	// OperationKindShl is the Kind for NewOperationShl.
   516  	OperationKindShl
   517  	// OperationKindShr is the Kind for NewOperationShr.
   518  	OperationKindShr
   519  	// OperationKindRotl is the Kind for NewOperationRotl.
   520  	OperationKindRotl
   521  	// OperationKindRotr is the Kind for NewOperationRotr.
   522  	OperationKindRotr
   523  	// OperationKindAbs is the Kind for NewOperationAbs.
   524  	OperationKindAbs
   525  	// OperationKindNeg is the Kind for NewOperationNeg.
   526  	OperationKindNeg
   527  	// OperationKindCeil is the Kind for NewOperationCeil.
   528  	OperationKindCeil
   529  	// OperationKindFloor is the Kind for NewOperationFloor.
   530  	OperationKindFloor
   531  	// OperationKindTrunc is the Kind for NewOperationTrunc.
   532  	OperationKindTrunc
   533  	// OperationKindNearest is the Kind for NewOperationNearest.
   534  	OperationKindNearest
   535  	// OperationKindSqrt is the Kind for NewOperationSqrt.
   536  	OperationKindSqrt
   537  	// OperationKindMin is the Kind for NewOperationMin.
   538  	OperationKindMin
   539  	// OperationKindMax is the Kind for NewOperationMax.
   540  	OperationKindMax
   541  	// OperationKindCopysign is the Kind for NewOperationCopysign.
   542  	OperationKindCopysign
   543  	// OperationKindI32WrapFromI64 is the Kind for NewOperationI32WrapFromI64.
   544  	OperationKindI32WrapFromI64
   545  	// OperationKindITruncFromF is the Kind for NewOperationITruncFromF.
   546  	OperationKindITruncFromF
   547  	// OperationKindFConvertFromI is the Kind for NewOperationFConvertFromI.
   548  	OperationKindFConvertFromI
   549  	// OperationKindF32DemoteFromF64 is the Kind for NewOperationF32DemoteFromF64.
   550  	OperationKindF32DemoteFromF64
   551  	// OperationKindF64PromoteFromF32 is the Kind for NewOperationF64PromoteFromF32.
   552  	OperationKindF64PromoteFromF32
   553  	// OperationKindI32ReinterpretFromF32 is the Kind for NewOperationI32ReinterpretFromF32.
   554  	OperationKindI32ReinterpretFromF32
   555  	// OperationKindI64ReinterpretFromF64 is the Kind for NewOperationI64ReinterpretFromF64.
   556  	OperationKindI64ReinterpretFromF64
   557  	// OperationKindF32ReinterpretFromI32 is the Kind for NewOperationF32ReinterpretFromI32.
   558  	OperationKindF32ReinterpretFromI32
   559  	// OperationKindF64ReinterpretFromI64 is the Kind for NewOperationF64ReinterpretFromI64.
   560  	OperationKindF64ReinterpretFromI64
   561  	// OperationKindExtend is the Kind for NewOperationExtend.
   562  	OperationKindExtend
   563  	// OperationKindSignExtend32From8 is the Kind for NewOperationSignExtend32From8.
   564  	OperationKindSignExtend32From8
   565  	// OperationKindSignExtend32From16 is the Kind for NewOperationSignExtend32From16.
   566  	OperationKindSignExtend32From16
   567  	// OperationKindSignExtend64From8 is the Kind for NewOperationSignExtend64From8.
   568  	OperationKindSignExtend64From8
   569  	// OperationKindSignExtend64From16 is the Kind for NewOperationSignExtend64From16.
   570  	OperationKindSignExtend64From16
   571  	// OperationKindSignExtend64From32 is the Kind for NewOperationSignExtend64From32.
   572  	OperationKindSignExtend64From32
   573  	// OperationKindMemoryInit is the Kind for NewOperationMemoryInit.
   574  	OperationKindMemoryInit
   575  	// OperationKindDataDrop is the Kind for NewOperationDataDrop.
   576  	OperationKindDataDrop
   577  	// OperationKindMemoryCopy is the Kind for NewOperationMemoryCopy.
   578  	OperationKindMemoryCopy
   579  	// OperationKindMemoryFill is the Kind for NewOperationMemoryFill.
   580  	OperationKindMemoryFill
   581  	// OperationKindTableInit is the Kind for NewOperationTableInit.
   582  	OperationKindTableInit
   583  	// OperationKindElemDrop is the Kind for NewOperationElemDrop.
   584  	OperationKindElemDrop
   585  	// OperationKindTableCopy is the Kind for NewOperationTableCopy.
   586  	OperationKindTableCopy
   587  	// OperationKindRefFunc is the Kind for NewOperationRefFunc.
   588  	OperationKindRefFunc
   589  	// OperationKindTableGet is the Kind for NewOperationTableGet.
   590  	OperationKindTableGet
   591  	// OperationKindTableSet is the Kind for NewOperationTableSet.
   592  	OperationKindTableSet
   593  	// OperationKindTableSize is the Kind for NewOperationTableSize.
   594  	OperationKindTableSize
   595  	// OperationKindTableGrow is the Kind for NewOperationTableGrow.
   596  	OperationKindTableGrow
   597  	// OperationKindTableFill is the Kind for NewOperationTableFill.
   598  	OperationKindTableFill
   599  
   600  	// Vector value related instructions are prefixed by V128.
   601  
   602  	// OperationKindV128Const is the Kind for NewOperationV128Const.
   603  	OperationKindV128Const
   604  	// OperationKindV128Add is the Kind for NewOperationV128Add.
   605  	OperationKindV128Add
   606  	// OperationKindV128Sub is the Kind for NewOperationV128Sub.
   607  	OperationKindV128Sub
   608  	// OperationKindV128Load is the Kind for NewOperationV128Load.
   609  	OperationKindV128Load
   610  	// OperationKindV128LoadLane is the Kind for NewOperationV128LoadLane.
   611  	OperationKindV128LoadLane
   612  	// OperationKindV128Store is the Kind for NewOperationV128Store.
   613  	OperationKindV128Store
   614  	// OperationKindV128StoreLane is the Kind for NewOperationV128StoreLane.
   615  	OperationKindV128StoreLane
   616  	// OperationKindV128ExtractLane is the Kind for NewOperationV128ExtractLane.
   617  	OperationKindV128ExtractLane
   618  	// OperationKindV128ReplaceLane is the Kind for NewOperationV128ReplaceLane.
   619  	OperationKindV128ReplaceLane
   620  	// OperationKindV128Splat is the Kind for NewOperationV128Splat.
   621  	OperationKindV128Splat
   622  	// OperationKindV128Shuffle is the Kind for NewOperationV128Shuffle.
   623  	OperationKindV128Shuffle
   624  	// OperationKindV128Swizzle is the Kind for NewOperationV128Swizzle.
   625  	OperationKindV128Swizzle
   626  	// OperationKindV128AnyTrue is the Kind for NewOperationV128AnyTrue.
   627  	OperationKindV128AnyTrue
   628  	// OperationKindV128AllTrue is the Kind for NewOperationV128AllTrue.
   629  	OperationKindV128AllTrue
   630  	// OperationKindV128BitMask is the Kind for NewOperationV128BitMask.
   631  	OperationKindV128BitMask
   632  	// OperationKindV128And is the Kind for NewOperationV128And.
   633  	OperationKindV128And
   634  	// OperationKindV128Not is the Kind for NewOperationV128Not.
   635  	OperationKindV128Not
   636  	// OperationKindV128Or is the Kind for NewOperationV128Or.
   637  	OperationKindV128Or
   638  	// OperationKindV128Xor is the Kind for NewOperationV128Xor.
   639  	OperationKindV128Xor
   640  	// OperationKindV128Bitselect is the Kind for NewOperationV128Bitselect.
   641  	OperationKindV128Bitselect
   642  	// OperationKindV128AndNot is the Kind for NewOperationV128AndNot.
   643  	OperationKindV128AndNot
   644  	// OperationKindV128Shl is the Kind for NewOperationV128Shl.
   645  	OperationKindV128Shl
   646  	// OperationKindV128Shr is the Kind for NewOperationV128Shr.
   647  	OperationKindV128Shr
   648  	// OperationKindV128Cmp is the Kind for NewOperationV128Cmp.
   649  	OperationKindV128Cmp
   650  	// OperationKindV128AddSat is the Kind for NewOperationV128AddSat.
   651  	OperationKindV128AddSat
   652  	// OperationKindV128SubSat is the Kind for NewOperationV128SubSat.
   653  	OperationKindV128SubSat
   654  	// OperationKindV128Mul is the Kind for NewOperationV128Mul.
   655  	OperationKindV128Mul
   656  	// OperationKindV128Div is the Kind for NewOperationV128Div.
   657  	OperationKindV128Div
   658  	// OperationKindV128Neg is the Kind for NewOperationV128Neg.
   659  	OperationKindV128Neg
   660  	// OperationKindV128Sqrt is the Kind for NewOperationV128Sqrt.
   661  	OperationKindV128Sqrt
   662  	// OperationKindV128Abs is the Kind for NewOperationV128Abs.
   663  	OperationKindV128Abs
   664  	// OperationKindV128Popcnt is the Kind for NewOperationV128Popcnt.
   665  	OperationKindV128Popcnt
   666  	// OperationKindV128Min is the Kind for NewOperationV128Min.
   667  	OperationKindV128Min
   668  	// OperationKindV128Max is the Kind for NewOperationV128Max.
   669  	OperationKindV128Max
   670  	// OperationKindV128AvgrU is the Kind for NewOperationV128AvgrU.
   671  	OperationKindV128AvgrU
   672  	// OperationKindV128Pmin is the Kind for NewOperationV128Pmin.
   673  	OperationKindV128Pmin
   674  	// OperationKindV128Pmax is the Kind for NewOperationV128Pmax.
   675  	OperationKindV128Pmax
   676  	// OperationKindV128Ceil is the Kind for NewOperationV128Ceil.
   677  	OperationKindV128Ceil
   678  	// OperationKindV128Floor is the Kind for NewOperationV128Floor.
   679  	OperationKindV128Floor
   680  	// OperationKindV128Trunc is the Kind for NewOperationV128Trunc.
   681  	OperationKindV128Trunc
   682  	// OperationKindV128Nearest is the Kind for NewOperationV128Nearest.
   683  	OperationKindV128Nearest
   684  	// OperationKindV128Extend is the Kind for NewOperationV128Extend.
   685  	OperationKindV128Extend
   686  	// OperationKindV128ExtMul is the Kind for NewOperationV128ExtMul.
   687  	OperationKindV128ExtMul
   688  	// OperationKindV128Q15mulrSatS is the Kind for NewOperationV128Q15mulrSatS.
   689  	OperationKindV128Q15mulrSatS
   690  	// OperationKindV128ExtAddPairwise is the Kind for NewOperationV128ExtAddPairwise.
   691  	OperationKindV128ExtAddPairwise
   692  	// OperationKindV128FloatPromote is the Kind for NewOperationV128FloatPromote.
   693  	OperationKindV128FloatPromote
   694  	// OperationKindV128FloatDemote is the Kind for NewOperationV128FloatDemote.
   695  	OperationKindV128FloatDemote
   696  	// OperationKindV128FConvertFromI is the Kind for NewOperationV128FConvertFromI.
   697  	OperationKindV128FConvertFromI
   698  	// OperationKindV128Dot is the Kind for NewOperationV128Dot.
   699  	OperationKindV128Dot
   700  	// OperationKindV128Narrow is the Kind for NewOperationV128Narrow.
   701  	OperationKindV128Narrow
   702  	// OperationKindV128ITruncSatFromF is the Kind for NewOperationV128ITruncSatFromF.
   703  	OperationKindV128ITruncSatFromF
   704  
   705  	// OperationKindBuiltinFunctionCheckExitCode is the Kind for NewOperationBuiltinFunctionCheckExitCode.
   706  	OperationKindBuiltinFunctionCheckExitCode
   707  
   708  	// operationKindEnd is always placed at the bottom of this iota definition to be used in the test.
   709  	operationKindEnd
   710  )
   711  
   712  // NewOperationBuiltinFunctionCheckExitCode is a constructor for UnionOperation with Kind OperationKindBuiltinFunctionCheckExitCode.
   713  //
   714  // OperationBuiltinFunctionCheckExitCode corresponds to the instruction to check the api.Module is already closed due to
   715  // context.DeadlineExceeded, context.Canceled, or the explicit call of CloseWithExitCode on api.Module.
   716  func NewOperationBuiltinFunctionCheckExitCode() UnionOperation {
   717  	return UnionOperation{Kind: OperationKindBuiltinFunctionCheckExitCode}
   718  }
   719  
   720  // Label is the unique identifier for each block in a single function in wazeroir
   721  // where "block" consists of multiple operations, and must End with branching operations
   722  // (e.g. OperationKindBr or OperationKindBrIf).
   723  type Label uint64
   724  
   725  // Kind returns the LabelKind encoded in this Label.
   726  func (l Label) Kind() LabelKind {
   727  	return LabelKind(uint32(l))
   728  }
   729  
   730  // FrameID returns the frame id encoded in this Label.
   731  func (l Label) FrameID() int {
   732  	return int(uint32(l >> 32))
   733  }
   734  
   735  // NewLabel is a constructor for a Label.
   736  func NewLabel(kind LabelKind, frameID uint32) Label {
   737  	return Label(kind) | Label(frameID)<<32
   738  }
   739  
   740  // String implements fmt.Stringer.
   741  func (l Label) String() (ret string) {
   742  	frameID := l.FrameID()
   743  	switch l.Kind() {
   744  	case LabelKindHeader:
   745  		ret = fmt.Sprintf(".L%d", frameID)
   746  	case LabelKindElse:
   747  		ret = fmt.Sprintf(".L%d_else", frameID)
   748  	case LabelKindContinuation:
   749  		ret = fmt.Sprintf(".L%d_cont", frameID)
   750  	case LabelKindReturn:
   751  		return ".return"
   752  	}
   753  	return
   754  }
   755  
   756  func (l Label) IsReturnTarget() bool {
   757  	return l.Kind() == LabelKindReturn
   758  }
   759  
   760  // LabelKind is the Kind of the label.
   761  type LabelKind = byte
   762  
   763  const (
   764  	// LabelKindHeader is the header for various blocks. For example, the "then" block of
   765  	// wasm.OpcodeIfName in Wasm has the label of this Kind.
   766  	LabelKindHeader LabelKind = iota
   767  	// LabelKindElse is the Kind of label for "else" block of wasm.OpcodeIfName in Wasm.
   768  	LabelKindElse
   769  	// LabelKindContinuation is the Kind of label which is the continuation of blocks.
   770  	// For example, for wasm text like
   771  	// (func
   772  	//   ....
   773  	//   (if (local.get 0) (then (nop)) (else (nop)))
   774  	//   return
   775  	// )
   776  	// we have the continuation block (of if-block) corresponding to "return" opcode.
   777  	LabelKindContinuation
   778  	LabelKindReturn
   779  	LabelKindNum
   780  )
   781  
   782  // UnionOperation implements Operation and is the compilation (engine.lowerIR) result of a wazeroir.Operation.
   783  //
   784  // Not all operations result in a UnionOperation, e.g. wazeroir.OperationI32ReinterpretFromF32, and some operations are
   785  // more complex than others, e.g. wazeroir.NewOperationBrTable.
   786  //
   787  // Note: This is a form of union type as it can store fields needed for any operation. Hence, most fields are opaque and
   788  // only relevant when in context of its kind.
   789  type UnionOperation struct {
   790  	// Kind determines how to interpret the other fields in this struct.
   791  	Kind   OperationKind
   792  	B1, B2 byte
   793  	B3     bool
   794  	U1, U2 uint64
   795  	U3     uint64
   796  	Us     []uint64
   797  }
   798  
   799  // String implements fmt.Stringer.
   800  func (o UnionOperation) String() string {
   801  	switch o.Kind {
   802  	case OperationKindUnreachable,
   803  		OperationKindSelect,
   804  		OperationKindMemorySize,
   805  		OperationKindMemoryGrow,
   806  		OperationKindI32WrapFromI64,
   807  		OperationKindF32DemoteFromF64,
   808  		OperationKindF64PromoteFromF32,
   809  		OperationKindI32ReinterpretFromF32,
   810  		OperationKindI64ReinterpretFromF64,
   811  		OperationKindF32ReinterpretFromI32,
   812  		OperationKindF64ReinterpretFromI64,
   813  		OperationKindSignExtend32From8,
   814  		OperationKindSignExtend32From16,
   815  		OperationKindSignExtend64From8,
   816  		OperationKindSignExtend64From16,
   817  		OperationKindSignExtend64From32,
   818  		OperationKindMemoryInit,
   819  		OperationKindDataDrop,
   820  		OperationKindMemoryCopy,
   821  		OperationKindMemoryFill,
   822  		OperationKindTableInit,
   823  		OperationKindElemDrop,
   824  		OperationKindTableCopy,
   825  		OperationKindRefFunc,
   826  		OperationKindTableGet,
   827  		OperationKindTableSet,
   828  		OperationKindTableSize,
   829  		OperationKindTableGrow,
   830  		OperationKindTableFill,
   831  		OperationKindBuiltinFunctionCheckExitCode:
   832  		return o.Kind.String()
   833  
   834  	case OperationKindCall,
   835  		OperationKindGlobalGet,
   836  		OperationKindGlobalSet:
   837  		return fmt.Sprintf("%s %d", o.Kind, o.B1)
   838  
   839  	case OperationKindLabel:
   840  		return Label(o.U1).String()
   841  
   842  	case OperationKindBr:
   843  		return fmt.Sprintf("%s %s", o.Kind, Label(o.U1).String())
   844  
   845  	case OperationKindBrIf:
   846  		thenTarget := Label(o.U1)
   847  		elseTarget := Label(o.U2)
   848  		return fmt.Sprintf("%s %s, %s", o.Kind, thenTarget, elseTarget)
   849  
   850  	case OperationKindBrTable:
   851  		var targets []string
   852  		var defaultLabel Label
   853  		if len(o.Us) > 0 {
   854  			targets = make([]string, len(o.Us)-1)
   855  			for i, t := range o.Us[1:] {
   856  				targets[i] = Label(t).String()
   857  			}
   858  			defaultLabel = Label(o.Us[0])
   859  		}
   860  		return fmt.Sprintf("%s [%s] %s", o.Kind, strings.Join(targets, ","), defaultLabel)
   861  
   862  	case OperationKindCallIndirect:
   863  		return fmt.Sprintf("%s: type=%d, table=%d", o.Kind, o.U1, o.U2)
   864  
   865  	case OperationKindDrop:
   866  		start := int64(o.U1)
   867  		end := int64(o.U2)
   868  		return fmt.Sprintf("%s %d..%d", o.Kind, start, end)
   869  
   870  	case OperationKindPick, OperationKindSet:
   871  		return fmt.Sprintf("%s %d (is_vector=%v)", o.Kind, o.U1, o.B3)
   872  
   873  	case OperationKindLoad, OperationKindStore:
   874  		return fmt.Sprintf("%s.%s (align=%d, offset=%d)", UnsignedType(o.B1), o.Kind, o.U1, o.U2)
   875  
   876  	case OperationKindLoad8,
   877  		OperationKindLoad16:
   878  		return fmt.Sprintf("%s.%s (align=%d, offset=%d)", SignedType(o.B1), o.Kind, o.U1, o.U2)
   879  
   880  	case OperationKindStore8,
   881  		OperationKindStore16,
   882  		OperationKindStore32:
   883  		return fmt.Sprintf("%s (align=%d, offset=%d)", o.Kind, o.U1, o.U2)
   884  
   885  	case OperationKindLoad32:
   886  		var t string
   887  		if o.B1 == 1 {
   888  			t = "i64"
   889  		} else {
   890  			t = "u64"
   891  		}
   892  		return fmt.Sprintf("%s.%s (align=%d, offset=%d)", t, o.Kind, o.U1, o.U2)
   893  
   894  	case OperationKindEq,
   895  		OperationKindNe,
   896  		OperationKindAdd,
   897  		OperationKindSub,
   898  		OperationKindMul:
   899  		return fmt.Sprintf("%s.%s", UnsignedType(o.B1), o.Kind)
   900  
   901  	case OperationKindEqz,
   902  		OperationKindClz,
   903  		OperationKindCtz,
   904  		OperationKindPopcnt,
   905  		OperationKindAnd,
   906  		OperationKindOr,
   907  		OperationKindXor,
   908  		OperationKindShl,
   909  		OperationKindRotl,
   910  		OperationKindRotr:
   911  		return fmt.Sprintf("%s.%s", UnsignedInt(o.B1), o.Kind)
   912  
   913  	case OperationKindRem, OperationKindShr:
   914  		return fmt.Sprintf("%s.%s", SignedInt(o.B1), o.Kind)
   915  
   916  	case OperationKindLt,
   917  		OperationKindGt,
   918  		OperationKindLe,
   919  		OperationKindGe,
   920  		OperationKindDiv:
   921  		return fmt.Sprintf("%s.%s", SignedType(o.B1), o.Kind)
   922  
   923  	case OperationKindAbs,
   924  		OperationKindNeg,
   925  		OperationKindCeil,
   926  		OperationKindFloor,
   927  		OperationKindTrunc,
   928  		OperationKindNearest,
   929  		OperationKindSqrt,
   930  		OperationKindMin,
   931  		OperationKindMax,
   932  		OperationKindCopysign:
   933  		return fmt.Sprintf("%s.%s", Float(o.B1), o.Kind)
   934  
   935  	case OperationKindConstI32,
   936  		OperationKindConstI64:
   937  		return fmt.Sprintf("%s %#x", o.Kind, o.U1)
   938  
   939  	case OperationKindConstF32:
   940  		return fmt.Sprintf("%s %f", o.Kind, math.Float32frombits(uint32(o.U1)))
   941  	case OperationKindConstF64:
   942  		return fmt.Sprintf("%s %f", o.Kind, math.Float64frombits(o.U1))
   943  
   944  	case OperationKindITruncFromF:
   945  		return fmt.Sprintf("%s.%s.%s (non_trapping=%v)", SignedInt(o.B2), o.Kind, Float(o.B1), o.B3)
   946  	case OperationKindFConvertFromI:
   947  		return fmt.Sprintf("%s.%s.%s", Float(o.B2), o.Kind, SignedInt(o.B1))
   948  	case OperationKindExtend:
   949  		var in, out string
   950  		if o.B3 {
   951  			in = "i32"
   952  			out = "i64"
   953  		} else {
   954  			in = "u32"
   955  			out = "u64"
   956  		}
   957  		return fmt.Sprintf("%s.%s.%s", out, o.Kind, in)
   958  
   959  	case OperationKindV128Const:
   960  		return fmt.Sprintf("%s [%#x, %#x]", o.Kind, o.U1, o.U2)
   961  	case OperationKindV128Add,
   962  		OperationKindV128Sub:
   963  		return fmt.Sprintf("%s (shape=%s)", o.Kind, shapeName(o.B1))
   964  	case OperationKindV128Load,
   965  		OperationKindV128LoadLane,
   966  		OperationKindV128Store,
   967  		OperationKindV128StoreLane,
   968  		OperationKindV128ExtractLane,
   969  		OperationKindV128ReplaceLane,
   970  		OperationKindV128Splat,
   971  		OperationKindV128Shuffle,
   972  		OperationKindV128Swizzle,
   973  		OperationKindV128AnyTrue,
   974  		OperationKindV128AllTrue,
   975  		OperationKindV128BitMask,
   976  		OperationKindV128And,
   977  		OperationKindV128Not,
   978  		OperationKindV128Or,
   979  		OperationKindV128Xor,
   980  		OperationKindV128Bitselect,
   981  		OperationKindV128AndNot,
   982  		OperationKindV128Shl,
   983  		OperationKindV128Shr,
   984  		OperationKindV128Cmp,
   985  		OperationKindV128AddSat,
   986  		OperationKindV128SubSat,
   987  		OperationKindV128Mul,
   988  		OperationKindV128Div,
   989  		OperationKindV128Neg,
   990  		OperationKindV128Sqrt,
   991  		OperationKindV128Abs,
   992  		OperationKindV128Popcnt,
   993  		OperationKindV128Min,
   994  		OperationKindV128Max,
   995  		OperationKindV128AvgrU,
   996  		OperationKindV128Pmin,
   997  		OperationKindV128Pmax,
   998  		OperationKindV128Ceil,
   999  		OperationKindV128Floor,
  1000  		OperationKindV128Trunc,
  1001  		OperationKindV128Nearest,
  1002  		OperationKindV128Extend,
  1003  		OperationKindV128ExtMul,
  1004  		OperationKindV128Q15mulrSatS,
  1005  		OperationKindV128ExtAddPairwise,
  1006  		OperationKindV128FloatPromote,
  1007  		OperationKindV128FloatDemote,
  1008  		OperationKindV128FConvertFromI,
  1009  		OperationKindV128Dot,
  1010  		OperationKindV128Narrow:
  1011  		return o.Kind.String()
  1012  
  1013  	case OperationKindV128ITruncSatFromF:
  1014  		if o.B3 {
  1015  			return fmt.Sprintf("%s.%sS", o.Kind, shapeName(o.B1))
  1016  		} else {
  1017  			return fmt.Sprintf("%s.%sU", o.Kind, shapeName(o.B1))
  1018  		}
  1019  
  1020  	default:
  1021  		panic(fmt.Sprintf("TODO: %v", o.Kind))
  1022  	}
  1023  }
  1024  
  1025  // NewOperationUnreachable is a constructor for UnionOperation with OperationKindUnreachable
  1026  //
  1027  // This corresponds to wasm.OpcodeUnreachable.
  1028  //
  1029  // The engines are expected to exit the execution with wasmruntime.ErrRuntimeUnreachable error.
  1030  func NewOperationUnreachable() UnionOperation {
  1031  	return UnionOperation{Kind: OperationKindUnreachable}
  1032  }
  1033  
  1034  // NewOperationLabel is a constructor for UnionOperation with OperationKindLabel.
  1035  //
  1036  // This is used to inform the engines of the beginning of a label.
  1037  func NewOperationLabel(label Label) UnionOperation {
  1038  	return UnionOperation{Kind: OperationKindLabel, U1: uint64(label)}
  1039  }
  1040  
  1041  // NewOperationBr is a constructor for UnionOperation with OperationKindBr.
  1042  //
  1043  // The engines are expected to branch into U1 label.
  1044  func NewOperationBr(target Label) UnionOperation {
  1045  	return UnionOperation{Kind: OperationKindBr, U1: uint64(target)}
  1046  }
  1047  
  1048  // NewOperationBrIf is a constructor for UnionOperation with OperationKindBrIf.
  1049  //
  1050  // The engines are expected to pop a value and branch into U1 label if the value equals 1.
  1051  // Otherwise, the code branches into U2 label.
  1052  func NewOperationBrIf(thenTarget, elseTarget Label, thenDrop InclusiveRange) UnionOperation {
  1053  	return UnionOperation{
  1054  		Kind: OperationKindBrIf,
  1055  		U1:   uint64(thenTarget),
  1056  		U2:   uint64(elseTarget),
  1057  		U3:   thenDrop.AsU64(),
  1058  	}
  1059  }
  1060  
  1061  // NewOperationBrTable is a constructor for UnionOperation with OperationKindBrTable.
  1062  //
  1063  // This corresponds to wasm.OpcodeBrTableName except that the label
  1064  // here means the wazeroir level, not the ones of Wasm.
  1065  //
  1066  // The engines are expected to do the br_table operation based on the default (Us[len(Us)-1], Us[len(Us)-2]) and
  1067  // targets (Us[:len(Us)-1], Rs[:len(Us)-1]). More precisely, this pops a value from the stack (called "index")
  1068  // and decides which branch we go into next based on the value.
  1069  //
  1070  // For example, assume we have operations like {default: L_DEFAULT, targets: [L0, L1, L2]}.
  1071  // If "index" >= len(defaults), then branch into the L_DEFAULT label.
  1072  // Otherwise, we enter label of targets[index].
  1073  func NewOperationBrTable(targetLabelsAndRanges []uint64) UnionOperation {
  1074  	return UnionOperation{
  1075  		Kind: OperationKindBrTable,
  1076  		Us:   targetLabelsAndRanges,
  1077  	}
  1078  }
  1079  
  1080  // NewOperationCall is a constructor for UnionOperation with OperationKindCall.
  1081  //
  1082  // This corresponds to wasm.OpcodeCallName, and engines are expected to
  1083  // enter into a function whose index equals OperationCall.FunctionIndex.
  1084  func NewOperationCall(functionIndex uint32) UnionOperation {
  1085  	return UnionOperation{Kind: OperationKindCall, U1: uint64(functionIndex)}
  1086  }
  1087  
  1088  // NewOperationCallIndirect implements Operation.
  1089  //
  1090  // This corresponds to wasm.OpcodeCallIndirectName, and engines are expected to
  1091  // consume the one value from the top of stack (called "offset"),
  1092  // and make a function call against the function whose function address equals
  1093  // Tables[OperationCallIndirect.TableIndex][offset].
  1094  //
  1095  // Note: This is called indirect function call in the sense that the target function is indirectly
  1096  // determined by the current state (top value) of the stack.
  1097  // Therefore, two checks are performed at runtime before entering the target function:
  1098  // 1) whether "offset" exceeds the length of table Tables[OperationCallIndirect.TableIndex].
  1099  // 2) whether the type of the function table[offset] matches the function type specified by OperationCallIndirect.TypeIndex.
  1100  func NewOperationCallIndirect(typeIndex, tableIndex uint32) UnionOperation {
  1101  	return UnionOperation{Kind: OperationKindCallIndirect, U1: uint64(typeIndex), U2: uint64(tableIndex)}
  1102  }
  1103  
  1104  // InclusiveRange is the range which spans across the value stack starting from the top to the bottom, and
  1105  // both boundary are included in the range.
  1106  type InclusiveRange struct {
  1107  	Start, End int32
  1108  }
  1109  
  1110  // AsU64 is be used to convert InclusiveRange to uint64 so that it can be stored in UnionOperation.
  1111  func (i InclusiveRange) AsU64() uint64 {
  1112  	return uint64(uint32(i.Start))<<32 | uint64(uint32(i.End))
  1113  }
  1114  
  1115  // InclusiveRangeFromU64 retrieves InclusiveRange from the given uint64 which is stored in UnionOperation.
  1116  func InclusiveRangeFromU64(v uint64) InclusiveRange {
  1117  	return InclusiveRange{
  1118  		Start: int32(uint32(v >> 32)),
  1119  		End:   int32(uint32(v)),
  1120  	}
  1121  }
  1122  
  1123  // NopInclusiveRange is InclusiveRange which corresponds to no-operation.
  1124  var NopInclusiveRange = InclusiveRange{Start: -1, End: -1}
  1125  
  1126  // NewOperationDrop is a constructor for UnionOperation with OperationKindDrop.
  1127  //
  1128  // The engines are expected to discard the values selected by NewOperationDrop.Depth which
  1129  // starts from the top of the stack to the bottom.
  1130  //
  1131  // depth spans across the uint64 value stack at runtime to be dropped by this operation.
  1132  func NewOperationDrop(depth InclusiveRange) UnionOperation {
  1133  	return UnionOperation{Kind: OperationKindDrop, U1: depth.AsU64()}
  1134  }
  1135  
  1136  // NewOperationSelect is a constructor for UnionOperation with OperationKindSelect.
  1137  //
  1138  // This corresponds to wasm.OpcodeSelect.
  1139  //
  1140  // The engines are expected to pop three values, say [..., x2, x1, c], then if the value "c" equals zero,
  1141  // "x1" is pushed back onto the stack and, otherwise "x2" is pushed back.
  1142  //
  1143  // isTargetVector true if the selection target value's type is wasm.ValueTypeV128.
  1144  func NewOperationSelect(isTargetVector bool) UnionOperation {
  1145  	return UnionOperation{Kind: OperationKindSelect, B3: isTargetVector}
  1146  }
  1147  
  1148  // NewOperationPick is a constructor for UnionOperation with OperationKindPick.
  1149  //
  1150  // The engines are expected to copy a value pointed by depth, and push the
  1151  // copied value onto the top of the stack.
  1152  //
  1153  // depth is the location of the pick target in the uint64 value stack at runtime.
  1154  // If isTargetVector=true, this points to the location of the lower 64-bits of the vector.
  1155  func NewOperationPick(depth int, isTargetVector bool) UnionOperation {
  1156  	return UnionOperation{Kind: OperationKindPick, U1: uint64(depth), B3: isTargetVector}
  1157  }
  1158  
  1159  // NewOperationSet is a constructor for UnionOperation with OperationKindSet.
  1160  //
  1161  // The engines are expected to set the top value of the stack to the location specified by
  1162  // depth.
  1163  //
  1164  // depth is the location of the set target in the uint64 value stack at runtime.
  1165  // If isTargetVector=true, this points the location of the lower 64-bits of the vector.
  1166  func NewOperationSet(depth int, isTargetVector bool) UnionOperation {
  1167  	return UnionOperation{Kind: OperationKindSet, U1: uint64(depth), B3: isTargetVector}
  1168  }
  1169  
  1170  // NewOperationGlobalGet is a constructor for UnionOperation with OperationKindGlobalGet.
  1171  //
  1172  // The engines are expected to read the global value specified by OperationGlobalGet.Index,
  1173  // and push the copy of the value onto the stack.
  1174  //
  1175  // See wasm.OpcodeGlobalGet.
  1176  func NewOperationGlobalGet(index uint32) UnionOperation {
  1177  	return UnionOperation{Kind: OperationKindGlobalGet, U1: uint64(index)}
  1178  }
  1179  
  1180  // NewOperationGlobalSet is a constructor for UnionOperation with OperationKindGlobalSet.
  1181  //
  1182  // The engines are expected to consume the value from the top of the stack,
  1183  // and write the value into the global specified by OperationGlobalSet.Index.
  1184  //
  1185  // See wasm.OpcodeGlobalSet.
  1186  func NewOperationGlobalSet(index uint32) UnionOperation {
  1187  	return UnionOperation{Kind: OperationKindGlobalSet, U1: uint64(index)}
  1188  }
  1189  
  1190  // MemoryArg is the "memarg" to all memory instructions.
  1191  //
  1192  // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#memory-instructions%E2%91%A0
  1193  type MemoryArg struct {
  1194  	// Alignment the expected alignment (expressed as the exponent of a power of 2). Default to the natural alignment.
  1195  	//
  1196  	// "Natural alignment" is defined here as the smallest power of two that can hold the size of the value type. Ex
  1197  	// wasm.ValueTypeI64 is encoded in 8 little-endian bytes. 2^3 = 8, so the natural alignment is three.
  1198  	Alignment uint32
  1199  
  1200  	// Offset is the address offset added to the instruction's dynamic address operand, yielding a 33-bit effective
  1201  	// address that is the zero-based index at which the memory is accessed. Default to zero.
  1202  	Offset uint32
  1203  }
  1204  
  1205  // NewOperationLoad is a constructor for UnionOperation with OperationKindLoad.
  1206  //
  1207  // This corresponds to wasm.OpcodeI32LoadName wasm.OpcodeI64LoadName wasm.OpcodeF32LoadName and wasm.OpcodeF64LoadName.
  1208  //
  1209  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1210  // otherwise load the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1211  func NewOperationLoad(unsignedType UnsignedType, arg MemoryArg) UnionOperation {
  1212  	return UnionOperation{Kind: OperationKindLoad, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1213  }
  1214  
  1215  // NewOperationLoad8 is a constructor for UnionOperation with OperationKindLoad8.
  1216  //
  1217  // This corresponds to wasm.OpcodeI32Load8SName wasm.OpcodeI32Load8UName wasm.OpcodeI64Load8SName wasm.OpcodeI64Load8UName.
  1218  //
  1219  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1220  // otherwise load the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1221  func NewOperationLoad8(signedInt SignedInt, arg MemoryArg) UnionOperation {
  1222  	return UnionOperation{Kind: OperationKindLoad8, B1: byte(signedInt), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1223  }
  1224  
  1225  // NewOperationLoad16 is a constructor for UnionOperation with OperationKindLoad16.
  1226  //
  1227  // This corresponds to wasm.OpcodeI32Load16SName wasm.OpcodeI32Load16UName wasm.OpcodeI64Load16SName wasm.OpcodeI64Load16UName.
  1228  //
  1229  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1230  // otherwise load the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1231  func NewOperationLoad16(signedInt SignedInt, arg MemoryArg) UnionOperation {
  1232  	return UnionOperation{Kind: OperationKindLoad16, B1: byte(signedInt), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1233  }
  1234  
  1235  // NewOperationLoad32 is a constructor for UnionOperation with OperationKindLoad32.
  1236  //
  1237  // This corresponds to wasm.OpcodeI64Load32SName wasm.OpcodeI64Load32UName.
  1238  //
  1239  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1240  // otherwise load the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1241  func NewOperationLoad32(signed bool, arg MemoryArg) UnionOperation {
  1242  	sigB := byte(0)
  1243  	if signed {
  1244  		sigB = 1
  1245  	}
  1246  	return UnionOperation{Kind: OperationKindLoad32, B1: sigB, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1247  }
  1248  
  1249  // NewOperationStore is a constructor for UnionOperation with OperationKindStore.
  1250  //
  1251  // # This corresponds to wasm.OpcodeI32StoreName wasm.OpcodeI64StoreName wasm.OpcodeF32StoreName wasm.OpcodeF64StoreName
  1252  //
  1253  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1254  // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1255  func NewOperationStore(unsignedType UnsignedType, arg MemoryArg) UnionOperation {
  1256  	return UnionOperation{Kind: OperationKindStore, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1257  }
  1258  
  1259  // NewOperationStore8 is a constructor for UnionOperation with OperationKindStore8.
  1260  //
  1261  // # This corresponds to wasm.OpcodeI32Store8Name wasm.OpcodeI64Store8Name
  1262  //
  1263  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1264  // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1265  func NewOperationStore8(arg MemoryArg) UnionOperation {
  1266  	return UnionOperation{Kind: OperationKindStore8, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1267  }
  1268  
  1269  // NewOperationStore16 is a constructor for UnionOperation with OperationKindStore16.
  1270  //
  1271  // # This corresponds to wasm.OpcodeI32Store16Name wasm.OpcodeI64Store16Name
  1272  //
  1273  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1274  // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1275  func NewOperationStore16(arg MemoryArg) UnionOperation {
  1276  	return UnionOperation{Kind: OperationKindStore16, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1277  }
  1278  
  1279  // NewOperationStore32 is a constructor for UnionOperation with OperationKindStore32.
  1280  //
  1281  // # This corresponds to wasm.OpcodeI64Store32Name
  1282  //
  1283  // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary,
  1284  // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction.
  1285  func NewOperationStore32(arg MemoryArg) UnionOperation {
  1286  	return UnionOperation{Kind: OperationKindStore32, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1287  }
  1288  
  1289  // NewOperationMemorySize is a constructor for UnionOperation with OperationKindMemorySize.
  1290  //
  1291  // This corresponds to wasm.OpcodeMemorySize.
  1292  //
  1293  // The engines are expected to push the current page size of the memory onto the stack.
  1294  func NewOperationMemorySize() UnionOperation {
  1295  	return UnionOperation{Kind: OperationKindMemorySize}
  1296  }
  1297  
  1298  // NewOperationMemoryGrow is a constructor for UnionOperation with OperationKindMemoryGrow.
  1299  //
  1300  // This corresponds to wasm.OpcodeMemoryGrow.
  1301  //
  1302  // The engines are expected to pop one value from the top of the stack, then
  1303  // execute wasm.MemoryInstance Grow with the value, and push the previous
  1304  // page size of the memory onto the stack.
  1305  func NewOperationMemoryGrow() UnionOperation {
  1306  	return UnionOperation{Kind: OperationKindMemoryGrow}
  1307  }
  1308  
  1309  // NewOperationConstI32 is a constructor for UnionOperation with OperationConstI32.
  1310  //
  1311  // This corresponds to wasm.OpcodeI32Const.
  1312  func NewOperationConstI32(value uint32) UnionOperation {
  1313  	return UnionOperation{Kind: OperationKindConstI32, U1: uint64(value)}
  1314  }
  1315  
  1316  // NewOperationConstI64 is a constructor for UnionOperation with OperationConstI64.
  1317  //
  1318  // This corresponds to wasm.OpcodeI64Const.
  1319  func NewOperationConstI64(value uint64) UnionOperation {
  1320  	return UnionOperation{Kind: OperationKindConstI64, U1: value}
  1321  }
  1322  
  1323  // NewOperationConstF32 is a constructor for UnionOperation with OperationConstF32.
  1324  //
  1325  // This corresponds to wasm.OpcodeF32Const.
  1326  func NewOperationConstF32(value float32) UnionOperation {
  1327  	return UnionOperation{Kind: OperationKindConstF32, U1: uint64(math.Float32bits(value))}
  1328  }
  1329  
  1330  // NewOperationConstF64 is a constructor for UnionOperation with OperationConstF64.
  1331  //
  1332  // This corresponds to wasm.OpcodeF64Const.
  1333  func NewOperationConstF64(value float64) UnionOperation {
  1334  	return UnionOperation{Kind: OperationKindConstF64, U1: math.Float64bits(value)}
  1335  }
  1336  
  1337  // NewOperationEq is a constructor for UnionOperation with OperationKindEq.
  1338  //
  1339  // This corresponds to wasm.OpcodeI32EqName wasm.OpcodeI64EqName wasm.OpcodeF32EqName wasm.OpcodeF64EqName
  1340  func NewOperationEq(b UnsignedType) UnionOperation {
  1341  	return UnionOperation{Kind: OperationKindEq, B1: byte(b)}
  1342  }
  1343  
  1344  // NewOperationNe is a constructor for UnionOperation with OperationKindNe.
  1345  //
  1346  // This corresponds to wasm.OpcodeI32NeName wasm.OpcodeI64NeName wasm.OpcodeF32NeName wasm.OpcodeF64NeName
  1347  func NewOperationNe(b UnsignedType) UnionOperation {
  1348  	return UnionOperation{Kind: OperationKindNe, B1: byte(b)}
  1349  }
  1350  
  1351  // NewOperationEqz is a constructor for UnionOperation with OperationKindEqz.
  1352  //
  1353  // This corresponds to wasm.OpcodeI32EqzName wasm.OpcodeI64EqzName
  1354  func NewOperationEqz(b UnsignedInt) UnionOperation {
  1355  	return UnionOperation{Kind: OperationKindEqz, B1: byte(b)}
  1356  }
  1357  
  1358  // NewOperationLt is a constructor for UnionOperation with OperationKindLt.
  1359  //
  1360  // This corresponds to wasm.OpcodeI32LtS wasm.OpcodeI32LtU wasm.OpcodeI64LtS wasm.OpcodeI64LtU wasm.OpcodeF32Lt wasm.OpcodeF64Lt
  1361  func NewOperationLt(b SignedType) UnionOperation {
  1362  	return UnionOperation{Kind: OperationKindLt, B1: byte(b)}
  1363  }
  1364  
  1365  // NewOperationGt is a constructor for UnionOperation with OperationKindGt.
  1366  //
  1367  // This corresponds to wasm.OpcodeI32GtS wasm.OpcodeI32GtU wasm.OpcodeI64GtS wasm.OpcodeI64GtU wasm.OpcodeF32Gt wasm.OpcodeF64Gt
  1368  func NewOperationGt(b SignedType) UnionOperation {
  1369  	return UnionOperation{Kind: OperationKindGt, B1: byte(b)}
  1370  }
  1371  
  1372  // NewOperationLe is a constructor for UnionOperation with OperationKindLe.
  1373  //
  1374  // This corresponds to wasm.OpcodeI32LeS wasm.OpcodeI32LeU wasm.OpcodeI64LeS wasm.OpcodeI64LeU wasm.OpcodeF32Le wasm.OpcodeF64Le
  1375  func NewOperationLe(b SignedType) UnionOperation {
  1376  	return UnionOperation{Kind: OperationKindLe, B1: byte(b)}
  1377  }
  1378  
  1379  // NewOperationGe is a constructor for UnionOperation with OperationKindGe.
  1380  //
  1381  // This corresponds to wasm.OpcodeI32GeS wasm.OpcodeI32GeU wasm.OpcodeI64GeS wasm.OpcodeI64GeU wasm.OpcodeF32Ge wasm.OpcodeF64Ge
  1382  // NewOperationGe is the constructor for OperationGe
  1383  func NewOperationGe(b SignedType) UnionOperation {
  1384  	return UnionOperation{Kind: OperationKindGe, B1: byte(b)}
  1385  }
  1386  
  1387  // NewOperationAdd is a constructor for UnionOperation with OperationKindAdd.
  1388  //
  1389  // This corresponds to wasm.OpcodeI32AddName wasm.OpcodeI64AddName wasm.OpcodeF32AddName wasm.OpcodeF64AddName.
  1390  func NewOperationAdd(b UnsignedType) UnionOperation {
  1391  	return UnionOperation{Kind: OperationKindAdd, B1: byte(b)}
  1392  }
  1393  
  1394  // NewOperationSub is a constructor for UnionOperation with OperationKindSub.
  1395  //
  1396  // This corresponds to wasm.OpcodeI32SubName wasm.OpcodeI64SubName wasm.OpcodeF32SubName wasm.OpcodeF64SubName.
  1397  func NewOperationSub(b UnsignedType) UnionOperation {
  1398  	return UnionOperation{Kind: OperationKindSub, B1: byte(b)}
  1399  }
  1400  
  1401  // NewOperationMul is a constructor for UnionOperation with wperationKindMul.
  1402  //
  1403  // This corresponds to wasm.OpcodeI32MulName wasm.OpcodeI64MulName wasm.OpcodeF32MulName wasm.OpcodeF64MulName.
  1404  // NewOperationMul is the constructor for OperationMul
  1405  func NewOperationMul(b UnsignedType) UnionOperation {
  1406  	return UnionOperation{Kind: OperationKindMul, B1: byte(b)}
  1407  }
  1408  
  1409  // NewOperationClz is a constructor for UnionOperation with OperationKindClz.
  1410  //
  1411  // This corresponds to wasm.OpcodeI32ClzName wasm.OpcodeI64ClzName.
  1412  //
  1413  // The engines are expected to count up the leading zeros in the
  1414  // current top of the stack, and push the count result.
  1415  // For example, stack of [..., 0x00_ff_ff_ff] results in [..., 8].
  1416  // See wasm.OpcodeI32Clz wasm.OpcodeI64Clz
  1417  func NewOperationClz(b UnsignedInt) UnionOperation {
  1418  	return UnionOperation{Kind: OperationKindClz, B1: byte(b)}
  1419  }
  1420  
  1421  // NewOperationCtz is a constructor for UnionOperation with OperationKindCtz.
  1422  //
  1423  // This corresponds to wasm.OpcodeI32CtzName wasm.OpcodeI64CtzName.
  1424  //
  1425  // The engines are expected to count up the trailing zeros in the
  1426  // current top of the stack, and push the count result.
  1427  // For example, stack of [..., 0xff_ff_ff_00] results in [..., 8].
  1428  func NewOperationCtz(b UnsignedInt) UnionOperation {
  1429  	return UnionOperation{Kind: OperationKindCtz, B1: byte(b)}
  1430  }
  1431  
  1432  // NewOperationPopcnt is a constructor for UnionOperation with OperationKindPopcnt.
  1433  //
  1434  // This corresponds to wasm.OpcodeI32PopcntName wasm.OpcodeI64PopcntName.
  1435  //
  1436  // The engines are expected to count up the number of set bits in the
  1437  // current top of the stack, and push the count result.
  1438  // For example, stack of [..., 0b00_00_00_11] results in [..., 2].
  1439  func NewOperationPopcnt(b UnsignedInt) UnionOperation {
  1440  	return UnionOperation{Kind: OperationKindPopcnt, B1: byte(b)}
  1441  }
  1442  
  1443  // NewOperationDiv is a constructor for UnionOperation with OperationKindDiv.
  1444  //
  1445  // This corresponds to wasm.OpcodeI32DivS wasm.OpcodeI32DivU wasm.OpcodeI64DivS
  1446  //
  1447  //	wasm.OpcodeI64DivU wasm.OpcodeF32Div wasm.OpcodeF64Div.
  1448  func NewOperationDiv(b SignedType) UnionOperation {
  1449  	return UnionOperation{Kind: OperationKindDiv, B1: byte(b)}
  1450  }
  1451  
  1452  // NewOperationRem is a constructor for UnionOperation with OperationKindRem.
  1453  //
  1454  // This corresponds to wasm.OpcodeI32RemS wasm.OpcodeI32RemU wasm.OpcodeI64RemS wasm.OpcodeI64RemU.
  1455  //
  1456  // The engines are expected to perform division on the top
  1457  // two values of integer type on the stack and puts the remainder of the result
  1458  // onto the stack. For example, stack [..., 10, 3] results in [..., 1] where
  1459  // the quotient is discarded.
  1460  // NewOperationRem is the constructor for OperationRem
  1461  func NewOperationRem(b SignedInt) UnionOperation {
  1462  	return UnionOperation{Kind: OperationKindRem, B1: byte(b)}
  1463  }
  1464  
  1465  // NewOperationAnd is a constructor for UnionOperation with OperationKindAnd.
  1466  //
  1467  // # This corresponds to wasm.OpcodeI32AndName wasm.OpcodeI64AndName
  1468  //
  1469  // The engines are expected to perform "And" operation on
  1470  // top two values on the stack, and pushes the result.
  1471  func NewOperationAnd(b UnsignedInt) UnionOperation {
  1472  	return UnionOperation{Kind: OperationKindAnd, B1: byte(b)}
  1473  }
  1474  
  1475  // NewOperationOr is a constructor for UnionOperation with OperationKindOr.
  1476  //
  1477  // # This corresponds to wasm.OpcodeI32OrName wasm.OpcodeI64OrName
  1478  //
  1479  // The engines are expected to perform "Or" operation on
  1480  // top two values on the stack, and pushes the result.
  1481  func NewOperationOr(b UnsignedInt) UnionOperation {
  1482  	return UnionOperation{Kind: OperationKindOr, B1: byte(b)}
  1483  }
  1484  
  1485  // NewOperationXor is a constructor for UnionOperation with OperationKindXor.
  1486  //
  1487  // # This corresponds to wasm.OpcodeI32XorName wasm.OpcodeI64XorName
  1488  //
  1489  // The engines are expected to perform "Xor" operation on
  1490  // top two values on the stack, and pushes the result.
  1491  func NewOperationXor(b UnsignedInt) UnionOperation {
  1492  	return UnionOperation{Kind: OperationKindXor, B1: byte(b)}
  1493  }
  1494  
  1495  // NewOperationShl is a constructor for UnionOperation with OperationKindShl.
  1496  //
  1497  // # This corresponds to wasm.OpcodeI32ShlName wasm.OpcodeI64ShlName
  1498  //
  1499  // The engines are expected to perform "Shl" operation on
  1500  // top two values on the stack, and pushes the result.
  1501  func NewOperationShl(b UnsignedInt) UnionOperation {
  1502  	return UnionOperation{Kind: OperationKindShl, B1: byte(b)}
  1503  }
  1504  
  1505  // NewOperationShr is a constructor for UnionOperation with OperationKindShr.
  1506  //
  1507  // # This corresponds to wasm.OpcodeI32ShrSName wasm.OpcodeI32ShrUName wasm.OpcodeI64ShrSName wasm.OpcodeI64ShrUName
  1508  //
  1509  // If OperationShr.Type is signed integer, then, the engines are expected to perform arithmetic right shift on the two
  1510  // top values on the stack, otherwise do the logical right shift.
  1511  func NewOperationShr(b SignedInt) UnionOperation {
  1512  	return UnionOperation{Kind: OperationKindShr, B1: byte(b)}
  1513  }
  1514  
  1515  // NewOperationRotl is a constructor for UnionOperation with OperationKindRotl.
  1516  //
  1517  // # This corresponds to wasm.OpcodeI32RotlName wasm.OpcodeI64RotlName
  1518  //
  1519  // The engines are expected to perform "Rotl" operation on
  1520  // top two values on the stack, and pushes the result.
  1521  func NewOperationRotl(b UnsignedInt) UnionOperation {
  1522  	return UnionOperation{Kind: OperationKindRotl, B1: byte(b)}
  1523  }
  1524  
  1525  // NewOperationRotr is a constructor for UnionOperation with OperationKindRotr.
  1526  //
  1527  // # This corresponds to wasm.OpcodeI32RotrName wasm.OpcodeI64RotrName
  1528  //
  1529  // The engines are expected to perform "Rotr" operation on
  1530  // top two values on the stack, and pushes the result.
  1531  func NewOperationRotr(b UnsignedInt) UnionOperation {
  1532  	return UnionOperation{Kind: OperationKindRotr, B1: byte(b)}
  1533  }
  1534  
  1535  // NewOperationAbs is a constructor for UnionOperation with OperationKindAbs.
  1536  //
  1537  // This corresponds to wasm.OpcodeF32Abs wasm.OpcodeF64Abs
  1538  func NewOperationAbs(b Float) UnionOperation {
  1539  	return UnionOperation{Kind: OperationKindAbs, B1: byte(b)}
  1540  }
  1541  
  1542  // NewOperationNeg is a constructor for UnionOperation with OperationKindNeg.
  1543  //
  1544  // This corresponds to wasm.OpcodeF32Neg wasm.OpcodeF64Neg
  1545  func NewOperationNeg(b Float) UnionOperation {
  1546  	return UnionOperation{Kind: OperationKindNeg, B1: byte(b)}
  1547  }
  1548  
  1549  // NewOperationCeil is a constructor for UnionOperation with OperationKindCeil.
  1550  //
  1551  // This corresponds to wasm.OpcodeF32CeilName wasm.OpcodeF64CeilName
  1552  func NewOperationCeil(b Float) UnionOperation {
  1553  	return UnionOperation{Kind: OperationKindCeil, B1: byte(b)}
  1554  }
  1555  
  1556  // NewOperationFloor is a constructor for UnionOperation with OperationKindFloor.
  1557  //
  1558  // This corresponds to wasm.OpcodeF32FloorName wasm.OpcodeF64FloorName
  1559  func NewOperationFloor(b Float) UnionOperation {
  1560  	return UnionOperation{Kind: OperationKindFloor, B1: byte(b)}
  1561  }
  1562  
  1563  // NewOperationTrunc is a constructor for UnionOperation with OperationKindTrunc.
  1564  //
  1565  // This corresponds to wasm.OpcodeF32TruncName wasm.OpcodeF64TruncName
  1566  func NewOperationTrunc(b Float) UnionOperation {
  1567  	return UnionOperation{Kind: OperationKindTrunc, B1: byte(b)}
  1568  }
  1569  
  1570  // NewOperationNearest is a constructor for UnionOperation with OperationKindNearest.
  1571  //
  1572  // # This corresponds to wasm.OpcodeF32NearestName wasm.OpcodeF64NearestName
  1573  //
  1574  // Note: this is *not* equivalent to math.Round and instead has the same
  1575  // the semantics of LLVM's rint intrinsic. See https://llvm.org/docs/LangRef.html#llvm-rint-intrinsic.
  1576  // For example, math.Round(-4.5) produces -5 while we want to produce -4.
  1577  func NewOperationNearest(b Float) UnionOperation {
  1578  	return UnionOperation{Kind: OperationKindNearest, B1: byte(b)}
  1579  }
  1580  
  1581  // NewOperationSqrt is a constructor for UnionOperation with OperationKindSqrt.
  1582  //
  1583  // This corresponds to wasm.OpcodeF32SqrtName wasm.OpcodeF64SqrtName
  1584  func NewOperationSqrt(b Float) UnionOperation {
  1585  	return UnionOperation{Kind: OperationKindSqrt, B1: byte(b)}
  1586  }
  1587  
  1588  // NewOperationMin is a constructor for UnionOperation with OperationKindMin.
  1589  //
  1590  // # This corresponds to wasm.OpcodeF32MinName wasm.OpcodeF64MinName
  1591  //
  1592  // The engines are expected to pop two values from the stack, and push back the maximum of
  1593  // these two values onto the stack. For example, stack [..., 100.1, 1.9] results in [..., 1.9].
  1594  //
  1595  // Note: WebAssembly specifies that min/max must always return NaN if one of values is NaN,
  1596  // which is a different behavior different from math.Min.
  1597  func NewOperationMin(b Float) UnionOperation {
  1598  	return UnionOperation{Kind: OperationKindMin, B1: byte(b)}
  1599  }
  1600  
  1601  // NewOperationMax is a constructor for UnionOperation with OperationKindMax.
  1602  //
  1603  // # This corresponds to wasm.OpcodeF32MaxName wasm.OpcodeF64MaxName
  1604  //
  1605  // The engines are expected to pop two values from the stack, and push back the maximum of
  1606  // these two values onto the stack. For example, stack [..., 100.1, 1.9] results in [..., 100.1].
  1607  //
  1608  // Note: WebAssembly specifies that min/max must always return NaN if one of values is NaN,
  1609  // which is a different behavior different from math.Max.
  1610  func NewOperationMax(b Float) UnionOperation {
  1611  	return UnionOperation{Kind: OperationKindMax, B1: byte(b)}
  1612  }
  1613  
  1614  // NewOperationCopysign is a constructor for UnionOperation with OperationKindCopysign.
  1615  //
  1616  // # This corresponds to wasm.OpcodeF32CopysignName wasm.OpcodeF64CopysignName
  1617  //
  1618  // The engines are expected to pop two float values from the stack, and copy the signbit of
  1619  // the first-popped value to the last one.
  1620  // For example, stack [..., 1.213, -5.0] results in [..., -1.213].
  1621  func NewOperationCopysign(b Float) UnionOperation {
  1622  	return UnionOperation{Kind: OperationKindCopysign, B1: byte(b)}
  1623  }
  1624  
  1625  // NewOperationI32WrapFromI64 is a constructor for UnionOperation with OperationKindI32WrapFromI64.
  1626  //
  1627  // This corresponds to wasm.OpcodeI32WrapI64 and equivalent to uint64(uint32(v)) in Go.
  1628  //
  1629  // The engines are expected to replace the 64-bit int on top of the stack
  1630  // with the corresponding 32-bit integer.
  1631  func NewOperationI32WrapFromI64() UnionOperation {
  1632  	return UnionOperation{Kind: OperationKindI32WrapFromI64}
  1633  }
  1634  
  1635  // NewOperationITruncFromF is a constructor for UnionOperation with OperationKindITruncFromF.
  1636  //
  1637  // This corresponds to
  1638  //
  1639  //	wasm.OpcodeI32TruncF32SName wasm.OpcodeI32TruncF32UName wasm.OpcodeI32TruncF64SName
  1640  //	wasm.OpcodeI32TruncF64UName wasm.OpcodeI64TruncF32SName wasm.OpcodeI64TruncF32UName wasm.OpcodeI64TruncF64SName
  1641  //	wasm.OpcodeI64TruncF64UName. wasm.OpcodeI32TruncSatF32SName wasm.OpcodeI32TruncSatF32UName
  1642  //	wasm.OpcodeI32TruncSatF64SName wasm.OpcodeI32TruncSatF64UName wasm.OpcodeI64TruncSatF32SName
  1643  //	wasm.OpcodeI64TruncSatF32UName wasm.OpcodeI64TruncSatF64SName wasm.OpcodeI64TruncSatF64UName
  1644  //
  1645  // See [1] and [2] for when we encounter undefined behavior in the WebAssembly specification if NewOperationITruncFromF.NonTrapping == false.
  1646  // To summarize, if the source float value is NaN or doesn't fit in the destination range of integers (incl. +=Inf),
  1647  // then the runtime behavior is undefined. In wazero, the engines are expected to exit the execution in these undefined cases with
  1648  // wasmruntime.ErrRuntimeInvalidConversionToInteger error.
  1649  //
  1650  // [1] https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#-hrefop-trunc-umathrmtruncmathsfu_m-n-z for unsigned integers.
  1651  // [2] https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#-hrefop-trunc-smathrmtruncmathsfs_m-n-z for signed integers.
  1652  //
  1653  // nonTrapping true if this conversion is "nontrapping" in the sense of the
  1654  // https://github.com/WebAssembly/spec/blob/ce4b6c4d47eb06098cc7ab2e81f24748da822f20/proposals/nontrapping-float-to-int-conversion/Overview.md
  1655  func NewOperationITruncFromF(inputType Float, outputType SignedInt, nonTrapping bool) UnionOperation {
  1656  	return UnionOperation{
  1657  		Kind: OperationKindITruncFromF,
  1658  		B1:   byte(inputType),
  1659  		B2:   byte(outputType),
  1660  		B3:   nonTrapping,
  1661  	}
  1662  }
  1663  
  1664  // NewOperationFConvertFromI is a constructor for UnionOperation with OperationKindFConvertFromI.
  1665  //
  1666  // This corresponds to
  1667  //
  1668  //	wasm.OpcodeF32ConvertI32SName wasm.OpcodeF32ConvertI32UName wasm.OpcodeF32ConvertI64SName wasm.OpcodeF32ConvertI64UName
  1669  //	wasm.OpcodeF64ConvertI32SName wasm.OpcodeF64ConvertI32UName wasm.OpcodeF64ConvertI64SName wasm.OpcodeF64ConvertI64UName
  1670  //
  1671  // and equivalent to float32(uint32(x)), float32(int32(x)), etc in Go.
  1672  func NewOperationFConvertFromI(inputType SignedInt, outputType Float) UnionOperation {
  1673  	return UnionOperation{
  1674  		Kind: OperationKindFConvertFromI,
  1675  		B1:   byte(inputType),
  1676  		B2:   byte(outputType),
  1677  	}
  1678  }
  1679  
  1680  // NewOperationF32DemoteFromF64 is a constructor for UnionOperation with OperationKindF32DemoteFromF64.
  1681  //
  1682  // This corresponds to wasm.OpcodeF32DemoteF64 and is equivalent float32(float64(v)).
  1683  func NewOperationF32DemoteFromF64() UnionOperation {
  1684  	return UnionOperation{Kind: OperationKindF32DemoteFromF64}
  1685  }
  1686  
  1687  // NewOperationF64PromoteFromF32 is a constructor for UnionOperation with OperationKindF64PromoteFromF32.
  1688  //
  1689  // This corresponds to wasm.OpcodeF64PromoteF32 and is equivalent float64(float32(v)).
  1690  func NewOperationF64PromoteFromF32() UnionOperation {
  1691  	return UnionOperation{Kind: OperationKindF64PromoteFromF32}
  1692  }
  1693  
  1694  // NewOperationI32ReinterpretFromF32 is a constructor for UnionOperation with OperationKindI32ReinterpretFromF32.
  1695  //
  1696  // This corresponds to wasm.OpcodeI32ReinterpretF32Name.
  1697  func NewOperationI32ReinterpretFromF32() UnionOperation {
  1698  	return UnionOperation{Kind: OperationKindI32ReinterpretFromF32}
  1699  }
  1700  
  1701  // NewOperationI64ReinterpretFromF64 is a constructor for UnionOperation with OperationKindI64ReinterpretFromF64.
  1702  //
  1703  // This corresponds to wasm.OpcodeI64ReinterpretF64Name.
  1704  func NewOperationI64ReinterpretFromF64() UnionOperation {
  1705  	return UnionOperation{Kind: OperationKindI64ReinterpretFromF64}
  1706  }
  1707  
  1708  // NewOperationF32ReinterpretFromI32 is a constructor for UnionOperation with OperationKindF32ReinterpretFromI32.
  1709  //
  1710  // This corresponds to wasm.OpcodeF32ReinterpretI32Name.
  1711  func NewOperationF32ReinterpretFromI32() UnionOperation {
  1712  	return UnionOperation{Kind: OperationKindF32ReinterpretFromI32}
  1713  }
  1714  
  1715  // NewOperationF64ReinterpretFromI64 is a constructor for UnionOperation with OperationKindF64ReinterpretFromI64.
  1716  //
  1717  // This corresponds to wasm.OpcodeF64ReinterpretI64Name.
  1718  func NewOperationF64ReinterpretFromI64() UnionOperation {
  1719  	return UnionOperation{Kind: OperationKindF64ReinterpretFromI64}
  1720  }
  1721  
  1722  // NewOperationExtend is a constructor for UnionOperation with OperationKindExtend.
  1723  //
  1724  // # This corresponds to wasm.OpcodeI64ExtendI32SName wasm.OpcodeI64ExtendI32UName
  1725  //
  1726  // The engines are expected to extend the 32-bit signed or unsigned int on top of the stack
  1727  // as a 64-bit integer of corresponding signedness. For unsigned case, this is just reinterpreting the
  1728  // underlying bit pattern as 64-bit integer. For signed case, this is sign-extension which preserves the
  1729  // original integer's sign.
  1730  func NewOperationExtend(signed bool) UnionOperation {
  1731  	op := UnionOperation{Kind: OperationKindExtend}
  1732  	if signed {
  1733  		op.B1 = 1
  1734  	}
  1735  	return op
  1736  }
  1737  
  1738  // NewOperationSignExtend32From8 is a constructor for UnionOperation with OperationKindSignExtend32From8.
  1739  //
  1740  // This corresponds to wasm.OpcodeI32Extend8SName.
  1741  //
  1742  // The engines are expected to sign-extend the first 8-bits of 32-bit in as signed 32-bit int.
  1743  func NewOperationSignExtend32From8() UnionOperation {
  1744  	return UnionOperation{Kind: OperationKindSignExtend32From8}
  1745  }
  1746  
  1747  // NewOperationSignExtend32From16 is a constructor for UnionOperation with OperationKindSignExtend32From16.
  1748  //
  1749  // This corresponds to wasm.OpcodeI32Extend16SName.
  1750  //
  1751  // The engines are expected to sign-extend the first 16-bits of 32-bit in as signed 32-bit int.
  1752  func NewOperationSignExtend32From16() UnionOperation {
  1753  	return UnionOperation{Kind: OperationKindSignExtend32From16}
  1754  }
  1755  
  1756  // NewOperationSignExtend64From8 is a constructor for UnionOperation with OperationKindSignExtend64From8.
  1757  //
  1758  // This corresponds to wasm.OpcodeI64Extend8SName.
  1759  //
  1760  // The engines are expected to sign-extend the first 8-bits of 64-bit in as signed 32-bit int.
  1761  func NewOperationSignExtend64From8() UnionOperation {
  1762  	return UnionOperation{Kind: OperationKindSignExtend64From8}
  1763  }
  1764  
  1765  // NewOperationSignExtend64From16 is a constructor for UnionOperation with OperationKindSignExtend64From16.
  1766  //
  1767  // This corresponds to wasm.OpcodeI64Extend16SName.
  1768  //
  1769  // The engines are expected to sign-extend the first 16-bits of 64-bit in as signed 32-bit int.
  1770  func NewOperationSignExtend64From16() UnionOperation {
  1771  	return UnionOperation{Kind: OperationKindSignExtend64From16}
  1772  }
  1773  
  1774  // NewOperationSignExtend64From32 is a constructor for UnionOperation with OperationKindSignExtend64From32.
  1775  //
  1776  // This corresponds to wasm.OpcodeI64Extend32SName.
  1777  //
  1778  // The engines are expected to sign-extend the first 32-bits of 64-bit in as signed 32-bit int.
  1779  func NewOperationSignExtend64From32() UnionOperation {
  1780  	return UnionOperation{Kind: OperationKindSignExtend64From32}
  1781  }
  1782  
  1783  // NewOperationMemoryInit is a constructor for UnionOperation with OperationKindMemoryInit.
  1784  //
  1785  // This corresponds to wasm.OpcodeMemoryInitName.
  1786  //
  1787  // dataIndex is the index of the data instance in ModuleInstance.DataInstances
  1788  // by which this operation instantiates a part of the memory.
  1789  func NewOperationMemoryInit(dataIndex uint32) UnionOperation {
  1790  	return UnionOperation{Kind: OperationKindMemoryInit, U1: uint64(dataIndex)}
  1791  }
  1792  
  1793  // NewOperationDataDrop implements Operation.
  1794  //
  1795  // This corresponds to wasm.OpcodeDataDropName.
  1796  //
  1797  // dataIndex is the index of the data instance in ModuleInstance.DataInstances
  1798  // which this operation drops.
  1799  func NewOperationDataDrop(dataIndex uint32) UnionOperation {
  1800  	return UnionOperation{Kind: OperationKindDataDrop, U1: uint64(dataIndex)}
  1801  }
  1802  
  1803  // NewOperationMemoryCopy is a consuctor for UnionOperation with OperationKindMemoryCopy.
  1804  //
  1805  // This corresponds to wasm.OpcodeMemoryCopyName.
  1806  func NewOperationMemoryCopy() UnionOperation {
  1807  	return UnionOperation{Kind: OperationKindMemoryCopy}
  1808  }
  1809  
  1810  // NewOperationMemoryFill is a consuctor for UnionOperation with OperationKindMemoryFill.
  1811  func NewOperationMemoryFill() UnionOperation {
  1812  	return UnionOperation{Kind: OperationKindMemoryFill}
  1813  }
  1814  
  1815  // NewOperationTableInit is a constructor for UnionOperation with OperationKindTableInit.
  1816  //
  1817  // This corresponds to wasm.OpcodeTableInitName.
  1818  //
  1819  // elemIndex is the index of the element by which this operation initializes a part of the table.
  1820  // tableIndex is the index of the table on which this operation initialize by the target element.
  1821  func NewOperationTableInit(elemIndex, tableIndex uint32) UnionOperation {
  1822  	return UnionOperation{Kind: OperationKindTableInit, U1: uint64(elemIndex), U2: uint64(tableIndex)}
  1823  }
  1824  
  1825  // NewOperationElemDrop is a constructor for UnionOperation with OperationKindElemDrop.
  1826  //
  1827  // This corresponds to wasm.OpcodeElemDropName.
  1828  //
  1829  // elemIndex is the index of the element which this operation drops.
  1830  func NewOperationElemDrop(elemIndex uint32) UnionOperation {
  1831  	return UnionOperation{Kind: OperationKindElemDrop, U1: uint64(elemIndex)}
  1832  }
  1833  
  1834  // NewOperationTableCopy implements Operation.
  1835  //
  1836  // This corresponds to wasm.OpcodeTableCopyName.
  1837  func NewOperationTableCopy(srcTableIndex, dstTableIndex uint32) UnionOperation {
  1838  	return UnionOperation{Kind: OperationKindTableCopy, U1: uint64(srcTableIndex), U2: uint64(dstTableIndex)}
  1839  }
  1840  
  1841  // NewOperationRefFunc constructor for UnionOperation with OperationKindRefFunc.
  1842  //
  1843  // This corresponds to wasm.OpcodeRefFuncName, and engines are expected to
  1844  // push the opaque pointer value of engine specific func for the given FunctionIndex.
  1845  //
  1846  // Note: in wazero, we express any reference types (funcref or externref) as opaque pointers which is uint64.
  1847  // Therefore, the engine implementations emit instructions to push the address of *function onto the stack.
  1848  func NewOperationRefFunc(functionIndex uint32) UnionOperation {
  1849  	return UnionOperation{Kind: OperationKindRefFunc, U1: uint64(functionIndex)}
  1850  }
  1851  
  1852  // NewOperationTableGet constructor for UnionOperation with OperationKindTableGet.
  1853  //
  1854  // This corresponds to wasm.OpcodeTableGetName.
  1855  func NewOperationTableGet(tableIndex uint32) UnionOperation {
  1856  	return UnionOperation{Kind: OperationKindTableGet, U1: uint64(tableIndex)}
  1857  }
  1858  
  1859  // NewOperationTableSet constructor for UnionOperation with OperationKindTableSet.
  1860  //
  1861  // This corresponds to wasm.OpcodeTableSetName.
  1862  func NewOperationTableSet(tableIndex uint32) UnionOperation {
  1863  	return UnionOperation{Kind: OperationKindTableSet, U1: uint64(tableIndex)}
  1864  }
  1865  
  1866  // NewOperationTableSize constructor for UnionOperation with OperationKindTableSize.
  1867  //
  1868  // This corresponds to wasm.OpcodeTableSizeName.
  1869  func NewOperationTableSize(tableIndex uint32) UnionOperation {
  1870  	return UnionOperation{Kind: OperationKindTableSize, U1: uint64(tableIndex)}
  1871  }
  1872  
  1873  // NewOperationTableGrow constructor for UnionOperation with OperationKindTableGrow.
  1874  //
  1875  // This corresponds to wasm.OpcodeTableGrowName.
  1876  func NewOperationTableGrow(tableIndex uint32) UnionOperation {
  1877  	return UnionOperation{Kind: OperationKindTableGrow, U1: uint64(tableIndex)}
  1878  }
  1879  
  1880  // NewOperationTableFill constructor for UnionOperation with OperationKindTableFill.
  1881  //
  1882  // This corresponds to wasm.OpcodeTableFillName.
  1883  func NewOperationTableFill(tableIndex uint32) UnionOperation {
  1884  	return UnionOperation{Kind: OperationKindTableFill, U1: uint64(tableIndex)}
  1885  }
  1886  
  1887  // NewOperationV128Const constructor for UnionOperation with OperationKindV128Const
  1888  func NewOperationV128Const(lo, hi uint64) UnionOperation {
  1889  	return UnionOperation{Kind: OperationKindV128Const, U1: lo, U2: hi}
  1890  }
  1891  
  1892  // Shape corresponds to a shape of v128 values.
  1893  // https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-shape
  1894  type Shape = byte
  1895  
  1896  const (
  1897  	ShapeI8x16 Shape = iota
  1898  	ShapeI16x8
  1899  	ShapeI32x4
  1900  	ShapeI64x2
  1901  	ShapeF32x4
  1902  	ShapeF64x2
  1903  )
  1904  
  1905  func shapeName(s Shape) (ret string) {
  1906  	switch s {
  1907  	case ShapeI8x16:
  1908  		ret = "I8x16"
  1909  	case ShapeI16x8:
  1910  		ret = "I16x8"
  1911  	case ShapeI32x4:
  1912  		ret = "I32x4"
  1913  	case ShapeI64x2:
  1914  		ret = "I64x2"
  1915  	case ShapeF32x4:
  1916  		ret = "F32x4"
  1917  	case ShapeF64x2:
  1918  		ret = "F64x2"
  1919  	}
  1920  	return
  1921  }
  1922  
  1923  // NewOperationV128Add constructor for UnionOperation with OperationKindV128Add.
  1924  //
  1925  // This corresponds to wasm.OpcodeVecI8x16AddName wasm.OpcodeVecI16x8AddName wasm.OpcodeVecI32x4AddName
  1926  //
  1927  //	wasm.OpcodeVecI64x2AddName wasm.OpcodeVecF32x4AddName wasm.OpcodeVecF64x2AddName
  1928  func NewOperationV128Add(shape Shape) UnionOperation {
  1929  	return UnionOperation{Kind: OperationKindV128Add, B1: shape}
  1930  }
  1931  
  1932  // NewOperationV128Sub constructor for UnionOperation with OperationKindV128Sub.
  1933  //
  1934  // This corresponds to wasm.OpcodeVecI8x16SubName wasm.OpcodeVecI16x8SubName wasm.OpcodeVecI32x4SubName
  1935  //
  1936  //	wasm.OpcodeVecI64x2SubName wasm.OpcodeVecF32x4SubName wasm.OpcodeVecF64x2SubName
  1937  func NewOperationV128Sub(shape Shape) UnionOperation {
  1938  	return UnionOperation{Kind: OperationKindV128Sub, B1: shape}
  1939  }
  1940  
  1941  // V128LoadType represents a type of wasm.OpcodeVecV128Load* instructions.
  1942  type V128LoadType = byte
  1943  
  1944  const (
  1945  	// V128LoadType128 corresponds to wasm.OpcodeVecV128LoadName.
  1946  	V128LoadType128 V128LoadType = iota
  1947  	// V128LoadType8x8s corresponds to wasm.OpcodeVecV128Load8x8SName.
  1948  	V128LoadType8x8s
  1949  	// V128LoadType8x8u corresponds to wasm.OpcodeVecV128Load8x8UName.
  1950  	V128LoadType8x8u
  1951  	// V128LoadType16x4s corresponds to wasm.OpcodeVecV128Load16x4SName
  1952  	V128LoadType16x4s
  1953  	// V128LoadType16x4u corresponds to wasm.OpcodeVecV128Load16x4UName
  1954  	V128LoadType16x4u
  1955  	// V128LoadType32x2s corresponds to wasm.OpcodeVecV128Load32x2SName
  1956  	V128LoadType32x2s
  1957  	// V128LoadType32x2u corresponds to wasm.OpcodeVecV128Load32x2UName
  1958  	V128LoadType32x2u
  1959  	// V128LoadType8Splat corresponds to wasm.OpcodeVecV128Load8SplatName
  1960  	V128LoadType8Splat
  1961  	// V128LoadType16Splat corresponds to wasm.OpcodeVecV128Load16SplatName
  1962  	V128LoadType16Splat
  1963  	// V128LoadType32Splat corresponds to wasm.OpcodeVecV128Load32SplatName
  1964  	V128LoadType32Splat
  1965  	// V128LoadType64Splat corresponds to wasm.OpcodeVecV128Load64SplatName
  1966  	V128LoadType64Splat
  1967  	// V128LoadType32zero corresponds to wasm.OpcodeVecV128Load32zeroName
  1968  	V128LoadType32zero
  1969  	// V128LoadType64zero corresponds to wasm.OpcodeVecV128Load64zeroName
  1970  	V128LoadType64zero
  1971  )
  1972  
  1973  // NewOperationV128Load is a constructor for UnionOperation with OperationKindV128Load.
  1974  //
  1975  // This corresponds to
  1976  //
  1977  //	wasm.OpcodeVecV128LoadName wasm.OpcodeVecV128Load8x8SName wasm.OpcodeVecV128Load8x8UName
  1978  //	wasm.OpcodeVecV128Load16x4SName wasm.OpcodeVecV128Load16x4UName wasm.OpcodeVecV128Load32x2SName
  1979  //	wasm.OpcodeVecV128Load32x2UName wasm.OpcodeVecV128Load8SplatName wasm.OpcodeVecV128Load16SplatName
  1980  //	wasm.OpcodeVecV128Load32SplatName wasm.OpcodeVecV128Load64SplatName wasm.OpcodeVecV128Load32zeroName
  1981  //	wasm.OpcodeVecV128Load64zeroName
  1982  func NewOperationV128Load(loadType V128LoadType, arg MemoryArg) UnionOperation {
  1983  	return UnionOperation{Kind: OperationKindV128Load, B1: loadType, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1984  }
  1985  
  1986  // NewOperationV128LoadLane is a constructor for UnionOperation with OperationKindV128LoadLane.
  1987  //
  1988  // This corresponds to wasm.OpcodeVecV128Load8LaneName wasm.OpcodeVecV128Load16LaneName
  1989  //
  1990  //	wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName.
  1991  //
  1992  // laneIndex is >=0 && <(128/LaneSize).
  1993  // laneSize is either 8, 16, 32, or 64.
  1994  func NewOperationV128LoadLane(laneIndex, laneSize byte, arg MemoryArg) UnionOperation {
  1995  	return UnionOperation{Kind: OperationKindV128LoadLane, B1: laneSize, B2: laneIndex, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)}
  1996  }
  1997  
  1998  // NewOperationV128Store is a constructor for UnionOperation with OperationKindV128Store.
  1999  //
  2000  // This corresponds to wasm.OpcodeVecV128Load8LaneName wasm.OpcodeVecV128Load16LaneName
  2001  //
  2002  //	wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName.
  2003  func NewOperationV128Store(arg MemoryArg) UnionOperation {
  2004  	return UnionOperation{
  2005  		Kind: OperationKindV128Store,
  2006  		U1:   uint64(arg.Alignment),
  2007  		U2:   uint64(arg.Offset),
  2008  	}
  2009  }
  2010  
  2011  // NewOperationV128StoreLane implements Operation.
  2012  //
  2013  // This corresponds to wasm.OpcodeVecV128Load8LaneName wasm.OpcodeVecV128Load16LaneName
  2014  //
  2015  //	wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName.
  2016  //
  2017  // laneIndex is >=0 && <(128/LaneSize).
  2018  // laneSize is either 8, 16, 32, or 64.
  2019  func NewOperationV128StoreLane(laneIndex byte, laneSize byte, arg MemoryArg) UnionOperation {
  2020  	return UnionOperation{
  2021  		Kind: OperationKindV128StoreLane,
  2022  		B1:   laneSize,
  2023  		B2:   laneIndex,
  2024  		U1:   uint64(arg.Alignment),
  2025  		U2:   uint64(arg.Offset),
  2026  	}
  2027  }
  2028  
  2029  // NewOperationV128ExtractLane is a constructor for UnionOperation with OperationKindV128ExtractLane.
  2030  //
  2031  // This corresponds to
  2032  //
  2033  //	wasm.OpcodeVecI8x16ExtractLaneSName wasm.OpcodeVecI8x16ExtractLaneUName
  2034  //	wasm.OpcodeVecI16x8ExtractLaneSName wasm.OpcodeVecI16x8ExtractLaneUName
  2035  //	wasm.OpcodeVecI32x4ExtractLaneName wasm.OpcodeVecI64x2ExtractLaneName
  2036  //	wasm.OpcodeVecF32x4ExtractLaneName wasm.OpcodeVecF64x2ExtractLaneName.
  2037  //
  2038  // laneIndex is >=0 && <M where shape = NxM.
  2039  // signed is used when shape is either i8x16 or i16x2 to specify whether to sign-extend or not.
  2040  func NewOperationV128ExtractLane(laneIndex byte, signed bool, shape Shape) UnionOperation {
  2041  	return UnionOperation{
  2042  		Kind: OperationKindV128ExtractLane,
  2043  		B1:   shape,
  2044  		B2:   laneIndex,
  2045  		B3:   signed,
  2046  	}
  2047  }
  2048  
  2049  // NewOperationV128ReplaceLane is a constructor for UnionOperation with OperationKindV128ReplaceLane.
  2050  //
  2051  // This corresponds to
  2052  //
  2053  //	wasm.OpcodeVecI8x16ReplaceLaneName wasm.OpcodeVecI16x8ReplaceLaneName
  2054  //	wasm.OpcodeVecI32x4ReplaceLaneName wasm.OpcodeVecI64x2ReplaceLaneName
  2055  //	wasm.OpcodeVecF32x4ReplaceLaneName wasm.OpcodeVecF64x2ReplaceLaneName.
  2056  //
  2057  // laneIndex is >=0 && <M where shape = NxM.
  2058  func NewOperationV128ReplaceLane(laneIndex byte, shape Shape) UnionOperation {
  2059  	return UnionOperation{Kind: OperationKindV128ReplaceLane, B1: shape, B2: laneIndex}
  2060  }
  2061  
  2062  // NewOperationV128Splat is a constructor for UnionOperation with OperationKindV128Splat.
  2063  //
  2064  // This corresponds to
  2065  //
  2066  //	wasm.OpcodeVecI8x16SplatName wasm.OpcodeVecI16x8SplatName
  2067  //	wasm.OpcodeVecI32x4SplatName wasm.OpcodeVecI64x2SplatName
  2068  //	wasm.OpcodeVecF32x4SplatName wasm.OpcodeVecF64x2SplatName.
  2069  func NewOperationV128Splat(shape Shape) UnionOperation {
  2070  	return UnionOperation{Kind: OperationKindV128Splat, B1: shape}
  2071  }
  2072  
  2073  // NewOperationV128Shuffle is a constructor for UnionOperation with OperationKindV128Shuffle.
  2074  func NewOperationV128Shuffle(lanes []uint64) UnionOperation {
  2075  	return UnionOperation{Kind: OperationKindV128Shuffle, Us: lanes}
  2076  }
  2077  
  2078  // NewOperationV128Swizzle is a constructor for UnionOperation with OperationKindV128Swizzle.
  2079  //
  2080  // This corresponds to wasm.OpcodeVecI8x16SwizzleName.
  2081  func NewOperationV128Swizzle() UnionOperation {
  2082  	return UnionOperation{Kind: OperationKindV128Swizzle}
  2083  }
  2084  
  2085  // NewOperationV128AnyTrue is a constructor for UnionOperation with OperationKindV128AnyTrue.
  2086  //
  2087  // This corresponds to wasm.OpcodeVecV128AnyTrueName.
  2088  func NewOperationV128AnyTrue() UnionOperation {
  2089  	return UnionOperation{Kind: OperationKindV128AnyTrue}
  2090  }
  2091  
  2092  // NewOperationV128AllTrue is a constructor for UnionOperation with OperationKindV128AllTrue.
  2093  //
  2094  // This corresponds to
  2095  //
  2096  //	wasm.OpcodeVecI8x16AllTrueName wasm.OpcodeVecI16x8AllTrueName
  2097  //	wasm.OpcodeVecI32x4AllTrueName wasm.OpcodeVecI64x2AllTrueName.
  2098  func NewOperationV128AllTrue(shape Shape) UnionOperation {
  2099  	return UnionOperation{Kind: OperationKindV128AllTrue, B1: shape}
  2100  }
  2101  
  2102  // NewOperationV128BitMask is a constructor for UnionOperation with OperationKindV128BitMask.
  2103  //
  2104  // This corresponds to
  2105  //
  2106  //	wasm.OpcodeVecI8x16BitMaskName wasm.OpcodeVecI16x8BitMaskName
  2107  //	wasm.OpcodeVecI32x4BitMaskName wasm.OpcodeVecI64x2BitMaskName.
  2108  func NewOperationV128BitMask(shape Shape) UnionOperation {
  2109  	return UnionOperation{Kind: OperationKindV128BitMask, B1: shape}
  2110  }
  2111  
  2112  // NewOperationV128And is a constructor for UnionOperation with OperationKindV128And.
  2113  //
  2114  // This corresponds to wasm.OpcodeVecV128And.
  2115  func NewOperationV128And() UnionOperation {
  2116  	return UnionOperation{Kind: OperationKindV128And}
  2117  }
  2118  
  2119  // NewOperationV128Not is a constructor for UnionOperation with OperationKindV128Not.
  2120  //
  2121  // This corresponds to wasm.OpcodeVecV128Not.
  2122  func NewOperationV128Not() UnionOperation {
  2123  	return UnionOperation{Kind: OperationKindV128Not}
  2124  }
  2125  
  2126  // NewOperationV128Or is a constructor for UnionOperation with OperationKindV128Or.
  2127  //
  2128  // This corresponds to wasm.OpcodeVecV128Or.
  2129  func NewOperationV128Or() UnionOperation {
  2130  	return UnionOperation{Kind: OperationKindV128Or}
  2131  }
  2132  
  2133  // NewOperationV128Xor is a constructor for UnionOperation with OperationKindV128Xor.
  2134  //
  2135  // This corresponds to wasm.OpcodeVecV128Xor.
  2136  func NewOperationV128Xor() UnionOperation {
  2137  	return UnionOperation{Kind: OperationKindV128Xor}
  2138  }
  2139  
  2140  // NewOperationV128Bitselect is a constructor for UnionOperation with OperationKindV128Bitselect.
  2141  //
  2142  // This corresponds to wasm.OpcodeVecV128Bitselect.
  2143  func NewOperationV128Bitselect() UnionOperation {
  2144  	return UnionOperation{Kind: OperationKindV128Bitselect}
  2145  }
  2146  
  2147  // NewOperationV128AndNot is a constructor for UnionOperation with OperationKindV128AndNot.
  2148  //
  2149  // This corresponds to wasm.OpcodeVecV128AndNot.
  2150  func NewOperationV128AndNot() UnionOperation {
  2151  	return UnionOperation{Kind: OperationKindV128AndNot}
  2152  }
  2153  
  2154  // NewOperationV128Shl is a constructor for UnionOperation with OperationKindV128Shl.
  2155  //
  2156  // This corresponds to
  2157  //
  2158  //	wasm.OpcodeVecI8x16ShlName wasm.OpcodeVecI16x8ShlName
  2159  //	wasm.OpcodeVecI32x4ShlName wasm.OpcodeVecI64x2ShlName
  2160  func NewOperationV128Shl(shape Shape) UnionOperation {
  2161  	return UnionOperation{Kind: OperationKindV128Shl, B1: shape}
  2162  }
  2163  
  2164  // NewOperationV128Shr is a constructor for UnionOperation with OperationKindV128Shr.
  2165  //
  2166  // This corresponds to
  2167  //
  2168  //	wasm.OpcodeVecI8x16ShrSName wasm.OpcodeVecI8x16ShrUName wasm.OpcodeVecI16x8ShrSName
  2169  //	wasm.OpcodeVecI16x8ShrUName wasm.OpcodeVecI32x4ShrSName wasm.OpcodeVecI32x4ShrUName.
  2170  //	wasm.OpcodeVecI64x2ShrSName wasm.OpcodeVecI64x2ShrUName.
  2171  func NewOperationV128Shr(shape Shape, signed bool) UnionOperation {
  2172  	return UnionOperation{Kind: OperationKindV128Shr, B1: shape, B3: signed}
  2173  }
  2174  
  2175  // NewOperationV128Cmp is a constructor for UnionOperation with OperationKindV128Cmp.
  2176  //
  2177  // This corresponds to
  2178  //
  2179  //	wasm.OpcodeVecI8x16EqName, wasm.OpcodeVecI8x16NeName, wasm.OpcodeVecI8x16LtSName, wasm.OpcodeVecI8x16LtUName, wasm.OpcodeVecI8x16GtSName,
  2180  //	wasm.OpcodeVecI8x16GtUName, wasm.OpcodeVecI8x16LeSName, wasm.OpcodeVecI8x16LeUName, wasm.OpcodeVecI8x16GeSName, wasm.OpcodeVecI8x16GeUName,
  2181  //	wasm.OpcodeVecI16x8EqName, wasm.OpcodeVecI16x8NeName, wasm.OpcodeVecI16x8LtSName, wasm.OpcodeVecI16x8LtUName, wasm.OpcodeVecI16x8GtSName,
  2182  //	wasm.OpcodeVecI16x8GtUName, wasm.OpcodeVecI16x8LeSName, wasm.OpcodeVecI16x8LeUName, wasm.OpcodeVecI16x8GeSName, wasm.OpcodeVecI16x8GeUName,
  2183  //	wasm.OpcodeVecI32x4EqName, wasm.OpcodeVecI32x4NeName, wasm.OpcodeVecI32x4LtSName, wasm.OpcodeVecI32x4LtUName, wasm.OpcodeVecI32x4GtSName,
  2184  //	wasm.OpcodeVecI32x4GtUName, wasm.OpcodeVecI32x4LeSName, wasm.OpcodeVecI32x4LeUName, wasm.OpcodeVecI32x4GeSName, wasm.OpcodeVecI32x4GeUName,
  2185  //	wasm.OpcodeVecI64x2EqName, wasm.OpcodeVecI64x2NeName, wasm.OpcodeVecI64x2LtSName, wasm.OpcodeVecI64x2GtSName, wasm.OpcodeVecI64x2LeSName,
  2186  //	wasm.OpcodeVecI64x2GeSName, wasm.OpcodeVecF32x4EqName, wasm.OpcodeVecF32x4NeName, wasm.OpcodeVecF32x4LtName, wasm.OpcodeVecF32x4GtName,
  2187  //	wasm.OpcodeVecF32x4LeName, wasm.OpcodeVecF32x4GeName, wasm.OpcodeVecF64x2EqName, wasm.OpcodeVecF64x2NeName, wasm.OpcodeVecF64x2LtName,
  2188  //	wasm.OpcodeVecF64x2GtName, wasm.OpcodeVecF64x2LeName, wasm.OpcodeVecF64x2GeName
  2189  func NewOperationV128Cmp(cmpType V128CmpType) UnionOperation {
  2190  	return UnionOperation{Kind: OperationKindV128Cmp, B1: cmpType}
  2191  }
  2192  
  2193  // V128CmpType represents a type of vector comparison operation.
  2194  type V128CmpType = byte
  2195  
  2196  const (
  2197  	// V128CmpTypeI8x16Eq corresponds to wasm.OpcodeVecI8x16EqName.
  2198  	V128CmpTypeI8x16Eq V128CmpType = iota
  2199  	// V128CmpTypeI8x16Ne corresponds to wasm.OpcodeVecI8x16NeName.
  2200  	V128CmpTypeI8x16Ne
  2201  	// V128CmpTypeI8x16LtS corresponds to wasm.OpcodeVecI8x16LtSName.
  2202  	V128CmpTypeI8x16LtS
  2203  	// V128CmpTypeI8x16LtU corresponds to wasm.OpcodeVecI8x16LtUName.
  2204  	V128CmpTypeI8x16LtU
  2205  	// V128CmpTypeI8x16GtS corresponds to wasm.OpcodeVecI8x16GtSName.
  2206  	V128CmpTypeI8x16GtS
  2207  	// V128CmpTypeI8x16GtU corresponds to wasm.OpcodeVecI8x16GtUName.
  2208  	V128CmpTypeI8x16GtU
  2209  	// V128CmpTypeI8x16LeS corresponds to wasm.OpcodeVecI8x16LeSName.
  2210  	V128CmpTypeI8x16LeS
  2211  	// V128CmpTypeI8x16LeU corresponds to wasm.OpcodeVecI8x16LeUName.
  2212  	V128CmpTypeI8x16LeU
  2213  	// V128CmpTypeI8x16GeS corresponds to wasm.OpcodeVecI8x16GeSName.
  2214  	V128CmpTypeI8x16GeS
  2215  	// V128CmpTypeI8x16GeU corresponds to wasm.OpcodeVecI8x16GeUName.
  2216  	V128CmpTypeI8x16GeU
  2217  	// V128CmpTypeI16x8Eq corresponds to wasm.OpcodeVecI16x8EqName.
  2218  	V128CmpTypeI16x8Eq
  2219  	// V128CmpTypeI16x8Ne corresponds to wasm.OpcodeVecI16x8NeName.
  2220  	V128CmpTypeI16x8Ne
  2221  	// V128CmpTypeI16x8LtS corresponds to wasm.OpcodeVecI16x8LtSName.
  2222  	V128CmpTypeI16x8LtS
  2223  	// V128CmpTypeI16x8LtU corresponds to wasm.OpcodeVecI16x8LtUName.
  2224  	V128CmpTypeI16x8LtU
  2225  	// V128CmpTypeI16x8GtS corresponds to wasm.OpcodeVecI16x8GtSName.
  2226  	V128CmpTypeI16x8GtS
  2227  	// V128CmpTypeI16x8GtU corresponds to wasm.OpcodeVecI16x8GtUName.
  2228  	V128CmpTypeI16x8GtU
  2229  	// V128CmpTypeI16x8LeS corresponds to wasm.OpcodeVecI16x8LeSName.
  2230  	V128CmpTypeI16x8LeS
  2231  	// V128CmpTypeI16x8LeU corresponds to wasm.OpcodeVecI16x8LeUName.
  2232  	V128CmpTypeI16x8LeU
  2233  	// V128CmpTypeI16x8GeS corresponds to wasm.OpcodeVecI16x8GeSName.
  2234  	V128CmpTypeI16x8GeS
  2235  	// V128CmpTypeI16x8GeU corresponds to wasm.OpcodeVecI16x8GeUName.
  2236  	V128CmpTypeI16x8GeU
  2237  	// V128CmpTypeI32x4Eq corresponds to wasm.OpcodeVecI32x4EqName.
  2238  	V128CmpTypeI32x4Eq
  2239  	// V128CmpTypeI32x4Ne corresponds to wasm.OpcodeVecI32x4NeName.
  2240  	V128CmpTypeI32x4Ne
  2241  	// V128CmpTypeI32x4LtS corresponds to wasm.OpcodeVecI32x4LtSName.
  2242  	V128CmpTypeI32x4LtS
  2243  	// V128CmpTypeI32x4LtU corresponds to wasm.OpcodeVecI32x4LtUName.
  2244  	V128CmpTypeI32x4LtU
  2245  	// V128CmpTypeI32x4GtS corresponds to wasm.OpcodeVecI32x4GtSName.
  2246  	V128CmpTypeI32x4GtS
  2247  	// V128CmpTypeI32x4GtU corresponds to wasm.OpcodeVecI32x4GtUName.
  2248  	V128CmpTypeI32x4GtU
  2249  	// V128CmpTypeI32x4LeS corresponds to wasm.OpcodeVecI32x4LeSName.
  2250  	V128CmpTypeI32x4LeS
  2251  	// V128CmpTypeI32x4LeU corresponds to wasm.OpcodeVecI32x4LeUName.
  2252  	V128CmpTypeI32x4LeU
  2253  	// V128CmpTypeI32x4GeS corresponds to wasm.OpcodeVecI32x4GeSName.
  2254  	V128CmpTypeI32x4GeS
  2255  	// V128CmpTypeI32x4GeU corresponds to wasm.OpcodeVecI32x4GeUName.
  2256  	V128CmpTypeI32x4GeU
  2257  	// V128CmpTypeI64x2Eq corresponds to wasm.OpcodeVecI64x2EqName.
  2258  	V128CmpTypeI64x2Eq
  2259  	// V128CmpTypeI64x2Ne corresponds to wasm.OpcodeVecI64x2NeName.
  2260  	V128CmpTypeI64x2Ne
  2261  	// V128CmpTypeI64x2LtS corresponds to wasm.OpcodeVecI64x2LtSName.
  2262  	V128CmpTypeI64x2LtS
  2263  	// V128CmpTypeI64x2GtS corresponds to wasm.OpcodeVecI64x2GtSName.
  2264  	V128CmpTypeI64x2GtS
  2265  	// V128CmpTypeI64x2LeS corresponds to wasm.OpcodeVecI64x2LeSName.
  2266  	V128CmpTypeI64x2LeS
  2267  	// V128CmpTypeI64x2GeS corresponds to wasm.OpcodeVecI64x2GeSName.
  2268  	V128CmpTypeI64x2GeS
  2269  	// V128CmpTypeF32x4Eq corresponds to wasm.OpcodeVecF32x4EqName.
  2270  	V128CmpTypeF32x4Eq
  2271  	// V128CmpTypeF32x4Ne corresponds to wasm.OpcodeVecF32x4NeName.
  2272  	V128CmpTypeF32x4Ne
  2273  	// V128CmpTypeF32x4Lt corresponds to wasm.OpcodeVecF32x4LtName.
  2274  	V128CmpTypeF32x4Lt
  2275  	// V128CmpTypeF32x4Gt corresponds to wasm.OpcodeVecF32x4GtName.
  2276  	V128CmpTypeF32x4Gt
  2277  	// V128CmpTypeF32x4Le corresponds to wasm.OpcodeVecF32x4LeName.
  2278  	V128CmpTypeF32x4Le
  2279  	// V128CmpTypeF32x4Ge corresponds to wasm.OpcodeVecF32x4GeName.
  2280  	V128CmpTypeF32x4Ge
  2281  	// V128CmpTypeF64x2Eq corresponds to wasm.OpcodeVecF64x2EqName.
  2282  	V128CmpTypeF64x2Eq
  2283  	// V128CmpTypeF64x2Ne corresponds to wasm.OpcodeVecF64x2NeName.
  2284  	V128CmpTypeF64x2Ne
  2285  	// V128CmpTypeF64x2Lt corresponds to wasm.OpcodeVecF64x2LtName.
  2286  	V128CmpTypeF64x2Lt
  2287  	// V128CmpTypeF64x2Gt corresponds to wasm.OpcodeVecF64x2GtName.
  2288  	V128CmpTypeF64x2Gt
  2289  	// V128CmpTypeF64x2Le corresponds to wasm.OpcodeVecF64x2LeName.
  2290  	V128CmpTypeF64x2Le
  2291  	// V128CmpTypeF64x2Ge corresponds to wasm.OpcodeVecF64x2GeName.
  2292  	V128CmpTypeF64x2Ge
  2293  )
  2294  
  2295  // NewOperationV128AddSat is a constructor for UnionOperation with OperationKindV128AddSat.
  2296  //
  2297  // This corresponds to wasm.OpcodeVecI8x16AddSatUName wasm.OpcodeVecI8x16AddSatSName
  2298  //
  2299  //	wasm.OpcodeVecI16x8AddSatUName wasm.OpcodeVecI16x8AddSatSName
  2300  //
  2301  // shape is either ShapeI8x16 or ShapeI16x8.
  2302  func NewOperationV128AddSat(shape Shape, signed bool) UnionOperation {
  2303  	return UnionOperation{Kind: OperationKindV128AddSat, B1: shape, B3: signed}
  2304  }
  2305  
  2306  // NewOperationV128SubSat is a constructor for UnionOperation with OperationKindV128SubSat.
  2307  //
  2308  // This corresponds to wasm.OpcodeVecI8x16SubSatUName wasm.OpcodeVecI8x16SubSatSName
  2309  //
  2310  //	wasm.OpcodeVecI16x8SubSatUName wasm.OpcodeVecI16x8SubSatSName
  2311  //
  2312  // shape is either ShapeI8x16 or ShapeI16x8.
  2313  func NewOperationV128SubSat(shape Shape, signed bool) UnionOperation {
  2314  	return UnionOperation{Kind: OperationKindV128SubSat, B1: shape, B3: signed}
  2315  }
  2316  
  2317  // NewOperationV128Mul is a constructor for UnionOperation with OperationKindV128Mul
  2318  //
  2319  // This corresponds to wasm.OpcodeVecF32x4MulName wasm.OpcodeVecF64x2MulName
  2320  //
  2321  //		wasm.OpcodeVecI16x8MulName wasm.OpcodeVecI32x4MulName wasm.OpcodeVecI64x2MulName.
  2322  //	 shape is either ShapeI16x8, ShapeI32x4, ShapeI64x2, ShapeF32x4 or ShapeF64x2.
  2323  func NewOperationV128Mul(shape Shape) UnionOperation {
  2324  	return UnionOperation{Kind: OperationKindV128Mul, B1: shape}
  2325  }
  2326  
  2327  // NewOperationV128Div is a constructor for UnionOperation with OperationKindV128Div.
  2328  //
  2329  // This corresponds to wasm.OpcodeVecF32x4DivName wasm.OpcodeVecF64x2DivName.
  2330  // shape is either ShapeF32x4 or ShapeF64x2.
  2331  func NewOperationV128Div(shape Shape) UnionOperation {
  2332  	return UnionOperation{Kind: OperationKindV128Div, B1: shape}
  2333  }
  2334  
  2335  // NewOperationV128Neg is a constructor for UnionOperation with OperationKindV128Neg.
  2336  //
  2337  // This corresponds to wasm.OpcodeVecI8x16NegName wasm.OpcodeVecI16x8NegName wasm.OpcodeVecI32x4NegName
  2338  //
  2339  //	wasm.OpcodeVecI64x2NegName wasm.OpcodeVecF32x4NegName wasm.OpcodeVecF64x2NegName.
  2340  func NewOperationV128Neg(shape Shape) UnionOperation {
  2341  	return UnionOperation{Kind: OperationKindV128Neg, B1: shape}
  2342  }
  2343  
  2344  // NewOperationV128Sqrt is a constructor for UnionOperation with 128OperationKindV128Sqrt.
  2345  //
  2346  // shape is either ShapeF32x4 or ShapeF64x2.
  2347  // This corresponds to wasm.OpcodeVecF32x4SqrtName wasm.OpcodeVecF64x2SqrtName.
  2348  func NewOperationV128Sqrt(shape Shape) UnionOperation {
  2349  	return UnionOperation{Kind: OperationKindV128Sqrt, B1: shape}
  2350  }
  2351  
  2352  // NewOperationV128Abs is a constructor for UnionOperation with OperationKindV128Abs.
  2353  //
  2354  // This corresponds to wasm.OpcodeVecI8x16AbsName wasm.OpcodeVecI16x8AbsName wasm.OpcodeVecI32x4AbsName
  2355  //
  2356  //	wasm.OpcodeVecI64x2AbsName wasm.OpcodeVecF32x4AbsName wasm.OpcodeVecF64x2AbsName.
  2357  func NewOperationV128Abs(shape Shape) UnionOperation {
  2358  	return UnionOperation{Kind: OperationKindV128Abs, B1: shape}
  2359  }
  2360  
  2361  // NewOperationV128Popcnt is a constructor for UnionOperation with OperationKindV128Popcnt.
  2362  //
  2363  // This corresponds to wasm.OpcodeVecI8x16PopcntName.
  2364  func NewOperationV128Popcnt(shape Shape) UnionOperation {
  2365  	return UnionOperation{Kind: OperationKindV128Popcnt, B1: shape}
  2366  }
  2367  
  2368  // NewOperationV128Min is a constructor for UnionOperation with OperationKindV128Min.
  2369  //
  2370  // This corresponds to
  2371  //
  2372  //	wasm.OpcodeVecI8x16MinSName wasm.OpcodeVecI8x16MinUName wasm.OpcodeVecI16x8MinSName wasm.OpcodeVecI16x8MinUName
  2373  //	wasm.OpcodeVecI32x4MinSName wasm.OpcodeVecI32x4MinUName wasm.OpcodeVecI16x8MinSName wasm.OpcodeVecI16x8MinUName
  2374  //	wasm.OpcodeVecF32x4MinName wasm.OpcodeVecF64x2MinName
  2375  func NewOperationV128Min(shape Shape, signed bool) UnionOperation {
  2376  	return UnionOperation{Kind: OperationKindV128Min, B1: shape, B3: signed}
  2377  }
  2378  
  2379  // NewOperationV128Max is a constructor for UnionOperation with OperationKindV128Max.
  2380  //
  2381  // This corresponds to
  2382  //
  2383  //	wasm.OpcodeVecI8x16MaxSName wasm.OpcodeVecI8x16MaxUName wasm.OpcodeVecI16x8MaxSName wasm.OpcodeVecI16x8MaxUName
  2384  //	wasm.OpcodeVecI32x4MaxSName wasm.OpcodeVecI32x4MaxUName wasm.OpcodeVecI16x8MaxSName wasm.OpcodeVecI16x8MaxUName
  2385  //	wasm.OpcodeVecF32x4MaxName wasm.OpcodeVecF64x2MaxName.
  2386  func NewOperationV128Max(shape Shape, signed bool) UnionOperation {
  2387  	return UnionOperation{Kind: OperationKindV128Max, B1: shape, B3: signed}
  2388  }
  2389  
  2390  // NewOperationV128AvgrU is a constructor for UnionOperation with OperationKindV128AvgrU.
  2391  //
  2392  // This corresponds to wasm.OpcodeVecI8x16AvgrUName.
  2393  func NewOperationV128AvgrU(shape Shape) UnionOperation {
  2394  	return UnionOperation{Kind: OperationKindV128AvgrU, B1: shape}
  2395  }
  2396  
  2397  // NewOperationV128Pmin is a constructor for UnionOperation with OperationKindV128Pmin.
  2398  //
  2399  // This corresponds to wasm.OpcodeVecF32x4PminName wasm.OpcodeVecF64x2PminName.
  2400  func NewOperationV128Pmin(shape Shape) UnionOperation {
  2401  	return UnionOperation{Kind: OperationKindV128Pmin, B1: shape}
  2402  }
  2403  
  2404  // NewOperationV128Pmax is a constructor for UnionOperation with OperationKindV128Pmax.
  2405  //
  2406  // This corresponds to wasm.OpcodeVecF32x4PmaxName wasm.OpcodeVecF64x2PmaxName.
  2407  func NewOperationV128Pmax(shape Shape) UnionOperation {
  2408  	return UnionOperation{Kind: OperationKindV128Pmax, B1: shape}
  2409  }
  2410  
  2411  // NewOperationV128Ceil is a constructor for UnionOperation with OperationKindV128Ceil.
  2412  //
  2413  // This corresponds to wasm.OpcodeVecF32x4CeilName wasm.OpcodeVecF64x2CeilName
  2414  func NewOperationV128Ceil(shape Shape) UnionOperation {
  2415  	return UnionOperation{Kind: OperationKindV128Ceil, B1: shape}
  2416  }
  2417  
  2418  // NewOperationV128Floor is a constructor for UnionOperation with OperationKindV128Floor.
  2419  //
  2420  // This corresponds to wasm.OpcodeVecF32x4FloorName wasm.OpcodeVecF64x2FloorName
  2421  func NewOperationV128Floor(shape Shape) UnionOperation {
  2422  	return UnionOperation{Kind: OperationKindV128Floor, B1: shape}
  2423  }
  2424  
  2425  // NewOperationV128Trunc is a constructor for UnionOperation with OperationKindV128Trunc.
  2426  //
  2427  // This corresponds to wasm.OpcodeVecF32x4TruncName wasm.OpcodeVecF64x2TruncName
  2428  func NewOperationV128Trunc(shape Shape) UnionOperation {
  2429  	return UnionOperation{Kind: OperationKindV128Trunc, B1: shape}
  2430  }
  2431  
  2432  // NewOperationV128Nearest is a constructor for UnionOperation with OperationKindV128Nearest.
  2433  //
  2434  // This corresponds to wasm.OpcodeVecF32x4NearestName wasm.OpcodeVecF64x2NearestName
  2435  func NewOperationV128Nearest(shape Shape) UnionOperation {
  2436  	return UnionOperation{Kind: OperationKindV128Nearest, B1: shape}
  2437  }
  2438  
  2439  // NewOperationV128Extend is a constructor for UnionOperation with OperationKindV128Extend.
  2440  //
  2441  // This corresponds to
  2442  //
  2443  //	wasm.OpcodeVecI16x8ExtendLowI8x16SName wasm.OpcodeVecI16x8ExtendHighI8x16SName
  2444  //	wasm.OpcodeVecI16x8ExtendLowI8x16UName wasm.OpcodeVecI16x8ExtendHighI8x16UName
  2445  //	wasm.OpcodeVecI32x4ExtendLowI16x8SName wasm.OpcodeVecI32x4ExtendHighI16x8SName
  2446  //	wasm.OpcodeVecI32x4ExtendLowI16x8UName wasm.OpcodeVecI32x4ExtendHighI16x8UName
  2447  //	wasm.OpcodeVecI64x2ExtendLowI32x4SName wasm.OpcodeVecI64x2ExtendHighI32x4SName
  2448  //	wasm.OpcodeVecI64x2ExtendLowI32x4UName wasm.OpcodeVecI64x2ExtendHighI32x4UName
  2449  //
  2450  // originShape is the shape of the original lanes for extension which is
  2451  // either ShapeI8x16, ShapeI16x8, or ShapeI32x4.
  2452  // useLow true if it uses the lower half of vector for extension.
  2453  func NewOperationV128Extend(originShape Shape, signed bool, useLow bool) UnionOperation {
  2454  	op := UnionOperation{Kind: OperationKindV128Extend}
  2455  	op.B1 = originShape
  2456  	if signed {
  2457  		op.B2 = 1
  2458  	}
  2459  	op.B3 = useLow
  2460  	return op
  2461  }
  2462  
  2463  // NewOperationV128ExtMul is a constructor for UnionOperation with OperationKindV128ExtMul.
  2464  //
  2465  // This corresponds to
  2466  //
  2467  //		wasm.OpcodeVecI16x8ExtMulLowI8x16SName wasm.OpcodeVecI16x8ExtMulLowI8x16UName
  2468  //		wasm.OpcodeVecI16x8ExtMulHighI8x16SName wasm.OpcodeVecI16x8ExtMulHighI8x16UName
  2469  //	 wasm.OpcodeVecI32x4ExtMulLowI16x8SName wasm.OpcodeVecI32x4ExtMulLowI16x8UName
  2470  //		wasm.OpcodeVecI32x4ExtMulHighI16x8SName wasm.OpcodeVecI32x4ExtMulHighI16x8UName
  2471  //	 wasm.OpcodeVecI64x2ExtMulLowI32x4SName wasm.OpcodeVecI64x2ExtMulLowI32x4UName
  2472  //		wasm.OpcodeVecI64x2ExtMulHighI32x4SName wasm.OpcodeVecI64x2ExtMulHighI32x4UName.
  2473  //
  2474  // originShape is the shape of the original lanes for extension which is
  2475  // either ShapeI8x16, ShapeI16x8, or ShapeI32x4.
  2476  // useLow true if it uses the lower half of vector for extension.
  2477  func NewOperationV128ExtMul(originShape Shape, signed bool, useLow bool) UnionOperation {
  2478  	op := UnionOperation{Kind: OperationKindV128ExtMul}
  2479  	op.B1 = originShape
  2480  	if signed {
  2481  		op.B2 = 1
  2482  	}
  2483  	op.B3 = useLow
  2484  	return op
  2485  }
  2486  
  2487  // NewOperationV128Q15mulrSatS is a constructor for UnionOperation with OperationKindV128Q15mulrSatS.
  2488  //
  2489  // This corresponds to wasm.OpcodeVecI16x8Q15mulrSatSName
  2490  func NewOperationV128Q15mulrSatS() UnionOperation {
  2491  	return UnionOperation{Kind: OperationKindV128Q15mulrSatS}
  2492  }
  2493  
  2494  // NewOperationV128ExtAddPairwise is a constructor for UnionOperation with OperationKindV128ExtAddPairwise.
  2495  //
  2496  // This corresponds to
  2497  //
  2498  //	wasm.OpcodeVecI16x8ExtaddPairwiseI8x16SName wasm.OpcodeVecI16x8ExtaddPairwiseI8x16UName
  2499  //	wasm.OpcodeVecI32x4ExtaddPairwiseI16x8SName wasm.OpcodeVecI32x4ExtaddPairwiseI16x8UName.
  2500  //
  2501  // originShape is the shape of the original lanes for extension which is
  2502  // either ShapeI8x16, or ShapeI16x8.
  2503  func NewOperationV128ExtAddPairwise(originShape Shape, signed bool) UnionOperation {
  2504  	return UnionOperation{Kind: OperationKindV128ExtAddPairwise, B1: originShape, B3: signed}
  2505  }
  2506  
  2507  // NewOperationV128FloatPromote is a constructor for UnionOperation with NewOperationV128FloatPromote.
  2508  //
  2509  // This corresponds to wasm.OpcodeVecF64x2PromoteLowF32x4ZeroName
  2510  // This discards the higher 64-bit of a vector, and promotes two
  2511  // 32-bit floats in the lower 64-bit as two 64-bit floats.
  2512  func NewOperationV128FloatPromote() UnionOperation {
  2513  	return UnionOperation{Kind: OperationKindV128FloatPromote}
  2514  }
  2515  
  2516  // NewOperationV128FloatDemote is a constructor for UnionOperation with NewOperationV128FloatDemote.
  2517  //
  2518  // This corresponds to wasm.OpcodeVecF32x4DemoteF64x2ZeroName.
  2519  func NewOperationV128FloatDemote() UnionOperation {
  2520  	return UnionOperation{Kind: OperationKindV128FloatDemote}
  2521  }
  2522  
  2523  // NewOperationV128FConvertFromI is a constructor for UnionOperation with NewOperationV128FConvertFromI.
  2524  //
  2525  // This corresponds to
  2526  //
  2527  //	wasm.OpcodeVecF32x4ConvertI32x4SName wasm.OpcodeVecF32x4ConvertI32x4UName
  2528  //	wasm.OpcodeVecF64x2ConvertLowI32x4SName wasm.OpcodeVecF64x2ConvertLowI32x4UName.
  2529  //
  2530  // destinationShape is the shape of the destination lanes for conversion which is
  2531  // either ShapeF32x4, or ShapeF64x2.
  2532  func NewOperationV128FConvertFromI(destinationShape Shape, signed bool) UnionOperation {
  2533  	return UnionOperation{Kind: OperationKindV128FConvertFromI, B1: destinationShape, B3: signed}
  2534  }
  2535  
  2536  // NewOperationV128Dot is a constructor for UnionOperation with OperationKindV128Dot.
  2537  //
  2538  // This corresponds to wasm.OpcodeVecI32x4DotI16x8SName
  2539  func NewOperationV128Dot() UnionOperation {
  2540  	return UnionOperation{Kind: OperationKindV128Dot}
  2541  }
  2542  
  2543  // NewOperationV128Narrow is a constructor for UnionOperation with OperationKindV128Narrow.
  2544  //
  2545  // This corresponds to
  2546  //
  2547  //	wasm.OpcodeVecI8x16NarrowI16x8SName wasm.OpcodeVecI8x16NarrowI16x8UName
  2548  //	wasm.OpcodeVecI16x8NarrowI32x4SName wasm.OpcodeVecI16x8NarrowI32x4UName.
  2549  //
  2550  // originShape is the shape of the original lanes for narrowing which is
  2551  // either ShapeI16x8, or ShapeI32x4.
  2552  func NewOperationV128Narrow(originShape Shape, signed bool) UnionOperation {
  2553  	return UnionOperation{Kind: OperationKindV128Narrow, B1: originShape, B3: signed}
  2554  }
  2555  
  2556  // NewOperationV128ITruncSatFromF is a constructor for UnionOperation with OperationKindV128ITruncSatFromF.
  2557  //
  2558  // This corresponds to
  2559  //
  2560  //	wasm.OpcodeVecI32x4TruncSatF64x2UZeroName wasm.OpcodeVecI32x4TruncSatF64x2SZeroName
  2561  //	wasm.OpcodeVecI32x4TruncSatF32x4UName wasm.OpcodeVecI32x4TruncSatF32x4SName.
  2562  //
  2563  // originShape is the shape of the original lanes for truncation which is
  2564  // either ShapeF32x4, or ShapeF64x2.
  2565  func NewOperationV128ITruncSatFromF(originShape Shape, signed bool) UnionOperation {
  2566  	return UnionOperation{Kind: OperationKindV128ITruncSatFromF, B1: originShape, B3: signed}
  2567  }
  2568  

View as plain text