blob: bdc300bf6eabd933e19dfdb09d307fcd094e5758 [file] [log] [blame] [edit]
;;
;; Text Format of Instructions
;;
;; Labels
grammar Tlabel_(I) : (name?, I) =
| eps => (eps, {LABELS eps} ++ I)
| id:Tid => (id, {LABELS id} ++ I) -- if ~(id <- I.LABELS)
| id:Tid => (id, {LABELS id} ++ I[.LABELS[x] = eps]) -- if id = I.LABELS[x]
;; Instruction forms
grammar Tinstr_(I) : instr =
| in:Tplaininstr_(I) => in
| in:Tblockinstr_(I) => in
grammar Tinstrs_(I) : instr* =
| in*:Tinstr_(I)* => in*
| ...
grammar Tinstrs_(I)/folded : instr* = ...
| in**:Tfoldedinstr_(I)* => $concat_(instr, in**)
grammar Tfoldedinstr_(I)/plain : instr* =
| "(" in:Tplaininstr_(I) in'*:Tinstrs_(I) ")" => in'* in
| ...
grammar Tfoldedinstr_(I)/block : instr* = ...
| "(" "block" (id?,I'):Tlabel_(I) bt:Tblocktype_(I) in*:Tinstrs_(I') ")" =>
BLOCK bt in*
| "(" "loop" (id?,I'):Tlabel_(I) bt:Tblocktype_(I) in*:Tinstrs_(I') ")" =>
LOOP bt in*
| "(" "if" (id?,I'):Tlabel_(I) bt:Tblocktype_(I) in*:Tinstrs_(I')
"(" "then" in_1*:Tinstrs_(I') ")"
("(" "else" in_2*:Tinstrs_(I') ")")? ")" =>
in* (IF bt in_1* ELSE in_2*)
| "(" "try_table" (id?,I'):Tlabel_(I) bt:Tblocktype_(I) c*:Tcatch_(I)* in*:Tinstrs_(I') ")" =>
TRY_TABLE bt c* in*
;; Parametric instructions
grammar Tplaininstr_(I)/parametric : instr =
| "unreachable" => UNREACHABLE
| "nop" => NOP
| "drop" => DROP
| "select" t?:Tresult_(I)? => SELECT t?
| ...
;; Block instructions
grammar Tblocktype_(I) : blocktype =
| t?:Tresult_(I)? => _RESULT t?
| (x,I'):Ttypeuse_(I) => _IDX x -- if I' = {LOCALS (eps)*}
grammar Tblockinstr_(I) : instr =
| "block" (id?,I'):Tlabel_(I) bt:Tblocktype_(I) in*:Tinstrs_(I') "end" id'?:Tid? =>
BLOCK bt in*
-- if id'? = eps \/ id'? = id?
| "loop" (id?,I'):Tlabel_(I) bt:Tblocktype_(I) in*:Tinstrs_(I') "end" id'?:Tid? =>
LOOP bt in*
-- if id'? = eps \/ id'? = id?
| "if" (id?,I'):Tlabel_(I) bt:Tblocktype_(I) in_1*:Tinstrs_(I') "else" id_1?:Tid? in_2*:Tinstrs_(I') "end" id_2?:Tid? =>
IF bt in_1* ELSE in_2*
-- if (id_1? = eps \/ id_1? = id?) /\ (id_2? = eps \/ id_2? = id?)
| "try_table" (id?,I'):Tlabel_(I) bt:Tblocktype_(I) c*:Tcatch_(I)* in*:Tinstrs_(I') "end" id'?:Tid? =>
TRY_TABLE bt c* in*
-- if id'? = eps \/ id'? = id?
| ...
grammar Tblockinstr_(I)/abbrev : instr = ...
| "if" Tlabel_(I) Tblocktype_(I) Tinstrs_(I) "end" Tid? ==
"if" Tlabel_(I) Tblocktype_(I) Tinstrs_(I) "else" "end" Tid?
grammar Tcatch_(I) : catch =
| "(" "catch" x:Ttagidx_(I) l:Tlabelidx_(I) ")" => CATCH x l
| "(" "catch_ref" x:Ttagidx_(I) l:Tlabelidx_(I) ")" => CATCH_REF x l
| "(" "catch_all" l:Tlabelidx_(I) ")" => CATCH_ALL l
| "(" "catch_all_ref" l:Tlabelidx_(I) ")" => CATCH_ALL_REF l
;; Plain control instructions
grammar Tplaininstr_(I)/br : instr = ...
| "br" l:Tlabelidx_(I) => BR l
| "br_if" l:Tlabelidx_(I) => BR_IF l
| "br_table" l*:Tlabelidx_(I)* l':Tlabelidx_(I) => BR_TABLE l* l'
| "br_on_null" l:Tlabelidx_(I) => BR_ON_NULL l
| "br_on_non_null" l:Tlabelidx_(I) => BR_ON_NON_NULL l
| "br_on_cast" l:Tlabelidx_(I) rt_1:Treftype_(I) rt_2:Treftype_(I) => BR_ON_CAST l rt_1 rt_2
| "br_on_cast_fail" l:Tlabelidx_(I) rt_1:Treftype_(I) rt_2:Treftype_(I) => BR_ON_CAST_FAIL l rt_1 rt_2
| ...
grammar Tplaininstr_(I)/func : instr = ...
| "call" x:Tfuncidx_(I) => CALL x
| "call_ref" x:Ttypeidx_(I) => CALL_REF $($(_IDX x))
| "call_indirect" x:Ttableidx_(I) (y,I'):Ttypeuse_(I) => CALL_INDIRECT x $($(_IDX y))
-- if I' = {LOCALS (eps)*}
| "return" => RETURN
| "return_call" x:Tfuncidx_(I) => RETURN_CALL x
| "return_call_ref" x:Ttypeidx_(I) => RETURN_CALL_REF $($(_IDX x))
| "return_call_indirect" x:Ttableidx_(I) (y,I'):Ttypeuse_(I) => RETURN_CALL_INDIRECT x $($(_IDX y))
-- if I' = {LOCALS (eps)*}
| ...
grammar Tplaininstr_(I)/func/abbrev : instr = ...
| "call_indirect" Ttypeuse_(I) == "call_indirect" "0" Ttypeuse_(I)
| "return_call_indirect" Ttypeuse_(I) == "return_call_indirect" "0" Ttypeuse_(I)
| ...
grammar Tplaininstr_(I)/exn : instr = ...
| "throw" x:Ttagidx_(I) => THROW x
| "throw_ref" => THROW_REF
| ...
;; Variable instructions
grammar Tplaininstr_(I)/local : instr = ...
| "local.get" x:Tlocalidx_(I) => LOCAL.GET x
| "local.set" x:Tlocalidx_(I) => LOCAL.SET x
| "local.tee" x:Tlocalidx_(I) => LOCAL.TEE x
| ...
grammar Tplaininstr_(I)/global : instr = ...
| "global.get" x:Tglobalidx_(I) => GLOBAL.GET x
| "global.set" x:Tglobalidx_(I) => GLOBAL.SET x
| ...
;; Table instructions
grammar Tplaininstr_(I)/table : instr = ...
| "table.get" x:Ttableidx_(I) => TABLE.GET x
| "table.set" x:Ttableidx_(I) => TABLE.SET x
| "table.size" x:Ttableidx_(I) => TABLE.SIZE x
| "table.grow" x:Ttableidx_(I) => TABLE.GROW x
| "table.fill" x:Ttableidx_(I) => TABLE.FILL x
| "table.copy" x_1:Ttableidx_(I) x_2:Ttableidx_(I) => TABLE.COPY x_1 x_2
| "table.init" x:Ttableidx_(I) y:Telemidx_(I) => TABLE.INIT x y
| ...
grammar Tplaininstr_(I)/table/abbrev : instr = ...
| "table.get" == "table.get" "0"
| "table.set" == "table.set" "0"
| "table.size" == "table.size" "0"
| "table.grow" == "table.grow" "0"
| "table.fill" == "table.fill" "0"
| "table.copy" == "table.copy" "0" "0"
| "table.init" Telemidx_(I) == "table.init" "0" Telemidx_(I)
| ...
grammar Tplaininstr_(I)/elem : instr = ...
| "elem.drop" x:Telemidx_(I) => ELEM.DROP x
| ...
;; Memory instructions
grammar Tmemarg_(N) : memarg =
| n:Toffset m:Talign_(N) => {ALIGN n, OFFSET m}
grammar Toffset : u64 =
| "offset=" n:Tu64 => n
grammar Talign_(N) : u64 =
| "align=" m:Tu64 => m -- if $(m = 2^n)
grammar Tlaneidx : laneidx =
| i:Tu8 => i
grammar Tplaininstr_(I)/memory : instr = ...
| "i32.load" x:Tmemidx_(I) ao:Tmemarg_(4) => LOAD I32 x ao
| "i64.load" x:Tmemidx_(I) ao:Tmemarg_(8) => LOAD I64 x ao
| "f32.load" x:Tmemidx_(I) ao:Tmemarg_(4) => LOAD F32 x ao
| "f64.load" x:Tmemidx_(I) ao:Tmemarg_(8) => LOAD F64 x ao
| "i32.load8_s" x:Tmemidx_(I) ao:Tmemarg_(1) => LOAD I32 (`8 _ S) x ao
| "i32.load8_u" x:Tmemidx_(I) ao:Tmemarg_(1) => LOAD I32 (`8 _ U) x ao
| "i32.load16_s" x:Tmemidx_(I) ao:Tmemarg_(2) => LOAD I32 (`16 _ S) x ao
| "i32.load16_u" x:Tmemidx_(I) ao:Tmemarg_(2) => LOAD I32 (`16 _ U) x ao
| "i64.load8_s" x:Tmemidx_(I) ao:Tmemarg_(1) => LOAD I64 (`8 _ S) x ao
| "i64.load8_u" x:Tmemidx_(I) ao:Tmemarg_(1) => LOAD I64 (`8 _ U) x ao
| "i64.load16_s" x:Tmemidx_(I) ao:Tmemarg_(2) => LOAD I64 (`16 _ S) x ao
| "i64.load16_u" x:Tmemidx_(I) ao:Tmemarg_(2) => LOAD I64 (`16 _ U) x ao
| "i64.load32_s" x:Tmemidx_(I) ao:Tmemarg_(4) => LOAD I64 (`32 _ S) x ao
| "i64.load32_u" x:Tmemidx_(I) ao:Tmemarg_(4) => LOAD I64 (`32 _ U) x ao
| "v128.load" x:Tmemidx_(I) ao:Tmemarg_(16) => VLOAD V128 x ao
| "v128.load8x8_s" x:Tmemidx_(I) ao:Tmemarg_(8) => VLOAD V128 (SHAPE `8 X `8 _ S) x ao
| "v128.load8x8_u" x:Tmemidx_(I) ao:Tmemarg_(8) => VLOAD V128 (SHAPE `8 X `8 _ U) x ao
| "v128.load16x4_s" x:Tmemidx_(I) ao:Tmemarg_(8) => VLOAD V128 (SHAPE `16 X `4 _ S) x ao
| "v128.load16x4_u" x:Tmemidx_(I) ao:Tmemarg_(8) => VLOAD V128 (SHAPE `16 X `4 _ U) x ao
| "v128.load32x2_s" x:Tmemidx_(I) ao:Tmemarg_(8) => VLOAD V128 (SHAPE `32 X `2 _ S) x ao
| "v128.load32x2_u" x:Tmemidx_(I) ao:Tmemarg_(8) => VLOAD V128 (SHAPE `32 X `2 _ U) x ao
| "v128.load8_splat" x:Tmemidx_(I) ao:Tmemarg_(1) => VLOAD V128 (SPLAT `8) x ao
| "v128.load16_splat" x:Tmemidx_(I) ao:Tmemarg_(2) => VLOAD V128 (SPLAT `16) x ao
| "v128.load32_splat" x:Tmemidx_(I) ao:Tmemarg_(4) => VLOAD V128 (SPLAT `32) x ao
| "v128.load64_splat" x:Tmemidx_(I) ao:Tmemarg_(8) => VLOAD V128 (SPLAT `64) x ao
| "v128.load32_zero" x:Tmemidx_(I) ao:Tmemarg_(4) => VLOAD V128 (ZERO `32) x ao
| "v128.load64_zero" x:Tmemidx_(I) ao:Tmemarg_(8) => VLOAD V128 (ZERO `64) x ao
| "v128.load8_lane" x:Tmemidx_(I) ao:Tmemarg_(1) i:Tlaneidx => VLOAD_LANE V128 `8 x ao i
| "v128.load16_lane" x:Tmemidx_(I) ao:Tmemarg_(2) i:Tlaneidx => VLOAD_LANE V128 `16 x ao i
| "v128.load32_lane" x:Tmemidx_(I) ao:Tmemarg_(4) i:Tlaneidx => VLOAD_LANE V128 `32 x ao i
| "v128.load64_lane" x:Tmemidx_(I) ao:Tmemarg_(8) i:Tlaneidx => VLOAD_LANE V128 `64 x ao i
| "i32.store" x:Tmemidx_(I) ao:Tmemarg_(4) => STORE I32 x ao
| "i64.store" x:Tmemidx_(I) ao:Tmemarg_(8) => STORE I64 x ao
| "f32.store" x:Tmemidx_(I) ao:Tmemarg_(4) => STORE F32 x ao
| "f64.store" x:Tmemidx_(I) ao:Tmemarg_(8) => STORE F64 x ao
| "i32.store8" x:Tmemidx_(I) ao:Tmemarg_(1) => STORE I32 `8 x ao
| "i32.store16" x:Tmemidx_(I) ao:Tmemarg_(2) => STORE I32 `16 x ao
| "i64.store8" x:Tmemidx_(I) ao:Tmemarg_(1) => STORE I64 `8 x ao
| "i64.store16" x:Tmemidx_(I) ao:Tmemarg_(2) => STORE I64 `16 x ao
| "i64.store32" x:Tmemidx_(I) ao:Tmemarg_(4) => STORE I64 `32 x ao
| "v128.store" x:Tmemidx_(I) ao:Tmemarg_(16) => VSTORE V128 x ao
| "v128.store8_lane" x:Tmemidx_(I) ao:Tmemarg_(1) i:Tlaneidx => VSTORE_LANE V128 `8 x ao i
| "v128.store16_lane" x:Tmemidx_(I) ao:Tmemarg_(2) i:Tlaneidx => VSTORE_LANE V128 `16 x ao i
| "v128.store32_lane" x:Tmemidx_(I) ao:Tmemarg_(4) i:Tlaneidx => VSTORE_LANE V128 `32 x ao i
| "v128.store64_lane" x:Tmemidx_(I) ao:Tmemarg_(8) i:Tlaneidx => VSTORE_LANE V128 `64 x ao i
| "memory.size" x:Tmemidx_(I) => MEMORY.SIZE x
| "memory.grow" x:Tmemidx_(I) => MEMORY.GROW x
| "memory.fill" x:Tmemidx_(I) => MEMORY.FILL x
| "memory.copy" x_1:Tmemidx_(I) x_2:Tmemidx_(I) => MEMORY.COPY x_1 x_2
| "memory.init" x:Tmemidx_(I) y:Tdataidx_(I) => MEMORY.INIT x y
| ...
grammar Tplaininstr_(I)/memory/abbrev : instr = ...
| "i32.load" Tmemarg_(4) == "i32.load" "0" Tmemarg_(4)
| "i64.load" Tmemarg_(8) == "i64.load" "0" Tmemarg_(8)
| "f32.load" Tmemarg_(4) == "f32.load" "0" Tmemarg_(4)
| "f64.load" Tmemarg_(8) == "f64.load" "0" Tmemarg_(8)
| "i32.load8_s" Tmemarg_(1) == "i32.load8_s" "0" Tmemarg_(1)
| "i32.load8_u" Tmemarg_(1) == "i32.load8_u" "0" Tmemarg_(1)
| "i32.load16_s" Tmemarg_(2) == "i32.load16_s" "0" Tmemarg_(2)
| "i32.load16_u" Tmemarg_(2) == "i32.load16_u" "0" Tmemarg_(2)
| "i64.load8_s" Tmemarg_(1) == "i64.load8_s" "0" Tmemarg_(1)
| "i64.load8_u" Tmemarg_(1) == "i64.load8_u" "0" Tmemarg_(1)
| "i64.load16_s" Tmemarg_(2) == "i64.load16_s" "0" Tmemarg_(2)
| "i64.load16_u" Tmemarg_(2) == "i64.load16_u" "0" Tmemarg_(2)
| "i64.load32_s" Tmemarg_(4) == "i64.load32_s" "0" Tmemarg_(4)
| "i64.load32_u" Tmemarg_(4) == "i64.load32_u" "0" Tmemarg_(4)
| "v128.load" Tmemarg_(16) == "v128.load" "0" Tmemarg_(16)
| "v128.load8x8_s" Tmemarg_(8) == "v128.load8x8_s" "0" Tmemarg_(8)
| "v128.load8x8_u" Tmemarg_(8) == "v128.load8x8_u" "0" Tmemarg_(8)
| "v128.load16x4_s" Tmemarg_(8) == "v128.load16x4_s" "0" Tmemarg_(8)
| "v128.load16x4_u" Tmemarg_(8) == "v128.load16x4_u" "0" Tmemarg_(8)
| "v128.load32x2_s" Tmemarg_(8) == "v128.load32x2_s" "0" Tmemarg_(8)
| "v128.load32x2_u" Tmemarg_(8) == "v128.load32x2_u" "0" Tmemarg_(8)
| "v128.load8_splat" Tmemarg_(1) == "v128.load8_splat" "0" Tmemarg_(1)
| "v128.load16_splat" Tmemarg_(2) == "v128.load16_splat" "0" Tmemarg_(2)
| "v128.load32_splat" Tmemarg_(4) == "v128.load32_splat" "0" Tmemarg_(4)
| "v128.load64_splat" Tmemarg_(8) == "v128.load64_splat" "0" Tmemarg_(8)
| "v128.load32_zero" Tmemarg_(4) == "v128.load32_zero" "0" Tmemarg_(4)
| "v128.load64_zero" Tmemarg_(8) == "v128.load64_zero" "0" Tmemarg_(8)
| "v128.load8_lane" Tmemarg_(1) Tlaneidx == "v128.load8_lane" "0" Tmemarg_(1) Tlaneidx
| "v128.load16_lane" Tmemarg_(2) Tlaneidx == "v128.load16_lane" "0" Tmemarg_(2) Tlaneidx
| "v128.load32_lane" Tmemarg_(4) Tlaneidx == "v128.load32_lane" "0" Tmemarg_(4) Tlaneidx
| "v128.load64_lane" Tmemarg_(8) Tlaneidx == "v128.load64_lane" "0" Tmemarg_(8) Tlaneidx
| "i32.store" Tmemarg_(4) == "i32.store" "0" Tmemarg_(4)
| "i64.store" Tmemarg_(8) == "i64.store" "0" Tmemarg_(8)
| "f32.store" Tmemarg_(4) == "f32.store" "0" Tmemarg_(4)
| "f64.store" Tmemarg_(8) == "f64.store" "0" Tmemarg_(8)
| "i32.store8" Tmemarg_(1) == "i32.store8" "0" Tmemarg_(1)
| "i32.store16" Tmemarg_(2) == "i32.store16" "0" Tmemarg_(2)
| "i64.store8" Tmemarg_(1) == "i64.store8" "0" Tmemarg_(1)
| "i64.store16" Tmemarg_(2) == "i64.store16" "0" Tmemarg_(2)
| "i64.store32" Tmemarg_(4) == "i64.store32" "0" Tmemarg_(4)
| "v128.store" Tmemarg_(16) == "v128.store" "0" Tmemarg_(16)
| "v128.store8_lane" Tmemarg_(1) Tlaneidx == "v128.store8_lane" "0" Tmemarg_(1) Tlaneidx
| "v128.store16_lane" Tmemarg_(2) Tlaneidx == "v128.store16_lane" "0" Tmemarg_(1) Tlaneidx
| "v128.store32_lane" Tmemarg_(4) Tlaneidx == "v128.store32_lane" "0" Tmemarg_(1) Tlaneidx
| "v128.store64_lane" Tmemarg_(8) Tlaneidx == "v128.store64_lane" "0" Tmemarg_(1) Tlaneidx
| "memory.size" == "memory.size" "0"
| "memory.grow" == "memory.grow" "0"
| "memory.fill" == "memory.fill" "0"
| "memory.copy" == "memory.copy" "0" "0"
| "memory.init" Tdataidx_(I) == "memory.init" "0" Tdataidx_(I)
| ...
grammar Tplaininstr_(I)/data : instr = ...
| "data.drop" x:Tdataidx_(I) => DATA.DROP x
| ...
;; Reference instructions
grammar Tplaininstr_(I)/ref : instr = ...
| "ref.null" ht:Theaptype_(I) => REF.NULL ht
| "ref.func" x:Tfuncidx_(I) => REF.FUNC x
| "ref.is_null" => REF.IS_NULL
| "ref.as_non_null" => REF.AS_NON_NULL
| "ref.eq" => REF.EQ
| "ref.test" rt:Treftype_(I) => REF.TEST rt
| "ref.cast" rt:Treftype_(I) => REF.CAST rt
| ...
grammar Tplaininstr_(I)/i31 : instr = ...
| "ref.i31" => REF.I31
| "i31.get_s" => I31.GET S
| "i31.get_u" => I31.GET U
| ...
grammar Tplaininstr_(I)/struct : instr = ...
| "struct.new" x:Ttypeidx_(I) => STRUCT.NEW x
| "struct.new_default" x:Ttypeidx_(I) => STRUCT.NEW_DEFAULT x
| "struct.get" x:Ttypeidx_(I) i:Tfieldidx__(I,x) => STRUCT.GET x i
| "struct.get_s" x:Ttypeidx_(I) i:Tfieldidx__(I,x) => STRUCT.GET S x i
| "struct.get_u" x:Ttypeidx_(I) i:Tfieldidx__(I,x) => STRUCT.GET U x i
| "struct.set" x:Ttypeidx_(I) i:Tfieldidx__(I,x) => STRUCT.SET x i
| ...
grammar Tplaininstr_(I)/array : instr = ...
| "array.new" x:Ttypeidx_(I) => ARRAY.NEW x
| "array.new_default" x:Ttypeidx_(I) => ARRAY.NEW_DEFAULT x
| "array.new_fixed" x:Ttypeidx_(I) n:Tu32 => ARRAY.NEW_FIXED x n
| "array.new_data" x:Ttypeidx_(I) y:Tdataidx_(I) => ARRAY.NEW_DATA x y
| "array.new_elem" x:Ttypeidx_(I) y:Telemidx_(I) => ARRAY.NEW_ELEM x y
| "array.get" x:Ttypeidx_(I) => ARRAY.GET x
| "array.get_s" x:Ttypeidx_(I) => ARRAY.GET S x
| "array.get_u" x:Ttypeidx_(I) => ARRAY.GET U x
| "array.set" x:Ttypeidx_(I) => ARRAY.SET x
| "array.len" => ARRAY.LEN
| "array.fill" x:Ttypeidx_(I) => ARRAY.FILL x
| "array.copy" x_1:Ttypeidx_(I) x_2:Ttypeidx_(I) => ARRAY.COPY x_1 x_2
| "array.init_data" x:Ttypeidx_(I) y:Tdataidx_(I) => ARRAY.INIT_DATA x y
| "array.init_elem" x:Ttypeidx_(I) y:Telemidx_(I) => ARRAY.INIT_ELEM x y
| ...
grammar Tplaininstr_(I)/extern : instr = ...
| "any.convert_extern" => ANY.CONVERT_EXTERN
| "extern.convert_any" => EXTERN.CONVERT_ANY
| ...
;; Numeric instructions
grammar Tplaininstr_(I)/num-const : instr = ...
| "i32.const" c:Ti32 => CONST I32 c
| "i64.const" c:Ti64 => CONST I64 c
| "f32.const" c:Tf32 => CONST F32 c
| "f64.const" c:Tf64 => CONST F64 c
| ...
grammar Tplaininstr_(I)/num-test-i32 : instr = ...
| "i32.eqz" => TESTOP I32 EQZ
| ...
grammar Tplaininstr_(I)/num-test-i64 : instr = ...
| "i64.eqz" => TESTOP I64 EQZ
| ...
grammar Tplaininstr_(I)/num-rel-i32 : instr = ...
| "i32.eq" => RELOP I32 EQ
| "i32.ne" => RELOP I32 NE
| "i32.lt_s" => RELOP I32 LT S
| "i32.lt_u" => RELOP I32 LT U
| "i32.gt_s" => RELOP I32 GT S
| "i32.gt_u" => RELOP I32 GT U
| "i32.le_s" => RELOP I32 LE S
| "i32.le_u" => RELOP I32 LE U
| "i32.ge_s" => RELOP I32 GE S
| "i32.ge_u" => RELOP I32 GE U
| ...
grammar Tplaininstr_(I)/num-rel-i64 : instr = ...
| "i64.eq" => RELOP I64 EQ
| "i64.ne" => RELOP I64 NE
| "i64.lt_s" => RELOP I64 LT S
| "i64.lt_u" => RELOP I64 LT U
| "i64.gt_s" => RELOP I64 GT S
| "i64.gt_u" => RELOP I64 GT U
| "i64.le_s" => RELOP I64 LE S
| "i64.le_u" => RELOP I64 LE U
| "i64.ge_s" => RELOP I64 GE S
| "i64.ge_u" => RELOP I64 GE U
| ...
grammar Tplaininstr_(I)/num-rel-f32 : instr = ...
| "f32.eq" => RELOP F32 EQ
| "f32.ne" => RELOP F32 NE
| "f32.lt" => RELOP F32 LT
| "f32.gt" => RELOP F32 GT
| "f32.le" => RELOP F32 LE
| "f32.ge" => RELOP F32 GE
| ...
grammar Tplaininstr_(I)/num-rel-f64 : instr = ...
| "f64.eq" => RELOP F64 EQ
| "f64.ne" => RELOP F64 NE
| "f64.lt" => RELOP F64 LT
| "f64.gt" => RELOP F64 GT
| "f64.le" => RELOP F64 LE
| "f64.ge" => RELOP F64 GE
| ...
grammar Tplaininstr_(I)/num-un-i32 : instr = ...
| "i32.clz" => UNOP I32 CLZ
| "i32.ctz" => UNOP I32 CTZ
| "i32.popcnt" => UNOP I32 POPCNT
| "i32.extend8_s" => UNOP I32 EXTEND `8
| "i32.extend16_s" => UNOP I32 EXTEND `16
| ...
grammar Tplaininstr_(I)/num-un-i64 : instr = ...
| "i64.clz" => UNOP I64 CLZ
| "i64.ctz" => UNOP I64 CTZ
| "i64.popcnt" => UNOP I64 POPCNT
| "i64.extend8_s" => UNOP I64 EXTEND `8
| "i64.extend16_s" => UNOP I64 EXTEND `16
| "i64.extend32_s" => UNOP I64 EXTEND `32
| ...
grammar Tplaininstr_(I)/num-un-f32 : instr = ...
| "f32.abs" => UNOP F32 ABS
| "f32.neg" => UNOP F32 NEG
| "f32.sqrt" => UNOP F32 SQRT
| "f32.ceil" => UNOP F32 CEIL
| "f32.floor" => UNOP F32 FLOOR
| "f32.trunc" => UNOP F32 TRUNC
| "f32.nearest" => UNOP F32 NEAREST
| ...
grammar Tplaininstr_(I)/num-un-f64 : instr = ...
| "f64.abs" => UNOP F64 ABS
| "f64.neg" => UNOP F64 NEG
| "f64.sqrt" => UNOP F64 SQRT
| "f64.ceil" => UNOP F64 CEIL
| "f64.floor" => UNOP F64 FLOOR
| "f64.trunc" => UNOP F64 TRUNC
| "f64.nearest" => UNOP F64 NEAREST
| ...
grammar Tplaininstr_(I)/num-bin-i32 : instr = ...
| "i32.add" => BINOP I32 ADD
| "i32.sub" => BINOP I32 SUB
| "i32.mul" => BINOP I32 MUL
| "i32.div_s" => BINOP I32 DIV S
| "i32.div_u" => BINOP I32 DIV U
| "i32.rem_s" => BINOP I32 REM S
| "i32.rem_u" => BINOP I32 REM U
| "i32.and" => BINOP I32 AND
| "i32.or" => BINOP I32 OR
| "i32.xor" => BINOP I32 XOR
| "i32.shl" => BINOP I32 SHL
| "i32.shr_s" => BINOP I32 SHR S
| "i32.shr_u" => BINOP I32 SHR U
| "i32.rotl" => BINOP I32 ROTL
| "i32.rotr" => BINOP I32 ROTR
| ...
grammar Tplaininstr_(I)/num-bin-i64 : instr = ...
| "i64.add" => BINOP I64 ADD
| "i64.sub" => BINOP I64 SUB
| "i64.mul" => BINOP I64 MUL
| "i64.div_s" => BINOP I64 DIV S
| "i64.div_u" => BINOP I64 DIV U
| "i64.rem_s" => BINOP I64 REM S
| "i64.rem_u" => BINOP I64 REM U
| "i64.and" => BINOP I64 AND
| "i64.or" => BINOP I64 OR
| "i64.xor" => BINOP I64 XOR
| "i64.shl" => BINOP I64 SHL
| "i64.shr_s" => BINOP I64 SHR S
| "i64.shr_u" => BINOP I64 SHR U
| "i64.rotl" => BINOP I64 ROTL
| "i64.rotr" => BINOP I64 ROTR
| ...
grammar Tplaininstr_(I)/num-bin-f32 : instr = ...
| "f32.add" => BINOP F32 ADD
| "f32.sub" => BINOP F32 SUB
| "f32.mul" => BINOP F32 MUL
| "f32.div" => BINOP F32 DIV
| "f32.min" => BINOP F32 MIN
| "f32.max" => BINOP F32 MAX
| "f32.copysign" => BINOP F32 COPYSIGN
| ...
grammar Tplaininstr_(I)/num-bin-f64 : instr = ...
| "f64.add" => BINOP F64 ADD
| "f64.sub" => BINOP F64 SUB
| "f64.mul" => BINOP F64 MUL
| "f64.div" => BINOP F64 DIV
| "f64.min" => BINOP F64 MIN
| "f64.max" => BINOP F64 MAX
| "f64.copysign" => BINOP F64 COPYSIGN
| ...
grammar Tplaininstr_(I)/num-cvt-i32 : instr = ...
| "i32.wrap_i64" => CVTOP I32 I64 WRAP
| "i32.trunc_f32_s" => CVTOP I32 F32 TRUNC S
| "i32.trunc_f32_u" => CVTOP I32 F32 TRUNC U
| "i32.trunc_f64_s" => CVTOP I32 F64 TRUNC S
| "i32.trunc_f64_u" => CVTOP I32 F64 TRUNC U
| "i32.trunc_sat_f32_s" => CVTOP I32 F32 TRUNC_SAT S
| "i32.trunc_sat_f32_u" => CVTOP I32 F32 TRUNC_SAT U
| "i32.trunc_sat_f64_s" => CVTOP I32 F64 TRUNC_SAT S
| "i32.trunc_sat_f64_u" => CVTOP I32 F64 TRUNC_SAT U
| ...
grammar Tplaininstr_(I)/num-cvt-i64 : instr = ...
| "i64.extend_i64_s" => CVTOP I64 I64 EXTEND S
| "i64.extend_i64_u" => CVTOP I64 I64 EXTEND U
| "i64.trunc_f32_s" => CVTOP I64 F32 TRUNC S
| "i64.trunc_f32_u" => CVTOP I64 F32 TRUNC U
| "i64.trunc_f64_s" => CVTOP I64 F64 TRUNC S
| "i64.trunc_f64_u" => CVTOP I64 F64 TRUNC U
| "i64.trunc_sat_f32_s" => CVTOP I64 F32 TRUNC_SAT S
| "i64.trunc_sat_f32_u" => CVTOP I64 F32 TRUNC_SAT U
| "i64.trunc_sat_f64_s" => CVTOP I64 F64 TRUNC_SAT S
| "i64.trunc_sat_f64_u" => CVTOP I64 F64 TRUNC_SAT U
| ...
grammar Tplaininstr_(I)/num-cvt-f32 : instr = ...
| "f32.demote_f64" => CVTOP F32 F64 DEMOTE
| "f32.convert_i32_s" => CVTOP F32 I32 CONVERT S
| "f32.convert_i32_u" => CVTOP F32 I32 CONVERT U
| "f32.convert_i64_s" => CVTOP F32 I64 CONVERT S
| "f32.convert_i64_u" => CVTOP F32 I64 CONVERT U
| ...
grammar Tplaininstr_(I)/num-cvt-f64 : instr = ...
| "f64.promote_f32" => CVTOP F64 F32 PROMOTE
| "f64.convert_i32_s" => CVTOP F64 I32 CONVERT S
| "f64.convert_i32_u" => CVTOP F64 I32 CONVERT U
| "f64.convert_i64_s" => CVTOP F64 I64 CONVERT S
| "f64.convert_i64_u" => CVTOP F64 I64 CONVERT U
| ...
grammar Tplaininstr_(I)/num-cvt-reinterpret : instr = ...
| "i32.reinterpret_f32" => CVTOP I32 F32 REINTERPRET
| "i64.reinterpret_f64" => CVTOP I64 F64 REINTERPRET
| "f32.reinterpret_i32" => CVTOP F32 I32 REINTERPRET
| "f64.reinterpret_i64" => CVTOP F64 I64 REINTERPRET
| ...
;; Vector instructions
grammar Tplaininstr_(I)/vec-const : instr = ...
| "v128.const" "i8x16" c*:Ti8^16 => VCONST V128 $inv_ibytes_(128, $concat_(byte, $ibytes_(8, c)*))
| "v128.const" "i16x8" c*:Ti16^8 => VCONST V128 $inv_ibytes_(128, $concat_(byte, $ibytes_(16, c)*))
| "v128.const" "i32x4" c*:Ti32^4 => VCONST V128 $inv_ibytes_(128, $concat_(byte, $ibytes_(32, c)*))
| "v128.const" "i64x2" c*:Ti64^2 => VCONST V128 $inv_ibytes_(128, $concat_(byte, $ibytes_(64, c)*))
| "v128.const" "f32x4" c*:Tf32^4 => VCONST V128 $inv_ibytes_(128, $concat_(byte, $fbytes_(32, c)*))
| "v128.const" "f64x2" c*:Tf64^2 => VCONST V128 $inv_ibytes_(128, $concat_(byte, $fbytes_(64, c)*))
| ...
grammar Tplaininstr_(I)/vec-shuffle : instr = ...
| "i8x16.shuffle" i*:Tlaneidx^16 => VSHUFFLE (I8 X `16) i*
| "i8x16.swizzle" => VSWIZZLOP (I8 X `16) SWIZZLE
| "i8x16.relaxed_swizzle" => VSWIZZLOP (I8 X `16) RELAXED_SWIZZLE
| ...
grammar Tplaininstr_(I)/vec-splat : instr = ...
| "i8x16.splat" => VSPLAT (I8 X `16)
| "i16x8.splat" => VSPLAT (I16 X `8)
| "i32x4.splat" => VSPLAT (I32 X `4)
| "i64x2.splat" => VSPLAT (I64 X `2)
| "f32x4.splat" => VSPLAT (F32 X `4)
| "f64x2.splat" => VSPLAT (F64 X `2)
| ...
grammar Tplaininstr_(I)/vec-lane : instr = ...
| "i8x16.extract_lane_s" l:Tlaneidx => VEXTRACT_LANE (I8 X `16) S l
| "i8x16.extract_lane_u" l:Tlaneidx => VEXTRACT_LANE (I8 X `16) U l
| "i16x8.extract_lane_s" l:Tlaneidx => VEXTRACT_LANE (I16 X `8) S l
| "i16x8.extract_lane_u" l:Tlaneidx => VEXTRACT_LANE (I16 X `8) U l
| "i32x4.extract_lane" l:Tlaneidx => VEXTRACT_LANE (I32 X `4) l
| "i64x2.extract_lane" l:Tlaneidx => VEXTRACT_LANE (I64 X `2) l
| "f32x4.extract_lane" l:Tlaneidx => VEXTRACT_LANE (F32 X `4) l
| "f64x2.extract_lane" l:Tlaneidx => VEXTRACT_LANE (F64 X `2) l
| "i8x16.replace_lane" l:Tlaneidx => VREPLACE_LANE (I8 X `16) l
| "i16x8.replace_lane" l:Tlaneidx => VREPLACE_LANE (I16 X `8) l
| "i32x4.replace_lane" l:Tlaneidx => VREPLACE_LANE (I32 X `4) l
| "i64x2.replace_lane" l:Tlaneidx => VREPLACE_LANE (I64 X `2) l
| "f32x4.replace_lane" l:Tlaneidx => VREPLACE_LANE (F32 X `4) l
| "f64x2.replace_lane" l:Tlaneidx => VREPLACE_LANE (F64 X `2) l
| ...
grammar Tplaininstr_(I)/vec-test-v128 : instr = ...
| "v128.any_true" => VVTESTOP V128 ANY_TRUE
| ...
grammar Tplaininstr_(I)/vec-test-i8x16 : instr = ...
| "i8x16.all_true" => VTESTOP (I8 X `16) ALL_TRUE
| ...
grammar Tplaininstr_(I)/vec-test-i16x8 : instr = ...
| "i16x8.all_true" => VTESTOP (I16 X `8) ALL_TRUE
| ...
grammar Tplaininstr_(I)/vec-test-i32x4 : instr = ...
| "i32x4.all_true" => VTESTOP (I32 X `4) ALL_TRUE
| ...
grammar Tplaininstr_(I)/vec-test-i64x2 : instr = ...
| "i64x2.all_true" => VTESTOP (I64 X `2) ALL_TRUE
| ...
grammar Tplaininstr_(I)/vec-rel-i8x16 : instr = ...
| "i8x16.eq" => VRELOP (I8 X `16) EQ
| "i8x16.ne" => VRELOP (I8 X `16) NE
| "i8x16.lt_s" => VRELOP (I8 X `16) LT S
| "i8x16.lt_u" => VRELOP (I8 X `16) LT U
| "i8x16.gt_s" => VRELOP (I8 X `16) GT S
| "i8x16.gt_u" => VRELOP (I8 X `16) GT U
| "i8x16.le_s" => VRELOP (I8 X `16) LE S
| "i8x16.le_u" => VRELOP (I8 X `16) LE U
| "i8x16.ge_s" => VRELOP (I8 X `16) GE S
| "i8x16.ge_u" => VRELOP (I8 X `16) GE U
| ...
grammar Tplaininstr_(I)/vec-rel-i16x8 : instr = ...
| "i16x8.eq" => VRELOP (I16 X `8) EQ
| "i16x8.ne" => VRELOP (I16 X `8) NE
| "i16x8.lt_s" => VRELOP (I16 X `8) LT S
| "i16x8.lt_u" => VRELOP (I16 X `8) LT U
| "i16x8.gt_s" => VRELOP (I16 X `8) GT S
| "i16x8.gt_u" => VRELOP (I16 X `8) GT U
| "i16x8.le_s" => VRELOP (I16 X `8) LE S
| "i16x8.le_u" => VRELOP (I16 X `8) LE U
| "i16x8.ge_s" => VRELOP (I16 X `8) GE S
| "i16x8.ge_u" => VRELOP (I16 X `8) GE U
| ...
grammar Tplaininstr_(I)/vec-rel-i32x4 : instr = ...
| "i32x4.eq" => VRELOP (I32 X `4) EQ
| "i32x4.ne" => VRELOP (I32 X `4) NE
| "i32x4.lt_s" => VRELOP (I32 X `4) LT S
| "i32x4.lt_u" => VRELOP (I32 X `4) LT U
| "i32x4.gt_s" => VRELOP (I32 X `4) GT S
| "i32x4.gt_u" => VRELOP (I32 X `4) GT U
| "i32x4.le_s" => VRELOP (I32 X `4) LE S
| "i32x4.le_u" => VRELOP (I32 X `4) LE U
| "i32x4.ge_s" => VRELOP (I32 X `4) GE S
| "i32x4.ge_u" => VRELOP (I32 X `4) GE U
| ...
grammar Tplaininstr_(I)/vec-rel-i64x2 : instr = ...
| "i64x2.eq" => VRELOP (I64 X `2) EQ
| "i64x2.ne" => VRELOP (I64 X `2) NE
| "i64x2.lt_s" => VRELOP (I64 X `2) LT S
;;| "i64x2.lt_u" => VRELOP (I64 X `2) LT U ;; does not exist!
| "i64x2.gt_s" => VRELOP (I64 X `2) GT S
;;| "i64x2.gt_u" => VRELOP (I64 X `2) GT U ;; does not exist!
| "i64x2.le_s" => VRELOP (I64 X `2) LE S
;;| "i64x2.le_u" => VRELOP (I64 X `2) LE U ;; does not exist!
| "i64x2.ge_s" => VRELOP (I64 X `2) GE S
;;| "i64x2.ge_u" => VRELOP (I64 X `2) GE U ;; does not exist!
| ...
grammar Tplaininstr_(I)/vec-rel-f32x4 : instr = ...
| "f32x4.eq" => VRELOP (F32 X `4) EQ
| "f32x4.ne" => VRELOP (F32 X `4) NE
| "f32x4.lt" => VRELOP (F32 X `4) LT
| "f32x4.gt" => VRELOP (F32 X `4) GT
| "f32x4.le" => VRELOP (F32 X `4) LE
| "f32x4.ge" => VRELOP (F32 X `4) GE
| ...
grammar Tplaininstr_(I)/vec-rel-f64x2 : instr = ...
| "f64x2.eq" => VRELOP (F64 X `2) EQ
| "f64x2.ne" => VRELOP (F64 X `2) NE
| "f64x2.lt" => VRELOP (F64 X `2) LT
| "f64x2.gt" => VRELOP (F64 X `2) GT
| "f64x2.le" => VRELOP (F64 X `2) LE
| "f64x2.ge" => VRELOP (F64 X `2) GE
| ...
grammar Tplaininstr_(I)/vec-un-v128 : instr = ...
| "v128.not" => VVUNOP V128 NOT
| ...
grammar Tplaininstr_(I)/vec-un-i8x16 : instr = ...
| "i8x16.abs" => VUNOP (I8 X `16) ABS
| "i8x16.neg" => VUNOP (I8 X `16) NEG
| "i8x16.popcnt" => VUNOP (I8 X `16) POPCNT
| ...
grammar Tplaininstr_(I)/vec-un-i16x8 : instr = ...
| "i16x8.abs" => VUNOP (I16 X `8) ABS
| "i16x8.neg" => VUNOP (I16 X `8) NEG
;;| "i16x8.popcnt" => VUNOP (I16 X `8) POPCNT ;; does not exist!
| ...
grammar Tplaininstr_(I)/vec-un-i32x4 : instr = ...
| "i32x4.abs" => VUNOP (I32 X `4) ABS
| "i32x4.neg" => VUNOP (I32 X `4) NEG
;;| "i32x4.popcnt" => VUNOP (I32 X `4) POPCNT ;; does not exist!
| ...
grammar Tplaininstr_(I)/vec-un-i64x2 : instr = ...
| "i64x2.abs" => VUNOP (I64 X `2) ABS
| "i64x2.neg" => VUNOP (I64 X `2) NEG
;;| "i64x2.popcnt" => VUNOP (I64 X `2) POPCNT ;; does not exist!
| ...
grammar Tplaininstr_(I)/vec-un-f32x4 : instr = ...
| "f32x4.abs" => VUNOP (F32 X `4) ABS
| "f32x4.neg" => VUNOP (F32 X `4) NEG
| "f32x4.sqrt" => VUNOP (F32 X `4) SQRT
| "f32x4.ceil" => VUNOP (F32 X `4) CEIL
| "f32x4.floor" => VUNOP (F32 X `4) FLOOR
| "f32x4.trunc" => VUNOP (F32 X `4) TRUNC
| "f32x4.nearest" => VUNOP (F32 X `4) NEAREST
| ...
grammar Tplaininstr_(I)/vec-un-f64x2 : instr = ...
| "f64x2.abs" => VUNOP (F64 X `2) ABS
| "f64x2.neg" => VUNOP (F64 X `2) NEG
| "f64x2.sqrt" => VUNOP (F64 X `2) SQRT
| "f64x2.ceil" => VUNOP (F64 X `2) CEIL
| "f64x2.floor" => VUNOP (F64 X `2) FLOOR
| "f64x2.trunc" => VUNOP (F64 X `2) TRUNC
| "f64x2.nearest" => VUNOP (F64 X `2) NEAREST
| ...
grammar Tplaininstr_(I)/vec-bin-v128 : instr = ...
| "v128.and" => VVBINOP V128 AND
| "v128.andnot" => VVBINOP V128 ANDNOT
| "v128.or" => VVBINOP V128 OR
| "v128.xor" => VVBINOP V128 XOR
| ...
grammar Tplaininstr_(I)/vec-bin-i8x16 : instr = ...
| "i8x16.add" => VBINOP (I8 X `16) ADD
| "i8x16.add_sat_s" => VBINOP (I8 X `16) ADD_SAT S
| "i8x16.add_sat_u" => VBINOP (I8 X `16) ADD_SAT U
| "i8x16.sub" => VBINOP (I8 X `16) SUB
| "i8x16.sub_sat_s" => VBINOP (I8 X `16) SUB_SAT S
| "i8x16.sub_sat_u" => VBINOP (I8 X `16) SUB_SAT U
;;| "i8x16.mul" => VBINOP (I8 X `16) MUL ;; does not exist!
| "i8x16.min_s" => VBINOP (I8 X `16) MIN S
| "i8x16.min_u" => VBINOP (I8 X `16) MIN U
| "i8x16.max_s" => VBINOP (I8 X `16) MAX S
| "i8x16.max_u" => VBINOP (I8 X `16) MAX U
| "i8x16.avgr_u" => VBINOP (I8 X `16) AVGR U
| ...
grammar Tplaininstr_(I)/vec-bin-i16x8 : instr = ...
| "i16x8.add" => VBINOP (I16 X `8) ADD
| "i16x8.add_sat_s" => VBINOP (I16 X `8) ADD_SAT S
| "i16x8.add_sat_u" => VBINOP (I16 X `8) ADD_SAT U
| "i16x8.sub" => VBINOP (I16 X `8) SUB
| "i16x8.sub_sat_s" => VBINOP (I16 X `8) SUB_SAT S
| "i16x8.sub_sat_u" => VBINOP (I16 X `8) SUB_SAT U
| "i16x8.mul" => VBINOP (I16 X `8) MUL
| "i16x8.min_s" => VBINOP (I16 X `8) MIN S
| "i16x8.min_u" => VBINOP (I16 X `8) MIN U
| "i16x8.max_s" => VBINOP (I16 X `8) MAX S
| "i16x8.max_u" => VBINOP (I16 X `8) MAX U
| "i16x8.avgr_u" => VBINOP (I16 X `8) AVGR U
| "i16x8.q15mulr_sat_s" => VBINOP (I16 X `8) Q15MULR_SAT S
| "i16x8.relaxed_q15mulr_s" => VBINOP (I16 X `8) RELAXED_Q15MULR S
| ...
grammar Tplaininstr_(I)/vec-bin-i32x4 : instr = ...
| "i32x4.add" => VBINOP (I32 X `4) ADD
;;| "i32x4.add_sat_s" => VBINOP (I32 X `4) ADD_SAT S ;; does not exist!
;;| "i32x4.add_sat_u" => VBINOP (I32 X `4) ADD_SAT U ;; does not exist!
| "i32x4.sub" => VBINOP (I32 X `4) SUB
;;| "i32x4.sub_sat_s" => VBINOP (I32 X `4) SUB_SAT S ;; does not exist!
;;| "i32x4.sub_sat_u" => VBINOP (I32 X `4) SUB_SAT U ;; does not exist!
| "i32x4.mul" => VBINOP (I32 X `4) MUL
| "i32x4.min_s" => VBINOP (I32 X `4) MIN S
| "i32x4.min_u" => VBINOP (I32 X `4) MIN U
| "i32x4.max_s" => VBINOP (I32 X `4) MAX S
| "i32x4.max_u" => VBINOP (I32 X `4) MAX U
;;| "i32x4.avgr_u" => VBINOP (I32 X `4) AVGR U ;; does not exist!
| ...
grammar Tplaininstr_(I)/vec-bin-i64x2 : instr = ...
| "i64x2.add" => VBINOP (I64 X `2) ADD
;;| "i64x2.add_sat_s" => VBINOP (I64 X `2) ADD_SAT S ;; does not exist!
;;| "i64x2.add_sat_u" => VBINOP (I64 X `2) ADD_SAT U ;; does not exist!
| "i64x2.sub" => VBINOP (I64 X `2) SUB
;;| "i64x2.sub_sat_s" => VBINOP (I64 X `2) SUB_SAT S ;; does not exist!
;;| "i64x2.sub_sat_u" => VBINOP (I64 X `2) SUB_SAT U ;; does not exist!
| "i64x2.mul" => VBINOP (I64 X `2) MUL
;;| "i64x2.min_s" => VBINOP (I64 X `2) MIN S ;; does not exist!
;;| "i64x2.min_u" => VBINOP (I64 X `2) MIN U ;; does not exist!
;;| "i64x2.max_s" => VBINOP (I64 X `2) MAX S ;; does not exist!
;;| "i64x2.max_u" => VBINOP (I64 X `2) MAX U ;; does not exist!
;;| "i64x2.avgr_u" => VBINOP (I64 X `2) AVGR U ;; does not exist!
| ...
grammar Tplaininstr_(I)/vec-bin-f32x4 : instr = ...
| "f32x4.add" => VBINOP (F32 X `4) ADD
| "f32x4.sub" => VBINOP (F32 X `4) SUB
| "f32x4.mul" => VBINOP (F32 X `4) MUL
| "f32x4.div" => VBINOP (F32 X `4) DIV
| "f32x4.min" => VBINOP (F32 X `4) MIN
| "f32x4.max" => VBINOP (F32 X `4) MAX
| "f32x4.pmin" => VBINOP (F32 X `4) PMIN
| "f32x4.pmax" => VBINOP (F32 X `4) PMAX
| "f32x4.relaxed_min" => VBINOP (F32 X `4) RELAXED_MIN
| "f32x4.relaxed_max" => VBINOP (F32 X `4) RELAXED_MAX
| ...
grammar Tplaininstr_(I)/vec-bin-f64x2 : instr = ...
| "f64x2.add" => VBINOP (F64 X `2) ADD
| "f64x2.sub" => VBINOP (F64 X `2) SUB
| "f64x2.mul" => VBINOP (F64 X `2) MUL
| "f64x2.div" => VBINOP (F64 X `2) DIV
| "f64x2.min" => VBINOP (F64 X `2) MIN
| "f64x2.max" => VBINOP (F64 X `2) MAX
| "f64x2.pmin" => VBINOP (F64 X `2) PMIN
| "f64x2.pmax" => VBINOP (F64 X `2) PMAX
| "f64x2.relaxed_min" => VBINOP (F64 X `2) RELAXED_MIN
| "f64x2.relaxed_max" => VBINOP (F64 X `2) RELAXED_MAX
| ...
grammar Tplaininstr_(I)/vec-tern-v128 : instr = ...
| "v128.bitselect" => VVTERNOP V128 BITSELECT
| ...
grammar Tplaininstr_(I)/vec-tern-i8x16 : instr = ...
| "i8x16.relaxed_laneselect" => VTERNOP (I8 X `16) RELAXED_LANESELECT
| ...
grammar Tplaininstr_(I)/vec-tern-i16x8 : instr = ...
| "i16x8.relaxed_laneselect" => VTERNOP (I16 X `8) RELAXED_LANESELECT
| ...
grammar Tplaininstr_(I)/vec-tern-i32x4 : instr = ...
| "i32x4.relaxed_laneselect" => VTERNOP (I32 X `4) RELAXED_LANESELECT
| ...
grammar Tplaininstr_(I)/vec-tern-i64x2 : instr = ...
| "i64x2.relaxed_laneselect" => VTERNOP (I64 X `2) RELAXED_LANESELECT
| ...
grammar Tplaininstr_(I)/vec-tern-f32x4 : instr = ...
| "f32x4.relaxed_madd" => VTERNOP (F32 X `4) RELAXED_MADD
| "f32x4.relaxed_nmadd" => VTERNOP (F32 X `4) RELAXED_NMADD
| ...
grammar Tplaininstr_(I)/vec-tern-f64x2 : instr = ...
| "f64x2.relaxed_madd" => VTERNOP (F64 X `2) RELAXED_MADD
| "f64x2.relaxed_nmadd" => VTERNOP (F64 X `2) RELAXED_NMADD
| ...
grammar Tplaininstr_(I)/vec-shift-i8x16 : instr = ...
| "i8x16.shl" => VSHIFTOP (I8 X `16) SHL
| "i8x16.shr_s" => VSHIFTOP (I8 X `16) SHR S
| "i8x16.shr_u" => VSHIFTOP (I8 X `16) SHR U
| ...
grammar Tplaininstr_(I)/vec-shift-i16x8 : instr = ...
| "i16x8.shl" => VSHIFTOP (I16 X `8) SHL
| "i16x8.shr_s" => VSHIFTOP (I16 X `8) SHR S
| "i16x8.shr_u" => VSHIFTOP (I16 X `8) SHR U
| ...
grammar Tplaininstr_(I)/vec-shift-i32x4 : instr = ...
| "i32x4.shl" => VSHIFTOP (I32 X `4) SHL
| "i32x4.shr_s" => VSHIFTOP (I32 X `4) SHR S
| "i32x4.shr_u" => VSHIFTOP (I32 X `4) SHR U
| ...
grammar Tplaininstr_(I)/vec-shift-i64x2 : instr = ...
| "i64x2.shl" => VSHIFTOP (I64 X `2) SHL
| "i64x2.shr_s" => VSHIFTOP (I64 X `2) SHR S
| "i64x2.shr_u" => VSHIFTOP (I64 X `2) SHR U
| ...
grammar Tplaininstr_(I)/vec-bitmask-i8x16 : instr = ...
| "i8x16.bitmask" => VBITMASK (I8 X `16)
| ...
grammar Tplaininstr_(I)/vec-bitmask-i16x8 : instr = ...
| "i16x8.bitmask" => VBITMASK (I16 X `8)
| ...
grammar Tplaininstr_(I)/vec-bitmask-i32x4 : instr = ...
| "i32x4.bitmask" => VBITMASK (I32 X `4)
| ...
grammar Tplaininstr_(I)/vec-bitmask-i64x2 : instr = ...
| "i64x2.bitmask" => VBITMASK (I64 X `2)
| ...
grammar Tplaininstr_(I)/vec-narrow-i8x16 : instr = ...
| "i8x16.narrow_i16x8_s" => VNARROW (I8 X `16) (I16 X `8) S
| "i8x16.narrow_i16x8_u" => VNARROW (I8 X `16) (I16 X `8) U
| ...
grammar Tplaininstr_(I)/vec-narrow-i16x8 : instr = ...
| "i16x8.narrow_i32x4_s" => VNARROW (I16 X `8) (I32 X `4) S
| "i16x8.narrow_i32x4_u" => VNARROW (I16 X `8) (I32 X `4) U
| ...
grammar Tplaininstr_(I)/vec-narrow-i32x4 : instr = ...
;;| "i32x4.narrow_i64x2_s" => VNARROW (I32 X `4) (I64 X `2) S ;; does not exist!
;;| "i32x4.narrow_i64x2_u" => VNARROW (I32 X `4) (I64 X `2) U ;; does not exist!
| ...
grammar Tplaininstr_(I)/vec-cvt-i16x8 : instr = ...
| "i16x8.extend_low_i8x16_s" => VCVTOP (I16 X `8) (I8 X `16) EXTEND LOW S
| "i16x8.extend_low_i8x16_u" => VCVTOP (I16 X `8) (I8 X `16) EXTEND LOW U
| "i16x8.extend_high_i8x16_s" => VCVTOP (I16 X `8) (I8 X `16) EXTEND HIGH S
| "i16x8.extend_high_i8x16_u" => VCVTOP (I16 X `8) (I8 X `16) EXTEND HIGH U
| ...
grammar Tplaininstr_(I)/vec-cvt-i32x4 : instr = ...
| "i32x4.extend_low_i16x8_s" => VCVTOP (I32 X `4) (I16 X `8) EXTEND LOW S
| "i32x4.extend_low_i16x8_u" => VCVTOP (I32 X `4) (I16 X `8) EXTEND LOW U
| "i32x4.extend_high_i16x8_s" => VCVTOP (I32 X `4) (I16 X `8) EXTEND HIGH S
| "i32x4.extend_high_i16x8_u" => VCVTOP (I32 X `4) (I16 X `8) EXTEND HIGH U
| "i32x4.trunc_sat_f32x4_s" => VCVTOP (I32 X `4) (F32 X `4) TRUNC_SAT S
| "i32x4.trunc_sat_f32x4_u" => VCVTOP (I32 X `4) (F32 X `4) TRUNC_SAT U
| "i32x4.trunc_sat_f64x2_s_zero" => VCVTOP (I32 X `4) (F64 X `2) TRUNC_SAT S ZERO
| "i32x4.trunc_sat_f64x2_u_zero" => VCVTOP (I32 X `4) (F64 X `2) TRUNC_SAT U ZERO
| "i32x4.relaxed_trunc_f32x4_s" => VCVTOP (I32 X `4) (F32 X `4) RELAXED_TRUNC S
| "i32x4.relaxed_trunc_f32x4_u" => VCVTOP (I32 X `4) (F32 X `4) RELAXED_TRUNC U
| "i32x4.relaxed_trunc_f64x2_s_zero" => VCVTOP (I32 X `4) (F64 X `2) RELAXED_TRUNC S ZERO
| "i32x4.relaxed_trunc_f64x2_u_zero" => VCVTOP (I32 X `4) (F64 X `2) RELAXED_TRUNC U ZERO
| ...
grammar Tplaininstr_(I)/vec-cvt-i64x2 : instr = ...
| "i64x2.extend_low_i32x4_s" => VCVTOP (I64 X `2) (I32 X `4) EXTEND LOW S
| "i64x2.extend_low_i32x4_u" => VCVTOP (I64 X `2) (I32 X `4) EXTEND LOW U
| "i64x2.extend_high_i32x4_s" => VCVTOP (I64 X `2) (I32 X `4) EXTEND HIGH S
| "i64x2.extend_high_i32x4_u" => VCVTOP (I64 X `2) (I32 X `4) EXTEND HIGH U
;;| "i64x2.trunc_sat_low_f32x4_s" => VCVTOP (I64 X `2) (F32 X `4) TRUNC_SAT LOW S ;; does not exist!
;;| "i64x2.trunc_sat_low_f32x4_u" => VCVTOP (I64 X `2) (F32 X `4) TRUNC_SAT LOW U ;; does not exist!
;;| "i64x2.trunc_sat_high_f32x4_s" => VCVTOP (I64 X `2) (F32 X `4) TRUNC_SAT HIGH S ;; does not exist!
;;| "i64x2.trunc_sat_high_f32x4_u" => VCVTOP (I64 X `2) (F32 X `4) TRUNC_SAT HIGH U ;; does not exist!
;;| "i64x2.trunc_sat_f64x2_s_zero" => VCVTOP (I64 X `2) (F64 X `2) TRUNC_SAT S ;; does not exist!
;;| "i64x2.trunc_sat_f64x2_u_zero" => VCVTOP (I64 X `2) (F64 X `2) TRUNC_SAT U ;; does not exist!
| ...
grammar Tplaininstr_(I)/vec-cvt-f32x4 : instr = ...
| "f32x4.demote_f64x2_zero" => VCVTOP (F32 X `4) (F64 X `2) DEMOTE ZERO
| "f32x4.convert_i32x4_s" => VCVTOP (F32 X `4) (I32 X `4) CONVERT S
| "f32x4.convert_i32x4_u" => VCVTOP (F32 X `4) (I32 X `4) CONVERT U
;;| "f32x4.convert_i64x2_s_zero" => VCVTOP (F32 X `4) (I64 X `2) CONVERT S ZERO ;; does not exist!
;;| "f32x4.convert_i64x2_u_zero" => VCVTOP (F32 X `4) (I64 X `2) CONVERT U ZERO ;; does not exist!
| ...
grammar Tplaininstr_(I)/vec-cvt-f64x2 : instr = ...
| "f64x2.promote_low_f32x4" => VCVTOP (F64 X `2) (F32 X `4) PROMOTE LOW
;;| "f64x2.promote_high_f32x4" => VCVTOP (F64 X `2) (F32 X `4) PROMOTE HIGH ;; does not exist!
| "f64x2.convert_low_i32x4_s" => VCVTOP (F64 X `2) (I32 X `4) CONVERT LOW S
| "f64x2.convert_low_i32x4_u" => VCVTOP (F64 X `2) (I32 X `4) CONVERT LOW U
;;| "f64x2.convert_high_i32x4_s" => VCVTOP (F64 X `2) (I32 X `4) CONVERT HIGH S ;; does not exist!
;;| "f64x2.convert_high_i32x4_u" => VCVTOP (F64 X `2) (I32 X `4) CONVERT HIGH U ;; does not exist!
;;| "f64x2.convert_i64x2_s" => VCVTOP (F64 X `2) (I64 X `2) CONVERT S ;; does not exist!
;;| "f64x2.convert_i64x2_u" => VCVTOP (F64 X `2) (I64 X `2) CONVERT U ;; does not exist!
| ...
grammar Tplaininstr_(I)/vec-extun-i16x8 : instr = ...
| "i16x8.extadd_pairwise_i8x16_s" => VEXTUNOP (I16 X `8) (I8 X `16) EXTADD_PAIRWISE S
| "i16x8.extadd_pairwise_i8x16_u" => VEXTUNOP (I16 X `8) (I8 X `16) EXTADD_PAIRWISE U
| ...
grammar Tplaininstr_(I)/vec-extun-i32x4 : instr = ...
| "i32x4.extadd_pairwise_i16x8_s" => VEXTUNOP (I32 X `4) (I16 X `8) EXTADD_PAIRWISE S
| "i32x4.extadd_pairwise_i16x8_u" => VEXTUNOP (I32 X `4) (I16 X `8) EXTADD_PAIRWISE U
| ...
grammar Tplaininstr_(I)/vec-extbin-i16x8 : instr = ...
| "i16x8.extmul_low_i8x16_s" => VEXTBINOP (I16 X `8) (I8 X `16) EXTMUL LOW S
| "i16x8.extmul_low_i8x16_u" => VEXTBINOP (I16 X `8) (I8 X `16) EXTMUL LOW U
| "i16x8.extmul_high_i8x16_s" => VEXTBINOP (I16 X `8) (I8 X `16) EXTMUL HIGH S
| "i16x8.extmul_high_i8x16_u" => VEXTBINOP (I16 X `8) (I8 X `16) EXTMUL HIGH U
;;| "i16x8.dot_i8x16_s" => VEXTBINOP (I16 X `8) (I8 X `16) DOT S ;; does not exist!
| ...
grammar Tplaininstr_(I)/vec-extbin-i32x4 : instr = ...
| "i32x4.extmul_low_i16x8_s" => VEXTBINOP (I32 X `4) (I16 X `8) EXTMUL LOW S
| "i32x4.extmul_low_i16x8_u" => VEXTBINOP (I32 X `4) (I16 X `8) EXTMUL LOW U
| "i32x4.extmul_high_i16x8_s" => VEXTBINOP (I32 X `4) (I16 X `8) EXTMUL HIGH S
| "i32x4.extmul_high_i16x8_u" => VEXTBINOP (I32 X `4) (I16 X `8) EXTMUL HIGH U
| "i32x4.dot_i16x8_s" => VEXTBINOP (I32 X `4) (I16 X `8) DOT S
| ...
grammar Tplaininstr_(I)/vec-extbin-i64x2 : instr = ...
| "i64x2.extmul_low_i32x4_s" => VEXTBINOP (I64 X `2) (I32 X `4) EXTMUL LOW S
| "i64x2.extmul_low_i32x4_u" => VEXTBINOP (I64 X `2) (I32 X `4) EXTMUL LOW U
| "i64x2.extmul_high_i32x4_s" => VEXTBINOP (I64 X `2) (I32 X `4) EXTMUL HIGH S
| "i64x2.extmul_high_i32x4_u" => VEXTBINOP (I64 X `2) (I32 X `4) EXTMUL HIGH U
;;| "i64x2.dot_i32x4_s" => VEXTBINOP (I64 X `2) (I32 X `4) DOT S ;; does not exist!
;; Expressions
grammar Texpr_(I) : expr =
| in*:Tinstrs_(I) => in*