blob: e51133cb7166274844ae7db7ec99bbbeca073f0b [file] [log] [blame] [edit]
;;
;; Syntax of Instructions
;;
;; Constants
syntax num_(numtype)
syntax num_(Inn) = iN($sizenn(Inn))
syntax num_(Fnn) = fN($sizenn(Fnn))
syntax pack_(Pnn) = iN($psizenn(Pnn))
syntax lane_(lanetype)
syntax lane_(numtype) = num_(numtype)
syntax lane_(packtype) = pack_(packtype)
syntax lane_(Jnn) = iN($lsize(Jnn)) ;; HACK
syntax vec_(Vnn) = vN($vsize(Vnn))
syntax lit_(storagetype)
syntax lit_(numtype) = num_(numtype)
syntax lit_(vectype) = vec_(vectype)
syntax lit_(packtype) = pack_(packtype)
;; Numeric operators
syntax sz hint(desc "pack size") = `8 | `16 | `32 | `64
syntax sx hint(desc "signedness") = U | S
syntax unop_(numtype)
syntax unop_(Inn) = CLZ | CTZ | POPCNT | EXTEND sz hint(show EXTEND#%#_#S) -- if $(sz < $sizenn(Inn))
syntax unop_(Fnn) = ABS | NEG | SQRT | CEIL | FLOOR | TRUNC | NEAREST
syntax binop_(numtype)
syntax binop_(Inn) =
| ADD | SUB | MUL | DIV sx hint(show DIV#_#%) | REM sx hint(show REM#_#%)
| AND | OR | XOR | SHL | SHR sx hint(show SHR#_#%) | ROTL | ROTR
syntax binop_(Fnn) =
| ADD | SUB | MUL | DIV | MIN hint(macro "FMIN") | MAX hint(macro "FMAX") | COPYSIGN
syntax testop_(numtype)
syntax testop_(Inn) = EQZ
;; syntax testop_(Fnn) = | ;; uninhabited
syntax relop_(numtype)
syntax relop_(Inn) =
| EQ | NE \
| LT sx hint(show LT#_#%) | GT sx hint(show GT#_#%) \
| LE sx hint(show LE#_#%) | GE sx hint(show GE#_#%)
syntax relop_(Fnn) =
| EQ | NE | LT | GT | LE | GE
;; TODO(3, rossberg): change order of parameters?
syntax cvtop__(numtype_1, numtype_2)
syntax cvtop__(Inn_1, Inn_2) =
| EXTEND sx hint(show %0#_#%1) -- if $sizenn1(Inn_1) < $sizenn2(Inn_2)
| WRAP -- if $sizenn1(Inn_1) > $sizenn2(Inn_2)
syntax cvtop__(Inn_1, Fnn_2) =
| CONVERT sx hint(show %0#_#%1)
| REINTERPRET -- if $sizenn1(Inn_1) = $sizenn2(Fnn_2)
syntax cvtop__(Fnn_1, Inn_2) =
| TRUNC sx hint(show %0#_#%1)
| TRUNC_SAT sx hint(show %0#_#%1)
| REINTERPRET -- if $sizenn1(Fnn_1) = $sizenn2(Inn_2)
syntax cvtop__(Fnn_1, Fnn_2) =
| PROMOTE -- if $sizenn1(Fnn_1) < $sizenn2(Fnn_2)
| DEMOTE -- if $sizenn1(Fnn_1) > $sizenn2(Fnn_2)
;; Vector shapes
syntax dim hint(desc "dimension") = `1 | `2 | `4 | `8 | `16
syntax shape hint(desc "shape") = lanetype X dim hint(show %0#X#%2) hint(macro "%shape")
-- if $($lsize(lanetype) * dim = 128)
def $dim(shape) : dim hint(macro "shdim")
def $dim(Lnn X N) = N
def $lanetype(shape) : lanetype hint(macro "shlanetype")
def $lanetype(Lnn X N) = Lnn
def $unpackshape(shape) : numtype hint(show $unpack(%))
def $unpackshape(Lnn X N) = $lunpack(Lnn)
syntax ishape hint(desc "integer shape") = shape -- if $lanetype(shape) = Jnn
syntax bshape hint(desc "byte shape") = shape -- if $lanetype(shape) = I8
;; Vector operators
syntax zero = ZERO
syntax half = LOW | HIGH
syntax vvunop hint(macro "%" "V%") = NOT
syntax vvbinop hint(macro "%" "V%") = AND | ANDNOT | OR | XOR
syntax vvternop hint(macro "%" "V%") = BITSELECT
syntax vvtestop hint(macro "%" "V%") = ANY_TRUE
syntax vunop_(shape) hint(macro "%" "V%")
syntax vunop_(Jnn X M) = ABS | NEG
| POPCNT -- if $lsizenn(Jnn) = `8
syntax vunop_(Fnn X M) = ABS | NEG | SQRT | CEIL | FLOOR | TRUNC | NEAREST
syntax vbinop_(shape) hint(macro "%" "V%")
syntax vbinop_(Jnn X M) =
| ADD
| SUB
| ADD_SAT sx hint(show ADD_SAT#_#%) -- if $lsizenn(Jnn) <= `16
| SUB_SAT sx hint(show SUB_SAT#_#%) -- if $lsizenn(Jnn) <= `16
| MUL -- if $lsizenn(Jnn) >= `16
| AVGR U hint(show AVGR#_#%) -- if $lsizenn(Jnn) <= `16
| Q15MULR_SAT S hint(show Q15MULR_SAT#_#%) -- if $lsizenn(Jnn) = `16
| RELAXED_Q15MULR S hint(show RELAXED_Q15MULR#_#%) -- if $lsizenn(Jnn) = `16
| MIN sx hint(show MIN#_#%) -- if $lsizenn(Jnn) <= `32
| MAX sx hint(show MAX#_#%) -- if $lsizenn(Jnn) <= `32
syntax vbinop_(Fnn X M) = ADD | SUB | MUL | DIV | MIN | MAX | PMIN | PMAX
| RELAXED_MIN | RELAXED_MAX
syntax vternop_(shape) hint(macro "%" "V%")
syntax vternop_(Jnn X M) = RELAXED_LANESELECT
syntax vternop_(Fnn X M) = RELAXED_MADD | RELAXED_NMADD
syntax vtestop_(shape) hint(macro "%" "V%")
syntax vtestop_(Jnn X M) = ALL_TRUE
;; syntax vtestop_(Fnn X N) = | ;; uninhabited
syntax vrelop_(shape) hint(macro "%" "V%")
syntax vrelop_(Jnn X M) = EQ | NE
| LT sx hint(show LT#_#%) -- if $lsizenn(Jnn) =/= `64 \/ sx = S
| GT sx hint(show GT#_#%) -- if $lsizenn(Jnn) =/= `64 \/ sx = S
| LE sx hint(show LE#_#%) -- if $lsizenn(Jnn) =/= `64 \/ sx = S
| GE sx hint(show GE#_#%) -- if $lsizenn(Jnn) =/= `64 \/ sx = S
syntax vrelop_(Fnn X M) = EQ | NE | LT | GT | LE | GE
syntax vshiftop_(ishape) hint(macro "%" "V%")
syntax vshiftop_(Jnn X M) = SHL | SHR sx hint(show SHR#_#%)
syntax vswizzlop_(bshape) hint(macro "%" "V%")
syntax vswizzlop_(I8 X M) = SWIZZLE | RELAXED_SWIZZLE
syntax vextunop__(ishape_1, ishape_2) hint(macro "%" "V%")
syntax vextunop__(Jnn_1 X M_1, Jnn_2 X M_2) =
| EXTADD_PAIRWISE sx hint(show EXTADD_PAIRWISE#_#%)
-- if 16 <= $(2 * $lsizenn1(Jnn_1)) = $lsizenn2(Jnn_2) <= `32
syntax vextbinop__(ishape_1, ishape_2) hint(macro "%" "V%")
syntax vextbinop__(Jnn_1 X M_1, Jnn_2 X M_2) =
| EXTMUL half sx hint(show EXTMUL#_#%#_#%)
-- if $(2 * $lsizenn1(Jnn_1)) = $lsizenn2(Jnn_2) >= `16
| DOT S hint(show DOT#_#%)
-- if $(2 * $lsizenn1(Jnn_1)) = $lsizenn2(Jnn_2) = `32
| RELAXED_DOT S hint(show RELAXED_DOT#_#%)
-- if $(2 * $lsizenn1(Jnn_1)) = $lsizenn2(Jnn_2) = `16
syntax vextternop__(ishape_1, ishape_2) hint(macro "%" "V%")
syntax vextternop__(Jnn_1 X M_1, Jnn_2 X M_2) =
| RELAXED_DOT_ADD S hint(show RELAXED_DOT_ADD#_#%)
-- if $(4 * $lsizenn1(Jnn_1)) = $lsizenn2(Jnn_2) = `32
syntax vcvtop__(shape_1, shape_2) hint(macro "%" "V%")
syntax vcvtop__(Jnn_1 X M_1, Jnn_2 X M_2) =
| EXTEND half sx hint(show EXTEND#_#%#_#%)
-- if $lsizenn2(Jnn_2) = $(2 * $lsizenn1(Jnn_1))
syntax vcvtop__(Jnn_1 X M_1, Fnn_2 X M_2) =
| CONVERT half? sx hint(show CONVERT#_#%#_#%) hint(show CONVERT#_#%)
-- if $sizenn2(Fnn_2) = $lsizenn1(Jnn_1) = `32 /\ half? = eps
\/ $sizenn2(Fnn_2) = $(2 * $lsizenn1(Jnn_1)) /\ half? = LOW
syntax vcvtop__(Fnn_1 X M_1, Jnn_2 X M_2) =
| TRUNC_SAT sx zero? hint(show TRUNC_SAT#_#%#_#%) hint(show TRUNC_SAT#_#%)
-- if $sizenn1(Fnn_1) = $lsizenn2(Jnn_2) = `32 /\ zero? = eps
\/ $sizenn1(Fnn_1) = $(2 * $lsizenn2(Jnn_2)) /\ zero? = ZERO
| RELAXED_TRUNC sx zero? hint(show RELAXED_TRUNC#_#%#_#%) hint(show RELAXED_TRUNC#_#%)
-- if $sizenn1(Fnn_1) = $lsizenn2(Jnn_2) = `32 /\ zero? = eps
\/ $sizenn1(Fnn_1) = $(2 * $lsizenn2(Jnn_2)) /\ zero? = ZERO
syntax vcvtop__(Fnn_1 X M_1, Fnn_2 X M_2) =
| DEMOTE zero hint(show DEMOTE#_#ZERO)
-- if $sizenn1(Fnn_1) = $(2 * $sizenn2(Fnn_2))
| PROMOTE LOW hint(show PROMOTE#_#LOW)
-- if $(2 * $sizenn1(Fnn_1)) = $sizenn2(Fnn_2)
;; Memory operators
syntax memarg hint(desc "memory argument") = {ALIGN u32, OFFSET u64}
var ao : memarg
syntax loadop_(numtype)
syntax loadop_(Inn) = sz _ sx hint(show %0#_#%2) -- if sz < $sizenn(Inn)
syntax storeop_(numtype)
syntax storeop_(Inn) = sz -- if sz < $sizenn(Inn)
syntax vloadop_(vectype) hint(macro "%" "L%") =
| SHAPE sz X M _ sx hint(show %1#X#%3#_#%5) hint(macro "%shape") -- if $(sz * M = $vsize(vectype)/2)
| SPLAT sz hint(show %#_#SPLAT)
| ZERO sz hint(show %#_#ZERO) -- if sz >= `32
;; Block types
syntax blocktype hint(desc "block type") =
| _RESULT valtype?
| _IDX typeidx
var bt : blocktype
;; Instructions
syntax instr hint(desc "instruction")
syntax instr/parametric hint(desc "parametric instruction") =
| NOP
| UNREACHABLE
| DROP
| SELECT (valtype*)?
| ...
syntax instr/block hint(desc "block instruction") = ...
| BLOCK blocktype instr*
| LOOP blocktype instr*
| IF blocktype instr* ELSE instr*
| ...
syntax instr/br hint(desc "branch instruction") = ...
| BR labelidx
| BR_IF labelidx
| BR_TABLE labelidx* labelidx
| BR_ON_NULL labelidx
| BR_ON_NON_NULL labelidx
| BR_ON_CAST labelidx reftype reftype
| BR_ON_CAST_FAIL labelidx reftype reftype
| ...
syntax instr/call hint(desc "function instruction") = ...
| CALL funcidx
| CALL_REF typeuse
| CALL_INDIRECT tableidx typeuse
| RETURN
| RETURN_CALL funcidx
| RETURN_CALL_REF typeuse
| RETURN_CALL_INDIRECT tableidx typeuse
| ...
syntax instr/exn hint(desc "exception instructions") = ...
| THROW tagidx
| THROW_REF
| TRY_TABLE blocktype list(catch) instr*
| ...
syntax catch hint(desc "catch clause") =
| CATCH tagidx labelidx
| CATCH_REF tagidx labelidx
| CATCH_ALL labelidx
| CATCH_ALL_REF labelidx
syntax instr/local hint(desc "local instruction") = ...
| LOCAL.GET localidx
| LOCAL.SET localidx
| LOCAL.TEE localidx
| ...
syntax instr/global hint(desc "global instruction") = ...
| GLOBAL.GET globalidx
| GLOBAL.SET globalidx
| ...
syntax instr/table hint(desc "table instruction") = ...
| TABLE.GET tableidx
| TABLE.SET tableidx
| TABLE.SIZE tableidx
| TABLE.GROW tableidx
| TABLE.FILL tableidx
| TABLE.COPY tableidx tableidx
| TABLE.INIT tableidx elemidx
| ...
syntax instr/elem hint(desc "element instruction") = ...
| ELEM.DROP elemidx
| ...
syntax instr/memory hint(desc "memory instruction") = ...
| LOAD numtype loadop_(numtype)? memidx memarg hint(show %.LOAD % %) hint(show %.LOAD# ##% % %)
| STORE numtype storeop_(numtype)? memidx memarg hint(show %.STORE % %) hint(show %.STORE#% % %)
| VLOAD vectype vloadop_(vectype)? memidx memarg hint(show %.LOAD % %) hint(show %.LOAD# ##% % %) hint(macro "V%")
| VLOAD_LANE vectype sz memidx memarg laneidx hint(show %.LOAD#%#_#LANE % % %) hint(macro "V%")
| VSTORE vectype memidx memarg hint(show %.STORE % %) hint(macro "V%")
| VSTORE_LANE vectype sz memidx memarg laneidx hint(show %.STORE#%#_#LANE % % %) hint(macro "V%")
| MEMORY.SIZE memidx
| MEMORY.GROW memidx
| MEMORY.FILL memidx
| MEMORY.COPY memidx memidx
| MEMORY.INIT memidx dataidx
| ...
syntax instr/data hint(desc "data instruction") = ...
| DATA.DROP dataidx
| ...
syntax instr/ref hint(desc "reference instruction") = ...
| REF.NULL heaptype
| REF.IS_NULL
| REF.AS_NON_NULL
| REF.EQ
| REF.TEST reftype
| REF.CAST reftype
| ...
syntax instr/func hint(desc "function reference instruction") = ...
| REF.FUNC funcidx
| ...
syntax instr/i31 hint(desc "scalar reference instruction") = ...
| REF.I31
| I31.GET sx hint(show I31.GET#_#%)
| ...
syntax instr/struct hint(desc "structure reference instruction") = ...
| STRUCT.NEW typeidx
| STRUCT.NEW_DEFAULT typeidx
| STRUCT.GET sx? typeidx u32 hint(show STRUCT.GET#_#% % %)
| STRUCT.SET typeidx u32
| ...
syntax instr/array hint(desc "array reference instruction") = ...
| ARRAY.NEW typeidx
| ARRAY.NEW_DEFAULT typeidx
| ARRAY.NEW_FIXED typeidx u32
| ARRAY.NEW_DATA typeidx dataidx
| ARRAY.NEW_ELEM typeidx elemidx
| ARRAY.GET sx? typeidx hint(show ARRAY.GET#_#% %)
| ARRAY.SET typeidx
| ARRAY.LEN
| ARRAY.FILL typeidx
| ARRAY.COPY typeidx typeidx
| ARRAY.INIT_DATA typeidx dataidx
| ARRAY.INIT_ELEM typeidx elemidx
| ...
syntax instr/extern hint(desc "external reference instruction") = ...
| EXTERN.CONVERT_ANY
| ANY.CONVERT_EXTERN
| ...
syntax instr/num hint(desc "numeric instruction") = ...
| CONST numtype num_(numtype) hint(show %.CONST %)
| UNOP numtype unop_(numtype) hint(show %.##%)
| BINOP numtype binop_(numtype) hint(show %.##%)
| TESTOP numtype testop_(numtype) hint(show %.##%)
| RELOP numtype relop_(numtype) hint(show %.##%)
| CVTOP numtype_1 numtype_2 cvtop__(numtype_2, numtype_1) hint(show %1.##%3#_#%2)
| ...
syntax instr/vec hint(desc "vector instruction") = ...
| VCONST vectype vec_(vectype) hint(show %.CONST %)
| VVUNOP vectype vvunop hint(show %.##%)
| VVBINOP vectype vvbinop hint(show %.##%)
| VVTERNOP vectype vvternop hint(show %.##%)
| VVTESTOP vectype vvtestop hint(show %.##%)
| VUNOP shape vunop_(shape) hint(show ##%.##%)
| VBINOP shape vbinop_(shape) hint(show ##%.##%)
| VTERNOP shape vternop_(shape) hint(show ##%.##%)
| VTESTOP shape vtestop_(shape) hint(show ##%.##%)
| VRELOP shape vrelop_(shape) hint(show ##%.##%)
| VSHIFTOP ishape vshiftop_(ishape) hint(show ##%.##%)
| VBITMASK ishape hint(show ##%.BITMASK) hint(macro "VBITMASK")
| VSWIZZLOP bshape vswizzlop_(bshape) hint(show ##%.##%)
| VSHUFFLE bshape laneidx* hint(show ##%.SHUFFLE %) hint(macro "VSHUFFLE")
-- if |laneidx*| = $dim(bshape)
| VEXTUNOP ishape_1 ishape_2 vextunop__(ishape_2, ishape_1)
hint(show ##%1.##%3#_# ##%2)
| VEXTBINOP ishape_1 ishape_2 vextbinop__(ishape_2, ishape_1)
hint(show ##%1.##%3#_# ##%2)
| VEXTTERNOP ishape_1 ishape_2 vextternop__(ishape_2, ishape_1)
hint(show ##%1.##%3#_# ##%2)
| VNARROW ishape_1 ishape_2 sx hint(show ##%.NARROW#_# ##%#_#%) hint(macro "VNARROW")
-- if $($lsize($lanetype(ishape_2)) = 2*$lsize($lanetype(ishape_1)) <= `32)
| VCVTOP shape_1 shape_2 vcvtop__(shape_2, shape_1) hint(show ##%1.%3#_# ##%2)
| VSPLAT shape hint(show ##%.SPLAT) hint(macro "VSPLAT")
| VEXTRACT_LANE shape sx? laneidx hint(show ##%.EXTRACT_LANE %) hint(show ##%.EXTRACT_LANE#_#% %) hint(macro "VEXTRACT_LANE")
-- if sx? = eps <=> $lanetype(shape) <- I32 I64 F32 F64
| VREPLACE_LANE shape laneidx hint(show ##%.REPLACE_LANE %) hint(macro "VREPLACE_LANE")
| ...
;; Expressions
syntax expr hint(desc "expression") =
instr*
;; Meta variables
var in : instr
var e : expr
;; Shorthands
def $memarg0 : memarg hint(show )
def $memarg0 = {ALIGN 0, OFFSET 0}
def $const(consttype, lit_(consttype)) : instr hint(show %.CONST %)
def $const(numtype, c) = (CONST numtype c)
def $const(vectype, c) = (VCONST vectype c)
;; Free indices
def $free_shape(shape) : free
def $free_blocktype(blocktype) : free
def $free_instr(instr) : free
def $free_block(instr*) : free
def $free_expr(expr) : free
def $free_shape(lanetype X dim) = $free_lanetype(lanetype)
def $free_blocktype(_RESULT valtype?) = $free_opt($free_valtype(valtype)?)
def $free_blocktype(_IDX typeidx) = $free_typeidx(typeidx)
def $free_instr(NOP) = {}
def $free_instr(UNREACHABLE) = {}
def $free_instr(DROP) = {}
def $free_instr(SELECT (valtype*)?) = $free_opt($free_list($free_valtype(valtype)*)?)
def $free_instr(BLOCK blocktype instr*) = $free_blocktype(blocktype) ++ $free_block(instr*)
def $free_instr(LOOP blocktype instr*) = $free_blocktype(blocktype) ++ $free_block(instr*)
def $free_instr(IF blocktype instr_1* ELSE instr_2*) =
$free_blocktype(blocktype) ++ $free_block(instr_1*) ++ $free_block(instr_2*)
def $free_instr(BR labelidx) = $free_labelidx(labelidx)
def $free_instr(BR_IF labelidx) = $free_labelidx(labelidx)
def $free_instr(BR_TABLE labelidx* labelidx') =
$free_list($free_labelidx(labelidx)*) ++ $free_labelidx(labelidx')
def $free_instr(BR_ON_NULL labelidx) = $free_labelidx(labelidx)
def $free_instr(BR_ON_NON_NULL labelidx) = $free_labelidx(labelidx)
def $free_instr(BR_ON_CAST labelidx reftype_1 reftype_2) =
$free_labelidx(labelidx) ++ $free_reftype(reftype_1) ++ $free_reftype(reftype_2)
def $free_instr(BR_ON_CAST_FAIL labelidx reftype_1 reftype_2) =
$free_labelidx(labelidx) ++ $free_reftype(reftype_1) ++ $free_reftype(reftype_2)
def $free_instr(CALL funcidx) = $free_funcidx(funcidx)
def $free_instr(CALL_REF typeuse) = $free_typeuse(typeuse)
def $free_instr(CALL_INDIRECT tableidx typeuse) =
$free_tableidx(tableidx) ++ $free_typeuse(typeuse)
def $free_instr(RETURN) = {}
def $free_instr(RETURN_CALL funcidx) = $free_funcidx(funcidx)
def $free_instr(RETURN_CALL_REF typeuse) = $free_typeuse(typeuse)
def $free_instr(RETURN_CALL_INDIRECT tableidx typeuse) =
$free_tableidx(tableidx) ++ $free_typeuse(typeuse)
def $free_instr(CONST numtype numlit) = $free_numtype(numtype)
def $free_instr(UNOP numtype unop) = $free_numtype(numtype)
def $free_instr(BINOP numtype binop) = $free_numtype(numtype)
def $free_instr(TESTOP numtype testop) = $free_numtype(numtype)
def $free_instr(RELOP numtype relop) = $free_numtype(numtype)
def $free_instr(CVTOP numtype_1 numtype_2 cvtop) =
$free_numtype(numtype_1) ++ $free_numtype(numtype_2)
def $free_instr(VCONST vectype veclit) = $free_vectype(vectype)
def $free_instr(VVUNOP vectype vvunop) = $free_vectype(vectype)
def $free_instr(VVBINOP vectype vvbinop) = $free_vectype(vectype)
def $free_instr(VVTERNOP vectype vvternop) = $free_vectype(vectype)
def $free_instr(VVTESTOP vectype vvtestop) = $free_vectype(vectype)
def $free_instr(VUNOP shape vunop) = $free_shape(shape)
def $free_instr(VBINOP shape vbinop) = $free_shape(shape)
def $free_instr(VTERNOP shape vternop) = $free_shape(shape)
def $free_instr(VTESTOP shape vtestop) = $free_shape(shape)
def $free_instr(VRELOP shape vrelop) = $free_shape(shape)
def $free_instr(VSHIFTOP ishape vshiftop) = $free_shape(ishape)
def $free_instr(VBITMASK ishape) = $free_shape(ishape)
def $free_instr(VSWIZZLOP bshape vswizzlop) = $free_shape(bshape)
def $free_instr(VSHUFFLE bshape laneidx*) = $free_shape(bshape)
def $free_instr(VEXTUNOP ishape_1 ishape_2 vextunop) =
$free_shape(ishape_1) ++ $free_shape(ishape_2)
def $free_instr(VEXTBINOP ishape_1 ishape_2 vextbinop) =
$free_shape(ishape_1) ++ $free_shape(ishape_2)
def $free_instr(VEXTTERNOP ishape_1 ishape_2 vextternop) =
$free_shape(ishape_1) ++ $free_shape(ishape_2)
def $free_instr(VNARROW ishape_1 ishape_2 sx) =
$free_shape(ishape_1) ++ $free_shape(ishape_2)
def $free_instr(VCVTOP shape_1 shape_2 vcvtop) =
$free_shape(shape_1) ++ $free_shape(shape_2)
def $free_instr(VSPLAT shape) = $free_shape(shape)
def $free_instr(VEXTRACT_LANE shape sx? laneidx) = $free_shape(shape)
def $free_instr(VREPLACE_LANE shape laneidx) = $free_shape(shape)
def $free_instr(REF.NULL heaptype) = $free_heaptype(heaptype)
def $free_instr(REF.IS_NULL) = {}
def $free_instr(REF.AS_NON_NULL) = {}
def $free_instr(REF.EQ) = {}
def $free_instr(REF.TEST reftype) = $free_reftype(reftype)
def $free_instr(REF.CAST reftype) = $free_reftype(reftype)
def $free_instr(REF.FUNC funcidx) = $free_funcidx(funcidx)
def $free_instr(REF.I31) = {}
def $free_instr(I31.GET sx) = {}
def $free_instr(STRUCT.NEW typeidx) = {}
def $free_instr(STRUCT.NEW_DEFAULT typeidx) = $free_typeidx(typeidx)
def $free_instr(STRUCT.GET sx? typeidx u32) = $free_typeidx(typeidx)
def $free_instr(STRUCT.SET typeidx u32) = $free_typeidx(typeidx)
def $free_instr(ARRAY.NEW typeidx) = $free_typeidx(typeidx)
def $free_instr(ARRAY.NEW_DEFAULT typeidx) = $free_typeidx(typeidx)
def $free_instr(ARRAY.NEW_FIXED typeidx u32) = $free_typeidx(typeidx)
def $free_instr(ARRAY.NEW_DATA typeidx dataidx) =
$free_typeidx(typeidx) ++ $free_dataidx(dataidx)
def $free_instr(ARRAY.NEW_ELEM typeidx elemidx) =
$free_typeidx(typeidx) ++ $free_elemidx(elemidx)
def $free_instr(ARRAY.GET sx? typeidx) = $free_typeidx(typeidx)
def $free_instr(ARRAY.SET typeidx) = $free_typeidx(typeidx)
def $free_instr(ARRAY.LEN) = {}
def $free_instr(ARRAY.FILL typeidx) = $free_typeidx(typeidx)
def $free_instr(ARRAY.COPY typeidx_1 typeidx_2) =
$free_typeidx(typeidx_1) ++ $free_typeidx(typeidx_2)
def $free_instr(ARRAY.INIT_DATA typeidx dataidx) =
$free_typeidx(typeidx) ++ $free_dataidx(dataidx)
def $free_instr(ARRAY.INIT_ELEM typeidx elemidx) =
$free_typeidx(typeidx) ++ $free_elemidx(elemidx)
def $free_instr(EXTERN.CONVERT_ANY) = {}
def $free_instr(ANY.CONVERT_EXTERN) = {}
def $free_instr(LOCAL.GET localidx) = $free_localidx(localidx)
def $free_instr(LOCAL.SET localidx) = $free_localidx(localidx)
def $free_instr(LOCAL.TEE localidx) = $free_localidx(localidx)
def $free_instr(GLOBAL.GET globalidx) = $free_globalidx(globalidx)
def $free_instr(GLOBAL.SET globalidx) = $free_globalidx(globalidx)
def $free_instr(TABLE.GET tableidx) = $free_tableidx(tableidx)
def $free_instr(TABLE.SET tableidx) = $free_tableidx(tableidx)
def $free_instr(TABLE.SIZE tableidx) = $free_tableidx(tableidx)
def $free_instr(TABLE.GROW tableidx) = $free_tableidx(tableidx)
def $free_instr(TABLE.FILL tableidx) = $free_tableidx(tableidx)
def $free_instr(TABLE.COPY tableidx_1 tableidx_2) =
$free_tableidx(tableidx_1) ++ $free_tableidx(tableidx_2)
def $free_instr(TABLE.INIT tableidx elemidx) =
$free_tableidx(tableidx) ++ $free_elemidx(elemidx)
def $free_instr(ELEM.DROP elemidx) = $free_elemidx(elemidx)
def $free_instr(LOAD numtype loadop? memidx memarg) =
$free_numtype(numtype) ++ $free_memidx(memidx)
def $free_instr(STORE numtype storeop? memidx memarg) =
$free_numtype(numtype) ++ $free_memidx(memidx)
def $free_instr(VLOAD vectype vloadop? memidx memarg) =
$free_vectype(vectype) ++ $free_memidx(memidx)
def $free_instr(VLOAD_LANE vectype sz memidx memarg laneidx) =
$free_vectype(vectype) ++ $free_memidx(memidx)
def $free_instr(VSTORE vectype memidx memarg) =
$free_vectype(vectype) ++ $free_memidx(memidx)
def $free_instr(VSTORE_LANE vectype sz memidx memarg laneidx) =
$free_vectype(vectype) ++ $free_memidx(memidx)
def $free_instr(MEMORY.SIZE memidx) = $free_memidx(memidx)
def $free_instr(MEMORY.GROW memidx) = $free_memidx(memidx)
def $free_instr(MEMORY.FILL memidx) = $free_memidx(memidx)
def $free_instr(MEMORY.COPY memidx_1 memidx_2) =
$free_memidx(memidx_1) ++ $free_memidx(memidx_2)
def $free_instr(MEMORY.INIT memidx dataidx) =
$free_memidx(memidx) ++ $free_dataidx(dataidx)
def $free_instr(DATA.DROP dataidx) = $free_dataidx(dataidx)
def $shift_labelidxs(labelidx*) : labelidx*
def $shift_labelidxs(eps) = eps
def $shift_labelidxs(0 labelidx'*) = $shift_labelidxs(labelidx'*)
def $shift_labelidxs(labelidx labelidx'*) = ($(labelidx - 1)) $shift_labelidxs(labelidx'*)
def $free_block(instr*) = free[.LABELS = $shift_labelidxs(free.LABELS)]
-- if free = $free_list($free_instr(instr)*)
def $free_expr(instr*) = $free_list($free_instr(instr)*)