operations.go

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