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