blob: ac06754ab2254b25fdb18fadebd09db37b7ba229 [file] [edit]
;;
;; Binary Format of Instructions
;;
;; Parametric instructions
grammar Binstr/parametric : instr =
| 0x00 => UNREACHABLE
| 0x01 => NOP
| 0x1A => DROP
| 0x1B => SELECT
| 0x1C t*:Blist(Bvaltype) => SELECT t*
| ...
;; Control instructions
syntax castop = (null?, null?)
grammar Bcastop : castop =
| 0x00 => (eps, eps)
| 0x01 => (NULL, eps)
| 0x02 => (eps, NULL)
| 0x03 => (NULL, NULL)
grammar Bblocktype : blocktype =
| 0x40 => _RESULT eps
| t:Bvaltype => _RESULT t
| i:Bs33 => _IDX i -- if i >= 0
grammar Binstr/block : instr = ...
| 0x02 bt:Bblocktype (in:Binstr)* 0x0B => BLOCK bt in*
| 0x03 bt:Bblocktype (in:Binstr)* 0x0B => LOOP bt in*
| 0x04 bt:Bblocktype (in:Binstr)* 0x0B => IF bt in* ELSE eps
| 0x04 bt:Bblocktype (in_1:Binstr)*
0x05 (in_2:Binstr)* 0x0B => IF bt in_1* ELSE in_2*
| ...
grammar Binstr/control : instr = ...
| 0x08 x:Btagidx => THROW x
| 0x0A => THROW_REF
| 0x0C l:Blabelidx => BR l
| 0x0D l:Blabelidx => BR_IF l
| 0x0E l*:Blist(Blabelidx) l_n:Blabelidx => BR_TABLE l* l_n
| 0x0F => RETURN
| 0x10 x:Bfuncidx => CALL x
| 0x11 y:Btypeidx x:Btableidx => CALL_INDIRECT x (_IDX y)
| 0x12 x:Bfuncidx => RETURN_CALL x
| 0x13 y:Btypeidx x:Btableidx => RETURN_CALL_INDIRECT x (_IDX y)
| 0x14 x:Btypeidx => CALL_REF (_IDX x)
| 0x15 x:Btypeidx => RETURN_CALL_REF (_IDX x)
| 0x1F bt:Bblocktype c*:Blist(Bcatch) (in:Binstr)* 0x0B => TRY_TABLE bt c* in*
| 0xD5 l:Blabelidx => BR_ON_NULL l
| 0xD6 l:Blabelidx => BR_ON_NON_NULL l
| 0xFB 24:Bu32 (null_1?, null_2?):Bcastop
l:Blabelidx ht_1:Bheaptype ht_2:Bheaptype => BR_ON_CAST l (REF null_1? ht_1) (REF null_2? ht_2)
| 0xFB 25:Bu32 (null_1?, null_2?):Bcastop
l:Blabelidx ht_1:Bheaptype ht_2:Bheaptype => BR_ON_CAST_FAIL l (REF null_1? ht_1) (REF null_2? ht_2)
| ...
grammar Bcatch : catch =
| 0x00 x:Btagidx l:Blabelidx => CATCH x l
| 0x01 x:Btagidx l:Blabelidx => CATCH_REF x l
| 0x02 l:Blabelidx => CATCH_ALL l
| 0x03 l:Blabelidx => CATCH_ALL_REF l
;; Variable instructions
grammar Binstr/local : instr = ...
| 0x20 x:Blocalidx => LOCAL.GET x
| 0x21 x:Blocalidx => LOCAL.SET x
| 0x22 x:Blocalidx => LOCAL.TEE x
| ...
grammar Binstr/global : instr = ...
| 0x23 x:Bglobalidx => GLOBAL.GET x
| 0x24 x:Bglobalidx => GLOBAL.SET x
| ...
;; Table instructions
grammar Binstr/table : instr = ...
| 0x25 x:Btableidx => TABLE.GET x
| 0x26 x:Btableidx => TABLE.SET x
| 0xFC 12:Bu32 y:Belemidx x:Btableidx => TABLE.INIT x y
| 0xFC 13:Bu32 x:Belemidx => ELEM.DROP x
| 0xFC 14:Bu32 x_1:Btableidx x_2:Btableidx => TABLE.COPY x_1 x_2
| 0xFC 15:Bu32 x:Btableidx => TABLE.GROW x
| 0xFC 16:Bu32 x:Btableidx => TABLE.SIZE x
| 0xFC 17:Bu32 x:Btableidx => TABLE.FILL x
| ...
;; Memory instructions
syntax memidxop = (memidx, memarg)
grammar Bmemarg : memidxop =
| n:Bu32 m:Bu64 => (0, {ALIGN n, OFFSET m}) -- if $(n < 2^6)
| n:Bu32 x:Bmemidx m:Bu64 => (x, {ALIGN $((n - 2^6)), OFFSET m}) -- if $(2^6 <= n < 2^7)
grammar Binstr/memory : instr = ...
| 0x28 (x,ao):Bmemarg => LOAD I32 x ao
| 0x29 (x,ao):Bmemarg => LOAD I64 x ao
| 0x2A (x,ao):Bmemarg => LOAD F32 x ao
| 0x2B (x,ao):Bmemarg => LOAD F64 x ao
| 0x2C (x,ao):Bmemarg => LOAD I32 (`8 _ S) x ao
| 0x2D (x,ao):Bmemarg => LOAD I32 (`8 _ U) x ao
| 0x2E (x,ao):Bmemarg => LOAD I32 (`16 _ S) x ao
| 0x2F (x,ao):Bmemarg => LOAD I32 (`16 _ U) x ao
| 0x30 (x,ao):Bmemarg => LOAD I64 (`8 _ S) x ao
| 0x31 (x,ao):Bmemarg => LOAD I64 (`8 _ U) x ao
| 0x32 (x,ao):Bmemarg => LOAD I64 (`16 _ S) x ao
| 0x33 (x,ao):Bmemarg => LOAD I64 (`16 _ U) x ao
| 0x34 (x,ao):Bmemarg => LOAD I64 (`32 _ S) x ao
| 0x35 (x,ao):Bmemarg => LOAD I64 (`32 _ U) x ao
| 0x36 (x,ao):Bmemarg => STORE I32 x ao
| 0x37 (x,ao):Bmemarg => STORE I64 x ao
| 0x38 (x,ao):Bmemarg => STORE F32 x ao
| 0x39 (x,ao):Bmemarg => STORE F64 x ao
| 0x3A (x,ao):Bmemarg => STORE I32 `8 x ao
| 0x3B (x,ao):Bmemarg => STORE I32 `16 x ao
| 0x3C (x,ao):Bmemarg => STORE I64 `8 x ao
| 0x3D (x,ao):Bmemarg => STORE I64 `16 x ao
| 0x3E (x,ao):Bmemarg => STORE I64 `32 x ao
| 0x3F x:Bmemidx => MEMORY.SIZE x
| 0x40 x:Bmemidx => MEMORY.GROW x
| 0xFC 8:Bu32 y:Bdataidx x:Bmemidx => MEMORY.INIT x y
| 0xFC 9:Bu32 x:Bdataidx => DATA.DROP x
| 0xFC 10:Bu32 x_1:Bmemidx x_2:Bmemidx => MEMORY.COPY x_1 x_2
| 0xFC 11:Bu32 x:Bmemidx => MEMORY.FILL x
| ...
;; Reference instructions
grammar Binstr/ref : instr = ...
| 0xD0 ht:Bheaptype => REF.NULL ht
| 0xD1 => REF.IS_NULL
| 0xD2 x:Bfuncidx => REF.FUNC x
| 0xD3 => REF.EQ
| 0xD4 => REF.AS_NON_NULL
| 0xFB 20:Bu32 ht:Bheaptype => REF.TEST (REF ht)
| 0xFB 21:Bu32 ht:Bheaptype => REF.TEST (REF NULL ht)
| 0xFB 22:Bu32 ht:Bheaptype => REF.CAST (REF ht)
| 0xFB 23:Bu32 ht:Bheaptype => REF.CAST (REF NULL ht)
| ...
grammar Binstr/struct : instr = ...
| 0xFB 0:Bu32 x:Btypeidx => STRUCT.NEW x
| 0xFB 1:Bu32 x:Btypeidx => STRUCT.NEW_DEFAULT x
| 0xFB 2:Bu32 x:Btypeidx i:Bu32 => STRUCT.GET x i
| 0xFB 3:Bu32 x:Btypeidx i:Bu32 => STRUCT.GET S x i
| 0xFB 4:Bu32 x:Btypeidx i:Bu32 => STRUCT.GET U x i
| 0xFB 5:Bu32 x:Btypeidx i:Bu32 => STRUCT.SET x i
| ...
grammar Binstr/array : instr = ...
| 0xFB 6:Bu32 x:Btypeidx => ARRAY.NEW x
| 0xFB 7:Bu32 x:Btypeidx => ARRAY.NEW_DEFAULT x
| 0xFB 8:Bu32 x:Btypeidx n:Bu32 => ARRAY.NEW_FIXED x n
| 0xFB 9:Bu32 x:Btypeidx y:Bdataidx => ARRAY.NEW_DATA x y
| 0xFB 10:Bu32 x:Btypeidx y:Belemidx => ARRAY.NEW_ELEM x y
| 0xFB 11:Bu32 x:Btypeidx => ARRAY.GET x
| 0xFB 12:Bu32 x:Btypeidx => ARRAY.GET S x
| 0xFB 13:Bu32 x:Btypeidx => ARRAY.GET U x
| 0xFB 14:Bu32 x:Btypeidx => ARRAY.SET x
| 0xFB 15:Bu32 => ARRAY.LEN
| 0xFB 16:Bu32 x:Btypeidx => ARRAY.FILL x
| 0xFB 17:Bu32 x_1:Btypeidx x_2:Btypeidx => ARRAY.COPY x_1 x_2
| 0xFB 18:Bu32 x:Btypeidx y:Bdataidx => ARRAY.INIT_DATA x y
| 0xFB 19:Bu32 x:Btypeidx y:Belemidx => ARRAY.INIT_ELEM x y
| ...
grammar Binstr/extern : instr = ...
| 0xFB 26:Bu32 => ANY.CONVERT_EXTERN
| 0xFB 27:Bu32 => EXTERN.CONVERT_ANY
| ...
grammar Binstr/i31 : instr = ...
| 0xFB 28:Bu32 => REF.I31
| 0xFB 29:Bu32 => I31.GET S
| 0xFB 30:Bu32 => I31.GET U
| ...
;; Numeric instructions
grammar Binstr/num-const : instr = ...
| 0x41 i:Bi32 => CONST I32 i
| 0x42 i:Bi64 => CONST I64 i
| 0x43 p:Bf32 => CONST F32 p
| 0x44 p:Bf64 => CONST F64 p
| ...
grammar Binstr/num-test-i32 : instr = ...
| 0x45 => TESTOP I32 EQZ
| ...
grammar Binstr/num-rel-i32 : instr = ...
| 0x46 => RELOP I32 EQ
| 0x47 => RELOP I32 NE
| 0x48 => RELOP I32 LT S
| 0x49 => RELOP I32 LT U
| 0x4A => RELOP I32 GT S
| 0x4B => RELOP I32 GT U
| 0x4C => RELOP I32 LE S
| 0x4D => RELOP I32 LE U
| 0x4E => RELOP I32 GE S
| 0x4F => RELOP I32 GE U
| ...
grammar Binstr/num-test-i64 : instr = ...
| 0x50 => TESTOP I64 EQZ
| ...
grammar Binstr/num-rel-i64 : instr = ...
| 0x51 => RELOP I64 EQ
| 0x52 => RELOP I64 NE
| 0x53 => RELOP I64 LT S
| 0x54 => RELOP I64 LT U
| 0x55 => RELOP I64 GT S
| 0x56 => RELOP I64 GT U
| 0x57 => RELOP I64 LE S
| 0x58 => RELOP I64 LE U
| 0x59 => RELOP I64 GE S
| 0x5A => RELOP I64 GE U
| ...
grammar Binstr/num-rel-f32 : instr = ...
| 0x5B => RELOP F32 EQ
| 0x5C => RELOP F32 NE
| 0x5D => RELOP F32 LT
| 0x5E => RELOP F32 GT
| 0x5F => RELOP F32 LE
| 0x60 => RELOP F32 GE
| ...
grammar Binstr/num-rel-f64 : instr = ...
| 0x61 => RELOP F64 EQ
| 0x62 => RELOP F64 NE
| 0x63 => RELOP F64 LT
| 0x64 => RELOP F64 GT
| 0x65 => RELOP F64 LE
| 0x66 => RELOP F64 GE
| ...
grammar Binstr/num-un-i32 : instr = ...
| 0x67 => UNOP I32 CLZ
| 0x68 => UNOP I32 CTZ
| 0x69 => UNOP I32 POPCNT
| ...
grammar Binstr/num-bin-i32 : instr = ...
| 0x6A => BINOP I32 ADD
| 0x6B => BINOP I32 SUB
| 0x6C => BINOP I32 MUL
| 0x6D => BINOP I32 DIV S
| 0x6E => BINOP I32 DIV U
| 0x6F => BINOP I32 REM S
| 0x70 => BINOP I32 REM U
| 0x71 => BINOP I32 AND
| 0x72 => BINOP I32 OR
| 0x73 => BINOP I32 XOR
| 0x74 => BINOP I32 SHL
| 0x75 => BINOP I32 SHR S
| 0x76 => BINOP I32 SHR U
| 0x77 => BINOP I32 ROTL
| 0x78 => BINOP I32 ROTR
| ...
grammar Binstr/num-un-i64 : instr = ...
| 0x79 => UNOP I64 CLZ
| 0x7A => UNOP I64 CTZ
| 0x7B => UNOP I64 POPCNT
| ...
grammar Binstr/num-un-ext-i32 : instr = ...
| 0xC0 => UNOP I32 EXTEND `8
| 0xC1 => UNOP I32 EXTEND `16
| ...
grammar Binstr/num-un-ext-i64 : instr = ...
| 0xC2 => UNOP I64 EXTEND `8
| 0xC3 => UNOP I64 EXTEND `16
| 0xC4 => UNOP I64 EXTEND `32
| ...
grammar Binstr/num-bin-i64 : instr = ...
| 0x7C => BINOP I64 ADD
| 0x7D => BINOP I64 SUB
| 0x7E => BINOP I64 MUL
| 0x7F => BINOP I64 DIV S
| 0x80 => BINOP I64 DIV U
| 0x81 => BINOP I64 REM S
| 0x82 => BINOP I64 REM U
| 0x83 => BINOP I64 AND
| 0x84 => BINOP I64 OR
| 0x85 => BINOP I64 XOR
| 0x86 => BINOP I64 SHL
| 0x87 => BINOP I64 SHR S
| 0x88 => BINOP I64 SHR U
| 0x89 => BINOP I64 ROTL
| 0x8A => BINOP I64 ROTR
| ...
grammar Binstr/num-un-f32 : instr = ...
| 0x8B => UNOP F32 ABS
| 0x8C => UNOP F32 NEG
| 0x8D => UNOP F32 CEIL
| 0x8E => UNOP F32 FLOOR
| 0x8F => UNOP F32 TRUNC
| 0x90 => UNOP F32 NEAREST
| 0x91 => UNOP F32 SQRT
| ...
grammar Binstr/num-bin-f32 : instr = ...
| 0x92 => BINOP F32 ADD
| 0x93 => BINOP F32 SUB
| 0x94 => BINOP F32 MUL
| 0x95 => BINOP F32 DIV
| 0x96 => BINOP F32 MIN
| 0x97 => BINOP F32 MAX
| 0x98 => BINOP F32 COPYSIGN
| ...
grammar Binstr/num-un-f64 : instr = ...
| 0x99 => UNOP F64 ABS
| 0x9A => UNOP F64 NEG
| 0x9B => UNOP F64 CEIL
| 0x9C => UNOP F64 FLOOR
| 0x9D => UNOP F64 TRUNC
| 0x9E => UNOP F64 NEAREST
| 0x9F => UNOP F64 SQRT
| ...
grammar Binstr/num-bin-f64 : instr = ...
| 0xA0 => BINOP F64 ADD
| 0xA1 => BINOP F64 SUB
| 0xA2 => BINOP F64 MUL
| 0xA3 => BINOP F64 DIV
| 0xA4 => BINOP F64 MIN
| 0xA5 => BINOP F64 MAX
| 0xA6 => BINOP F64 COPYSIGN
| ...
grammar Binstr/num-cvt : instr = ...
| 0xA7 => CVTOP I32 I64 WRAP
| 0xA8 => CVTOP I32 F32 TRUNC S
| 0xA9 => CVTOP I32 F32 TRUNC U
| 0xAA => CVTOP I32 F64 TRUNC S
| 0xAB => CVTOP I32 F64 TRUNC U
| 0xAC => CVTOP I64 I32 EXTEND S
| 0xAD => CVTOP I64 I32 EXTEND U
| 0xAE => CVTOP I64 F32 TRUNC S
| 0xAF => CVTOP I64 F32 TRUNC U
| 0xB0 => CVTOP I64 F64 TRUNC S
| 0xB1 => CVTOP I64 F64 TRUNC U
| 0xB2 => CVTOP F32 I32 CONVERT S
| 0xB3 => CVTOP F32 I32 CONVERT U
| 0xB4 => CVTOP F32 I64 CONVERT S
| 0xB5 => CVTOP F32 I64 CONVERT U
| 0xB6 => CVTOP F32 F64 DEMOTE
| 0xB7 => CVTOP F64 I32 CONVERT S
| 0xB8 => CVTOP F64 I32 CONVERT U
| 0xB9 => CVTOP F64 I64 CONVERT S
| 0xBA => CVTOP F64 I64 CONVERT U
| 0xBB => CVTOP F64 F32 PROMOTE
| 0xBC => CVTOP I32 F32 REINTERPRET
| 0xBD => CVTOP I64 F64 REINTERPRET
| 0xBE => CVTOP F32 I32 REINTERPRET
| 0xBF => CVTOP F64 I64 REINTERPRET
| ...
grammar Binstr/num-cvt-sat : instr = ...
| 0xFC 0:Bu32 => CVTOP I32 F32 TRUNC_SAT S
| 0xFC 1:Bu32 => CVTOP I32 F32 TRUNC_SAT U
| 0xFC 2:Bu32 => CVTOP I32 F64 TRUNC_SAT S
| 0xFC 3:Bu32 => CVTOP I32 F64 TRUNC_SAT U
| 0xFC 4:Bu32 => CVTOP I64 F32 TRUNC_SAT S
| 0xFC 5:Bu32 => CVTOP I64 F32 TRUNC_SAT U
| 0xFC 6:Bu32 => CVTOP I64 F64 TRUNC_SAT S
| 0xFC 7:Bu32 => CVTOP I64 F64 TRUNC_SAT U
| ...
;; Vector instructions
grammar Blaneidx : laneidx =
| l:Bbyte => l
grammar Binstr/vec-memory : instr = ...
| 0xFD 0:Bu32 (x,ao):Bmemarg => VLOAD V128 x ao
| 0xFD 1:Bu32 (x,ao):Bmemarg => VLOAD V128 (SHAPE `8 X `8 _ S) x ao
| 0xFD 2:Bu32 (x,ao):Bmemarg => VLOAD V128 (SHAPE `8 X `8 _ U) x ao
| 0xFD 3:Bu32 (x,ao):Bmemarg => VLOAD V128 (SHAPE `16 X `4 _ S) x ao
| 0xFD 4:Bu32 (x,ao):Bmemarg => VLOAD V128 (SHAPE `16 X `4 _ U) x ao
| 0xFD 5:Bu32 (x,ao):Bmemarg => VLOAD V128 (SHAPE `32 X `2 _ S) x ao
| 0xFD 6:Bu32 (x,ao):Bmemarg => VLOAD V128 (SHAPE `32 X `2 _ U) x ao
| 0xFD 7:Bu32 (x,ao):Bmemarg => VLOAD V128 (SPLAT `8) x ao
| 0xFD 8:Bu32 (x,ao):Bmemarg => VLOAD V128 (SPLAT `16) x ao
| 0xFD 9:Bu32 (x,ao):Bmemarg => VLOAD V128 (SPLAT `32) x ao
| 0xFD 10:Bu32 (x,ao):Bmemarg => VLOAD V128 (SPLAT `64) x ao
| 0xFD 11:Bu32 (x,ao):Bmemarg => VSTORE V128 x ao
| 0xFD 84:Bu32 (x,ao):Bmemarg i:Blaneidx => VLOAD_LANE V128 `8 x ao i
| 0xFD 85:Bu32 (x,ao):Bmemarg i:Blaneidx => VLOAD_LANE V128 `16 x ao i
| 0xFD 86:Bu32 (x,ao):Bmemarg i:Blaneidx => VLOAD_LANE V128 `32 x ao i
| 0xFD 87:Bu32 (x,ao):Bmemarg i:Blaneidx => VLOAD_LANE V128 `64 x ao i
| 0xFD 88:Bu32 (x,ao):Bmemarg i:Blaneidx => VSTORE_LANE V128 `8 x ao i
| 0xFD 89:Bu32 (x,ao):Bmemarg i:Blaneidx => VSTORE_LANE V128 `16 x ao i
| 0xFD 90:Bu32 (x,ao):Bmemarg i:Blaneidx => VSTORE_LANE V128 `32 x ao i
| 0xFD 91:Bu32 (x,ao):Bmemarg i:Blaneidx => VSTORE_LANE V128 `64 x ao i
| 0xFD 92:Bu32 (x,ao):Bmemarg => VLOAD V128 (ZERO `32) x ao
| 0xFD 93:Bu32 (x,ao):Bmemarg => VLOAD V128 (ZERO `64) x ao
| ...
grammar Binstr/vec-const : instr = ...
| 0xFD 12:Bu32 (b:Bbyte)^16 => VCONST V128 $inv_ibytes_(`128, (b)^16)
| ...
grammar Binstr/vec-shuffle : instr = ...
| 0xFD 13:Bu32 (l:Blaneidx)^16 => VSHUFFLE (I8 X `16) l^16
| 0xFD 14:Bu32 => VSWIZZLOP (I8 X `16) SWIZZLE
| 0xFD 256:Bu32 => VSWIZZLOP (I8 X `16) RELAXED_SWIZZLE
| ...
grammar Binstr/vec-splat : instr = ...
| 0xFD 15:Bu32 => VSPLAT (I8 X `16)
| 0xFD 16:Bu32 => VSPLAT (I16 X `8)
| 0xFD 17:Bu32 => VSPLAT (I32 X `4)
| 0xFD 18:Bu32 => VSPLAT (I64 X `2)
| 0xFD 19:Bu32 => VSPLAT (F32 X `4)
| 0xFD 20:Bu32 => VSPLAT (F64 X `2)
| ...
grammar Binstr/vec-lane : instr = ...
| 0xFD 21:Bu32 l:Blaneidx => VEXTRACT_LANE (I8 X `16) S l
| 0xFD 22:Bu32 l:Blaneidx => VEXTRACT_LANE (I8 X `16) U l
| 0xFD 23:Bu32 l:Blaneidx => VREPLACE_LANE (I8 X `16) l
| 0xFD 24:Bu32 l:Blaneidx => VEXTRACT_LANE (I16 X `8) S l
| 0xFD 25:Bu32 l:Blaneidx => VEXTRACT_LANE (I16 X `8) U l
| 0xFD 26:Bu32 l:Blaneidx => VREPLACE_LANE (I16 X `8) l
| 0xFD 27:Bu32 l:Blaneidx => VEXTRACT_LANE (I32 X `4) l
| 0xFD 28:Bu32 l:Blaneidx => VREPLACE_LANE (I32 X `4) l
| 0xFD 29:Bu32 l:Blaneidx => VEXTRACT_LANE (I64 X `2) l
| 0xFD 30:Bu32 l:Blaneidx => VREPLACE_LANE (I64 X `2) l
| 0xFD 31:Bu32 l:Blaneidx => VEXTRACT_LANE (F32 X `4) l
| 0xFD 32:Bu32 l:Blaneidx => VREPLACE_LANE (F32 X `4) l
| 0xFD 33:Bu32 l:Blaneidx => VEXTRACT_LANE (F64 X `2) l
| 0xFD 34:Bu32 l:Blaneidx => VREPLACE_LANE (F64 X `2) l
| ...
grammar Binstr/vec-rel-i8x16 : instr = ...
| 0xFD 35:Bu32 => VRELOP (I8 X `16) EQ
| 0xFD 36:Bu32 => VRELOP (I8 X `16) NE
| 0xFD 37:Bu32 => VRELOP (I8 X `16) LT S
| 0xFD 38:Bu32 => VRELOP (I8 X `16) LT U
| 0xFD 39:Bu32 => VRELOP (I8 X `16) GT S
| 0xFD 40:Bu32 => VRELOP (I8 X `16) GT U
| 0xFD 41:Bu32 => VRELOP (I8 X `16) LE S
| 0xFD 42:Bu32 => VRELOP (I8 X `16) LE U
| 0xFD 43:Bu32 => VRELOP (I8 X `16) GE S
| 0xFD 44:Bu32 => VRELOP (I8 X `16) GE U
| ...
grammar Binstr/vec-rel-i16x8 : instr = ...
| 0xFD 45:Bu32 => VRELOP (I16 X `8) EQ
| 0xFD 46:Bu32 => VRELOP (I16 X `8) NE
| 0xFD 47:Bu32 => VRELOP (I16 X `8) LT S
| 0xFD 48:Bu32 => VRELOP (I16 X `8) LT U
| 0xFD 49:Bu32 => VRELOP (I16 X `8) GT S
| 0xFD 50:Bu32 => VRELOP (I16 X `8) GT U
| 0xFD 51:Bu32 => VRELOP (I16 X `8) LE S
| 0xFD 52:Bu32 => VRELOP (I16 X `8) LE U
| 0xFD 53:Bu32 => VRELOP (I16 X `8) GE S
| 0xFD 54:Bu32 => VRELOP (I16 X `8) GE U
| ...
grammar Binstr/vec-rel-i32x4 : instr = ...
| 0xFD 55:Bu32 => VRELOP (I32 X `4) EQ
| 0xFD 56:Bu32 => VRELOP (I32 X `4) NE
| 0xFD 57:Bu32 => VRELOP (I32 X `4) LT S
| 0xFD 58:Bu32 => VRELOP (I32 X `4) LT U
| 0xFD 59:Bu32 => VRELOP (I32 X `4) GT S
| 0xFD 60:Bu32 => VRELOP (I32 X `4) GT U
| 0xFD 61:Bu32 => VRELOP (I32 X `4) LE S
| 0xFD 62:Bu32 => VRELOP (I32 X `4) LE U
| 0xFD 63:Bu32 => VRELOP (I32 X `4) GE S
| 0xFD 64:Bu32 => VRELOP (I32 X `4) GE U
| ...
grammar Binstr/vec-rel-f32x4 : instr = ...
| 0xFD 65:Bu32 => VRELOP (F32 X `4) EQ
| 0xFD 66:Bu32 => VRELOP (F32 X `4) NE
| 0xFD 67:Bu32 => VRELOP (F32 X `4) LT
| 0xFD 68:Bu32 => VRELOP (F32 X `4) GT
| 0xFD 69:Bu32 => VRELOP (F32 X `4) LE
| 0xFD 70:Bu32 => VRELOP (F32 X `4) GE
| ...
grammar Binstr/vec-rel-f64x2 : instr = ...
| 0xFD 71:Bu32 => VRELOP (F64 X `2) EQ
| 0xFD 72:Bu32 => VRELOP (F64 X `2) NE
| 0xFD 73:Bu32 => VRELOP (F64 X `2) LT
| 0xFD 74:Bu32 => VRELOP (F64 X `2) GT
| 0xFD 75:Bu32 => VRELOP (F64 X `2) LE
| 0xFD 76:Bu32 => VRELOP (F64 X `2) GE
| ...
grammar Binstr/vec-un-v128 : instr = ...
| 0xFD 77:Bu32 => VVUNOP V128 NOT
| ...
grammar Binstr/vec-bin-v128 : instr = ...
| 0xFD 78:Bu32 => VVBINOP V128 AND
| 0xFD 79:Bu32 => VVBINOP V128 ANDNOT
| 0xFD 80:Bu32 => VVBINOP V128 OR
| 0xFD 81:Bu32 => VVBINOP V128 XOR
| ...
grammar Binstr/vec-tern-v128 : instr = ...
| 0xFD 82:Bu32 => VVTERNOP V128 BITSELECT
| ...
grammar Binstr/vec-test-v128 : instr = ...
| 0xFD 83:Bu32 => VVTESTOP V128 ANY_TRUE
| ...
grammar Binstr/vec-un-i8x16 : instr = ...
| 0xFD 96:Bu32 => VUNOP (I8 X `16) ABS
| 0xFD 97:Bu32 => VUNOP (I8 X `16) NEG
| 0xFD 98:Bu32 => VUNOP (I8 X `16) POPCNT
| ...
grammar Binstr/vec-test-i8x16 : instr = ...
| 0xFD 99:Bu32 => VTESTOP (I8 X `16) ALL_TRUE
| ...
grammar Binstr/vec-bitmask-i8x16 : instr = ...
| 0xFD 100:Bu32 => VBITMASK (I8 X `16)
| ...
grammar Binstr/vec-narrow-i8x16 : instr = ...
| 0xFD 101:Bu32 => VNARROW (I8 X `16) (I16 X `8) S
| 0xFD 102:Bu32 => VNARROW (I8 X `16) (I16 X `8) U
| ...
grammar Binstr/vec-shift-i8x16 : instr = ...
| 0xFD 107:Bu32 => VSHIFTOP (I8 X `16) SHL
| 0xFD 108:Bu32 => VSHIFTOP (I8 X `16) SHR S
| 0xFD 109:Bu32 => VSHIFTOP (I8 X `16) SHR U
| ...
grammar Binstr/vec-bin-i8x16 : instr = ...
| 0xFD 110:Bu32 => VBINOP (I8 X `16) ADD
| 0xFD 111:Bu32 => VBINOP (I8 X `16) ADD_SAT S
| 0xFD 112:Bu32 => VBINOP (I8 X `16) ADD_SAT U
| 0xFD 113:Bu32 => VBINOP (I8 X `16) SUB
| 0xFD 114:Bu32 => VBINOP (I8 X `16) SUB_SAT S
| 0xFD 115:Bu32 => VBINOP (I8 X `16) SUB_SAT U
| 0xFD 118:Bu32 => VBINOP (I8 X `16) MIN S
| 0xFD 119:Bu32 => VBINOP (I8 X `16) MIN U
| 0xFD 120:Bu32 => VBINOP (I8 X `16) MAX S
| 0xFD 121:Bu32 => VBINOP (I8 X `16) MAX U
| 0xFD 123:Bu32 => VBINOP (I8 X `16) AVGR U
| ...
grammar Binstr/vec-extun-i16x8 : instr = ...
| 0xFD 124:Bu32 => VEXTUNOP (I16 X `8) (I8 X `16) EXTADD_PAIRWISE S
| 0xFD 125:Bu32 => VEXTUNOP (I16 X `8) (I8 X `16) EXTADD_PAIRWISE U
| ...
grammar Binstr/vec-un-i16x8 : instr = ...
| 0xFD 128:Bu32 => VUNOP (I16 X `8) ABS
| 0xFD 129:Bu32 => VUNOP (I16 X `8) NEG
| ...
grammar Binstr/vec-bin-i16x8 : instr = ...
| 0xFD 130:Bu32 => VBINOP (I16 X `8) Q15MULR_SAT S
| 0xFD 142:Bu32 => VBINOP (I16 X `8) ADD
| 0xFD 143:Bu32 => VBINOP (I16 X `8) ADD_SAT S
| 0xFD 144:Bu32 => VBINOP (I16 X `8) ADD_SAT U
| 0xFD 145:Bu32 => VBINOP (I16 X `8) SUB
| 0xFD 146:Bu32 => VBINOP (I16 X `8) SUB_SAT S
| 0xFD 147:Bu32 => VBINOP (I16 X `8) SUB_SAT U
| 0xFD 149:Bu32 => VBINOP (I16 X `8) MUL
| 0xFD 150:Bu32 => VBINOP (I16 X `8) MIN S
| 0xFD 151:Bu32 => VBINOP (I16 X `8) MIN U
| 0xFD 152:Bu32 => VBINOP (I16 X `8) MAX S
| 0xFD 153:Bu32 => VBINOP (I16 X `8) MAX U
| 0xFD 155:Bu32 => VBINOP (I16 X `8) AVGR U
| 0xFD 273:Bu32 => VBINOP (I16 X `8) RELAXED_Q15MULR S
| ...
grammar Binstr/vec-test-i16x8 : instr = ...
| 0xFD 131:Bu32 => VTESTOP (I16 X `8) ALL_TRUE
| ...
grammar Binstr/vec-bitmask-i16x8 : instr = ...
| 0xFD 132:Bu32 => VBITMASK (I16 X `8)
| ...
grammar Binstr/vec-narrow-i16x8 : instr = ...
| 0xFD 133:Bu32 => VNARROW (I16 X `8) (I32 X `4) S
| 0xFD 134:Bu32 => VNARROW (I16 X `8) (I32 X `4) U
| ...
grammar Binstr/vec-ext-i16x8 : instr = ...
| 0xFD 135:Bu32 => VCVTOP (I16 X `8) (I8 X `16) EXTEND LOW S
| 0xFD 136:Bu32 => VCVTOP (I16 X `8) (I8 X `16) EXTEND HIGH S
| 0xFD 137:Bu32 => VCVTOP (I16 X `8) (I8 X `16) EXTEND LOW U
| 0xFD 138:Bu32 => VCVTOP (I16 X `8) (I8 X `16) EXTEND HIGH U
| ...
grammar Binstr/vec-shift-i16x8 : instr = ...
| 0xFD 139:Bu32 => VSHIFTOP (I16 X `8) SHL
| 0xFD 140:Bu32 => VSHIFTOP (I16 X `8) SHR S
| 0xFD 141:Bu32 => VSHIFTOP (I16 X `8) SHR U
| ...
grammar Binstr/vec-extbin-i16x8 : instr = ...
| 0xFD 156:Bu32 => VEXTBINOP (I16 X `8) (I8 X `16) EXTMUL LOW S
| 0xFD 157:Bu32 => VEXTBINOP (I16 X `8) (I8 X `16) EXTMUL HIGH S
| 0xFD 158:Bu32 => VEXTBINOP (I16 X `8) (I8 X `16) EXTMUL LOW U
| 0xFD 159:Bu32 => VEXTBINOP (I16 X `8) (I8 X `16) EXTMUL HIGH U
| 0xFD 274:Bu32 => VEXTBINOP (I16 X `8) (I8 X `16) RELAXED_DOT S
| ...
grammar Binstr/vec-extun-i32x4 : instr = ...
| 0xFD 126:Bu32 => VEXTUNOP (I32 X `4) (I16 X `8) EXTADD_PAIRWISE S
| 0xFD 127:Bu32 => VEXTUNOP (I32 X `4) (I16 X `8) EXTADD_PAIRWISE U
| ...
grammar Binstr/vec-un-i32x4 : instr = ...
| 0xFD 160:Bu32 => VUNOP (I32 X `4) ABS
| 0xFD 161:Bu32 => VUNOP (I32 X `4) NEG
| ...
grammar Binstr/vec-test-i32x4 : instr = ...
| 0xFD 163:Bu32 => VTESTOP (I32 X `4) ALL_TRUE
| ...
grammar Binstr/vec-bitmask-i32x4 : instr = ...
| 0xFD 164:Bu32 => VBITMASK (I32 X `4)
| ...
grammar Binstr/vec-ext-i32x4 : instr = ...
| 0xFD 167:Bu32 => VCVTOP (I32 X `4) (I16 X `8) EXTEND LOW S
| 0xFD 168:Bu32 => VCVTOP (I32 X `4) (I16 X `8) EXTEND HIGH S
| 0xFD 169:Bu32 => VCVTOP (I32 X `4) (I16 X `8) EXTEND LOW U
| 0xFD 170:Bu32 => VCVTOP (I32 X `4) (I16 X `8) EXTEND HIGH U
| ...
grammar Binstr/vec-shift-i32x4 : instr = ...
| 0xFD 171:Bu32 => VSHIFTOP (I32 X `4) SHL
| 0xFD 172:Bu32 => VSHIFTOP (I32 X `4) (SHR S)
| 0xFD 173:Bu32 => VSHIFTOP (I32 X `4) (SHR U)
| ...
grammar Binstr/vec-bin-i32x4 : instr = ...
| 0xFD 174:Bu32 => VBINOP (I32 X `4) ADD
| 0xFD 177:Bu32 => VBINOP (I32 X `4) SUB
| 0xFD 181:Bu32 => VBINOP (I32 X `4) MUL
| 0xFD 182:Bu32 => VBINOP (I32 X `4) MIN S
| 0xFD 183:Bu32 => VBINOP (I32 X `4) MIN U
| 0xFD 184:Bu32 => VBINOP (I32 X `4) MAX S
| 0xFD 185:Bu32 => VBINOP (I32 X `4) MAX U
| ...
grammar Binstr/vec-extbin-i32x4 : instr = ...
| 0xFD 186:Bu32 => VEXTBINOP (I32 X `4) (I16 X `8) DOT S
| 0xFD 188:Bu32 => VEXTBINOP (I32 X `4) (I16 X `8) EXTMUL LOW S
| 0xFD 189:Bu32 => VEXTBINOP (I32 X `4) (I16 X `8) EXTMUL HIGH S
| 0xFD 190:Bu32 => VEXTBINOP (I32 X `4) (I16 X `8) EXTMUL LOW U
| 0xFD 191:Bu32 => VEXTBINOP (I32 X `4) (I16 X `8) EXTMUL HIGH U
| ...
grammar Binstr/vec-exttern-i32x4 : instr = ...
| 0xFD 275:Bu32 => VEXTTERNOP (I32 X `4) (I16 X `8) RELAXED_DOT_ADD S
| ...
grammar Binstr/vec-un-i64x2 : instr = ...
| 0xFD 192:Bu32 => VUNOP (I64 X `2) ABS
| 0xFD 193:Bu32 => VUNOP (I64 X `2) NEG
| ...
grammar Binstr/vec-test-i64x2 : instr = ...
| 0xFD 195:Bu32 => VTESTOP (I64 X `2) ALL_TRUE
| ...
grammar Binstr/vec-bitmask-i64x2 : instr = ...
| 0xFD 196:Bu32 => VBITMASK (I64 X `2)
| ...
grammar Binstr/vec-ext-i64x2 : instr = ...
| 0xFD 199:Bu32 => VCVTOP (I64 X `2) (I32 X `4) EXTEND LOW S
| 0xFD 200:Bu32 => VCVTOP (I64 X `2) (I32 X `4) EXTEND HIGH S
| 0xFD 201:Bu32 => VCVTOP (I64 X `2) (I32 X `4) EXTEND LOW U
| 0xFD 202:Bu32 => VCVTOP (I64 X `2) (I32 X `4) EXTEND HIGH U
| ...
grammar Binstr/vec-shift-i64x2 : instr = ...
| 0xFD 203:Bu32 => VSHIFTOP (I64 X `2) SHL
| 0xFD 204:Bu32 => VSHIFTOP (I64 X `2) (SHR S)
| 0xFD 205:Bu32 => VSHIFTOP (I64 X `2) (SHR U)
| ...
grammar Binstr/vec-bin-i64x2 : instr = ...
| 0xFD 206:Bu32 => VBINOP (I64 X `2) ADD
| 0xFD 209:Bu32 => VBINOP (I64 X `2) SUB
| 0xFD 213:Bu32 => VBINOP (I64 X `2) MUL
| ...
grammar Binstr/vec-rel-i64x2 : instr = ...
| 0xFD 214:Bu32 => VRELOP (I64 X `2) EQ
| 0xFD 215:Bu32 => VRELOP (I64 X `2) NE
| 0xFD 216:Bu32 => VRELOP (I64 X `2) (LT S)
| 0xFD 217:Bu32 => VRELOP (I64 X `2) (GT S)
| 0xFD 218:Bu32 => VRELOP (I64 X `2) (LE S)
| 0xFD 219:Bu32 => VRELOP (I64 X `2) (GE S)
| ...
grammar Binstr/vec-extbin-i64x2 : instr = ...
| 0xFD 220:Bu32 => VEXTBINOP (I64 X `2) (I32 X `4) EXTMUL LOW S
| 0xFD 221:Bu32 => VEXTBINOP (I64 X `2) (I32 X `4) EXTMUL HIGH S
| 0xFD 222:Bu32 => VEXTBINOP (I64 X `2) (I32 X `4) EXTMUL LOW U
| 0xFD 223:Bu32 => VEXTBINOP (I64 X `2) (I32 X `4) EXTMUL HIGH U
| ...
grammar Binstr/vec-un-f32x4 : instr = ...
| 0xFD 103:Bu32 => VUNOP (F32 X `4) CEIL
| 0xFD 104:Bu32 => VUNOP (F32 X `4) FLOOR
| 0xFD 105:Bu32 => VUNOP (F32 X `4) TRUNC
| 0xFD 106:Bu32 => VUNOP (F32 X `4) NEAREST
| 0xFD 224:Bu32 => VUNOP (F32 X `4) ABS
| 0xFD 225:Bu32 => VUNOP (F32 X `4) NEG
| 0xFD 227:Bu32 => VUNOP (F32 X `4) SQRT
| ...
grammar Binstr/vec-bin-f32x4 : instr = ...
| 0xFD 228:Bu32 => VBINOP (F32 X `4) ADD
| 0xFD 229:Bu32 => VBINOP (F32 X `4) SUB
| 0xFD 230:Bu32 => VBINOP (F32 X `4) MUL
| 0xFD 231:Bu32 => VBINOP (F32 X `4) DIV
| 0xFD 232:Bu32 => VBINOP (F32 X `4) MIN
| 0xFD 233:Bu32 => VBINOP (F32 X `4) MAX
| 0xFD 234:Bu32 => VBINOP (F32 X `4) PMIN
| 0xFD 235:Bu32 => VBINOP (F32 X `4) PMAX
| 0xFD 269:Bu32 => VBINOP (F32 X `4) RELAXED_MIN
| 0xFD 270:Bu32 => VBINOP (F32 X `4) RELAXED_MAX
| ...
grammar Binstr/vec-tern-f32x4 : instr = ...
| 0xFD 261:Bu32 => VTERNOP (F32 X `4) RELAXED_MADD
| 0xFD 262:Bu32 => VTERNOP (F32 X `4) RELAXED_NMADD
| ...
grammar Binstr/vec-un-f64x2 : instr = ...
| 0xFD 116:Bu32 => VUNOP (F64 X `2) CEIL
| 0xFD 117:Bu32 => VUNOP (F64 X `2) FLOOR
| 0xFD 122:Bu32 => VUNOP (F64 X `2) TRUNC
| 0xFD 148:Bu32 => VUNOP (F64 X `2) NEAREST
| 0xFD 236:Bu32 => VUNOP (F64 X `2) ABS
| 0xFD 237:Bu32 => VUNOP (F64 X `2) NEG
| 0xFD 239:Bu32 => VUNOP (F64 X `2) SQRT
| ...
grammar Binstr/vec-bin-f64x2 : instr = ...
| 0xFD 240:Bu32 => VBINOP (F64 X `2) ADD
| 0xFD 241:Bu32 => VBINOP (F64 X `2) SUB
| 0xFD 242:Bu32 => VBINOP (F64 X `2) MUL
| 0xFD 243:Bu32 => VBINOP (F64 X `2) DIV
| 0xFD 244:Bu32 => VBINOP (F64 X `2) MIN
| 0xFD 245:Bu32 => VBINOP (F64 X `2) MAX
| 0xFD 246:Bu32 => VBINOP (F64 X `2) PMIN
| 0xFD 247:Bu32 => VBINOP (F64 X `2) PMAX
| 0xFD 271:Bu32 => VBINOP (F64 X `2) RELAXED_MIN
| 0xFD 272:Bu32 => VBINOP (F64 X `2) RELAXED_MAX
| ...
grammar Binstr/vec-tern-f64x2 : instr = ...
| 0xFD 263:Bu32 => VTERNOP (F64 X `2) RELAXED_MADD
| 0xFD 264:Bu32 => VTERNOP (F64 X `2) RELAXED_NMADD
| 0xFD 265:Bu32 => VTERNOP (I8 X `16) RELAXED_LANESELECT
| 0xFD 266:Bu32 => VTERNOP (I16 X `8) RELAXED_LANESELECT
| 0xFD 267:Bu32 => VTERNOP (I32 X `4) RELAXED_LANESELECT
| 0xFD 268:Bu32 => VTERNOP (I64 X `2) RELAXED_LANESELECT
| ...
grammar Binstr/vec-cvt : instr = ...
| 0xFD 94:Bu32 => VCVTOP (F32 X `4) (F64 X `2) DEMOTE ZERO
| 0xFD 95:Bu32 => VCVTOP (F64 X `2) (F32 X `4) PROMOTE LOW
| 0xFD 248:Bu32 => VCVTOP (I32 X `4) (F32 X `4) TRUNC_SAT S
| 0xFD 249:Bu32 => VCVTOP (I32 X `4) (F32 X `4) TRUNC_SAT U
| 0xFD 250:Bu32 => VCVTOP (F32 X `4) (I32 X `4) CONVERT S
| 0xFD 251:Bu32 => VCVTOP (F32 X `4) (I32 X `4) CONVERT U
| 0xFD 252:Bu32 => VCVTOP (I32 X `4) (F64 X `2) TRUNC_SAT S ZERO
| 0xFD 253:Bu32 => VCVTOP (I32 X `4) (F64 X `2) TRUNC_SAT U ZERO
| 0xFD 254:Bu32 => VCVTOP (F64 X `2) (I32 X `4) CONVERT LOW S
| 0xFD 255:Bu32 => VCVTOP (F64 X `2) (I32 X `4) CONVERT LOW U
| 0xFD 257:Bu32 => VCVTOP (I32 X `4) (F32 X `4) RELAXED_TRUNC S
| 0xFD 258:Bu32 => VCVTOP (I32 X `4) (F32 X `4) RELAXED_TRUNC U
| 0xFD 259:Bu32 => VCVTOP (I32 X `4) (F64 X `2) RELAXED_TRUNC S ZERO
| 0xFD 260:Bu32 => VCVTOP (I32 X `4) (F64 X `2) RELAXED_TRUNC U ZERO
;; Expressions
grammar Bexpr : expr =
| (in:Binstr)* 0x0B => in*