github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/internal/wazeroir/operations.go (about) 1 package wazeroir 2 3 import ( 4 "fmt" 5 "math" 6 "strings" 7 ) 8 9 // UnsignedInt represents unsigned 32-bit or 64-bit integers. 10 type UnsignedInt byte 11 12 const ( 13 UnsignedInt32 UnsignedInt = iota 14 UnsignedInt64 15 ) 16 17 // String implements fmt.Stringer. 18 func (s UnsignedInt) String() (ret string) { 19 switch s { 20 case UnsignedInt32: 21 ret = "i32" 22 case UnsignedInt64: 23 ret = "i64" 24 } 25 return 26 } 27 28 // SignedInt represents signed or unsigned integers. 29 type SignedInt byte 30 31 const ( 32 SignedInt32 SignedInt = iota 33 SignedInt64 34 SignedUint32 35 SignedUint64 36 ) 37 38 // String implements fmt.Stringer. 39 func (s SignedInt) String() (ret string) { 40 switch s { 41 case SignedUint32: 42 ret = "u32" 43 case SignedUint64: 44 ret = "u64" 45 case SignedInt32: 46 ret = "s32" 47 case SignedInt64: 48 ret = "s64" 49 } 50 return 51 } 52 53 // Float represents the scalar double or single precision floating points. 54 type Float byte 55 56 const ( 57 Float32 Float = iota 58 Float64 59 ) 60 61 // String implements fmt.Stringer. 62 func (s Float) String() (ret string) { 63 switch s { 64 case Float32: 65 ret = "f32" 66 case Float64: 67 ret = "f64" 68 } 69 return 70 } 71 72 // UnsignedType is the union of UnsignedInt, Float and V128 vector type. 73 type UnsignedType byte 74 75 const ( 76 UnsignedTypeI32 UnsignedType = iota 77 UnsignedTypeI64 78 UnsignedTypeF32 79 UnsignedTypeF64 80 UnsignedTypeV128 81 UnsignedTypeUnknown 82 ) 83 84 // String implements fmt.Stringer. 85 func (s UnsignedType) String() (ret string) { 86 switch s { 87 case UnsignedTypeI32: 88 ret = "i32" 89 case UnsignedTypeI64: 90 ret = "i64" 91 case UnsignedTypeF32: 92 ret = "f32" 93 case UnsignedTypeF64: 94 ret = "f64" 95 case UnsignedTypeV128: 96 ret = "v128" 97 case UnsignedTypeUnknown: 98 ret = "unknown" 99 } 100 return 101 } 102 103 // SignedType is the union of SignedInt and Float types. 104 type SignedType byte 105 106 const ( 107 SignedTypeInt32 SignedType = iota 108 SignedTypeUint32 109 SignedTypeInt64 110 SignedTypeUint64 111 SignedTypeFloat32 112 SignedTypeFloat64 113 ) 114 115 // String implements fmt.Stringer. 116 func (s SignedType) String() (ret string) { 117 switch s { 118 case SignedTypeInt32: 119 ret = "s32" 120 case SignedTypeUint32: 121 ret = "u32" 122 case SignedTypeInt64: 123 ret = "s64" 124 case SignedTypeUint64: 125 ret = "u64" 126 case SignedTypeFloat32: 127 ret = "f32" 128 case SignedTypeFloat64: 129 ret = "f64" 130 } 131 return 132 } 133 134 // OperationKind is the Kind of each implementation of Operation interface. 135 type OperationKind uint16 136 137 // String implements fmt.Stringer. 138 func (o OperationKind) String() (ret string) { 139 switch o { 140 case OperationKindUnreachable: 141 ret = "Unreachable" 142 case OperationKindLabel: 143 ret = "label" 144 case OperationKindBr: 145 ret = "Br" 146 case OperationKindBrIf: 147 ret = "BrIf" 148 case OperationKindBrTable: 149 ret = "BrTable" 150 case OperationKindCall: 151 ret = "Call" 152 case OperationKindCallIndirect: 153 ret = "CallIndirect" 154 case OperationKindDrop: 155 ret = "Drop" 156 case OperationKindSelect: 157 ret = "Select" 158 case OperationKindPick: 159 ret = "Pick" 160 case OperationKindSet: 161 ret = "Swap" 162 case OperationKindGlobalGet: 163 ret = "GlobalGet" 164 case OperationKindGlobalSet: 165 ret = "GlobalSet" 166 case OperationKindLoad: 167 ret = "Load" 168 case OperationKindLoad8: 169 ret = "Load8" 170 case OperationKindLoad16: 171 ret = "Load16" 172 case OperationKindLoad32: 173 ret = "Load32" 174 case OperationKindStore: 175 ret = "Store" 176 case OperationKindStore8: 177 ret = "Store8" 178 case OperationKindStore16: 179 ret = "Store16" 180 case OperationKindStore32: 181 ret = "Store32" 182 case OperationKindMemorySize: 183 ret = "MemorySize" 184 case OperationKindMemoryGrow: 185 ret = "MemoryGrow" 186 case OperationKindConstI32: 187 ret = "ConstI32" 188 case OperationKindConstI64: 189 ret = "ConstI64" 190 case OperationKindConstF32: 191 ret = "ConstF32" 192 case OperationKindConstF64: 193 ret = "ConstF64" 194 case OperationKindEq: 195 ret = "Eq" 196 case OperationKindNe: 197 ret = "Ne" 198 case OperationKindEqz: 199 ret = "Eqz" 200 case OperationKindLt: 201 ret = "Lt" 202 case OperationKindGt: 203 ret = "Gt" 204 case OperationKindLe: 205 ret = "Le" 206 case OperationKindGe: 207 ret = "Ge" 208 case OperationKindAdd: 209 ret = "Add" 210 case OperationKindSub: 211 ret = "Sub" 212 case OperationKindMul: 213 ret = "Mul" 214 case OperationKindClz: 215 ret = "Clz" 216 case OperationKindCtz: 217 ret = "Ctz" 218 case OperationKindPopcnt: 219 ret = "Popcnt" 220 case OperationKindDiv: 221 ret = "Div" 222 case OperationKindRem: 223 ret = "Rem" 224 case OperationKindAnd: 225 ret = "And" 226 case OperationKindOr: 227 ret = "Or" 228 case OperationKindXor: 229 ret = "Xor" 230 case OperationKindShl: 231 ret = "Shl" 232 case OperationKindShr: 233 ret = "Shr" 234 case OperationKindRotl: 235 ret = "Rotl" 236 case OperationKindRotr: 237 ret = "Rotr" 238 case OperationKindAbs: 239 ret = "Abs" 240 case OperationKindNeg: 241 ret = "Neg" 242 case OperationKindCeil: 243 ret = "Ceil" 244 case OperationKindFloor: 245 ret = "Floor" 246 case OperationKindTrunc: 247 ret = "Trunc" 248 case OperationKindNearest: 249 ret = "Nearest" 250 case OperationKindSqrt: 251 ret = "Sqrt" 252 case OperationKindMin: 253 ret = "Min" 254 case OperationKindMax: 255 ret = "Max" 256 case OperationKindCopysign: 257 ret = "Copysign" 258 case OperationKindI32WrapFromI64: 259 ret = "I32WrapFromI64" 260 case OperationKindITruncFromF: 261 ret = "ITruncFromF" 262 case OperationKindFConvertFromI: 263 ret = "FConvertFromI" 264 case OperationKindF32DemoteFromF64: 265 ret = "F32DemoteFromF64" 266 case OperationKindF64PromoteFromF32: 267 ret = "F64PromoteFromF32" 268 case OperationKindI32ReinterpretFromF32: 269 ret = "I32ReinterpretFromF32" 270 case OperationKindI64ReinterpretFromF64: 271 ret = "I64ReinterpretFromF64" 272 case OperationKindF32ReinterpretFromI32: 273 ret = "F32ReinterpretFromI32" 274 case OperationKindF64ReinterpretFromI64: 275 ret = "F64ReinterpretFromI64" 276 case OperationKindExtend: 277 ret = "Extend" 278 case OperationKindMemoryInit: 279 ret = "MemoryInit" 280 case OperationKindDataDrop: 281 ret = "DataDrop" 282 case OperationKindMemoryCopy: 283 ret = "MemoryCopy" 284 case OperationKindMemoryFill: 285 ret = "MemoryFill" 286 case OperationKindTableInit: 287 ret = "TableInit" 288 case OperationKindElemDrop: 289 ret = "ElemDrop" 290 case OperationKindTableCopy: 291 ret = "TableCopy" 292 case OperationKindRefFunc: 293 ret = "RefFunc" 294 case OperationKindTableGet: 295 ret = "TableGet" 296 case OperationKindTableSet: 297 ret = "TableSet" 298 case OperationKindTableSize: 299 ret = "TableSize" 300 case OperationKindTableGrow: 301 ret = "TableGrow" 302 case OperationKindTableFill: 303 ret = "TableFill" 304 case OperationKindV128Const: 305 ret = "ConstV128" 306 case OperationKindV128Add: 307 ret = "V128Add" 308 case OperationKindV128Sub: 309 ret = "V128Sub" 310 case OperationKindV128Load: 311 ret = "V128Load" 312 case OperationKindV128LoadLane: 313 ret = "V128LoadLane" 314 case OperationKindV128Store: 315 ret = "V128Store" 316 case OperationKindV128StoreLane: 317 ret = "V128StoreLane" 318 case OperationKindV128ExtractLane: 319 ret = "V128ExtractLane" 320 case OperationKindV128ReplaceLane: 321 ret = "V128ReplaceLane" 322 case OperationKindV128Splat: 323 ret = "V128Splat" 324 case OperationKindV128Shuffle: 325 ret = "V128Shuffle" 326 case OperationKindV128Swizzle: 327 ret = "V128Swizzle" 328 case OperationKindV128AnyTrue: 329 ret = "V128AnyTrue" 330 case OperationKindV128AllTrue: 331 ret = "V128AllTrue" 332 case OperationKindV128And: 333 ret = "V128And" 334 case OperationKindV128Not: 335 ret = "V128Not" 336 case OperationKindV128Or: 337 ret = "V128Or" 338 case OperationKindV128Xor: 339 ret = "V128Xor" 340 case OperationKindV128Bitselect: 341 ret = "V128Bitselect" 342 case OperationKindV128AndNot: 343 ret = "V128AndNot" 344 case OperationKindV128BitMask: 345 ret = "V128BitMask" 346 case OperationKindV128Shl: 347 ret = "V128Shl" 348 case OperationKindV128Shr: 349 ret = "V128Shr" 350 case OperationKindV128Cmp: 351 ret = "V128Cmp" 352 case OperationKindSignExtend32From8: 353 ret = "SignExtend32From8" 354 case OperationKindSignExtend32From16: 355 ret = "SignExtend32From16" 356 case OperationKindSignExtend64From8: 357 ret = "SignExtend64From8" 358 case OperationKindSignExtend64From16: 359 ret = "SignExtend64From16" 360 case OperationKindSignExtend64From32: 361 ret = "SignExtend64From32" 362 case OperationKindV128AddSat: 363 ret = "V128AddSat" 364 case OperationKindV128SubSat: 365 ret = "V128SubSat" 366 case OperationKindV128Mul: 367 ret = "V128Mul" 368 case OperationKindV128Div: 369 ret = "V128Div" 370 case OperationKindV128Neg: 371 ret = "V128Neg" 372 case OperationKindV128Sqrt: 373 ret = "V128Sqrt" 374 case OperationKindV128Abs: 375 ret = "V128Abs" 376 case OperationKindV128Popcnt: 377 ret = "V128Popcnt" 378 case OperationKindV128Min: 379 ret = "V128Min" 380 case OperationKindV128Max: 381 ret = "V128Max" 382 case OperationKindV128AvgrU: 383 ret = "V128AvgrU" 384 case OperationKindV128Ceil: 385 ret = "V128Ceil" 386 case OperationKindV128Floor: 387 ret = "V128Floor" 388 case OperationKindV128Trunc: 389 ret = "V128Trunc" 390 case OperationKindV128Nearest: 391 ret = "V128Nearest" 392 case OperationKindV128Pmin: 393 ret = "V128Pmin" 394 case OperationKindV128Pmax: 395 ret = "V128Pmax" 396 case OperationKindV128Extend: 397 ret = "V128Extend" 398 case OperationKindV128ExtMul: 399 ret = "V128ExtMul" 400 case OperationKindV128Q15mulrSatS: 401 ret = "V128Q15mulrSatS" 402 case OperationKindV128ExtAddPairwise: 403 ret = "V128ExtAddPairwise" 404 case OperationKindV128FloatPromote: 405 ret = "V128FloatPromote" 406 case OperationKindV128FloatDemote: 407 ret = "V128FloatDemote" 408 case OperationKindV128FConvertFromI: 409 ret = "V128FConvertFromI" 410 case OperationKindV128Dot: 411 ret = "V128Dot" 412 case OperationKindV128Narrow: 413 ret = "V128Narrow" 414 case OperationKindV128ITruncSatFromF: 415 ret = "V128ITruncSatFromF" 416 case OperationKindBuiltinFunctionCheckExitCode: 417 ret = "BuiltinFunctionCheckExitCode" 418 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 // AtomicArithmeticOp is the type for the operation kind of atomic arithmetic operations. 776 type AtomicArithmeticOp byte 777 778 const ( 779 // AtomicArithmeticOpAdd is the kind for an add operation. 780 AtomicArithmeticOpAdd AtomicArithmeticOp = iota 781 // AtomicArithmeticOpSub is the kind for a sub operation. 782 AtomicArithmeticOpSub 783 // AtomicArithmeticOpAnd is the kind for a bitwise and operation. 784 AtomicArithmeticOpAnd 785 // AtomicArithmeticOpOr is the kind for a bitwise or operation. 786 AtomicArithmeticOpOr 787 // AtomicArithmeticOpXor is the kind for a bitwise xor operation. 788 AtomicArithmeticOpXor 789 // AtomicArithmeticOpNop is the kind for a nop operation. 790 AtomicArithmeticOpNop 791 ) 792 793 // NewOperationBuiltinFunctionCheckExitCode is a constructor for UnionOperation with Kind OperationKindBuiltinFunctionCheckExitCode. 794 // 795 // OperationBuiltinFunctionCheckExitCode corresponds to the instruction to check the api.Module is already closed due to 796 // context.DeadlineExceeded, context.Canceled, or the explicit call of CloseWithExitCode on api.Module. 797 func NewOperationBuiltinFunctionCheckExitCode() UnionOperation { 798 return UnionOperation{Kind: OperationKindBuiltinFunctionCheckExitCode} 799 } 800 801 // Label is the unique identifier for each block in a single function in wazeroir 802 // where "block" consists of multiple operations, and must End with branching operations 803 // (e.g. OperationKindBr or OperationKindBrIf). 804 type Label uint64 805 806 // Kind returns the LabelKind encoded in this Label. 807 func (l Label) Kind() LabelKind { 808 return LabelKind(uint32(l)) 809 } 810 811 // FrameID returns the frame id encoded in this Label. 812 func (l Label) FrameID() int { 813 return int(uint32(l >> 32)) 814 } 815 816 // NewLabel is a constructor for a Label. 817 func NewLabel(kind LabelKind, frameID uint32) Label { 818 return Label(kind) | Label(frameID)<<32 819 } 820 821 // String implements fmt.Stringer. 822 func (l Label) String() (ret string) { 823 frameID := l.FrameID() 824 switch l.Kind() { 825 case LabelKindHeader: 826 ret = fmt.Sprintf(".L%d", frameID) 827 case LabelKindElse: 828 ret = fmt.Sprintf(".L%d_else", frameID) 829 case LabelKindContinuation: 830 ret = fmt.Sprintf(".L%d_cont", frameID) 831 case LabelKindReturn: 832 return ".return" 833 } 834 return 835 } 836 837 func (l Label) IsReturnTarget() bool { 838 return l.Kind() == LabelKindReturn 839 } 840 841 // LabelKind is the Kind of the label. 842 type LabelKind = byte 843 844 const ( 845 // LabelKindHeader is the header for various blocks. For example, the "then" block of 846 // wasm.OpcodeIfName in Wasm has the label of this Kind. 847 LabelKindHeader LabelKind = iota 848 // LabelKindElse is the Kind of label for "else" block of wasm.OpcodeIfName in Wasm. 849 LabelKindElse 850 // LabelKindContinuation is the Kind of label which is the continuation of blocks. 851 // For example, for wasm text like 852 // (func 853 // .... 854 // (if (local.get 0) (then (nop)) (else (nop))) 855 // return 856 // ) 857 // we have the continuation block (of if-block) corresponding to "return" opcode. 858 LabelKindContinuation 859 LabelKindReturn 860 LabelKindNum 861 ) 862 863 // UnionOperation implements Operation and is the compilation (engine.lowerIR) result of a wazeroir.Operation. 864 // 865 // Not all operations result in a UnionOperation, e.g. wazeroir.OperationI32ReinterpretFromF32, and some operations are 866 // more complex than others, e.g. wazeroir.NewOperationBrTable. 867 // 868 // Note: This is a form of union type as it can store fields needed for any operation. Hence, most fields are opaque and 869 // only relevant when in context of its kind. 870 type UnionOperation struct { 871 // Kind determines how to interpret the other fields in this struct. 872 Kind OperationKind 873 B1, B2 byte 874 B3 bool 875 U1, U2 uint64 876 U3 uint64 877 Us []uint64 878 } 879 880 // String implements fmt.Stringer. 881 func (o UnionOperation) String() string { 882 switch o.Kind { 883 case OperationKindUnreachable, 884 OperationKindSelect, 885 OperationKindMemorySize, 886 OperationKindMemoryGrow, 887 OperationKindI32WrapFromI64, 888 OperationKindF32DemoteFromF64, 889 OperationKindF64PromoteFromF32, 890 OperationKindI32ReinterpretFromF32, 891 OperationKindI64ReinterpretFromF64, 892 OperationKindF32ReinterpretFromI32, 893 OperationKindF64ReinterpretFromI64, 894 OperationKindSignExtend32From8, 895 OperationKindSignExtend32From16, 896 OperationKindSignExtend64From8, 897 OperationKindSignExtend64From16, 898 OperationKindSignExtend64From32, 899 OperationKindMemoryInit, 900 OperationKindDataDrop, 901 OperationKindMemoryCopy, 902 OperationKindMemoryFill, 903 OperationKindTableInit, 904 OperationKindElemDrop, 905 OperationKindTableCopy, 906 OperationKindRefFunc, 907 OperationKindTableGet, 908 OperationKindTableSet, 909 OperationKindTableSize, 910 OperationKindTableGrow, 911 OperationKindTableFill, 912 OperationKindBuiltinFunctionCheckExitCode: 913 return o.Kind.String() 914 915 case OperationKindCall, 916 OperationKindGlobalGet, 917 OperationKindGlobalSet: 918 return fmt.Sprintf("%s %d", o.Kind, o.B1) 919 920 case OperationKindLabel: 921 return Label(o.U1).String() 922 923 case OperationKindBr: 924 return fmt.Sprintf("%s %s", o.Kind, Label(o.U1).String()) 925 926 case OperationKindBrIf: 927 thenTarget := Label(o.U1) 928 elseTarget := Label(o.U2) 929 return fmt.Sprintf("%s %s, %s", o.Kind, thenTarget, elseTarget) 930 931 case OperationKindBrTable: 932 var targets []string 933 var defaultLabel Label 934 if len(o.Us) > 0 { 935 targets = make([]string, len(o.Us)-1) 936 for i, t := range o.Us[1:] { 937 targets[i] = Label(t).String() 938 } 939 defaultLabel = Label(o.Us[0]) 940 } 941 return fmt.Sprintf("%s [%s] %s", o.Kind, strings.Join(targets, ","), defaultLabel) 942 943 case OperationKindCallIndirect: 944 return fmt.Sprintf("%s: type=%d, table=%d", o.Kind, o.U1, o.U2) 945 946 case OperationKindDrop: 947 start := int64(o.U1) 948 end := int64(o.U2) 949 return fmt.Sprintf("%s %d..%d", o.Kind, start, end) 950 951 case OperationKindPick, OperationKindSet: 952 return fmt.Sprintf("%s %d (is_vector=%v)", o.Kind, o.U1, o.B3) 953 954 case OperationKindLoad, OperationKindStore: 955 return fmt.Sprintf("%s.%s (align=%d, offset=%d)", UnsignedType(o.B1), o.Kind, o.U1, o.U2) 956 957 case OperationKindLoad8, 958 OperationKindLoad16: 959 return fmt.Sprintf("%s.%s (align=%d, offset=%d)", SignedType(o.B1), o.Kind, o.U1, o.U2) 960 961 case OperationKindStore8, 962 OperationKindStore16, 963 OperationKindStore32: 964 return fmt.Sprintf("%s (align=%d, offset=%d)", o.Kind, o.U1, o.U2) 965 966 case OperationKindLoad32: 967 var t string 968 if o.B1 == 1 { 969 t = "i64" 970 } else { 971 t = "u64" 972 } 973 return fmt.Sprintf("%s.%s (align=%d, offset=%d)", t, o.Kind, o.U1, o.U2) 974 975 case OperationKindEq, 976 OperationKindNe, 977 OperationKindAdd, 978 OperationKindSub, 979 OperationKindMul: 980 return fmt.Sprintf("%s.%s", UnsignedType(o.B1), o.Kind) 981 982 case OperationKindEqz, 983 OperationKindClz, 984 OperationKindCtz, 985 OperationKindPopcnt, 986 OperationKindAnd, 987 OperationKindOr, 988 OperationKindXor, 989 OperationKindShl, 990 OperationKindRotl, 991 OperationKindRotr: 992 return fmt.Sprintf("%s.%s", UnsignedInt(o.B1), o.Kind) 993 994 case OperationKindRem, OperationKindShr: 995 return fmt.Sprintf("%s.%s", SignedInt(o.B1), o.Kind) 996 997 case OperationKindLt, 998 OperationKindGt, 999 OperationKindLe, 1000 OperationKindGe, 1001 OperationKindDiv: 1002 return fmt.Sprintf("%s.%s", SignedType(o.B1), o.Kind) 1003 1004 case OperationKindAbs, 1005 OperationKindNeg, 1006 OperationKindCeil, 1007 OperationKindFloor, 1008 OperationKindTrunc, 1009 OperationKindNearest, 1010 OperationKindSqrt, 1011 OperationKindMin, 1012 OperationKindMax, 1013 OperationKindCopysign: 1014 return fmt.Sprintf("%s.%s", Float(o.B1), o.Kind) 1015 1016 case OperationKindConstI32, 1017 OperationKindConstI64: 1018 return fmt.Sprintf("%s %#x", o.Kind, o.U1) 1019 1020 case OperationKindConstF32: 1021 return fmt.Sprintf("%s %f", o.Kind, math.Float32frombits(uint32(o.U1))) 1022 case OperationKindConstF64: 1023 return fmt.Sprintf("%s %f", o.Kind, math.Float64frombits(o.U1)) 1024 1025 case OperationKindITruncFromF: 1026 return fmt.Sprintf("%s.%s.%s (non_trapping=%v)", SignedInt(o.B2), o.Kind, Float(o.B1), o.B3) 1027 case OperationKindFConvertFromI: 1028 return fmt.Sprintf("%s.%s.%s", Float(o.B2), o.Kind, SignedInt(o.B1)) 1029 case OperationKindExtend: 1030 var in, out string 1031 if o.B3 { 1032 in = "i32" 1033 out = "i64" 1034 } else { 1035 in = "u32" 1036 out = "u64" 1037 } 1038 return fmt.Sprintf("%s.%s.%s", out, o.Kind, in) 1039 1040 case OperationKindV128Const: 1041 return fmt.Sprintf("%s [%#x, %#x]", o.Kind, o.U1, o.U2) 1042 case OperationKindV128Add, 1043 OperationKindV128Sub: 1044 return fmt.Sprintf("%s (shape=%s)", o.Kind, shapeName(o.B1)) 1045 case OperationKindV128Load, 1046 OperationKindV128LoadLane, 1047 OperationKindV128Store, 1048 OperationKindV128StoreLane, 1049 OperationKindV128ExtractLane, 1050 OperationKindV128ReplaceLane, 1051 OperationKindV128Splat, 1052 OperationKindV128Shuffle, 1053 OperationKindV128Swizzle, 1054 OperationKindV128AnyTrue, 1055 OperationKindV128AllTrue, 1056 OperationKindV128BitMask, 1057 OperationKindV128And, 1058 OperationKindV128Not, 1059 OperationKindV128Or, 1060 OperationKindV128Xor, 1061 OperationKindV128Bitselect, 1062 OperationKindV128AndNot, 1063 OperationKindV128Shl, 1064 OperationKindV128Shr, 1065 OperationKindV128Cmp, 1066 OperationKindV128AddSat, 1067 OperationKindV128SubSat, 1068 OperationKindV128Mul, 1069 OperationKindV128Div, 1070 OperationKindV128Neg, 1071 OperationKindV128Sqrt, 1072 OperationKindV128Abs, 1073 OperationKindV128Popcnt, 1074 OperationKindV128Min, 1075 OperationKindV128Max, 1076 OperationKindV128AvgrU, 1077 OperationKindV128Pmin, 1078 OperationKindV128Pmax, 1079 OperationKindV128Ceil, 1080 OperationKindV128Floor, 1081 OperationKindV128Trunc, 1082 OperationKindV128Nearest, 1083 OperationKindV128Extend, 1084 OperationKindV128ExtMul, 1085 OperationKindV128Q15mulrSatS, 1086 OperationKindV128ExtAddPairwise, 1087 OperationKindV128FloatPromote, 1088 OperationKindV128FloatDemote, 1089 OperationKindV128FConvertFromI, 1090 OperationKindV128Dot, 1091 OperationKindV128Narrow: 1092 return o.Kind.String() 1093 1094 case OperationKindV128ITruncSatFromF: 1095 if o.B3 { 1096 return fmt.Sprintf("%s.%sS", o.Kind, shapeName(o.B1)) 1097 } else { 1098 return fmt.Sprintf("%s.%sU", o.Kind, shapeName(o.B1)) 1099 } 1100 1101 case OperationKindAtomicMemoryWait, 1102 OperationKindAtomicMemoryNotify, 1103 OperationKindAtomicFence, 1104 OperationKindAtomicLoad, 1105 OperationKindAtomicLoad8, 1106 OperationKindAtomicLoad16, 1107 OperationKindAtomicStore, 1108 OperationKindAtomicStore8, 1109 OperationKindAtomicStore16, 1110 OperationKindAtomicRMW, 1111 OperationKindAtomicRMW8, 1112 OperationKindAtomicRMW16, 1113 OperationKindAtomicRMWCmpxchg, 1114 OperationKindAtomicRMW8Cmpxchg, 1115 OperationKindAtomicRMW16Cmpxchg: 1116 return o.Kind.String() 1117 1118 default: 1119 panic(fmt.Sprintf("TODO: %v", o.Kind)) 1120 } 1121 } 1122 1123 // NewOperationUnreachable is a constructor for UnionOperation with OperationKindUnreachable 1124 // 1125 // This corresponds to wasm.OpcodeUnreachable. 1126 // 1127 // The engines are expected to exit the execution with wasmruntime.ErrRuntimeUnreachable error. 1128 func NewOperationUnreachable() UnionOperation { 1129 return UnionOperation{Kind: OperationKindUnreachable} 1130 } 1131 1132 // NewOperationLabel is a constructor for UnionOperation with OperationKindLabel. 1133 // 1134 // This is used to inform the engines of the beginning of a label. 1135 func NewOperationLabel(label Label) UnionOperation { 1136 return UnionOperation{Kind: OperationKindLabel, U1: uint64(label)} 1137 } 1138 1139 // NewOperationBr is a constructor for UnionOperation with OperationKindBr. 1140 // 1141 // The engines are expected to branch into U1 label. 1142 func NewOperationBr(target Label) UnionOperation { 1143 return UnionOperation{Kind: OperationKindBr, U1: uint64(target)} 1144 } 1145 1146 // NewOperationBrIf is a constructor for UnionOperation with OperationKindBrIf. 1147 // 1148 // The engines are expected to pop a value and branch into U1 label if the value equals 1. 1149 // Otherwise, the code branches into U2 label. 1150 func NewOperationBrIf(thenTarget, elseTarget Label, thenDrop InclusiveRange) UnionOperation { 1151 return UnionOperation{ 1152 Kind: OperationKindBrIf, 1153 U1: uint64(thenTarget), 1154 U2: uint64(elseTarget), 1155 U3: thenDrop.AsU64(), 1156 } 1157 } 1158 1159 // NewOperationBrTable is a constructor for UnionOperation with OperationKindBrTable. 1160 // 1161 // This corresponds to wasm.OpcodeBrTableName except that the label 1162 // here means the wazeroir level, not the ones of Wasm. 1163 // 1164 // The engines are expected to do the br_table operation based on the default (Us[len(Us)-1], Us[len(Us)-2]) and 1165 // targets (Us[:len(Us)-1], Rs[:len(Us)-1]). More precisely, this pops a value from the stack (called "index") 1166 // and decides which branch we go into next based on the value. 1167 // 1168 // For example, assume we have operations like {default: L_DEFAULT, targets: [L0, L1, L2]}. 1169 // If "index" >= len(defaults), then branch into the L_DEFAULT label. 1170 // Otherwise, we enter label of targets[index]. 1171 func NewOperationBrTable(targetLabelsAndRanges []uint64) UnionOperation { 1172 return UnionOperation{ 1173 Kind: OperationKindBrTable, 1174 Us: targetLabelsAndRanges, 1175 } 1176 } 1177 1178 // NewOperationCall is a constructor for UnionOperation with OperationKindCall. 1179 // 1180 // This corresponds to wasm.OpcodeCallName, and engines are expected to 1181 // enter into a function whose index equals OperationCall.FunctionIndex. 1182 func NewOperationCall(functionIndex uint32) UnionOperation { 1183 return UnionOperation{Kind: OperationKindCall, U1: uint64(functionIndex)} 1184 } 1185 1186 // NewOperationCallIndirect implements Operation. 1187 // 1188 // This corresponds to wasm.OpcodeCallIndirectName, and engines are expected to 1189 // consume the one value from the top of stack (called "offset"), 1190 // and make a function call against the function whose function address equals 1191 // Tables[OperationCallIndirect.TableIndex][offset]. 1192 // 1193 // Note: This is called indirect function call in the sense that the target function is indirectly 1194 // determined by the current state (top value) of the stack. 1195 // Therefore, two checks are performed at runtime before entering the target function: 1196 // 1) whether "offset" exceeds the length of table Tables[OperationCallIndirect.TableIndex]. 1197 // 2) whether the type of the function table[offset] matches the function type specified by OperationCallIndirect.TypeIndex. 1198 func NewOperationCallIndirect(typeIndex, tableIndex uint32) UnionOperation { 1199 return UnionOperation{Kind: OperationKindCallIndirect, U1: uint64(typeIndex), U2: uint64(tableIndex)} 1200 } 1201 1202 // InclusiveRange is the range which spans across the value stack starting from the top to the bottom, and 1203 // both boundary are included in the range. 1204 type InclusiveRange struct { 1205 Start, End int32 1206 } 1207 1208 // AsU64 is be used to convert InclusiveRange to uint64 so that it can be stored in UnionOperation. 1209 func (i InclusiveRange) AsU64() uint64 { 1210 return uint64(uint32(i.Start))<<32 | uint64(uint32(i.End)) 1211 } 1212 1213 // InclusiveRangeFromU64 retrieves InclusiveRange from the given uint64 which is stored in UnionOperation. 1214 func InclusiveRangeFromU64(v uint64) InclusiveRange { 1215 return InclusiveRange{ 1216 Start: int32(uint32(v >> 32)), 1217 End: int32(uint32(v)), 1218 } 1219 } 1220 1221 // NopInclusiveRange is InclusiveRange which corresponds to no-operation. 1222 var NopInclusiveRange = InclusiveRange{Start: -1, End: -1} 1223 1224 // NewOperationDrop is a constructor for UnionOperation with OperationKindDrop. 1225 // 1226 // The engines are expected to discard the values selected by NewOperationDrop.Depth which 1227 // starts from the top of the stack to the bottom. 1228 // 1229 // depth spans across the uint64 value stack at runtime to be dropped by this operation. 1230 func NewOperationDrop(depth InclusiveRange) UnionOperation { 1231 return UnionOperation{Kind: OperationKindDrop, U1: depth.AsU64()} 1232 } 1233 1234 // NewOperationSelect is a constructor for UnionOperation with OperationKindSelect. 1235 // 1236 // This corresponds to wasm.OpcodeSelect. 1237 // 1238 // The engines are expected to pop three values, say [..., x2, x1, c], then if the value "c" equals zero, 1239 // "x1" is pushed back onto the stack and, otherwise "x2" is pushed back. 1240 // 1241 // isTargetVector true if the selection target value's type is wasm.ValueTypeV128. 1242 func NewOperationSelect(isTargetVector bool) UnionOperation { 1243 return UnionOperation{Kind: OperationKindSelect, B3: isTargetVector} 1244 } 1245 1246 // NewOperationPick is a constructor for UnionOperation with OperationKindPick. 1247 // 1248 // The engines are expected to copy a value pointed by depth, and push the 1249 // copied value onto the top of the stack. 1250 // 1251 // depth is the location of the pick target in the uint64 value stack at runtime. 1252 // If isTargetVector=true, this points to the location of the lower 64-bits of the vector. 1253 func NewOperationPick(depth int, isTargetVector bool) UnionOperation { 1254 return UnionOperation{Kind: OperationKindPick, U1: uint64(depth), B3: isTargetVector} 1255 } 1256 1257 // NewOperationSet is a constructor for UnionOperation with OperationKindSet. 1258 // 1259 // The engines are expected to set the top value of the stack to the location specified by 1260 // depth. 1261 // 1262 // depth is the location of the set target in the uint64 value stack at runtime. 1263 // If isTargetVector=true, this points the location of the lower 64-bits of the vector. 1264 func NewOperationSet(depth int, isTargetVector bool) UnionOperation { 1265 return UnionOperation{Kind: OperationKindSet, U1: uint64(depth), B3: isTargetVector} 1266 } 1267 1268 // NewOperationGlobalGet is a constructor for UnionOperation with OperationKindGlobalGet. 1269 // 1270 // The engines are expected to read the global value specified by OperationGlobalGet.Index, 1271 // and push the copy of the value onto the stack. 1272 // 1273 // See wasm.OpcodeGlobalGet. 1274 func NewOperationGlobalGet(index uint32) UnionOperation { 1275 return UnionOperation{Kind: OperationKindGlobalGet, U1: uint64(index)} 1276 } 1277 1278 // NewOperationGlobalSet is a constructor for UnionOperation with OperationKindGlobalSet. 1279 // 1280 // The engines are expected to consume the value from the top of the stack, 1281 // and write the value into the global specified by OperationGlobalSet.Index. 1282 // 1283 // See wasm.OpcodeGlobalSet. 1284 func NewOperationGlobalSet(index uint32) UnionOperation { 1285 return UnionOperation{Kind: OperationKindGlobalSet, U1: uint64(index)} 1286 } 1287 1288 // MemoryArg is the "memarg" to all memory instructions. 1289 // 1290 // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#memory-instructions%E2%91%A0 1291 type MemoryArg struct { 1292 // Alignment the expected alignment (expressed as the exponent of a power of 2). Default to the natural alignment. 1293 // 1294 // "Natural alignment" is defined here as the smallest power of two that can hold the size of the value type. Ex 1295 // wasm.ValueTypeI64 is encoded in 8 little-endian bytes. 2^3 = 8, so the natural alignment is three. 1296 Alignment uint32 1297 1298 // Offset is the address offset added to the instruction's dynamic address operand, yielding a 33-bit effective 1299 // address that is the zero-based index at which the memory is accessed. Default to zero. 1300 Offset uint32 1301 } 1302 1303 // NewOperationLoad is a constructor for UnionOperation with OperationKindLoad. 1304 // 1305 // This corresponds to wasm.OpcodeI32LoadName wasm.OpcodeI64LoadName wasm.OpcodeF32LoadName and wasm.OpcodeF64LoadName. 1306 // 1307 // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary, 1308 // otherwise load the corresponding value following the semantics of the corresponding WebAssembly instruction. 1309 func NewOperationLoad(unsignedType UnsignedType, arg MemoryArg) UnionOperation { 1310 return UnionOperation{Kind: OperationKindLoad, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)} 1311 } 1312 1313 // NewOperationLoad8 is a constructor for UnionOperation with OperationKindLoad8. 1314 // 1315 // This corresponds to wasm.OpcodeI32Load8SName wasm.OpcodeI32Load8UName wasm.OpcodeI64Load8SName wasm.OpcodeI64Load8UName. 1316 // 1317 // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary, 1318 // otherwise load the corresponding value following the semantics of the corresponding WebAssembly instruction. 1319 func NewOperationLoad8(signedInt SignedInt, arg MemoryArg) UnionOperation { 1320 return UnionOperation{Kind: OperationKindLoad8, B1: byte(signedInt), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)} 1321 } 1322 1323 // NewOperationLoad16 is a constructor for UnionOperation with OperationKindLoad16. 1324 // 1325 // This corresponds to wasm.OpcodeI32Load16SName wasm.OpcodeI32Load16UName wasm.OpcodeI64Load16SName wasm.OpcodeI64Load16UName. 1326 // 1327 // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary, 1328 // otherwise load the corresponding value following the semantics of the corresponding WebAssembly instruction. 1329 func NewOperationLoad16(signedInt SignedInt, arg MemoryArg) UnionOperation { 1330 return UnionOperation{Kind: OperationKindLoad16, B1: byte(signedInt), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)} 1331 } 1332 1333 // NewOperationLoad32 is a constructor for UnionOperation with OperationKindLoad32. 1334 // 1335 // This corresponds to wasm.OpcodeI64Load32SName wasm.OpcodeI64Load32UName. 1336 // 1337 // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary, 1338 // otherwise load the corresponding value following the semantics of the corresponding WebAssembly instruction. 1339 func NewOperationLoad32(signed bool, arg MemoryArg) UnionOperation { 1340 sigB := byte(0) 1341 if signed { 1342 sigB = 1 1343 } 1344 return UnionOperation{Kind: OperationKindLoad32, B1: sigB, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)} 1345 } 1346 1347 // NewOperationStore is a constructor for UnionOperation with OperationKindStore. 1348 // 1349 // # This corresponds to wasm.OpcodeI32StoreName wasm.OpcodeI64StoreName wasm.OpcodeF32StoreName wasm.OpcodeF64StoreName 1350 // 1351 // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary, 1352 // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction. 1353 func NewOperationStore(unsignedType UnsignedType, arg MemoryArg) UnionOperation { 1354 return UnionOperation{Kind: OperationKindStore, B1: byte(unsignedType), U1: uint64(arg.Alignment), U2: uint64(arg.Offset)} 1355 } 1356 1357 // NewOperationStore8 is a constructor for UnionOperation with OperationKindStore8. 1358 // 1359 // # This corresponds to wasm.OpcodeI32Store8Name wasm.OpcodeI64Store8Name 1360 // 1361 // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary, 1362 // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction. 1363 func NewOperationStore8(arg MemoryArg) UnionOperation { 1364 return UnionOperation{Kind: OperationKindStore8, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)} 1365 } 1366 1367 // NewOperationStore16 is a constructor for UnionOperation with OperationKindStore16. 1368 // 1369 // # This corresponds to wasm.OpcodeI32Store16Name wasm.OpcodeI64Store16Name 1370 // 1371 // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary, 1372 // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction. 1373 func NewOperationStore16(arg MemoryArg) UnionOperation { 1374 return UnionOperation{Kind: OperationKindStore16, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)} 1375 } 1376 1377 // NewOperationStore32 is a constructor for UnionOperation with OperationKindStore32. 1378 // 1379 // # This corresponds to wasm.OpcodeI64Store32Name 1380 // 1381 // The engines are expected to check the boundary of memory length, and exit the execution if this exceeds the boundary, 1382 // otherwise store the corresponding value following the semantics of the corresponding WebAssembly instruction. 1383 func NewOperationStore32(arg MemoryArg) UnionOperation { 1384 return UnionOperation{Kind: OperationKindStore32, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)} 1385 } 1386 1387 // NewOperationMemorySize is a constructor for UnionOperation with OperationKindMemorySize. 1388 // 1389 // This corresponds to wasm.OpcodeMemorySize. 1390 // 1391 // The engines are expected to push the current page size of the memory onto the stack. 1392 func NewOperationMemorySize() UnionOperation { 1393 return UnionOperation{Kind: OperationKindMemorySize} 1394 } 1395 1396 // NewOperationMemoryGrow is a constructor for UnionOperation with OperationKindMemoryGrow. 1397 // 1398 // This corresponds to wasm.OpcodeMemoryGrow. 1399 // 1400 // The engines are expected to pop one value from the top of the stack, then 1401 // execute wasm.MemoryInstance Grow with the value, and push the previous 1402 // page size of the memory onto the stack. 1403 func NewOperationMemoryGrow() UnionOperation { 1404 return UnionOperation{Kind: OperationKindMemoryGrow} 1405 } 1406 1407 // NewOperationConstI32 is a constructor for UnionOperation with OperationConstI32. 1408 // 1409 // This corresponds to wasm.OpcodeI32Const. 1410 func NewOperationConstI32(value uint32) UnionOperation { 1411 return UnionOperation{Kind: OperationKindConstI32, U1: uint64(value)} 1412 } 1413 1414 // NewOperationConstI64 is a constructor for UnionOperation with OperationConstI64. 1415 // 1416 // This corresponds to wasm.OpcodeI64Const. 1417 func NewOperationConstI64(value uint64) UnionOperation { 1418 return UnionOperation{Kind: OperationKindConstI64, U1: value} 1419 } 1420 1421 // NewOperationConstF32 is a constructor for UnionOperation with OperationConstF32. 1422 // 1423 // This corresponds to wasm.OpcodeF32Const. 1424 func NewOperationConstF32(value float32) UnionOperation { 1425 return UnionOperation{Kind: OperationKindConstF32, U1: uint64(math.Float32bits(value))} 1426 } 1427 1428 // NewOperationConstF64 is a constructor for UnionOperation with OperationConstF64. 1429 // 1430 // This corresponds to wasm.OpcodeF64Const. 1431 func NewOperationConstF64(value float64) UnionOperation { 1432 return UnionOperation{Kind: OperationKindConstF64, U1: math.Float64bits(value)} 1433 } 1434 1435 // NewOperationEq is a constructor for UnionOperation with OperationKindEq. 1436 // 1437 // This corresponds to wasm.OpcodeI32EqName wasm.OpcodeI64EqName wasm.OpcodeF32EqName wasm.OpcodeF64EqName 1438 func NewOperationEq(b UnsignedType) UnionOperation { 1439 return UnionOperation{Kind: OperationKindEq, B1: byte(b)} 1440 } 1441 1442 // NewOperationNe is a constructor for UnionOperation with OperationKindNe. 1443 // 1444 // This corresponds to wasm.OpcodeI32NeName wasm.OpcodeI64NeName wasm.OpcodeF32NeName wasm.OpcodeF64NeName 1445 func NewOperationNe(b UnsignedType) UnionOperation { 1446 return UnionOperation{Kind: OperationKindNe, B1: byte(b)} 1447 } 1448 1449 // NewOperationEqz is a constructor for UnionOperation with OperationKindEqz. 1450 // 1451 // This corresponds to wasm.OpcodeI32EqzName wasm.OpcodeI64EqzName 1452 func NewOperationEqz(b UnsignedInt) UnionOperation { 1453 return UnionOperation{Kind: OperationKindEqz, B1: byte(b)} 1454 } 1455 1456 // NewOperationLt is a constructor for UnionOperation with OperationKindLt. 1457 // 1458 // This corresponds to wasm.OpcodeI32LtS wasm.OpcodeI32LtU wasm.OpcodeI64LtS wasm.OpcodeI64LtU wasm.OpcodeF32Lt wasm.OpcodeF64Lt 1459 func NewOperationLt(b SignedType) UnionOperation { 1460 return UnionOperation{Kind: OperationKindLt, B1: byte(b)} 1461 } 1462 1463 // NewOperationGt is a constructor for UnionOperation with OperationKindGt. 1464 // 1465 // This corresponds to wasm.OpcodeI32GtS wasm.OpcodeI32GtU wasm.OpcodeI64GtS wasm.OpcodeI64GtU wasm.OpcodeF32Gt wasm.OpcodeF64Gt 1466 func NewOperationGt(b SignedType) UnionOperation { 1467 return UnionOperation{Kind: OperationKindGt, B1: byte(b)} 1468 } 1469 1470 // NewOperationLe is a constructor for UnionOperation with OperationKindLe. 1471 // 1472 // This corresponds to wasm.OpcodeI32LeS wasm.OpcodeI32LeU wasm.OpcodeI64LeS wasm.OpcodeI64LeU wasm.OpcodeF32Le wasm.OpcodeF64Le 1473 func NewOperationLe(b SignedType) UnionOperation { 1474 return UnionOperation{Kind: OperationKindLe, B1: byte(b)} 1475 } 1476 1477 // NewOperationGe is a constructor for UnionOperation with OperationKindGe. 1478 // 1479 // This corresponds to wasm.OpcodeI32GeS wasm.OpcodeI32GeU wasm.OpcodeI64GeS wasm.OpcodeI64GeU wasm.OpcodeF32Ge wasm.OpcodeF64Ge 1480 // NewOperationGe is the constructor for OperationGe 1481 func NewOperationGe(b SignedType) UnionOperation { 1482 return UnionOperation{Kind: OperationKindGe, B1: byte(b)} 1483 } 1484 1485 // NewOperationAdd is a constructor for UnionOperation with OperationKindAdd. 1486 // 1487 // This corresponds to wasm.OpcodeI32AddName wasm.OpcodeI64AddName wasm.OpcodeF32AddName wasm.OpcodeF64AddName. 1488 func NewOperationAdd(b UnsignedType) UnionOperation { 1489 return UnionOperation{Kind: OperationKindAdd, B1: byte(b)} 1490 } 1491 1492 // NewOperationSub is a constructor for UnionOperation with OperationKindSub. 1493 // 1494 // This corresponds to wasm.OpcodeI32SubName wasm.OpcodeI64SubName wasm.OpcodeF32SubName wasm.OpcodeF64SubName. 1495 func NewOperationSub(b UnsignedType) UnionOperation { 1496 return UnionOperation{Kind: OperationKindSub, B1: byte(b)} 1497 } 1498 1499 // NewOperationMul is a constructor for UnionOperation with wperationKindMul. 1500 // 1501 // This corresponds to wasm.OpcodeI32MulName wasm.OpcodeI64MulName wasm.OpcodeF32MulName wasm.OpcodeF64MulName. 1502 // NewOperationMul is the constructor for OperationMul 1503 func NewOperationMul(b UnsignedType) UnionOperation { 1504 return UnionOperation{Kind: OperationKindMul, B1: byte(b)} 1505 } 1506 1507 // NewOperationClz is a constructor for UnionOperation with OperationKindClz. 1508 // 1509 // This corresponds to wasm.OpcodeI32ClzName wasm.OpcodeI64ClzName. 1510 // 1511 // The engines are expected to count up the leading zeros in the 1512 // current top of the stack, and push the count result. 1513 // For example, stack of [..., 0x00_ff_ff_ff] results in [..., 8]. 1514 // See wasm.OpcodeI32Clz wasm.OpcodeI64Clz 1515 func NewOperationClz(b UnsignedInt) UnionOperation { 1516 return UnionOperation{Kind: OperationKindClz, B1: byte(b)} 1517 } 1518 1519 // NewOperationCtz is a constructor for UnionOperation with OperationKindCtz. 1520 // 1521 // This corresponds to wasm.OpcodeI32CtzName wasm.OpcodeI64CtzName. 1522 // 1523 // The engines are expected to count up the trailing zeros in the 1524 // current top of the stack, and push the count result. 1525 // For example, stack of [..., 0xff_ff_ff_00] results in [..., 8]. 1526 func NewOperationCtz(b UnsignedInt) UnionOperation { 1527 return UnionOperation{Kind: OperationKindCtz, B1: byte(b)} 1528 } 1529 1530 // NewOperationPopcnt is a constructor for UnionOperation with OperationKindPopcnt. 1531 // 1532 // This corresponds to wasm.OpcodeI32PopcntName wasm.OpcodeI64PopcntName. 1533 // 1534 // The engines are expected to count up the number of set bits in the 1535 // current top of the stack, and push the count result. 1536 // For example, stack of [..., 0b00_00_00_11] results in [..., 2]. 1537 func NewOperationPopcnt(b UnsignedInt) UnionOperation { 1538 return UnionOperation{Kind: OperationKindPopcnt, B1: byte(b)} 1539 } 1540 1541 // NewOperationDiv is a constructor for UnionOperation with OperationKindDiv. 1542 // 1543 // This corresponds to wasm.OpcodeI32DivS wasm.OpcodeI32DivU wasm.OpcodeI64DivS 1544 // 1545 // wasm.OpcodeI64DivU wasm.OpcodeF32Div wasm.OpcodeF64Div. 1546 func NewOperationDiv(b SignedType) UnionOperation { 1547 return UnionOperation{Kind: OperationKindDiv, B1: byte(b)} 1548 } 1549 1550 // NewOperationRem is a constructor for UnionOperation with OperationKindRem. 1551 // 1552 // This corresponds to wasm.OpcodeI32RemS wasm.OpcodeI32RemU wasm.OpcodeI64RemS wasm.OpcodeI64RemU. 1553 // 1554 // The engines are expected to perform division on the top 1555 // two values of integer type on the stack and puts the remainder of the result 1556 // onto the stack. For example, stack [..., 10, 3] results in [..., 1] where 1557 // the quotient is discarded. 1558 // NewOperationRem is the constructor for OperationRem 1559 func NewOperationRem(b SignedInt) UnionOperation { 1560 return UnionOperation{Kind: OperationKindRem, B1: byte(b)} 1561 } 1562 1563 // NewOperationAnd is a constructor for UnionOperation with OperationKindAnd. 1564 // 1565 // # This corresponds to wasm.OpcodeI32AndName wasm.OpcodeI64AndName 1566 // 1567 // The engines are expected to perform "And" operation on 1568 // top two values on the stack, and pushes the result. 1569 func NewOperationAnd(b UnsignedInt) UnionOperation { 1570 return UnionOperation{Kind: OperationKindAnd, B1: byte(b)} 1571 } 1572 1573 // NewOperationOr is a constructor for UnionOperation with OperationKindOr. 1574 // 1575 // # This corresponds to wasm.OpcodeI32OrName wasm.OpcodeI64OrName 1576 // 1577 // The engines are expected to perform "Or" operation on 1578 // top two values on the stack, and pushes the result. 1579 func NewOperationOr(b UnsignedInt) UnionOperation { 1580 return UnionOperation{Kind: OperationKindOr, B1: byte(b)} 1581 } 1582 1583 // NewOperationXor is a constructor for UnionOperation with OperationKindXor. 1584 // 1585 // # This corresponds to wasm.OpcodeI32XorName wasm.OpcodeI64XorName 1586 // 1587 // The engines are expected to perform "Xor" operation on 1588 // top two values on the stack, and pushes the result. 1589 func NewOperationXor(b UnsignedInt) UnionOperation { 1590 return UnionOperation{Kind: OperationKindXor, B1: byte(b)} 1591 } 1592 1593 // NewOperationShl is a constructor for UnionOperation with OperationKindShl. 1594 // 1595 // # This corresponds to wasm.OpcodeI32ShlName wasm.OpcodeI64ShlName 1596 // 1597 // The engines are expected to perform "Shl" operation on 1598 // top two values on the stack, and pushes the result. 1599 func NewOperationShl(b UnsignedInt) UnionOperation { 1600 return UnionOperation{Kind: OperationKindShl, B1: byte(b)} 1601 } 1602 1603 // NewOperationShr is a constructor for UnionOperation with OperationKindShr. 1604 // 1605 // # This corresponds to wasm.OpcodeI32ShrSName wasm.OpcodeI32ShrUName wasm.OpcodeI64ShrSName wasm.OpcodeI64ShrUName 1606 // 1607 // If OperationShr.Type is signed integer, then, the engines are expected to perform arithmetic right shift on the two 1608 // top values on the stack, otherwise do the logical right shift. 1609 func NewOperationShr(b SignedInt) UnionOperation { 1610 return UnionOperation{Kind: OperationKindShr, B1: byte(b)} 1611 } 1612 1613 // NewOperationRotl is a constructor for UnionOperation with OperationKindRotl. 1614 // 1615 // # This corresponds to wasm.OpcodeI32RotlName wasm.OpcodeI64RotlName 1616 // 1617 // The engines are expected to perform "Rotl" operation on 1618 // top two values on the stack, and pushes the result. 1619 func NewOperationRotl(b UnsignedInt) UnionOperation { 1620 return UnionOperation{Kind: OperationKindRotl, B1: byte(b)} 1621 } 1622 1623 // NewOperationRotr is a constructor for UnionOperation with OperationKindRotr. 1624 // 1625 // # This corresponds to wasm.OpcodeI32RotrName wasm.OpcodeI64RotrName 1626 // 1627 // The engines are expected to perform "Rotr" operation on 1628 // top two values on the stack, and pushes the result. 1629 func NewOperationRotr(b UnsignedInt) UnionOperation { 1630 return UnionOperation{Kind: OperationKindRotr, B1: byte(b)} 1631 } 1632 1633 // NewOperationAbs is a constructor for UnionOperation with OperationKindAbs. 1634 // 1635 // This corresponds to wasm.OpcodeF32Abs wasm.OpcodeF64Abs 1636 func NewOperationAbs(b Float) UnionOperation { 1637 return UnionOperation{Kind: OperationKindAbs, B1: byte(b)} 1638 } 1639 1640 // NewOperationNeg is a constructor for UnionOperation with OperationKindNeg. 1641 // 1642 // This corresponds to wasm.OpcodeF32Neg wasm.OpcodeF64Neg 1643 func NewOperationNeg(b Float) UnionOperation { 1644 return UnionOperation{Kind: OperationKindNeg, B1: byte(b)} 1645 } 1646 1647 // NewOperationCeil is a constructor for UnionOperation with OperationKindCeil. 1648 // 1649 // This corresponds to wasm.OpcodeF32CeilName wasm.OpcodeF64CeilName 1650 func NewOperationCeil(b Float) UnionOperation { 1651 return UnionOperation{Kind: OperationKindCeil, B1: byte(b)} 1652 } 1653 1654 // NewOperationFloor is a constructor for UnionOperation with OperationKindFloor. 1655 // 1656 // This corresponds to wasm.OpcodeF32FloorName wasm.OpcodeF64FloorName 1657 func NewOperationFloor(b Float) UnionOperation { 1658 return UnionOperation{Kind: OperationKindFloor, B1: byte(b)} 1659 } 1660 1661 // NewOperationTrunc is a constructor for UnionOperation with OperationKindTrunc. 1662 // 1663 // This corresponds to wasm.OpcodeF32TruncName wasm.OpcodeF64TruncName 1664 func NewOperationTrunc(b Float) UnionOperation { 1665 return UnionOperation{Kind: OperationKindTrunc, B1: byte(b)} 1666 } 1667 1668 // NewOperationNearest is a constructor for UnionOperation with OperationKindNearest. 1669 // 1670 // # This corresponds to wasm.OpcodeF32NearestName wasm.OpcodeF64NearestName 1671 // 1672 // Note: this is *not* equivalent to math.Round and instead has the same 1673 // the semantics of LLVM's rint intrinsic. See https://llvm.org/docs/LangRef.html#llvm-rint-intrinsic. 1674 // For example, math.Round(-4.5) produces -5 while we want to produce -4. 1675 func NewOperationNearest(b Float) UnionOperation { 1676 return UnionOperation{Kind: OperationKindNearest, B1: byte(b)} 1677 } 1678 1679 // NewOperationSqrt is a constructor for UnionOperation with OperationKindSqrt. 1680 // 1681 // This corresponds to wasm.OpcodeF32SqrtName wasm.OpcodeF64SqrtName 1682 func NewOperationSqrt(b Float) UnionOperation { 1683 return UnionOperation{Kind: OperationKindSqrt, B1: byte(b)} 1684 } 1685 1686 // NewOperationMin is a constructor for UnionOperation with OperationKindMin. 1687 // 1688 // # This corresponds to wasm.OpcodeF32MinName wasm.OpcodeF64MinName 1689 // 1690 // The engines are expected to pop two values from the stack, and push back the maximum of 1691 // these two values onto the stack. For example, stack [..., 100.1, 1.9] results in [..., 1.9]. 1692 // 1693 // Note: WebAssembly specifies that min/max must always return NaN if one of values is NaN, 1694 // which is a different behavior different from math.Min. 1695 func NewOperationMin(b Float) UnionOperation { 1696 return UnionOperation{Kind: OperationKindMin, B1: byte(b)} 1697 } 1698 1699 // NewOperationMax is a constructor for UnionOperation with OperationKindMax. 1700 // 1701 // # This corresponds to wasm.OpcodeF32MaxName wasm.OpcodeF64MaxName 1702 // 1703 // The engines are expected to pop two values from the stack, and push back the maximum of 1704 // these two values onto the stack. For example, stack [..., 100.1, 1.9] results in [..., 100.1]. 1705 // 1706 // Note: WebAssembly specifies that min/max must always return NaN if one of values is NaN, 1707 // which is a different behavior different from math.Max. 1708 func NewOperationMax(b Float) UnionOperation { 1709 return UnionOperation{Kind: OperationKindMax, B1: byte(b)} 1710 } 1711 1712 // NewOperationCopysign is a constructor for UnionOperation with OperationKindCopysign. 1713 // 1714 // # This corresponds to wasm.OpcodeF32CopysignName wasm.OpcodeF64CopysignName 1715 // 1716 // The engines are expected to pop two float values from the stack, and copy the signbit of 1717 // the first-popped value to the last one. 1718 // For example, stack [..., 1.213, -5.0] results in [..., -1.213]. 1719 func NewOperationCopysign(b Float) UnionOperation { 1720 return UnionOperation{Kind: OperationKindCopysign, B1: byte(b)} 1721 } 1722 1723 // NewOperationI32WrapFromI64 is a constructor for UnionOperation with OperationKindI32WrapFromI64. 1724 // 1725 // This corresponds to wasm.OpcodeI32WrapI64 and equivalent to uint64(uint32(v)) in Go. 1726 // 1727 // The engines are expected to replace the 64-bit int on top of the stack 1728 // with the corresponding 32-bit integer. 1729 func NewOperationI32WrapFromI64() UnionOperation { 1730 return UnionOperation{Kind: OperationKindI32WrapFromI64} 1731 } 1732 1733 // NewOperationITruncFromF is a constructor for UnionOperation with OperationKindITruncFromF. 1734 // 1735 // This corresponds to 1736 // 1737 // wasm.OpcodeI32TruncF32SName wasm.OpcodeI32TruncF32UName wasm.OpcodeI32TruncF64SName 1738 // wasm.OpcodeI32TruncF64UName wasm.OpcodeI64TruncF32SName wasm.OpcodeI64TruncF32UName wasm.OpcodeI64TruncF64SName 1739 // wasm.OpcodeI64TruncF64UName. wasm.OpcodeI32TruncSatF32SName wasm.OpcodeI32TruncSatF32UName 1740 // wasm.OpcodeI32TruncSatF64SName wasm.OpcodeI32TruncSatF64UName wasm.OpcodeI64TruncSatF32SName 1741 // wasm.OpcodeI64TruncSatF32UName wasm.OpcodeI64TruncSatF64SName wasm.OpcodeI64TruncSatF64UName 1742 // 1743 // See [1] and [2] for when we encounter undefined behavior in the WebAssembly specification if NewOperationITruncFromF.NonTrapping == false. 1744 // To summarize, if the source float value is NaN or doesn't fit in the destination range of integers (incl. +=Inf), 1745 // then the runtime behavior is undefined. In wazero, the engines are expected to exit the execution in these undefined cases with 1746 // wasmruntime.ErrRuntimeInvalidConversionToInteger error. 1747 // 1748 // [1] https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#-hrefop-trunc-umathrmtruncmathsfu_m-n-z for unsigned integers. 1749 // [2] https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#-hrefop-trunc-smathrmtruncmathsfs_m-n-z for signed integers. 1750 // 1751 // nonTrapping true if this conversion is "nontrapping" in the sense of the 1752 // https://github.com/WebAssembly/spec/blob/ce4b6c4d47eb06098cc7ab2e81f24748da822f20/proposals/nontrapping-float-to-int-conversion/Overview.md 1753 func NewOperationITruncFromF(inputType Float, outputType SignedInt, nonTrapping bool) UnionOperation { 1754 return UnionOperation{ 1755 Kind: OperationKindITruncFromF, 1756 B1: byte(inputType), 1757 B2: byte(outputType), 1758 B3: nonTrapping, 1759 } 1760 } 1761 1762 // NewOperationFConvertFromI is a constructor for UnionOperation with OperationKindFConvertFromI. 1763 // 1764 // This corresponds to 1765 // 1766 // wasm.OpcodeF32ConvertI32SName wasm.OpcodeF32ConvertI32UName wasm.OpcodeF32ConvertI64SName wasm.OpcodeF32ConvertI64UName 1767 // wasm.OpcodeF64ConvertI32SName wasm.OpcodeF64ConvertI32UName wasm.OpcodeF64ConvertI64SName wasm.OpcodeF64ConvertI64UName 1768 // 1769 // and equivalent to float32(uint32(x)), float32(int32(x)), etc in Go. 1770 func NewOperationFConvertFromI(inputType SignedInt, outputType Float) UnionOperation { 1771 return UnionOperation{ 1772 Kind: OperationKindFConvertFromI, 1773 B1: byte(inputType), 1774 B2: byte(outputType), 1775 } 1776 } 1777 1778 // NewOperationF32DemoteFromF64 is a constructor for UnionOperation with OperationKindF32DemoteFromF64. 1779 // 1780 // This corresponds to wasm.OpcodeF32DemoteF64 and is equivalent float32(float64(v)). 1781 func NewOperationF32DemoteFromF64() UnionOperation { 1782 return UnionOperation{Kind: OperationKindF32DemoteFromF64} 1783 } 1784 1785 // NewOperationF64PromoteFromF32 is a constructor for UnionOperation with OperationKindF64PromoteFromF32. 1786 // 1787 // This corresponds to wasm.OpcodeF64PromoteF32 and is equivalent float64(float32(v)). 1788 func NewOperationF64PromoteFromF32() UnionOperation { 1789 return UnionOperation{Kind: OperationKindF64PromoteFromF32} 1790 } 1791 1792 // NewOperationI32ReinterpretFromF32 is a constructor for UnionOperation with OperationKindI32ReinterpretFromF32. 1793 // 1794 // This corresponds to wasm.OpcodeI32ReinterpretF32Name. 1795 func NewOperationI32ReinterpretFromF32() UnionOperation { 1796 return UnionOperation{Kind: OperationKindI32ReinterpretFromF32} 1797 } 1798 1799 // NewOperationI64ReinterpretFromF64 is a constructor for UnionOperation with OperationKindI64ReinterpretFromF64. 1800 // 1801 // This corresponds to wasm.OpcodeI64ReinterpretF64Name. 1802 func NewOperationI64ReinterpretFromF64() UnionOperation { 1803 return UnionOperation{Kind: OperationKindI64ReinterpretFromF64} 1804 } 1805 1806 // NewOperationF32ReinterpretFromI32 is a constructor for UnionOperation with OperationKindF32ReinterpretFromI32. 1807 // 1808 // This corresponds to wasm.OpcodeF32ReinterpretI32Name. 1809 func NewOperationF32ReinterpretFromI32() UnionOperation { 1810 return UnionOperation{Kind: OperationKindF32ReinterpretFromI32} 1811 } 1812 1813 // NewOperationF64ReinterpretFromI64 is a constructor for UnionOperation with OperationKindF64ReinterpretFromI64. 1814 // 1815 // This corresponds to wasm.OpcodeF64ReinterpretI64Name. 1816 func NewOperationF64ReinterpretFromI64() UnionOperation { 1817 return UnionOperation{Kind: OperationKindF64ReinterpretFromI64} 1818 } 1819 1820 // NewOperationExtend is a constructor for UnionOperation with OperationKindExtend. 1821 // 1822 // # This corresponds to wasm.OpcodeI64ExtendI32SName wasm.OpcodeI64ExtendI32UName 1823 // 1824 // The engines are expected to extend the 32-bit signed or unsigned int on top of the stack 1825 // as a 64-bit integer of corresponding signedness. For unsigned case, this is just reinterpreting the 1826 // underlying bit pattern as 64-bit integer. For signed case, this is sign-extension which preserves the 1827 // original integer's sign. 1828 func NewOperationExtend(signed bool) UnionOperation { 1829 op := UnionOperation{Kind: OperationKindExtend} 1830 if signed { 1831 op.B1 = 1 1832 } 1833 return op 1834 } 1835 1836 // NewOperationSignExtend32From8 is a constructor for UnionOperation with OperationKindSignExtend32From8. 1837 // 1838 // This corresponds to wasm.OpcodeI32Extend8SName. 1839 // 1840 // The engines are expected to sign-extend the first 8-bits of 32-bit in as signed 32-bit int. 1841 func NewOperationSignExtend32From8() UnionOperation { 1842 return UnionOperation{Kind: OperationKindSignExtend32From8} 1843 } 1844 1845 // NewOperationSignExtend32From16 is a constructor for UnionOperation with OperationKindSignExtend32From16. 1846 // 1847 // This corresponds to wasm.OpcodeI32Extend16SName. 1848 // 1849 // The engines are expected to sign-extend the first 16-bits of 32-bit in as signed 32-bit int. 1850 func NewOperationSignExtend32From16() UnionOperation { 1851 return UnionOperation{Kind: OperationKindSignExtend32From16} 1852 } 1853 1854 // NewOperationSignExtend64From8 is a constructor for UnionOperation with OperationKindSignExtend64From8. 1855 // 1856 // This corresponds to wasm.OpcodeI64Extend8SName. 1857 // 1858 // The engines are expected to sign-extend the first 8-bits of 64-bit in as signed 32-bit int. 1859 func NewOperationSignExtend64From8() UnionOperation { 1860 return UnionOperation{Kind: OperationKindSignExtend64From8} 1861 } 1862 1863 // NewOperationSignExtend64From16 is a constructor for UnionOperation with OperationKindSignExtend64From16. 1864 // 1865 // This corresponds to wasm.OpcodeI64Extend16SName. 1866 // 1867 // The engines are expected to sign-extend the first 16-bits of 64-bit in as signed 32-bit int. 1868 func NewOperationSignExtend64From16() UnionOperation { 1869 return UnionOperation{Kind: OperationKindSignExtend64From16} 1870 } 1871 1872 // NewOperationSignExtend64From32 is a constructor for UnionOperation with OperationKindSignExtend64From32. 1873 // 1874 // This corresponds to wasm.OpcodeI64Extend32SName. 1875 // 1876 // The engines are expected to sign-extend the first 32-bits of 64-bit in as signed 32-bit int. 1877 func NewOperationSignExtend64From32() UnionOperation { 1878 return UnionOperation{Kind: OperationKindSignExtend64From32} 1879 } 1880 1881 // NewOperationMemoryInit is a constructor for UnionOperation with OperationKindMemoryInit. 1882 // 1883 // This corresponds to wasm.OpcodeMemoryInitName. 1884 // 1885 // dataIndex is the index of the data instance in ModuleInstance.DataInstances 1886 // by which this operation instantiates a part of the memory. 1887 func NewOperationMemoryInit(dataIndex uint32) UnionOperation { 1888 return UnionOperation{Kind: OperationKindMemoryInit, U1: uint64(dataIndex)} 1889 } 1890 1891 // NewOperationDataDrop implements Operation. 1892 // 1893 // This corresponds to wasm.OpcodeDataDropName. 1894 // 1895 // dataIndex is the index of the data instance in ModuleInstance.DataInstances 1896 // which this operation drops. 1897 func NewOperationDataDrop(dataIndex uint32) UnionOperation { 1898 return UnionOperation{Kind: OperationKindDataDrop, U1: uint64(dataIndex)} 1899 } 1900 1901 // NewOperationMemoryCopy is a consuctor for UnionOperation with OperationKindMemoryCopy. 1902 // 1903 // This corresponds to wasm.OpcodeMemoryCopyName. 1904 func NewOperationMemoryCopy() UnionOperation { 1905 return UnionOperation{Kind: OperationKindMemoryCopy} 1906 } 1907 1908 // NewOperationMemoryFill is a consuctor for UnionOperation with OperationKindMemoryFill. 1909 func NewOperationMemoryFill() UnionOperation { 1910 return UnionOperation{Kind: OperationKindMemoryFill} 1911 } 1912 1913 // NewOperationTableInit is a constructor for UnionOperation with OperationKindTableInit. 1914 // 1915 // This corresponds to wasm.OpcodeTableInitName. 1916 // 1917 // elemIndex is the index of the element by which this operation initializes a part of the table. 1918 // tableIndex is the index of the table on which this operation initialize by the target element. 1919 func NewOperationTableInit(elemIndex, tableIndex uint32) UnionOperation { 1920 return UnionOperation{Kind: OperationKindTableInit, U1: uint64(elemIndex), U2: uint64(tableIndex)} 1921 } 1922 1923 // NewOperationElemDrop is a constructor for UnionOperation with OperationKindElemDrop. 1924 // 1925 // This corresponds to wasm.OpcodeElemDropName. 1926 // 1927 // elemIndex is the index of the element which this operation drops. 1928 func NewOperationElemDrop(elemIndex uint32) UnionOperation { 1929 return UnionOperation{Kind: OperationKindElemDrop, U1: uint64(elemIndex)} 1930 } 1931 1932 // NewOperationTableCopy implements Operation. 1933 // 1934 // This corresponds to wasm.OpcodeTableCopyName. 1935 func NewOperationTableCopy(srcTableIndex, dstTableIndex uint32) UnionOperation { 1936 return UnionOperation{Kind: OperationKindTableCopy, U1: uint64(srcTableIndex), U2: uint64(dstTableIndex)} 1937 } 1938 1939 // NewOperationRefFunc constructor for UnionOperation with OperationKindRefFunc. 1940 // 1941 // This corresponds to wasm.OpcodeRefFuncName, and engines are expected to 1942 // push the opaque pointer value of engine specific func for the given FunctionIndex. 1943 // 1944 // Note: in wazero, we express any reference types (funcref or externref) as opaque pointers which is uint64. 1945 // Therefore, the engine implementations emit instructions to push the address of *function onto the stack. 1946 func NewOperationRefFunc(functionIndex uint32) UnionOperation { 1947 return UnionOperation{Kind: OperationKindRefFunc, U1: uint64(functionIndex)} 1948 } 1949 1950 // NewOperationTableGet constructor for UnionOperation with OperationKindTableGet. 1951 // 1952 // This corresponds to wasm.OpcodeTableGetName. 1953 func NewOperationTableGet(tableIndex uint32) UnionOperation { 1954 return UnionOperation{Kind: OperationKindTableGet, U1: uint64(tableIndex)} 1955 } 1956 1957 // NewOperationTableSet constructor for UnionOperation with OperationKindTableSet. 1958 // 1959 // This corresponds to wasm.OpcodeTableSetName. 1960 func NewOperationTableSet(tableIndex uint32) UnionOperation { 1961 return UnionOperation{Kind: OperationKindTableSet, U1: uint64(tableIndex)} 1962 } 1963 1964 // NewOperationTableSize constructor for UnionOperation with OperationKindTableSize. 1965 // 1966 // This corresponds to wasm.OpcodeTableSizeName. 1967 func NewOperationTableSize(tableIndex uint32) UnionOperation { 1968 return UnionOperation{Kind: OperationKindTableSize, U1: uint64(tableIndex)} 1969 } 1970 1971 // NewOperationTableGrow constructor for UnionOperation with OperationKindTableGrow. 1972 // 1973 // This corresponds to wasm.OpcodeTableGrowName. 1974 func NewOperationTableGrow(tableIndex uint32) UnionOperation { 1975 return UnionOperation{Kind: OperationKindTableGrow, U1: uint64(tableIndex)} 1976 } 1977 1978 // NewOperationTableFill constructor for UnionOperation with OperationKindTableFill. 1979 // 1980 // This corresponds to wasm.OpcodeTableFillName. 1981 func NewOperationTableFill(tableIndex uint32) UnionOperation { 1982 return UnionOperation{Kind: OperationKindTableFill, U1: uint64(tableIndex)} 1983 } 1984 1985 // NewOperationV128Const constructor for UnionOperation with OperationKindV128Const 1986 func NewOperationV128Const(lo, hi uint64) UnionOperation { 1987 return UnionOperation{Kind: OperationKindV128Const, U1: lo, U2: hi} 1988 } 1989 1990 // Shape corresponds to a shape of v128 values. 1991 // https://webassembly.github.io/spec/core/syntax/instructions.html#syntax-shape 1992 type Shape = byte 1993 1994 const ( 1995 ShapeI8x16 Shape = iota 1996 ShapeI16x8 1997 ShapeI32x4 1998 ShapeI64x2 1999 ShapeF32x4 2000 ShapeF64x2 2001 ) 2002 2003 func shapeName(s Shape) (ret string) { 2004 switch s { 2005 case ShapeI8x16: 2006 ret = "I8x16" 2007 case ShapeI16x8: 2008 ret = "I16x8" 2009 case ShapeI32x4: 2010 ret = "I32x4" 2011 case ShapeI64x2: 2012 ret = "I64x2" 2013 case ShapeF32x4: 2014 ret = "F32x4" 2015 case ShapeF64x2: 2016 ret = "F64x2" 2017 } 2018 return 2019 } 2020 2021 // NewOperationV128Add constructor for UnionOperation with OperationKindV128Add. 2022 // 2023 // This corresponds to wasm.OpcodeVecI8x16AddName wasm.OpcodeVecI16x8AddName wasm.OpcodeVecI32x4AddName 2024 // 2025 // wasm.OpcodeVecI64x2AddName wasm.OpcodeVecF32x4AddName wasm.OpcodeVecF64x2AddName 2026 func NewOperationV128Add(shape Shape) UnionOperation { 2027 return UnionOperation{Kind: OperationKindV128Add, B1: shape} 2028 } 2029 2030 // NewOperationV128Sub constructor for UnionOperation with OperationKindV128Sub. 2031 // 2032 // This corresponds to wasm.OpcodeVecI8x16SubName wasm.OpcodeVecI16x8SubName wasm.OpcodeVecI32x4SubName 2033 // 2034 // wasm.OpcodeVecI64x2SubName wasm.OpcodeVecF32x4SubName wasm.OpcodeVecF64x2SubName 2035 func NewOperationV128Sub(shape Shape) UnionOperation { 2036 return UnionOperation{Kind: OperationKindV128Sub, B1: shape} 2037 } 2038 2039 // V128LoadType represents a type of wasm.OpcodeVecV128Load* instructions. 2040 type V128LoadType = byte 2041 2042 const ( 2043 // V128LoadType128 corresponds to wasm.OpcodeVecV128LoadName. 2044 V128LoadType128 V128LoadType = iota 2045 // V128LoadType8x8s corresponds to wasm.OpcodeVecV128Load8x8SName. 2046 V128LoadType8x8s 2047 // V128LoadType8x8u corresponds to wasm.OpcodeVecV128Load8x8UName. 2048 V128LoadType8x8u 2049 // V128LoadType16x4s corresponds to wasm.OpcodeVecV128Load16x4SName 2050 V128LoadType16x4s 2051 // V128LoadType16x4u corresponds to wasm.OpcodeVecV128Load16x4UName 2052 V128LoadType16x4u 2053 // V128LoadType32x2s corresponds to wasm.OpcodeVecV128Load32x2SName 2054 V128LoadType32x2s 2055 // V128LoadType32x2u corresponds to wasm.OpcodeVecV128Load32x2UName 2056 V128LoadType32x2u 2057 // V128LoadType8Splat corresponds to wasm.OpcodeVecV128Load8SplatName 2058 V128LoadType8Splat 2059 // V128LoadType16Splat corresponds to wasm.OpcodeVecV128Load16SplatName 2060 V128LoadType16Splat 2061 // V128LoadType32Splat corresponds to wasm.OpcodeVecV128Load32SplatName 2062 V128LoadType32Splat 2063 // V128LoadType64Splat corresponds to wasm.OpcodeVecV128Load64SplatName 2064 V128LoadType64Splat 2065 // V128LoadType32zero corresponds to wasm.OpcodeVecV128Load32zeroName 2066 V128LoadType32zero 2067 // V128LoadType64zero corresponds to wasm.OpcodeVecV128Load64zeroName 2068 V128LoadType64zero 2069 ) 2070 2071 // NewOperationV128Load is a constructor for UnionOperation with OperationKindV128Load. 2072 // 2073 // This corresponds to 2074 // 2075 // wasm.OpcodeVecV128LoadName wasm.OpcodeVecV128Load8x8SName wasm.OpcodeVecV128Load8x8UName 2076 // wasm.OpcodeVecV128Load16x4SName wasm.OpcodeVecV128Load16x4UName wasm.OpcodeVecV128Load32x2SName 2077 // wasm.OpcodeVecV128Load32x2UName wasm.OpcodeVecV128Load8SplatName wasm.OpcodeVecV128Load16SplatName 2078 // wasm.OpcodeVecV128Load32SplatName wasm.OpcodeVecV128Load64SplatName wasm.OpcodeVecV128Load32zeroName 2079 // wasm.OpcodeVecV128Load64zeroName 2080 func NewOperationV128Load(loadType V128LoadType, arg MemoryArg) UnionOperation { 2081 return UnionOperation{Kind: OperationKindV128Load, B1: loadType, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)} 2082 } 2083 2084 // NewOperationV128LoadLane is a constructor for UnionOperation with OperationKindV128LoadLane. 2085 // 2086 // This corresponds to wasm.OpcodeVecV128Load8LaneName wasm.OpcodeVecV128Load16LaneName 2087 // 2088 // wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName. 2089 // 2090 // laneIndex is >=0 && <(128/LaneSize). 2091 // laneSize is either 8, 16, 32, or 64. 2092 func NewOperationV128LoadLane(laneIndex, laneSize byte, arg MemoryArg) UnionOperation { 2093 return UnionOperation{Kind: OperationKindV128LoadLane, B1: laneSize, B2: laneIndex, U1: uint64(arg.Alignment), U2: uint64(arg.Offset)} 2094 } 2095 2096 // NewOperationV128Store is a constructor for UnionOperation with OperationKindV128Store. 2097 // 2098 // This corresponds to wasm.OpcodeVecV128Load8LaneName wasm.OpcodeVecV128Load16LaneName 2099 // 2100 // wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName. 2101 func NewOperationV128Store(arg MemoryArg) UnionOperation { 2102 return UnionOperation{ 2103 Kind: OperationKindV128Store, 2104 U1: uint64(arg.Alignment), 2105 U2: uint64(arg.Offset), 2106 } 2107 } 2108 2109 // NewOperationV128StoreLane implements Operation. 2110 // 2111 // This corresponds to wasm.OpcodeVecV128Load8LaneName wasm.OpcodeVecV128Load16LaneName 2112 // 2113 // wasm.OpcodeVecV128Load32LaneName wasm.OpcodeVecV128Load64LaneName. 2114 // 2115 // laneIndex is >=0 && <(128/LaneSize). 2116 // laneSize is either 8, 16, 32, or 64. 2117 func NewOperationV128StoreLane(laneIndex byte, laneSize byte, arg MemoryArg) UnionOperation { 2118 return UnionOperation{ 2119 Kind: OperationKindV128StoreLane, 2120 B1: laneSize, 2121 B2: laneIndex, 2122 U1: uint64(arg.Alignment), 2123 U2: uint64(arg.Offset), 2124 } 2125 } 2126 2127 // NewOperationV128ExtractLane is a constructor for UnionOperation with OperationKindV128ExtractLane. 2128 // 2129 // This corresponds to 2130 // 2131 // wasm.OpcodeVecI8x16ExtractLaneSName wasm.OpcodeVecI8x16ExtractLaneUName 2132 // wasm.OpcodeVecI16x8ExtractLaneSName wasm.OpcodeVecI16x8ExtractLaneUName 2133 // wasm.OpcodeVecI32x4ExtractLaneName wasm.OpcodeVecI64x2ExtractLaneName 2134 // wasm.OpcodeVecF32x4ExtractLaneName wasm.OpcodeVecF64x2ExtractLaneName. 2135 // 2136 // laneIndex is >=0 && <M where shape = NxM. 2137 // signed is used when shape is either i8x16 or i16x2 to specify whether to sign-extend or not. 2138 func NewOperationV128ExtractLane(laneIndex byte, signed bool, shape Shape) UnionOperation { 2139 return UnionOperation{ 2140 Kind: OperationKindV128ExtractLane, 2141 B1: shape, 2142 B2: laneIndex, 2143 B3: signed, 2144 } 2145 } 2146 2147 // NewOperationV128ReplaceLane is a constructor for UnionOperation with OperationKindV128ReplaceLane. 2148 // 2149 // This corresponds to 2150 // 2151 // wasm.OpcodeVecI8x16ReplaceLaneName wasm.OpcodeVecI16x8ReplaceLaneName 2152 // wasm.OpcodeVecI32x4ReplaceLaneName wasm.OpcodeVecI64x2ReplaceLaneName 2153 // wasm.OpcodeVecF32x4ReplaceLaneName wasm.OpcodeVecF64x2ReplaceLaneName. 2154 // 2155 // laneIndex is >=0 && <M where shape = NxM. 2156 func NewOperationV128ReplaceLane(laneIndex byte, shape Shape) UnionOperation { 2157 return UnionOperation{Kind: OperationKindV128ReplaceLane, B1: shape, B2: laneIndex} 2158 } 2159 2160 // NewOperationV128Splat is a constructor for UnionOperation with OperationKindV128Splat. 2161 // 2162 // This corresponds to 2163 // 2164 // wasm.OpcodeVecI8x16SplatName wasm.OpcodeVecI16x8SplatName 2165 // wasm.OpcodeVecI32x4SplatName wasm.OpcodeVecI64x2SplatName 2166 // wasm.OpcodeVecF32x4SplatName wasm.OpcodeVecF64x2SplatName. 2167 func NewOperationV128Splat(shape Shape) UnionOperation { 2168 return UnionOperation{Kind: OperationKindV128Splat, B1: shape} 2169 } 2170 2171 // NewOperationV128Shuffle is a constructor for UnionOperation with OperationKindV128Shuffle. 2172 func NewOperationV128Shuffle(lanes []uint64) UnionOperation { 2173 return UnionOperation{Kind: OperationKindV128Shuffle, Us: lanes} 2174 } 2175 2176 // NewOperationV128Swizzle is a constructor for UnionOperation with OperationKindV128Swizzle. 2177 // 2178 // This corresponds to wasm.OpcodeVecI8x16SwizzleName. 2179 func NewOperationV128Swizzle() UnionOperation { 2180 return UnionOperation{Kind: OperationKindV128Swizzle} 2181 } 2182 2183 // NewOperationV128AnyTrue is a constructor for UnionOperation with OperationKindV128AnyTrue. 2184 // 2185 // This corresponds to wasm.OpcodeVecV128AnyTrueName. 2186 func NewOperationV128AnyTrue() UnionOperation { 2187 return UnionOperation{Kind: OperationKindV128AnyTrue} 2188 } 2189 2190 // NewOperationV128AllTrue is a constructor for UnionOperation with OperationKindV128AllTrue. 2191 // 2192 // This corresponds to 2193 // 2194 // wasm.OpcodeVecI8x16AllTrueName wasm.OpcodeVecI16x8AllTrueName 2195 // wasm.OpcodeVecI32x4AllTrueName wasm.OpcodeVecI64x2AllTrueName. 2196 func NewOperationV128AllTrue(shape Shape) UnionOperation { 2197 return UnionOperation{Kind: OperationKindV128AllTrue, B1: shape} 2198 } 2199 2200 // NewOperationV128BitMask is a constructor for UnionOperation with OperationKindV128BitMask. 2201 // 2202 // This corresponds to 2203 // 2204 // wasm.OpcodeVecI8x16BitMaskName wasm.OpcodeVecI16x8BitMaskName 2205 // wasm.OpcodeVecI32x4BitMaskName wasm.OpcodeVecI64x2BitMaskName. 2206 func NewOperationV128BitMask(shape Shape) UnionOperation { 2207 return UnionOperation{Kind: OperationKindV128BitMask, B1: shape} 2208 } 2209 2210 // NewOperationV128And is a constructor for UnionOperation with OperationKindV128And. 2211 // 2212 // This corresponds to wasm.OpcodeVecV128And. 2213 func NewOperationV128And() UnionOperation { 2214 return UnionOperation{Kind: OperationKindV128And} 2215 } 2216 2217 // NewOperationV128Not is a constructor for UnionOperation with OperationKindV128Not. 2218 // 2219 // This corresponds to wasm.OpcodeVecV128Not. 2220 func NewOperationV128Not() UnionOperation { 2221 return UnionOperation{Kind: OperationKindV128Not} 2222 } 2223 2224 // NewOperationV128Or is a constructor for UnionOperation with OperationKindV128Or. 2225 // 2226 // This corresponds to wasm.OpcodeVecV128Or. 2227 func NewOperationV128Or() UnionOperation { 2228 return UnionOperation{Kind: OperationKindV128Or} 2229 } 2230 2231 // NewOperationV128Xor is a constructor for UnionOperation with OperationKindV128Xor. 2232 // 2233 // This corresponds to wasm.OpcodeVecV128Xor. 2234 func NewOperationV128Xor() UnionOperation { 2235 return UnionOperation{Kind: OperationKindV128Xor} 2236 } 2237 2238 // NewOperationV128Bitselect is a constructor for UnionOperation with OperationKindV128Bitselect. 2239 // 2240 // This corresponds to wasm.OpcodeVecV128Bitselect. 2241 func NewOperationV128Bitselect() UnionOperation { 2242 return UnionOperation{Kind: OperationKindV128Bitselect} 2243 } 2244 2245 // NewOperationV128AndNot is a constructor for UnionOperation with OperationKindV128AndNot. 2246 // 2247 // This corresponds to wasm.OpcodeVecV128AndNot. 2248 func NewOperationV128AndNot() UnionOperation { 2249 return UnionOperation{Kind: OperationKindV128AndNot} 2250 } 2251 2252 // NewOperationV128Shl is a constructor for UnionOperation with OperationKindV128Shl. 2253 // 2254 // This corresponds to 2255 // 2256 // wasm.OpcodeVecI8x16ShlName wasm.OpcodeVecI16x8ShlName 2257 // wasm.OpcodeVecI32x4ShlName wasm.OpcodeVecI64x2ShlName 2258 func NewOperationV128Shl(shape Shape) UnionOperation { 2259 return UnionOperation{Kind: OperationKindV128Shl, B1: shape} 2260 } 2261 2262 // NewOperationV128Shr is a constructor for UnionOperation with OperationKindV128Shr. 2263 // 2264 // This corresponds to 2265 // 2266 // wasm.OpcodeVecI8x16ShrSName wasm.OpcodeVecI8x16ShrUName wasm.OpcodeVecI16x8ShrSName 2267 // wasm.OpcodeVecI16x8ShrUName wasm.OpcodeVecI32x4ShrSName wasm.OpcodeVecI32x4ShrUName. 2268 // wasm.OpcodeVecI64x2ShrSName wasm.OpcodeVecI64x2ShrUName. 2269 func NewOperationV128Shr(shape Shape, signed bool) UnionOperation { 2270 return UnionOperation{Kind: OperationKindV128Shr, B1: shape, B3: signed} 2271 } 2272 2273 // NewOperationV128Cmp is a constructor for UnionOperation with OperationKindV128Cmp. 2274 // 2275 // This corresponds to 2276 // 2277 // wasm.OpcodeVecI8x16EqName, wasm.OpcodeVecI8x16NeName, wasm.OpcodeVecI8x16LtSName, wasm.OpcodeVecI8x16LtUName, wasm.OpcodeVecI8x16GtSName, 2278 // wasm.OpcodeVecI8x16GtUName, wasm.OpcodeVecI8x16LeSName, wasm.OpcodeVecI8x16LeUName, wasm.OpcodeVecI8x16GeSName, wasm.OpcodeVecI8x16GeUName, 2279 // wasm.OpcodeVecI16x8EqName, wasm.OpcodeVecI16x8NeName, wasm.OpcodeVecI16x8LtSName, wasm.OpcodeVecI16x8LtUName, wasm.OpcodeVecI16x8GtSName, 2280 // wasm.OpcodeVecI16x8GtUName, wasm.OpcodeVecI16x8LeSName, wasm.OpcodeVecI16x8LeUName, wasm.OpcodeVecI16x8GeSName, wasm.OpcodeVecI16x8GeUName, 2281 // wasm.OpcodeVecI32x4EqName, wasm.OpcodeVecI32x4NeName, wasm.OpcodeVecI32x4LtSName, wasm.OpcodeVecI32x4LtUName, wasm.OpcodeVecI32x4GtSName, 2282 // wasm.OpcodeVecI32x4GtUName, wasm.OpcodeVecI32x4LeSName, wasm.OpcodeVecI32x4LeUName, wasm.OpcodeVecI32x4GeSName, wasm.OpcodeVecI32x4GeUName, 2283 // wasm.OpcodeVecI64x2EqName, wasm.OpcodeVecI64x2NeName, wasm.OpcodeVecI64x2LtSName, wasm.OpcodeVecI64x2GtSName, wasm.OpcodeVecI64x2LeSName, 2284 // wasm.OpcodeVecI64x2GeSName, wasm.OpcodeVecF32x4EqName, wasm.OpcodeVecF32x4NeName, wasm.OpcodeVecF32x4LtName, wasm.OpcodeVecF32x4GtName, 2285 // wasm.OpcodeVecF32x4LeName, wasm.OpcodeVecF32x4GeName, wasm.OpcodeVecF64x2EqName, wasm.OpcodeVecF64x2NeName, wasm.OpcodeVecF64x2LtName, 2286 // wasm.OpcodeVecF64x2GtName, wasm.OpcodeVecF64x2LeName, wasm.OpcodeVecF64x2GeName 2287 func NewOperationV128Cmp(cmpType V128CmpType) UnionOperation { 2288 return UnionOperation{Kind: OperationKindV128Cmp, B1: cmpType} 2289 } 2290 2291 // V128CmpType represents a type of vector comparison operation. 2292 type V128CmpType = byte 2293 2294 const ( 2295 // V128CmpTypeI8x16Eq corresponds to wasm.OpcodeVecI8x16EqName. 2296 V128CmpTypeI8x16Eq V128CmpType = iota 2297 // V128CmpTypeI8x16Ne corresponds to wasm.OpcodeVecI8x16NeName. 2298 V128CmpTypeI8x16Ne 2299 // V128CmpTypeI8x16LtS corresponds to wasm.OpcodeVecI8x16LtSName. 2300 V128CmpTypeI8x16LtS 2301 // V128CmpTypeI8x16LtU corresponds to wasm.OpcodeVecI8x16LtUName. 2302 V128CmpTypeI8x16LtU 2303 // V128CmpTypeI8x16GtS corresponds to wasm.OpcodeVecI8x16GtSName. 2304 V128CmpTypeI8x16GtS 2305 // V128CmpTypeI8x16GtU corresponds to wasm.OpcodeVecI8x16GtUName. 2306 V128CmpTypeI8x16GtU 2307 // V128CmpTypeI8x16LeS corresponds to wasm.OpcodeVecI8x16LeSName. 2308 V128CmpTypeI8x16LeS 2309 // V128CmpTypeI8x16LeU corresponds to wasm.OpcodeVecI8x16LeUName. 2310 V128CmpTypeI8x16LeU 2311 // V128CmpTypeI8x16GeS corresponds to wasm.OpcodeVecI8x16GeSName. 2312 V128CmpTypeI8x16GeS 2313 // V128CmpTypeI8x16GeU corresponds to wasm.OpcodeVecI8x16GeUName. 2314 V128CmpTypeI8x16GeU 2315 // V128CmpTypeI16x8Eq corresponds to wasm.OpcodeVecI16x8EqName. 2316 V128CmpTypeI16x8Eq 2317 // V128CmpTypeI16x8Ne corresponds to wasm.OpcodeVecI16x8NeName. 2318 V128CmpTypeI16x8Ne 2319 // V128CmpTypeI16x8LtS corresponds to wasm.OpcodeVecI16x8LtSName. 2320 V128CmpTypeI16x8LtS 2321 // V128CmpTypeI16x8LtU corresponds to wasm.OpcodeVecI16x8LtUName. 2322 V128CmpTypeI16x8LtU 2323 // V128CmpTypeI16x8GtS corresponds to wasm.OpcodeVecI16x8GtSName. 2324 V128CmpTypeI16x8GtS 2325 // V128CmpTypeI16x8GtU corresponds to wasm.OpcodeVecI16x8GtUName. 2326 V128CmpTypeI16x8GtU 2327 // V128CmpTypeI16x8LeS corresponds to wasm.OpcodeVecI16x8LeSName. 2328 V128CmpTypeI16x8LeS 2329 // V128CmpTypeI16x8LeU corresponds to wasm.OpcodeVecI16x8LeUName. 2330 V128CmpTypeI16x8LeU 2331 // V128CmpTypeI16x8GeS corresponds to wasm.OpcodeVecI16x8GeSName. 2332 V128CmpTypeI16x8GeS 2333 // V128CmpTypeI16x8GeU corresponds to wasm.OpcodeVecI16x8GeUName. 2334 V128CmpTypeI16x8GeU 2335 // V128CmpTypeI32x4Eq corresponds to wasm.OpcodeVecI32x4EqName. 2336 V128CmpTypeI32x4Eq 2337 // V128CmpTypeI32x4Ne corresponds to wasm.OpcodeVecI32x4NeName. 2338 V128CmpTypeI32x4Ne 2339 // V128CmpTypeI32x4LtS corresponds to wasm.OpcodeVecI32x4LtSName. 2340 V128CmpTypeI32x4LtS 2341 // V128CmpTypeI32x4LtU corresponds to wasm.OpcodeVecI32x4LtUName. 2342 V128CmpTypeI32x4LtU 2343 // V128CmpTypeI32x4GtS corresponds to wasm.OpcodeVecI32x4GtSName. 2344 V128CmpTypeI32x4GtS 2345 // V128CmpTypeI32x4GtU corresponds to wasm.OpcodeVecI32x4GtUName. 2346 V128CmpTypeI32x4GtU 2347 // V128CmpTypeI32x4LeS corresponds to wasm.OpcodeVecI32x4LeSName. 2348 V128CmpTypeI32x4LeS 2349 // V128CmpTypeI32x4LeU corresponds to wasm.OpcodeVecI32x4LeUName. 2350 V128CmpTypeI32x4LeU 2351 // V128CmpTypeI32x4GeS corresponds to wasm.OpcodeVecI32x4GeSName. 2352 V128CmpTypeI32x4GeS 2353 // V128CmpTypeI32x4GeU corresponds to wasm.OpcodeVecI32x4GeUName. 2354 V128CmpTypeI32x4GeU 2355 // V128CmpTypeI64x2Eq corresponds to wasm.OpcodeVecI64x2EqName. 2356 V128CmpTypeI64x2Eq 2357 // V128CmpTypeI64x2Ne corresponds to wasm.OpcodeVecI64x2NeName. 2358 V128CmpTypeI64x2Ne 2359 // V128CmpTypeI64x2LtS corresponds to wasm.OpcodeVecI64x2LtSName. 2360 V128CmpTypeI64x2LtS 2361 // V128CmpTypeI64x2GtS corresponds to wasm.OpcodeVecI64x2GtSName. 2362 V128CmpTypeI64x2GtS 2363 // V128CmpTypeI64x2LeS corresponds to wasm.OpcodeVecI64x2LeSName. 2364 V128CmpTypeI64x2LeS 2365 // V128CmpTypeI64x2GeS corresponds to wasm.OpcodeVecI64x2GeSName. 2366 V128CmpTypeI64x2GeS 2367 // V128CmpTypeF32x4Eq corresponds to wasm.OpcodeVecF32x4EqName. 2368 V128CmpTypeF32x4Eq 2369 // V128CmpTypeF32x4Ne corresponds to wasm.OpcodeVecF32x4NeName. 2370 V128CmpTypeF32x4Ne 2371 // V128CmpTypeF32x4Lt corresponds to wasm.OpcodeVecF32x4LtName. 2372 V128CmpTypeF32x4Lt 2373 // V128CmpTypeF32x4Gt corresponds to wasm.OpcodeVecF32x4GtName. 2374 V128CmpTypeF32x4Gt 2375 // V128CmpTypeF32x4Le corresponds to wasm.OpcodeVecF32x4LeName. 2376 V128CmpTypeF32x4Le 2377 // V128CmpTypeF32x4Ge corresponds to wasm.OpcodeVecF32x4GeName. 2378 V128CmpTypeF32x4Ge 2379 // V128CmpTypeF64x2Eq corresponds to wasm.OpcodeVecF64x2EqName. 2380 V128CmpTypeF64x2Eq 2381 // V128CmpTypeF64x2Ne corresponds to wasm.OpcodeVecF64x2NeName. 2382 V128CmpTypeF64x2Ne 2383 // V128CmpTypeF64x2Lt corresponds to wasm.OpcodeVecF64x2LtName. 2384 V128CmpTypeF64x2Lt 2385 // V128CmpTypeF64x2Gt corresponds to wasm.OpcodeVecF64x2GtName. 2386 V128CmpTypeF64x2Gt 2387 // V128CmpTypeF64x2Le corresponds to wasm.OpcodeVecF64x2LeName. 2388 V128CmpTypeF64x2Le 2389 // V128CmpTypeF64x2Ge corresponds to wasm.OpcodeVecF64x2GeName. 2390 V128CmpTypeF64x2Ge 2391 ) 2392 2393 // NewOperationV128AddSat is a constructor for UnionOperation with OperationKindV128AddSat. 2394 // 2395 // This corresponds to wasm.OpcodeVecI8x16AddSatUName wasm.OpcodeVecI8x16AddSatSName 2396 // 2397 // wasm.OpcodeVecI16x8AddSatUName wasm.OpcodeVecI16x8AddSatSName 2398 // 2399 // shape is either ShapeI8x16 or ShapeI16x8. 2400 func NewOperationV128AddSat(shape Shape, signed bool) UnionOperation { 2401 return UnionOperation{Kind: OperationKindV128AddSat, B1: shape, B3: signed} 2402 } 2403 2404 // NewOperationV128SubSat is a constructor for UnionOperation with OperationKindV128SubSat. 2405 // 2406 // This corresponds to wasm.OpcodeVecI8x16SubSatUName wasm.OpcodeVecI8x16SubSatSName 2407 // 2408 // wasm.OpcodeVecI16x8SubSatUName wasm.OpcodeVecI16x8SubSatSName 2409 // 2410 // shape is either ShapeI8x16 or ShapeI16x8. 2411 func NewOperationV128SubSat(shape Shape, signed bool) UnionOperation { 2412 return UnionOperation{Kind: OperationKindV128SubSat, B1: shape, B3: signed} 2413 } 2414 2415 // NewOperationV128Mul is a constructor for UnionOperation with OperationKindV128Mul 2416 // 2417 // This corresponds to wasm.OpcodeVecF32x4MulName wasm.OpcodeVecF64x2MulName 2418 // 2419 // wasm.OpcodeVecI16x8MulName wasm.OpcodeVecI32x4MulName wasm.OpcodeVecI64x2MulName. 2420 // shape is either ShapeI16x8, ShapeI32x4, ShapeI64x2, ShapeF32x4 or ShapeF64x2. 2421 func NewOperationV128Mul(shape Shape) UnionOperation { 2422 return UnionOperation{Kind: OperationKindV128Mul, B1: shape} 2423 } 2424 2425 // NewOperationV128Div is a constructor for UnionOperation with OperationKindV128Div. 2426 // 2427 // This corresponds to wasm.OpcodeVecF32x4DivName wasm.OpcodeVecF64x2DivName. 2428 // shape is either ShapeF32x4 or ShapeF64x2. 2429 func NewOperationV128Div(shape Shape) UnionOperation { 2430 return UnionOperation{Kind: OperationKindV128Div, B1: shape} 2431 } 2432 2433 // NewOperationV128Neg is a constructor for UnionOperation with OperationKindV128Neg. 2434 // 2435 // This corresponds to wasm.OpcodeVecI8x16NegName wasm.OpcodeVecI16x8NegName wasm.OpcodeVecI32x4NegName 2436 // 2437 // wasm.OpcodeVecI64x2NegName wasm.OpcodeVecF32x4NegName wasm.OpcodeVecF64x2NegName. 2438 func NewOperationV128Neg(shape Shape) UnionOperation { 2439 return UnionOperation{Kind: OperationKindV128Neg, B1: shape} 2440 } 2441 2442 // NewOperationV128Sqrt is a constructor for UnionOperation with 128OperationKindV128Sqrt. 2443 // 2444 // shape is either ShapeF32x4 or ShapeF64x2. 2445 // This corresponds to wasm.OpcodeVecF32x4SqrtName wasm.OpcodeVecF64x2SqrtName. 2446 func NewOperationV128Sqrt(shape Shape) UnionOperation { 2447 return UnionOperation{Kind: OperationKindV128Sqrt, B1: shape} 2448 } 2449 2450 // NewOperationV128Abs is a constructor for UnionOperation with OperationKindV128Abs. 2451 // 2452 // This corresponds to wasm.OpcodeVecI8x16AbsName wasm.OpcodeVecI16x8AbsName wasm.OpcodeVecI32x4AbsName 2453 // 2454 // wasm.OpcodeVecI64x2AbsName wasm.OpcodeVecF32x4AbsName wasm.OpcodeVecF64x2AbsName. 2455 func NewOperationV128Abs(shape Shape) UnionOperation { 2456 return UnionOperation{Kind: OperationKindV128Abs, B1: shape} 2457 } 2458 2459 // NewOperationV128Popcnt is a constructor for UnionOperation with OperationKindV128Popcnt. 2460 // 2461 // This corresponds to wasm.OpcodeVecI8x16PopcntName. 2462 func NewOperationV128Popcnt(shape Shape) UnionOperation { 2463 return UnionOperation{Kind: OperationKindV128Popcnt, B1: shape} 2464 } 2465 2466 // NewOperationV128Min is a constructor for UnionOperation with OperationKindV128Min. 2467 // 2468 // This corresponds to 2469 // 2470 // wasm.OpcodeVecI8x16MinSName wasm.OpcodeVecI8x16MinUName wasm.OpcodeVecI16x8MinSName wasm.OpcodeVecI16x8MinUName 2471 // wasm.OpcodeVecI32x4MinSName wasm.OpcodeVecI32x4MinUName wasm.OpcodeVecI16x8MinSName wasm.OpcodeVecI16x8MinUName 2472 // wasm.OpcodeVecF32x4MinName wasm.OpcodeVecF64x2MinName 2473 func NewOperationV128Min(shape Shape, signed bool) UnionOperation { 2474 return UnionOperation{Kind: OperationKindV128Min, B1: shape, B3: signed} 2475 } 2476 2477 // NewOperationV128Max is a constructor for UnionOperation with OperationKindV128Max. 2478 // 2479 // This corresponds to 2480 // 2481 // wasm.OpcodeVecI8x16MaxSName wasm.OpcodeVecI8x16MaxUName wasm.OpcodeVecI16x8MaxSName wasm.OpcodeVecI16x8MaxUName 2482 // wasm.OpcodeVecI32x4MaxSName wasm.OpcodeVecI32x4MaxUName wasm.OpcodeVecI16x8MaxSName wasm.OpcodeVecI16x8MaxUName 2483 // wasm.OpcodeVecF32x4MaxName wasm.OpcodeVecF64x2MaxName. 2484 func NewOperationV128Max(shape Shape, signed bool) UnionOperation { 2485 return UnionOperation{Kind: OperationKindV128Max, B1: shape, B3: signed} 2486 } 2487 2488 // NewOperationV128AvgrU is a constructor for UnionOperation with OperationKindV128AvgrU. 2489 // 2490 // This corresponds to wasm.OpcodeVecI8x16AvgrUName. 2491 func NewOperationV128AvgrU(shape Shape) UnionOperation { 2492 return UnionOperation{Kind: OperationKindV128AvgrU, B1: shape} 2493 } 2494 2495 // NewOperationV128Pmin is a constructor for UnionOperation with OperationKindV128Pmin. 2496 // 2497 // This corresponds to wasm.OpcodeVecF32x4PminName wasm.OpcodeVecF64x2PminName. 2498 func NewOperationV128Pmin(shape Shape) UnionOperation { 2499 return UnionOperation{Kind: OperationKindV128Pmin, B1: shape} 2500 } 2501 2502 // NewOperationV128Pmax is a constructor for UnionOperation with OperationKindV128Pmax. 2503 // 2504 // This corresponds to wasm.OpcodeVecF32x4PmaxName wasm.OpcodeVecF64x2PmaxName. 2505 func NewOperationV128Pmax(shape Shape) UnionOperation { 2506 return UnionOperation{Kind: OperationKindV128Pmax, B1: shape} 2507 } 2508 2509 // NewOperationV128Ceil is a constructor for UnionOperation with OperationKindV128Ceil. 2510 // 2511 // This corresponds to wasm.OpcodeVecF32x4CeilName wasm.OpcodeVecF64x2CeilName 2512 func NewOperationV128Ceil(shape Shape) UnionOperation { 2513 return UnionOperation{Kind: OperationKindV128Ceil, B1: shape} 2514 } 2515 2516 // NewOperationV128Floor is a constructor for UnionOperation with OperationKindV128Floor. 2517 // 2518 // This corresponds to wasm.OpcodeVecF32x4FloorName wasm.OpcodeVecF64x2FloorName 2519 func NewOperationV128Floor(shape Shape) UnionOperation { 2520 return UnionOperation{Kind: OperationKindV128Floor, B1: shape} 2521 } 2522 2523 // NewOperationV128Trunc is a constructor for UnionOperation with OperationKindV128Trunc. 2524 // 2525 // This corresponds to wasm.OpcodeVecF32x4TruncName wasm.OpcodeVecF64x2TruncName 2526 func NewOperationV128Trunc(shape Shape) UnionOperation { 2527 return UnionOperation{Kind: OperationKindV128Trunc, B1: shape} 2528 } 2529 2530 // NewOperationV128Nearest is a constructor for UnionOperation with OperationKindV128Nearest. 2531 // 2532 // This corresponds to wasm.OpcodeVecF32x4NearestName wasm.OpcodeVecF64x2NearestName 2533 func NewOperationV128Nearest(shape Shape) UnionOperation { 2534 return UnionOperation{Kind: OperationKindV128Nearest, B1: shape} 2535 } 2536 2537 // NewOperationV128Extend is a constructor for UnionOperation with OperationKindV128Extend. 2538 // 2539 // This corresponds to 2540 // 2541 // wasm.OpcodeVecI16x8ExtendLowI8x16SName wasm.OpcodeVecI16x8ExtendHighI8x16SName 2542 // wasm.OpcodeVecI16x8ExtendLowI8x16UName wasm.OpcodeVecI16x8ExtendHighI8x16UName 2543 // wasm.OpcodeVecI32x4ExtendLowI16x8SName wasm.OpcodeVecI32x4ExtendHighI16x8SName 2544 // wasm.OpcodeVecI32x4ExtendLowI16x8UName wasm.OpcodeVecI32x4ExtendHighI16x8UName 2545 // wasm.OpcodeVecI64x2ExtendLowI32x4SName wasm.OpcodeVecI64x2ExtendHighI32x4SName 2546 // wasm.OpcodeVecI64x2ExtendLowI32x4UName wasm.OpcodeVecI64x2ExtendHighI32x4UName 2547 // 2548 // originShape is the shape of the original lanes for extension which is 2549 // either ShapeI8x16, ShapeI16x8, or ShapeI32x4. 2550 // useLow true if it uses the lower half of vector for extension. 2551 func NewOperationV128Extend(originShape Shape, signed bool, useLow bool) UnionOperation { 2552 op := UnionOperation{Kind: OperationKindV128Extend} 2553 op.B1 = originShape 2554 if signed { 2555 op.B2 = 1 2556 } 2557 op.B3 = useLow 2558 return op 2559 } 2560 2561 // NewOperationV128ExtMul is a constructor for UnionOperation with OperationKindV128ExtMul. 2562 // 2563 // This corresponds to 2564 // 2565 // wasm.OpcodeVecI16x8ExtMulLowI8x16SName wasm.OpcodeVecI16x8ExtMulLowI8x16UName 2566 // wasm.OpcodeVecI16x8ExtMulHighI8x16SName wasm.OpcodeVecI16x8ExtMulHighI8x16UName 2567 // wasm.OpcodeVecI32x4ExtMulLowI16x8SName wasm.OpcodeVecI32x4ExtMulLowI16x8UName 2568 // wasm.OpcodeVecI32x4ExtMulHighI16x8SName wasm.OpcodeVecI32x4ExtMulHighI16x8UName 2569 // wasm.OpcodeVecI64x2ExtMulLowI32x4SName wasm.OpcodeVecI64x2ExtMulLowI32x4UName 2570 // wasm.OpcodeVecI64x2ExtMulHighI32x4SName wasm.OpcodeVecI64x2ExtMulHighI32x4UName. 2571 // 2572 // originShape is the shape of the original lanes for extension which is 2573 // either ShapeI8x16, ShapeI16x8, or ShapeI32x4. 2574 // useLow true if it uses the lower half of vector for extension. 2575 func NewOperationV128ExtMul(originShape Shape, signed bool, useLow bool) UnionOperation { 2576 op := UnionOperation{Kind: OperationKindV128ExtMul} 2577 op.B1 = originShape 2578 if signed { 2579 op.B2 = 1 2580 } 2581 op.B3 = useLow 2582 return op 2583 } 2584 2585 // NewOperationV128Q15mulrSatS is a constructor for UnionOperation with OperationKindV128Q15mulrSatS. 2586 // 2587 // This corresponds to wasm.OpcodeVecI16x8Q15mulrSatSName 2588 func NewOperationV128Q15mulrSatS() UnionOperation { 2589 return UnionOperation{Kind: OperationKindV128Q15mulrSatS} 2590 } 2591 2592 // NewOperationV128ExtAddPairwise is a constructor for UnionOperation with OperationKindV128ExtAddPairwise. 2593 // 2594 // This corresponds to 2595 // 2596 // wasm.OpcodeVecI16x8ExtaddPairwiseI8x16SName wasm.OpcodeVecI16x8ExtaddPairwiseI8x16UName 2597 // wasm.OpcodeVecI32x4ExtaddPairwiseI16x8SName wasm.OpcodeVecI32x4ExtaddPairwiseI16x8UName. 2598 // 2599 // originShape is the shape of the original lanes for extension which is 2600 // either ShapeI8x16, or ShapeI16x8. 2601 func NewOperationV128ExtAddPairwise(originShape Shape, signed bool) UnionOperation { 2602 return UnionOperation{Kind: OperationKindV128ExtAddPairwise, B1: originShape, B3: signed} 2603 } 2604 2605 // NewOperationV128FloatPromote is a constructor for UnionOperation with NewOperationV128FloatPromote. 2606 // 2607 // This corresponds to wasm.OpcodeVecF64x2PromoteLowF32x4ZeroName 2608 // This discards the higher 64-bit of a vector, and promotes two 2609 // 32-bit floats in the lower 64-bit as two 64-bit floats. 2610 func NewOperationV128FloatPromote() UnionOperation { 2611 return UnionOperation{Kind: OperationKindV128FloatPromote} 2612 } 2613 2614 // NewOperationV128FloatDemote is a constructor for UnionOperation with NewOperationV128FloatDemote. 2615 // 2616 // This corresponds to wasm.OpcodeVecF32x4DemoteF64x2ZeroName. 2617 func NewOperationV128FloatDemote() UnionOperation { 2618 return UnionOperation{Kind: OperationKindV128FloatDemote} 2619 } 2620 2621 // NewOperationV128FConvertFromI is a constructor for UnionOperation with NewOperationV128FConvertFromI. 2622 // 2623 // This corresponds to 2624 // 2625 // wasm.OpcodeVecF32x4ConvertI32x4SName wasm.OpcodeVecF32x4ConvertI32x4UName 2626 // wasm.OpcodeVecF64x2ConvertLowI32x4SName wasm.OpcodeVecF64x2ConvertLowI32x4UName. 2627 // 2628 // destinationShape is the shape of the destination lanes for conversion which is 2629 // either ShapeF32x4, or ShapeF64x2. 2630 func NewOperationV128FConvertFromI(destinationShape Shape, signed bool) UnionOperation { 2631 return UnionOperation{Kind: OperationKindV128FConvertFromI, B1: destinationShape, B3: signed} 2632 } 2633 2634 // NewOperationV128Dot is a constructor for UnionOperation with OperationKindV128Dot. 2635 // 2636 // This corresponds to wasm.OpcodeVecI32x4DotI16x8SName 2637 func NewOperationV128Dot() UnionOperation { 2638 return UnionOperation{Kind: OperationKindV128Dot} 2639 } 2640 2641 // NewOperationV128Narrow is a constructor for UnionOperation with OperationKindV128Narrow. 2642 // 2643 // This corresponds to 2644 // 2645 // wasm.OpcodeVecI8x16NarrowI16x8SName wasm.OpcodeVecI8x16NarrowI16x8UName 2646 // wasm.OpcodeVecI16x8NarrowI32x4SName wasm.OpcodeVecI16x8NarrowI32x4UName. 2647 // 2648 // originShape is the shape of the original lanes for narrowing which is 2649 // either ShapeI16x8, or ShapeI32x4. 2650 func NewOperationV128Narrow(originShape Shape, signed bool) UnionOperation { 2651 return UnionOperation{Kind: OperationKindV128Narrow, B1: originShape, B3: signed} 2652 } 2653 2654 // NewOperationV128ITruncSatFromF is a constructor for UnionOperation with OperationKindV128ITruncSatFromF. 2655 // 2656 // This corresponds to 2657 // 2658 // wasm.OpcodeVecI32x4TruncSatF64x2UZeroName wasm.OpcodeVecI32x4TruncSatF64x2SZeroName 2659 // wasm.OpcodeVecI32x4TruncSatF32x4UName wasm.OpcodeVecI32x4TruncSatF32x4SName. 2660 // 2661 // originShape is the shape of the original lanes for truncation which is 2662 // either ShapeF32x4, or ShapeF64x2. 2663 func NewOperationV128ITruncSatFromF(originShape Shape, signed bool) UnionOperation { 2664 return UnionOperation{Kind: OperationKindV128ITruncSatFromF, B1: originShape, B3: signed} 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 }