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}