Instructions

WebAssembly code consists of sequences of instructions. Its computational model is based on a stack machine in that instructions manipulate values on an implicit operand stack, consuming (popping) argument values and producing or returning (pushing) result values.

In addition to dynamic operands from the stack, some instructions also have static immediate arguments, typically indices or type annotations, which are part of the instruction itself.

Some instructions are structured in that they bracket nested sequences of instructions.

The following sections group instructions into a number of different categories.

Numeric Instructions

Numeric instructions provide basic operations over numeric values of specific type. These operations closely match respective operations available in hardware.

\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{width} & \mathit{nn}, \mathit{mm} &::=& \mathsf{32} ~|~ \mathsf{64} \\ \def\mathdef2803#1{{}}\mathdef2803{signedness} & \href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} &::=& \mathsf{u} ~|~ \mathsf{s} \\ \def\mathdef2803#1{{}}\mathdef2803{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\href{../syntax/values.html#syntax-int}{\def\mathdef2842#1{{\mathit{u#1}}}\mathdef2842{\mathit{nn}}} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{const}}~\href{../syntax/values.html#syntax-float}{\def\mathdef2843#1{{\mathit{f#1}}}\mathdef2843{\mathit{nn}}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-iunop}{\mathit{iunop}} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-funop}{\mathit{funop}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-ibinop}{\mathit{ibinop}} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-fbinop}{\mathit{fbinop}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-itestop}{\mathit{itestop}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-irelop}{\mathit{irelop}} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-frelop}{\mathit{frelop}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{extend}}\mathsf{8\_s} ~|~ \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{extend}}\mathsf{16\_s} ~|~ \mathsf{i64.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{extend}}\mathsf{32\_s} \\&&|& \mathsf{i32.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{wrap}}\mathsf{\_i64} ~|~ \mathsf{i64.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{extend}}\mathsf{\_i32}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{trunc}}\mathsf{\_f}\mathit{mm}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{trunc}}\mathsf{\_sat\_f}\mathit{mm}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\&&|& \mathsf{f32.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{demote}}\mathsf{\_f64} ~|~ \mathsf{f64.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{promote}}\mathsf{\_f32} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{convert}}\mathsf{\_i}\mathit{mm}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{reinterpret}}\mathsf{\_f}\mathit{nn} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{reinterpret}}\mathsf{\_i}\mathit{nn} \\&&|& \dots \\ \def\mathdef2803#1{{}}\mathdef2803{integer unary operator} & \href{../syntax/instructions.html#syntax-iunop}{\mathit{iunop}} &::=& \mathsf{clz} ~|~ \mathsf{ctz} ~|~ \mathsf{popcnt} \\ \def\mathdef2803#1{{}}\mathdef2803{integer binary operator} & \href{../syntax/instructions.html#syntax-ibinop}{\mathit{ibinop}} &::=& \mathsf{add} ~|~ \mathsf{sub} ~|~ \mathsf{mul} ~|~ \mathsf{div\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{rem\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\&&|& \mathsf{and} ~|~ \mathsf{or} ~|~ \mathsf{xor} ~|~ \mathsf{shl} ~|~ \mathsf{shr\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{rotl} ~|~ \mathsf{rotr} \\ \def\mathdef2803#1{{}}\mathdef2803{floating-point unary operator} & \href{../syntax/instructions.html#syntax-funop}{\mathit{funop}} &::=& \mathsf{abs} ~|~ \mathsf{neg} ~|~ \mathsf{sqrt} ~|~ \mathsf{ceil} ~|~ \mathsf{floor} ~|~ \mathsf{trunc} ~|~ \mathsf{nearest} \\ \def\mathdef2803#1{{}}\mathdef2803{floating-point binary operator} & \href{../syntax/instructions.html#syntax-fbinop}{\mathit{fbinop}} &::=& \mathsf{add} ~|~ \mathsf{sub} ~|~ \mathsf{mul} ~|~ \mathsf{div} ~|~ \mathsf{min} ~|~ \mathsf{max} ~|~ \mathsf{copysign} \\ \def\mathdef2803#1{{}}\mathdef2803{integer test operator} & \href{../syntax/instructions.html#syntax-itestop}{\mathit{itestop}} &::=& \mathsf{eqz} \\ \def\mathdef2803#1{{}}\mathdef2803{integer relational operator} & \href{../syntax/instructions.html#syntax-irelop}{\mathit{irelop}} &::=& \mathsf{eq} ~|~ \mathsf{ne} ~|~ \mathsf{lt\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{gt\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{le\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{ge\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\ \def\mathdef2803#1{{}}\mathdef2803{floating-point relational operator} & \href{../syntax/instructions.html#syntax-frelop}{\mathit{frelop}} &::=& \mathsf{eq} ~|~ \mathsf{ne} ~|~ \mathsf{lt} ~|~ \mathsf{gt} ~|~ \mathsf{le} ~|~ \mathsf{ge} \\ \end{array}\end{split}\]

Numeric instructions are divided by number type. For each type, several subcategories can be distinguished:

  • Constants: return a static constant.

  • Unary Operations: consume one operand and produce one result of the respective type.

  • Binary Operations: consume two operands and produce one result of the respective type.

  • Tests: consume one operand of the respective type and produce a Boolean integer result.

  • Comparisons: consume two operands of the respective type and produce a Boolean integer result.

  • Conversions: consume a value of one type and produce a result of another (the source type of the conversion is the one after the “\(\mathsf{\_}\)”).

Some integer instructions come in two flavors, where a signedness annotation \(\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\) distinguishes whether the operands are to be interpreted as unsigned or signed integers. For the other integer instructions, the use of two’s complement for the signed interpretation means that they behave the same regardless of signedness.

Conventions

Occasionally, it is convenient to group operators together according to the following grammar shorthands:

\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{unary operator} & \href{../syntax/instructions.html#syntax-unop}{\mathit{unop}} &::=& \href{../syntax/instructions.html#syntax-iunop}{\mathit{iunop}} ~|~ \href{../syntax/instructions.html#syntax-funop}{\mathit{funop}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{extend}}{N}\mathsf{\_s} \\ \def\mathdef2803#1{{}}\mathdef2803{binary operator} & \href{../syntax/instructions.html#syntax-binop}{\mathit{binop}} &::=& \href{../syntax/instructions.html#syntax-ibinop}{\mathit{ibinop}} ~|~ \href{../syntax/instructions.html#syntax-fbinop}{\mathit{fbinop}} \\ \def\mathdef2803#1{{}}\mathdef2803{test operator} & \href{../syntax/instructions.html#syntax-testop}{\mathit{testop}} &::=& \href{../syntax/instructions.html#syntax-itestop}{\mathit{itestop}} \\ \def\mathdef2803#1{{}}\mathdef2803{relational operator} & \href{../syntax/instructions.html#syntax-relop}{\mathit{relop}} &::=& \href{../syntax/instructions.html#syntax-irelop}{\mathit{irelop}} ~|~ \href{../syntax/instructions.html#syntax-frelop}{\mathit{frelop}} \\ \def\mathdef2803#1{{}}\mathdef2803{conversion operator} & \href{../syntax/instructions.html#syntax-cvtop}{\mathit{cvtop}} &::=& \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{wrap}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{extend}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{trunc}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{trunc}}\mathsf{\_sat} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{convert}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{demote}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{promote}} ~|~ \href{../syntax/instructions.html#syntax-instr-numeric}{\mathsf{reinterpret}} \\ \end{array}\end{split}\]

Vector Instructions

Vector instructions (also known as SIMD instructions, single instruction multiple data) provide basic operations over values of vector type.

\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{ishape} & \href{../syntax/instructions.html#syntax-shape}{\mathit{ishape}} &::=& \mathsf{i8x16} ~|~ \mathsf{i16x8} ~|~ \mathsf{i32x4} ~|~ \mathsf{i64x2} \\ \def\mathdef2803#1{{}}\mathdef2803{fshape} & \href{../syntax/instructions.html#syntax-shape}{\mathit{fshape}} &::=& \mathsf{f32x4} ~|~ \mathsf{f64x2} \\ \def\mathdef2803#1{{}}\mathdef2803{shape} & \href{../syntax/instructions.html#syntax-shape}{\mathit{shape}} &::=& \href{../syntax/instructions.html#syntax-shape}{\mathit{ishape}} ~|~ \href{../syntax/instructions.html#syntax-shape}{\mathit{fshape}} \\ \def\mathdef2803#1{{}}\mathdef2803{half} & \href{../syntax/instructions.html#syntax-half}{\mathit{half}} &::=& \mathsf{low} ~|~ \mathsf{high} \\ \def\mathdef2803#1{{}}\mathdef2803{lane index} & \href{../syntax/instructions.html#syntax-laneidx}{\mathit{laneidx}} &::=& \href{../syntax/values.html#syntax-int}{\mathit{u8}} \\ \end{array}\end{split}\]
\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \dots \\&&|& \mathsf{v128.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{const}}~\href{../syntax/values.html#syntax-int}{\mathit{i128}} \\&&|& \mathsf{v128.}\href{../syntax/instructions.html#syntax-vvunop}{\mathit{vvunop}} \\&&|& \mathsf{v128.}\href{../syntax/instructions.html#syntax-vvbinop}{\mathit{vvbinop}} \\&&|& \mathsf{v128.}\href{../syntax/instructions.html#syntax-vvternop}{\mathit{vvternop}} \\&&|& \mathsf{v128.}\href{../syntax/instructions.html#syntax-vvtestop}{\mathit{vvtestop}} \\&&|& \mathsf{i8x16.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{shuffle}}~\href{../syntax/instructions.html#syntax-laneidx}{\mathit{laneidx}}^{16} \\&&|& \mathsf{i8x16.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{swizzle}} \\&&|& \href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{splat}} \\&&|& \mathsf{i8x16.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extract\_lane}}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-laneidx}{\mathit{laneidx}} ~|~ \mathsf{i16x8.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extract\_lane}}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-laneidx}{\mathit{laneidx}} \\&&|& \mathsf{i32x4.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extract\_lane}}~\href{../syntax/instructions.html#syntax-laneidx}{\mathit{laneidx}} ~|~ \mathsf{i64x2.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extract\_lane}}~\href{../syntax/instructions.html#syntax-laneidx}{\mathit{laneidx}} \\&&|& \href{../syntax/instructions.html#syntax-shape}{\mathit{fshape}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extract\_lane}}~\href{../syntax/instructions.html#syntax-laneidx}{\mathit{laneidx}} \\&&|& \href{../syntax/instructions.html#syntax-shape}{\mathit{shape}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{replace\_lane}}~\href{../syntax/instructions.html#syntax-laneidx}{\mathit{laneidx}} \\&&|& \mathsf{i8x16}\mathsf{.}\href{../syntax/instructions.html#syntax-virelop}{\mathit{virelop}} ~|~ \mathsf{i16x8}\mathsf{.}\href{../syntax/instructions.html#syntax-virelop}{\mathit{virelop}} ~|~ \mathsf{i32x4}\mathsf{.}\href{../syntax/instructions.html#syntax-virelop}{\mathit{virelop}} \\&&|& \mathsf{i64x2.}\mathsf{eq} ~|~ \mathsf{i64x2.}\mathsf{ne} ~|~ \mathsf{i64x2.}\mathsf{lt\_s} ~|~ \mathsf{i64x2.}\mathsf{gt\_s} ~|~ \mathsf{i64x2.}\mathsf{le\_s} ~|~ \mathsf{i64x2.}\mathsf{ge\_s} \\&&|& \href{../syntax/instructions.html#syntax-shape}{\mathit{fshape}}\mathsf{.}\href{../syntax/instructions.html#syntax-vfrelop}{\mathit{vfrelop}} \\&&|& \href{../syntax/instructions.html#syntax-shape}{\mathit{ishape}}\mathsf{.}\href{../syntax/instructions.html#syntax-viunop}{\mathit{viunop}} ~|~ \mathsf{i8x16.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{popcnt}} \\&&|& \mathsf{i16x8.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{q15mulr\_sat}}\mathsf{\_s} \\ &&|& \mathsf{i32x4.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{dot}}\mathsf{\_i16x8\_s} \\ &&|& \href{../syntax/instructions.html#syntax-shape}{\mathit{fshape}}\mathsf{.}\href{../syntax/instructions.html#syntax-vfunop}{\mathit{vfunop}} \\&&|& \href{../syntax/instructions.html#syntax-shape}{\mathit{ishape}}\mathsf{.}\href{../syntax/instructions.html#syntax-vitestop}{\mathit{vitestop}} \\ &&|& \href{../syntax/instructions.html#syntax-shape}{\mathit{ishape}}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{bitmask}} \\ &&|& \mathsf{i8x16.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{narrow}}\mathsf{\_i16x8\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{i16x8.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{narrow}}\mathsf{\_i32x4\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\&&|& \mathsf{i16x8.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extend}}\mathsf{\_}\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\mathsf{\_i8x16\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{i32x4.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extend}}\mathsf{\_}\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\mathsf{\_i16x8\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\&&|& \mathsf{i64x2.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extend}}\mathsf{\_}\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\mathsf{\_i32x4\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\&&|& \href{../syntax/instructions.html#syntax-shape}{\mathit{ishape}}\mathsf{.}\href{../syntax/instructions.html#syntax-vishiftop}{\mathit{vishiftop}} \\&&|& \href{../syntax/instructions.html#syntax-shape}{\mathit{ishape}}\mathsf{.}\href{../syntax/instructions.html#syntax-vibinop}{\mathit{vibinop}} \\&&|& \mathsf{i8x16.}\href{../syntax/instructions.html#syntax-viminmaxop}{\mathit{viminmaxop}} ~|~ \mathsf{i16x8.}\href{../syntax/instructions.html#syntax-viminmaxop}{\mathit{viminmaxop}} ~|~ \mathsf{i32x4.}\href{../syntax/instructions.html#syntax-viminmaxop}{\mathit{viminmaxop}} \\&&|& \mathsf{i8x16.}\href{../syntax/instructions.html#syntax-visatbinop}{\mathit{visatbinop}} ~|~ \mathsf{i16x8.}\href{../syntax/instructions.html#syntax-visatbinop}{\mathit{visatbinop}} \\&&|& \mathsf{i16x8.}\mathsf{mul} ~|~ \mathsf{i32x4.}\mathsf{mul} ~|~ \mathsf{i64x2.}\mathsf{mul} \\&&|& \mathsf{i8x16.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{avgr}}\mathsf{\_u} ~|~ \mathsf{i16x8.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{avgr}}\mathsf{\_u} \\&&|& \mathsf{i16x8.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extmul}}\mathsf{\_}\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\mathsf{\_i8x16\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{i32x4.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extmul}}\mathsf{\_}\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\mathsf{\_i16x8\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{i64x2.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extmul}}\mathsf{\_}\href{../syntax/instructions.html#syntax-half}{\mathit{half}}\mathsf{\_i32x4\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\ &&|& \mathsf{i16x8.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extadd\_pairwise}}\mathsf{\_i8x16\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{i32x4.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extadd\_pairwise}}\mathsf{\_i16x8\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\ &&|& \href{../syntax/instructions.html#syntax-shape}{\mathit{fshape}}\mathsf{.}\href{../syntax/instructions.html#syntax-vfbinop}{\mathit{vfbinop}} \\&&|& \mathsf{i32x4.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{trunc}}\mathsf{\_sat\_f32x4\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{i32x4.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{trunc}}\mathsf{\_sat\_f64x2\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\mathsf{\_zero} \\&&|& \mathsf{f32x4.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{convert}}\mathsf{\_i32x4\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{f32x4.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{demote}}\mathsf{\_f64x2\_zero} \\&&|& \mathsf{f64x2.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{convert}}\mathsf{\_low\_i32x4\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{f64x2.}\href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{promote}}\mathsf{\_low\_f32x4} \\&&|& \dots \\ \end{array}\end{split}\]
\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{vector bitwise unary operator} & \href{../syntax/instructions.html#syntax-vvunop}{\mathit{vvunop}} &::=& \mathsf{not} \\ \def\mathdef2803#1{{}}\mathdef2803{vector bitwise binary operator} & \href{../syntax/instructions.html#syntax-vvbinop}{\mathit{vvbinop}} &::=& \mathsf{and} ~|~ \mathsf{andnot} ~|~ \mathsf{or} ~|~ \mathsf{xor} \\ \def\mathdef2803#1{{}}\mathdef2803{vector bitwise ternary operator} & \href{../syntax/instructions.html#syntax-vvternop}{\mathit{vvternop}} &::=& \mathsf{bitselect} \\ \def\mathdef2803#1{{}}\mathdef2803{vector bitwise test operator} & \href{../syntax/instructions.html#syntax-vvtestop}{\mathit{vvtestop}} &::=& \mathsf{any\_true} \\ \def\mathdef2803#1{{}}\mathdef2803{vector integer test operator} & \href{../syntax/instructions.html#syntax-vitestop}{\mathit{vitestop}} &::=& \mathsf{all\_true} \\ \def\mathdef2803#1{{}}\mathdef2803{vector integer relational operator} & \href{../syntax/instructions.html#syntax-virelop}{\mathit{virelop}} &::=& \mathsf{eq} ~|~ \mathsf{ne} ~|~ \mathsf{lt\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{gt\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{le\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{ge\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\ \def\mathdef2803#1{{}}\mathdef2803{vector floating-point relational operator} & \href{../syntax/instructions.html#syntax-vfrelop}{\mathit{vfrelop}} &::=& \mathsf{eq} ~|~ \mathsf{ne} ~|~ \mathsf{lt} ~|~ \mathsf{gt} ~|~ \mathsf{le} ~|~ \mathsf{ge} \\ \def\mathdef2803#1{{}}\mathdef2803{vector integer unary operator} & \href{../syntax/instructions.html#syntax-viunop}{\mathit{viunop}} &::=& \mathsf{abs} ~|~ \mathsf{neg} \\ \def\mathdef2803#1{{}}\mathdef2803{vector integer binary operator} & \href{../syntax/instructions.html#syntax-vibinop}{\mathit{vibinop}} &::=& \mathsf{add} ~|~ \mathsf{sub} \\ \def\mathdef2803#1{{}}\mathdef2803{vector integer binary min/max operator} & \href{../syntax/instructions.html#syntax-viminmaxop}{\mathit{viminmaxop}} &::=& \mathsf{min\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{max\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\ \def\mathdef2803#1{{}}\mathdef2803{vector integer saturating binary operator} & \href{../syntax/instructions.html#syntax-visatbinop}{\mathit{visatbinop}} &::=& \mathsf{add\_sat\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} ~|~ \mathsf{sub\_sat\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\ \def\mathdef2803#1{{}}\mathdef2803{vector integer shift operator} & \href{../syntax/instructions.html#syntax-vishiftop}{\mathit{vishiftop}} &::=& \mathsf{shl} ~|~ \mathsf{shr\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\ \def\mathdef2803#1{{}}\mathdef2803{vector floating-point unary operator} & \href{../syntax/instructions.html#syntax-vfunop}{\mathit{vfunop}} &::=& \mathsf{abs} ~|~ \mathsf{neg} ~|~ \mathsf{sqrt} ~|~ \mathsf{ceil} ~|~ \mathsf{floor} ~|~ \mathsf{trunc} ~|~ \mathsf{nearest} \\ \def\mathdef2803#1{{}}\mathdef2803{vector floating-point binary operator} & \href{../syntax/instructions.html#syntax-vfbinop}{\mathit{vfbinop}} &::=& \mathsf{add} ~|~ \mathsf{sub} ~|~ \mathsf{mul} ~|~ \mathsf{div} ~|~ \mathsf{min} ~|~ \mathsf{max} ~|~ \mathsf{pmin} ~|~ \mathsf{pmax} \\ \end{array}\end{split}\]

Vector instructions have a naming convention involving a prefix that determines how their operands will be interpreted. This prefix describes the shape of the operand, written \(t\mathsf{x}N\), and consisting of a packed numeric type \(t\) and the number of lanes \(N\) of that type. Operations are performed point-wise on the values of each lane.

Note

For example, the shape \(\mathsf{i32x4}\) interprets the operand as four \(\href{../syntax/values.html#syntax-int}{\mathit{i32}}\) values, packed into an \(\href{../syntax/values.html#syntax-int}{\mathit{i128}}\). The bit width of the numeric type \(t\) times \(N\) always is 128.

Instructions prefixed with \(\mathsf{v128}\) do not involve a specific interpretation, and treat the \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) as an \(\href{../syntax/values.html#syntax-int}{\mathit{i128}}\) value or a vector of 128 individual bits.

Vector instructions can be grouped into several subcategories:

  • Constants: return a static constant.

  • Unary Operations: consume one \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) operand and produce one \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) result.

  • Binary Operations: consume two \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) operands and produce one \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) result.

  • Ternary Operations: consume three \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) operands and produce one \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) result.

  • Tests: consume one \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) operand and produce a Boolean integer result.

  • Shifts: consume a \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) operand and a \(\href{../syntax/values.html#syntax-int}{\mathit{i32}}\) operand, producing one \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) result.

  • Splats: consume a value of numeric type and produce a \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) result of a specified shape.

  • Extract lanes: consume a \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) operand and return the numeric value in a given lane.

  • Replace lanes: consume a \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) operand and a numeric value for a given lane, and produce a \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\) result.

Some vector instructions have a signedness annotation \(\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\) which distinguishes whether the elements in the operands are to be interpreted as unsigned or signed integers. For the other vector instructions, the use of two’s complement for the signed interpretation means that they behave the same regardless of signedness.

Conventions

Occasionally, it is convenient to group operators together according to the following grammar shorthands:

\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{unary operator} & \href{../syntax/instructions.html#syntax-vunop}{\mathit{vunop}} &::=& \href{../syntax/instructions.html#syntax-viunop}{\mathit{viunop}} ~|~ \href{../syntax/instructions.html#syntax-vfunop}{\mathit{vfunop}} ~|~ \href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{popcnt}} \\ \def\mathdef2803#1{{}}\mathdef2803{binary operator} & \href{../syntax/instructions.html#syntax-vbinop}{\mathit{vbinop}} &::=& \href{../syntax/instructions.html#syntax-vibinop}{\mathit{vibinop}} ~|~ \href{../syntax/instructions.html#syntax-vfbinop}{\mathit{vfbinop}} \\&&|& \href{../syntax/instructions.html#syntax-viminmaxop}{\mathit{viminmaxop}} ~|~ \href{../syntax/instructions.html#syntax-visatbinop}{\mathit{visatbinop}} \\&&|& \href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{mul}} ~|~ \href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{avgr}}\mathsf{\_u} ~|~ \href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{q15mulr\_sat}}\mathsf{\_s} \\ \def\mathdef2803#1{{}}\mathdef2803{test operator} & \href{../syntax/instructions.html#syntax-vtestop}{\mathit{vtestop}} &::=& \href{../syntax/instructions.html#syntax-vitestop}{\mathit{vitestop}} \\ \def\mathdef2803#1{{}}\mathdef2803{relational operator} & \href{../syntax/instructions.html#syntax-vrelop}{\mathit{vrelop}} &::=& \href{../syntax/instructions.html#syntax-virelop}{\mathit{virelop}} ~|~ \href{../syntax/instructions.html#syntax-vfrelop}{\mathit{vfrelop}} \\ \def\mathdef2803#1{{}}\mathdef2803{conversion operator} & \href{../syntax/instructions.html#syntax-vcvtop}{\mathit{vcvtop}} &::=& \href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{extend}} ~|~ \href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{trunc}}\mathsf{\_sat} ~|~ \href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{convert}} ~|~ \href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{demote}} ~|~ \href{../syntax/instructions.html#syntax-instr-vec}{\mathsf{promote}} \\ \end{array}\end{split}\]

Reference Instructions

Instructions in this group are concerned with accessing references.

\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \dots \\&&|& \href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.null}}~\href{../syntax/types.html#syntax-heaptype}{\mathit{heaptype}} \\&&|& \href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.func}}~\href{../syntax/modules.html#syntax-funcidx}{\mathit{funcidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.is\_null}} \\&&|& \href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.as\_non\_null}} \\&&|& \href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.eq}} \\&&|& \href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.test}}~\href{../syntax/types.html#syntax-reftype}{\mathit{reftype}} \\&&|& \href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.cast}}~\href{../syntax/types.html#syntax-reftype}{\mathit{reftype}} \\ \end{array}\end{split}\]

The \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.null}}\) and \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.func}}\) instructions produce a null value or a reference to a given function, respectively.

The instruction \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.is\_null}}\) checks for null, while \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.as\_non\_null}}\) converts a nullable to a non-null one, and traps if it encounters null.

The \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.eq}}\) compares two references.

The instructions \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.test}}\) and \(\href{../syntax/instructions.html#syntax-instr-ref}{\mathsf{ref.cast}}\) test the dynamic type of a reference operand. The former merely returns the result of the test, while the latter performs a downcast and traps if the operand’s type does not match.

Note

The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_on\_cast}}\) and \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_on\_cast\_fail}}\) instructions provides versions of the latter that branch depending on the success of the downcast instead of trapping.

Aggregate Instructions

Instructions in this group are concerned with creating and accessing references to aggregate types.

\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \dots \\&&|& \href{../syntax/instructions.html#syntax-instr-struct}{\mathsf{struct.new}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-struct}{\mathsf{struct.new\_default}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-struct}{\mathsf{struct.get}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}}~\href{../syntax/modules.html#syntax-fieldidx}{\mathit{fieldidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-struct}{\mathsf{struct.get}}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}}~\href{../syntax/modules.html#syntax-fieldidx}{\mathit{fieldidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-struct}{\mathsf{struct.set}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}}~\href{../syntax/modules.html#syntax-fieldidx}{\mathit{fieldidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.new}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.new\_fixed}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}}~\href{../syntax/values.html#syntax-int}{\mathit{u32}} \\&&|& \href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.new\_default}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.new\_data}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}}~\href{../syntax/modules.html#syntax-dataidx}{\mathit{dataidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.new\_elem}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}}~\href{../syntax/modules.html#syntax-elemidx}{\mathit{elemidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.get}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.get}}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.set}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.len}} \\&&|& \href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.fill}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.copy}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.init\_data}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}}~\href{../syntax/modules.html#syntax-dataidx}{\mathit{dataidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.init\_elem}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}}~\href{../syntax/modules.html#syntax-elemidx}{\mathit{elemidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-i31}{\mathsf{ref.i31}} \\&&|& \href{../syntax/instructions.html#syntax-instr-i31}{\mathsf{i31.get}}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-extern}{\mathsf{any.convert\_extern}} \\&&|& \href{../syntax/instructions.html#syntax-instr-extern}{\mathsf{extern.convert\_any}} \\ \end{array}\end{split}\]

The instructions \(\href{../syntax/instructions.html#syntax-instr-struct}{\mathsf{struct.new}}\) and \(\href{../syntax/instructions.html#syntax-instr-struct}{\mathsf{struct.new\_default}}\) allocate a new structure, initializing them either with operands or with default values. The remaining instructions on structs access individual fields, allowing for different sign extension modes in the case of packed storage types.

Similarly, arrays can be allocated either with an explicit initialization operand or a default value. Furthermore, \(\href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.new\_fixed}}\) allocates an array with statically fixed size, and \(\href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.new\_data}}\) and \(\href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.new\_elem}}\) allocate an array and initialize it from a data or element segment, respectively. \(\href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.get}}\), \(\href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.get\_s}}\), \(\href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.get\_u}}\), and \(\href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.set}}\) access individual slots, again allowing for different sign extension modes in the case of a packed storage type. \(\href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.len}}\) produces the length of an array. \(\href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.fill}}\) fills a specified slice of an array with a given value and \(\href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.copy}}\), \(\href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.init\_data}}\), and \(\href{../syntax/instructions.html#syntax-instr-array}{\mathsf{array.init\_elem}}\) copy elements to a specified slice of an array from a given array, data segment, or element segment, respectively.

The instructions \(\href{../syntax/instructions.html#syntax-instr-i31}{\mathsf{ref.i31}}\) and \(\href{../syntax/instructions.html#syntax-instr-i31}{\mathsf{i31.get}}\mathsf{\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\) convert between type \(\href{../syntax/types.html#syntax-heaptype}{\mathsf{i31}}\) and an unboxed scalar.

The instructions \(\href{../syntax/instructions.html#syntax-instr-extern}{\mathsf{any.convert\_extern}}\) and \(\href{../syntax/instructions.html#syntax-instr-extern}{\mathsf{extern.convert\_any}}\) allow lossless conversion between references represented as type \((\href{../syntax/types.html#syntax-reftype}{\mathsf{ref}}~\href{../syntax/types.html#syntax-reftype}{\mathsf{null}}~\href{../syntax/types.html#syntax-heaptype}{\mathsf{extern}})\).

Parametric Instructions

Instructions in this group can operate on operands of any value type.

\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \dots \\&&|& \href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{drop}} \\&&|& \href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{select}}~(\href{../syntax/types.html#syntax-valtype}{\mathit{valtype}}^\ast)^? \\ \end{array}\end{split}\]

The \(\href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{drop}}\) instruction simply throws away a single operand.

The \(\href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{select}}\) instruction selects one of its first two operands based on whether its third operand is zero or not. It may include a value type determining the type of these operands. If missing, the operands must be of numeric type.

Note

In future versions of WebAssembly, the type annotation on \(\href{../syntax/instructions.html#syntax-instr-parametric}{\mathsf{select}}\) may allow for more than a single value being selected at the same time.

Variable Instructions

Variable instructions are concerned with access to local or global variables.

\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \dots \\&&|& \href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.get}}~\href{../syntax/modules.html#syntax-localidx}{\mathit{localidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.set}}~\href{../syntax/modules.html#syntax-localidx}{\mathit{localidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.tee}}~\href{../syntax/modules.html#syntax-localidx}{\mathit{localidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{global.get}}~\href{../syntax/modules.html#syntax-globalidx}{\mathit{globalidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{global.set}}~\href{../syntax/modules.html#syntax-globalidx}{\mathit{globalidx}} \\ \end{array}\end{split}\]

These instructions get or set the values of variables, respectively. The \(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.tee}}\) instruction is like \(\href{../syntax/instructions.html#syntax-instr-variable}{\mathsf{local.set}}\) but also returns its argument.

Table Instructions

Instructions in this group are concerned with tables table.

\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \dots \\&&|& \href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.get}}~\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}~\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.size}}~\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.grow}}~\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.fill}}~\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.copy}}~\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}}~\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.init}}~\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}}~\href{../syntax/modules.html#syntax-elemidx}{\mathit{elemidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-table}{\mathsf{elem.drop}}~\href{../syntax/modules.html#syntax-elemidx}{\mathit{elemidx}} \\ \end{array}\end{split}\]

The \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.get}}\) and \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.set}}\) instructions load or store an element in a table, respectively.

The \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.size}}\) instruction returns the current size of a table. The \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.grow}}\) instruction grows table by a given delta and returns the previous size, or \(-1\) if enough space cannot be allocated. It also takes an initialization value for the newly allocated entries.

The \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.fill}}\) instruction sets all entries in a range to a given value.

The \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.copy}}\) instruction copies elements from a source table region to a possibly overlapping destination region; the first index denotes the destination. The \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{table.init}}\) instruction copies elements from a passive element segment into a table. The \(\href{../syntax/instructions.html#syntax-instr-table}{\mathsf{elem.drop}}\) instruction prevents further use of a passive element segment. This instruction is intended to be used as an optimization hint. After an element segment is dropped its elements can no longer be retrieved, so the memory used by this segment may be freed.

An additional instruction that accesses a table is the control instruction \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call\_indirect}}\).

Memory Instructions

Instructions in this group are concerned with linear memory.

\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{memory immediate} & \href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} &::=& \{ \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{offset}}~\href{../syntax/values.html#syntax-int}{\mathit{u32}}, \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{align}}~\href{../syntax/values.html#syntax-int}{\mathit{u32}} \} \\ \def\mathdef2803#1{{}}\mathdef2803{lane width} & \mathit{ww} &::=& 8 ~|~ 16 ~|~ 32 ~|~ 64 \\ \def\mathdef2803#1{{}}\mathdef2803{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \dots \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{v128.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{f}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{v128.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{8\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{16\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{i64.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{32\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} \\&&|& \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{8}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{i}\mathit{nn}\mathsf{.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{16}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{i64.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathsf{32}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} \\&&|& \mathsf{v128.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{8x8\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{v128.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{16x4\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{v128.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{32x2\_}\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} \\&&|& \mathsf{v128.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{32\_zero}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} ~|~ \mathsf{v128.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathsf{64\_zero}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} \\&&|& \mathsf{v128.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathit{ww}\mathsf{\_splat}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}} \\&&|& \mathsf{v128.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\mathit{ww}\mathsf{\_lane}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}~\href{../syntax/instructions.html#syntax-laneidx}{\mathit{laneidx}} ~|~ \mathsf{v128.}\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\mathit{ww}\mathsf{\_lane}~\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}~\href{../syntax/instructions.html#syntax-laneidx}{\mathit{laneidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.size}} \\&&|& \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.grow}} \\&&|& \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.fill}} \\&&|& \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.copy}} \\&&|& \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.init}}~\href{../syntax/modules.html#syntax-dataidx}{\mathit{dataidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{data.drop}}~\href{../syntax/modules.html#syntax-dataidx}{\mathit{dataidx}} \\ \end{array}\end{split}\]

Memory is accessed with \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{load}}\) and \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{store}}\) instructions for the different number types. They all take a memory immediate \(\href{../syntax/instructions.html#syntax-memarg}{\mathit{memarg}}\) that contains an address offset and the expected alignment (expressed as the exponent of a power of 2). Integer loads and stores can optionally specify a storage size that is smaller than the bit width of the respective value type. In the case of loads, a sign extension mode \(\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\) is then required to select appropriate behavior.

Vector loads can specify a shape that is half the bit width of \(\href{../syntax/types.html#syntax-valtype}{\mathsf{v128}}\). Each lane is half its usual size, and the sign extension mode \(\href{../syntax/instructions.html#syntax-sx}{\mathit{sx}}\) then specifies how the smaller lane is extended to the larger lane. Alternatively, vector loads can perform a splat, such that only a single lane of the specified storage size is loaded, and the result is duplicated to all lanes.

The static address offset is added to the dynamic address operand, yielding a 33 bit effective address that is the zero-based index at which the memory is accessed. All values are read and written in little endian byte order. A trap results if any of the accessed memory bytes lies outside the address range implied by the memory’s current size.

Note

Future versions of WebAssembly might provide memory instructions with 64 bit address ranges.

The \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.size}}\) instruction returns the current size of a memory. The \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.grow}}\) instruction grows memory by a given delta and returns the previous size, or \(-1\) if enough memory cannot be allocated. Both instructions operate in units of page size.

The \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.fill}}\) instruction sets all values in a region to a given byte. The \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.copy}}\) instruction copies data from a source memory region to a possibly overlapping destination region. The \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{memory.init}}\) instruction copies data from a passive data segment into a memory. The \(\href{../syntax/instructions.html#syntax-instr-memory}{\mathsf{data.drop}}\) instruction prevents further use of a passive data segment. This instruction is intended to be used as an optimization hint. After a data segment is dropped its data can no longer be retrieved, so the memory used by this segment may be freed.

Note

In the current version of WebAssembly, all memory instructions implicitly operate on memory index \(0\). This restriction may be lifted in future versions.

Control Instructions

Instructions in this group affect the flow of control.

\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{block type} & \href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}} &::=& \href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} ~|~ \href{../syntax/types.html#syntax-valtype}{\mathit{valtype}}^? \\ \def\mathdef2803#1{{}}\mathdef2803{instruction} & \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}} &::=& \dots \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{nop}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{unreachable}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}~\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{loop}}~\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{if}}~\href{../syntax/instructions.html#syntax-blocktype}{\mathit{blocktype}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{else}}~\href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}~\href{../syntax/modules.html#syntax-labelidx}{\mathit{labelidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_if}}~\href{../syntax/modules.html#syntax-labelidx}{\mathit{labelidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_table}}~\href{../syntax/conventions.html#syntax-vec}{\mathit{vec}}(\href{../syntax/modules.html#syntax-labelidx}{\mathit{labelidx}})~\href{../syntax/modules.html#syntax-labelidx}{\mathit{labelidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_on\_null}}~\href{../syntax/modules.html#syntax-labelidx}{\mathit{labelidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_on\_non\_null}}~\href{../syntax/modules.html#syntax-labelidx}{\mathit{labelidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_on\_cast}}~\href{../syntax/modules.html#syntax-labelidx}{\mathit{labelidx}}~\href{../syntax/types.html#syntax-reftype}{\mathit{reftype}}~\href{../syntax/types.html#syntax-reftype}{\mathit{reftype}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_on\_cast\_fail}}~\href{../syntax/modules.html#syntax-labelidx}{\mathit{labelidx}}~\href{../syntax/types.html#syntax-reftype}{\mathit{reftype}}~\href{../syntax/types.html#syntax-reftype}{\mathit{reftype}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call}}~\href{../syntax/modules.html#syntax-funcidx}{\mathit{funcidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call\_ref}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call\_indirect}}~\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return\_call}}~\href{../syntax/modules.html#syntax-funcidx}{\mathit{funcidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return\_call\_ref}}~\href{../syntax/modules.html#syntax-funcidx}{\mathit{funcidx}} \\&&|& \href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return\_call\_indirect}}~\href{../syntax/modules.html#syntax-tableidx}{\mathit{tableidx}}~\href{../syntax/modules.html#syntax-typeidx}{\mathit{typeidx}} \\ \end{array}\end{split}\]

The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{nop}}\) instruction does nothing.

The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{unreachable}}\) instruction causes an unconditional trap.

The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}\), \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{loop}}\) and \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{if}}\) instructions are structured instructions. They bracket nested sequences of instructions, called blocks, terminated with, or separated by, \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\) or \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{else}}\) pseudo-instructions. As the grammar prescribes, they must be well-nested.

A structured instruction can consume input and produce output on the operand stack according to its annotated block type. It is given either as a type index that refers to a suitable function type reinterpreted as an instruction type, or as an optional value type inline, which is a shorthand for the instruction type \([] \mathrel{\href{../valid/conventions.html#syntax-instrtype}{\rightarrow}} [\href{../syntax/types.html#syntax-valtype}{\mathit{valtype}}^?]\).

Each structured control instruction introduces an implicit label. Labels are targets for branch instructions that reference them with label indices. Unlike with other index spaces, indexing of labels is relative by nesting depth, that is, label \(0\) refers to the innermost structured control instruction enclosing the referring branch instruction, while increasing indices refer to those farther out. Consequently, labels can only be referenced from within the associated structured control instruction. This also implies that branches can only be directed outwards, “breaking” from the block of the control construct they target. The exact effect depends on that control construct. In case of \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}\) or \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{if}}\) it is a forward jump, resuming execution after the matching \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\). In case of \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{loop}}\) it is a backward jump to the beginning of the loop.

Note

This enforces structured control flow. Intuitively, a branch targeting a \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{block}}\) or \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{if}}\) behaves like a \(\mathsf{break}\) statement in most C-like languages, while a branch targeting a \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{loop}}\) behaves like a \(\mathsf{continue}\) statement.

Branch instructions come in several flavors: \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br}}\) performs an unconditional branch, \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_if}}\) performs a conditional branch, and \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_table}}\) performs an indirect branch through an operand indexing into the label vector that is an immediate to the instruction, or to a default target if the operand is out of bounds. The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_on\_null}}\) and \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_on\_non\_null}}\) instructions check whether a reference operand is null and branch if that is the case or not the case, respectively. Similarly, \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_on\_cast}}\) and \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{br\_on\_cast\_fail}}\) attempt a downcast on a reference operand and branch if that succeeds, or fails, respectively.

The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return}}\) instruction is a shortcut for an unconditional branch to the outermost block, which implicitly is the body of the current function. Taking a branch unwinds the operand stack up to the height where the targeted structured control instruction was entered. However, branches may additionally consume operands themselves, which they push back on the operand stack after unwinding. Forward branches require operands according to the output of the targeted block’s type, i.e., represent the values produced by the terminated block. Backward branches require operands according to the input of the targeted block’s type, i.e., represent the values consumed by the restarted block.

The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call}}\) instruction invokes another function, consuming the necessary arguments from the stack and returning the result values of the call. The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call\_ref}}\) instruction invokes a function indirectly through a function reference operand. The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{call\_indirect}}\) instruction calls a function indirectly through an operand indexing into a table that is denoted by a table index and must contain function references. Since it may contain functions of heterogeneous type, the callee is dynamically checked against the function type indexed by the instruction’s second immediate, and the call is aborted with a trap if it does not match.

The \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return\_call}}\), \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return\_call\_ref}}\), and \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{return\_call\_indirect}}\) instructions are tail-call variants of the previous ones. That is, they first return from the current function before actually performing the respective call. It is guaranteed that no sequence of nested calls using only these instructions can cause resource exhaustion due to hitting an implementation’s limit on the number of active calls.

Expressions

Function bodies, initialization values for globals, elements and offsets of element segments, and offsets of data segments are given as expressions, which are sequences of instructions terminated by an \(\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}}\) marker.

\[\begin{split}\begin{array}{llrl} \def\mathdef2803#1{{}}\mathdef2803{expression} & \href{../syntax/instructions.html#syntax-expr}{\mathit{expr}} &::=& \href{../syntax/instructions.html#syntax-instr}{\mathit{instr}}^\ast~\href{../syntax/instructions.html#syntax-instr-control}{\mathsf{end}} \\ \end{array}\end{split}\]

In some places, validation restricts expressions to be constant, which limits the set of allowable instructions.