profile
viewpoint
Marco A L Barbosa malbarbo Maringá, Paraná, Brasil malbarbo.pro.br

malbarbo/fera 9

An aggregation of algorithms, data structures and supporting crates

malbarbo/na-lp-copl 6

Notas de aula sobre linguagens de programação (baseado no livro "Concepts of Programming Languages")

malbarbo/dcmstp-instances 3

Instances and solvers for the degree constrained minimum spanning tree problem

malbarbo/dotfiles 1

Some of my dotfiles

malbarbo/na-progfun 1

Notas de aula sobre o paradigma de programação funcional

malbarbo/aports 0

Mirror of aports repository

malbarbo/backtrace-rs 0

Backtraces in Rust

malbarbo/cargo 0

The Rust package manager

malbarbo/cargo-kcov 0

Cargo subcommand to run kcov to get coverage report on Linux

malbarbo/cc-rs 0

Rust library for build scripts to compile C/C++ code into a Rust library

PR opened richfelker/musl-cross-make

update GCC 9.2.0 to 9.3.0

0017-pr93402.diff was removed, as it was merged upstream.

+1 -46

0 comment

20 changed files

pr created time in 6 hours

PR opened richfelker/musl-cross-make

update GCC 8.3.0 to 8.4.0

0017-pr93402.diff was removed, as it was merged upstream.

+1 -46

0 comment

20 changed files

pr created time in 7 hours

PR opened richfelker/musl-cross-make

replace GCC 7.3.0 with 7.5.0

painless upgrade, all patches still apply. simply moved them from one place to the other. 7.5.0 is the latest in the 7.x series.

+1 -1

0 comment

23 changed files

pr created time in 8 hours

Pull request review commentWebAssembly/exception-handling

formal spec overview for the 3rd exception handling proposal

+# 3rd proposal formal spec overview++This is an overview of the 3rd proposal's formal spec additions, to aid in discussions concerning the proposed semantics.++## Abstract Syntax++### Types++Exception Types++```+exntype ::= [t*] -> []+```++### Instructions++```+instr ::= ... | throw x | rethrow l+        | try bt instr* (catch x instr*)+ end+        | try bt instr* (catch x instr*)* catch_all instr* end+        | try bt instr* delegate l+        | try bt instr* unwind instr* end+```++### Modules++Exceptions (definitions)++```+exn ::= export* exception exntype  | export* exception exntype import+```++Modules+++```+mod ::= module ... exn*+```++## Validation (Typing)++To verify that a `try...delegate l` instruction refers to a label introduced by a try block (I'll call this a try-label), introduce a type attribute to labels in the validation context, which type attribute is set to `try` when the label is a try-label. The original notation `label [t*]` will then be a shortcut for `label {result [t*], type ε}`.++Moreover, to verify that the `rethrow l` instruction refers to a label introduced by a catch block (call this a catch-label), we allow this type attribute of labels in the validation context to be set to `catch` when the label is a catch label. This addition is reflected in the execution rules, by the administrative instruction `caught` which introduces a label around the instructions of the catching try-block's catch instructions.

I just pushed the promised commits. The first one's commit message contains the question "Should the administrative instruction caught be removed from the right hand side of rethrow's execution step?", because I ran out of time and I won't be able to think about it until the end of next week.

ioannad

comment created time in 12 hours

PR closed WebAssembly/threads

Mark explainer as outdated
+4 -0

8 comments

1 changed file

surma

pr closed time in 16 hours

pull request commentWebAssembly/threads

Mark explainer as outdated

Absolutely. Cheers.

surma

comment created time in 16 hours

pull request commentWebAssembly/threads

Mark explainer as outdated

@surma are you happy for this to be closed now that wabt has been updated? Please let us know if you're still dealing with inconsistencies.

surma

comment created time in 17 hours

Pull request review commentWebAssembly/exception-handling

formal spec overview for the 3rd exception handling proposal

+# 3rd proposal formal spec overview++This is an overview of the 3rd proposal's formal spec additions, to aid in discussions concerning the proposed semantics.++## Abstract Syntax++### Types++Exception Types++```+exntype ::= [t*] -> []+```++### Instructions++```+instr ::= ... | throw x | rethrow l+        | try bt instr* (catch x instr*)+ end+        | try bt instr* (catch x instr*)* catch_all instr* end+        | try bt instr* delegate l+        | try bt instr* unwind instr* end+```++### Modules++Exceptions (definitions)++```+exn ::= export* exception exntype  | export* exception exntype import+```++Modules+++```+mod ::= module ... exn*+```++## Validation (Typing)++To verify that a `try...delegate l` instruction refers to a label introduced by a try block (I'll call this a try-label), introduce a type attribute to labels in the validation context, which type attribute is set to `try` when the label is a try-label. The original notation `label [t*]` will then be a shortcut for `label {result [t*], type ε}`.++Moreover, to verify that the `rethrow l` instruction refers to a label introduced by a catch block (call this a catch-label), we allow this type attribute of labels in the validation context to be set to `catch` when the label is a catch label. This addition is reflected in the execution rules, by the administrative instruction `caught` which introduces a label around the instructions of the catching try-block's catch instructions.

@aheejin I see now what you mean, yes, you are right.

In the second example, the label from the catch block would interfere with delegate, when it shouldn't. Also rethrow should not interfere with other labels, it should just count the stack of nested catch blocks it is in - to rethrow an exception, an exception must be caught, so we can only rethrow n the exception caught by the nth surrounding catch block.

I think to solve this, the catch-labels should be removed, and a separate concept of a caught-stack should be added to the runtime, described by a parallel to blocks:

C^0 ::= val^m [_] instr
C^{n+1} ::= caught{exnaddr val^k} C^n end

Also a new stack caught to validation contexts, which gets an element "caught" prepended whenever we catch an exception by a catch block.

About the 3rd example, did you omit a catch in the outer try block on purpose, meaning that trys without catches could be allowed, as @tlively suggested in #131 ? In that case, in your 3rd example, if we replace ... by throw $exn then the example would reduce to throw $exn. I think it would be a nice simplification to the syntax to allow catchless try blocks. They are equivalent to try ... catch_all rethrow 0 end AFAICT, so no new behaviour would be introduced with this simplification.

If we additionally allow delegate to target any label, as @RossTate suggested, then we can have the same effect also without a try block, as he noted, and we wouldn't have to make any changes to labels. I admit I am not so fond of adding this auxiliary information to labels, I just thought I had to.

To clarify I'll commit the changes I'm suggesting later today, in three separate patches:

  1. add caught-stack to the runtime and to validation contexts and remove catch-labels (which actually should have been called "caught" labels but anyway)
  2. allow trys without catches
  3. remove auxiliary type of labels and allow delegate to reference any label

WDYT?

ioannad

comment created time in 18 hours

pull request commentWebAssembly/threads

Spec basic instructions

Thanks! No stress, I thought your thesis was already due in September.

yes

rossberg

comment created time in 19 hours

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & \meminst = S.\SMEMS[a]) \\      \end{array}-   \\[1ex]+   \\    %+   ~\\+   \\    \begin{array}{lcl@{\qquad}l}-   S; F; (\I32.\CONST~i)~\MEMORYGROW-     &\stepto^{(\ARMW~a.\LLEN~n~(n+k))~(\AWR~a.\LDATA[n]~(0)^k)}&+   S; F; (\I32.\CONST~n)~\MEMORYGROW+     &\stepto^{(\ARMW~a.\LLEN~l~(l+k))~(\AWR~a.\LDATA[l]~(0)^k)}&      S; F; (\I32.\CONST~\X{sz})    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined} \\-     \wedge & n = \X{sz} \cdot 64\,\F{Ki} \\-     \wedge & k = i \cdot 64\,\F{Ki}) \\+     \wedge & \X{sz} = l / 64\,\F{Ki} \\+     \wedge & n = k / 64\,\F{Ki}) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}    S; F; (\I32.\CONST~n)~\MEMORYGROW-     &\stepto^{(\ARD~a.\LLEN~n)}&+     &\stepto^{(\ARD_{\SEQCST}~a.\LLEN~n)}&      S; F; (\I32.\CONST~{-1})    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined}) \\      \end{array}    \end{array}-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}    (\where & a = F.\AMODULE.\MIMEMS[0]) \\    \end{array}    \end{array}  .. note::-   The |MEMORYGROW| instruction is non-deterministic.+   The |MEMORYGROW| instruction is non-deterministic, even on unshared memories.    It may either succeed, returning the old memory size :math:`\X{sz}`,    or fail, returning :math:`{-1}`.    Failure *must* occur if the referenced memory instance has a maximum size defined that would be exceeded.    However, failure *can* occur in other cases as well.    In practice, the choice depends on the :ref:`resources <impl-exec>` available to the :ref:`embedder <embedder>`.  -.. index:: atomic memory instruction, memory, frame, module++.. index:: atomic memory instruction, memory, frame, module, atomic operator    pair: execution; instruction    single: abstract syntax; instruction .. _exec-instr-atomic-memory:  Atomic Memory Instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~ -:math:`t\K{.}\ATOMICLOAD~\memarg` and :math:`t\K{.}\ATOMICLOAD{N}\K{\_u}~\memarg`-.................................................................................+.. _exec-atomic.load:+.. _exec-atomic.loadn: -See :ref:`above <exec-atomic-load>`.+:math:`t\K{.}\ATOMICLOAD({N}\K{\_u})^?~\memarg`+............................................... +The rules are identical to :ref:`non-atomic loads <exec-load>`, except that :math:`\ord = \SEQCST`. -:math:`t\K{.}\ATOMICSTORE~\memarg` and :math:`t\K{.}\ATOMICSTORE{N}~\memarg`-............................................................................ -See :ref:`above <exec-atomic-store>`.+.. _exec-atomic.store:+.. _exec-atomic.storen: +:math:`t\K{.}\ATOMICSTORE{N}^?~\memarg`+....................................... +The rules are identical to :ref:`non-atomic stores <exec-store>`, except that :math:`\ord = \SEQCST`. -.. _exec-atomic-rmw:-.. _exec-atomic-rmwn: -:math:`t\K{.}\ATOMICRMW{.}\atomicop~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\atomicop~\memarg`-.....................................................................................................+.. _exec-atomic.rmw:+.. _exec-atomic.rmwn: -.. todo:: update text to match formalism+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\atop~\memarg`+........................................................ -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+2. Else: -4. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`S.\SMEMS[a]` exists.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+   b. Let :math:`\X{st}` be the :ref:`value type <syntax-valtype>` :math:`t`. -6. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack.+3. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack. -7. Pop the value :math:`t.\CONST~c_2` from the stack.+4. Pop the value :math:`t.\CONST~c_2` from the stack. -8. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+5. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -9. Pop the value :math:`\I32.\CONST~i` from the stack.+6. Pop the value :math:`\I32.\CONST~i` from the stack. -10. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`.+7. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`. -11. If :math:`N` is not part of the instruction, then:+8. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then: -    a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+   a. Trap. -12. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+9. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -    a. Trap.+10. Assert: due to :ref:`validation <valid-atomic.rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -13. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then:+11. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -    a. Trap.+12. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -14. Let :math:`b^\ast_r` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+    a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -15. Let :math:`c_1` be the integer for which :math:`bytes_{\iN}(m) = b^\ast_r`.+    b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -16. Let :math:`m` be the result of computing :math:`\atomicop_t(c_1, c_2)`.+       a. Trap. -17. If :math:`N` is part of the instruction, then:+    c. Let :math:`b^\ast_{\F{r}}` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -    a. Let :math:`n` be the result of computing :math:`\wrap_{|t|,N}(m)`.+13. Else: -    b. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_{\iN}(n)`.+    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`. -18. Else:+    b. If :math:`n` is smaller than :math:`\X{ea} + N/8`, or :math:`\X{ea}` is not divisible by :math:`N/8`, then: -    a. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_t(m)`.+       i. Trap. -19. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_w`.+    c. Perform the atomic :ref:`action <syntax-act>` :math:`(\ARMW_{\SEQCST}~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)` to read the bytes :math:`b_{\F{r}}^\ast` from data offset :math:`\X{ea}` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a` and replace them with bytes :math:`b_{\F{w}}^\ast` (which are defined below). -20. Push the value :math:`t.\CONST~c_1` to the stack.+14. Let :math:`c_{\F{r}}` be the integer for which :math:`\bytes_{\X{st}}(n) = b_{\F{r}}^\ast`.++15. Let :math:`c_1` be the result of computing :math:`\extendtu_{\X{st},t}(c_{\F{r}})`.++16. Let :math:`c` be the result of computing :math:`\atop_t(c_1, c_2)`.++17. Let :math:`c_{\F{w}}` be the result of computing :math:`\wrapt_{t,\X{st}}(c)`.++18. Let :math:`b^\ast_{\F{w}}` be the byte sequence :math:`\bytes_{\X{st}}(c_{\F{w}})`.++19. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then:++    a. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_{\F{w}}`.++20. Push the value :math:`t.\CONST~c` to the stack.  .. math::    \begin{array}{l}    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)-     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_1^\ast~b^\ast)}&-     F; (t.\CONST~c_1)+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S'; F; (t.\CONST~c_1)    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}-     (\iff & \X{ea} + N/8 \leq n \\+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 \leq n \\      \wedge & \X{ea} \mod N/8 = 0 \\-     \wedge & b_1^\ast = \bytes_{\iN}(c_1) \\-     \wedge & b^\ast = \bytes_{\iN}(\wrap_{|t|,N}(\atomicop_t(c_1, c_2)))) \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(\meminst.\MIDATA[\X{ea} \slice N/8])) \\+     \wedge & S' = S \with \SMEMS[a].\MIDATA[\X{ea} \slice N/8] = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)+   S; F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S; F; \TRAP+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\+     \end{array}+   \\+   %+   ~\\+   \begin{array}{lcl@{\qquad}l}+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)}&+     S; F; (t.\CONST~c_1)+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & S.\SMEMS[a] ~\mbox{undefined} \\+     \wedge & \X{ea} + N/8 \leq n \\+     \wedge & \X{ea} \mod N/8 = 0 \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(b_{\F{r}}^\ast)) \\+     \wedge & b_{\F{r}}^\ast = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\+     \end{array}+   \\[1ex]+   \begin{array}{lcl@{\qquad}l}+   S; F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)      &\stepto^{(\ARD~a.\LLEN~n)}&-     F; \TRAP+     S; F; \TRAP    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}-     (\iff & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\+     (\iff & S.\SMEMS[a] ~\mbox{undefined} \\+     \wedge & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\      \end{array}-   \\[2ex]-   (\where N = |t| \iff ~\mbox{not present}) \\-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}-   (\where & N = |t| \iff ~\mbox{not present} \\+   (\where & N = |t| \iff N~\mbox{not present} \\+   \wedge & \X{st} = t \iff N~\mbox{not present}, ~\X{st} = \iN \otherwise \\    \wedge & a = F.\AMODULE.\MIMEMS[0] \\    \wedge & \X{ea} = i + \memarg.\OFFSET) \\    \end{array}    \end{array}  -.. _exec-atomic-rmw-cmpxchg:-.. _exec-atomic-rmwn-cmpxchg:+.. _exec-atomic.rmw.cmpxchg:+.. _exec-atomic.rmwn.cmpxchg: -:math:`t\K{.}\ATOMICRMW{.}\ATOMICCMPXCHG~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\ATOMICCMPXCHG~\memarg`-...............................................................................................................+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\ATCMPXCHG~\memarg`+............................................................. -.. todo:: update text to match formalism+.. todo:: should only emit |ARMW| if the condition is true? -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn-cmpxchg>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+2. Else: -4. Assert: due to :ref:`validation <valid-atomic-rmwn-cmpxchg>`, :math:`S.\SMEMS[a]` exists.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+   b. Let :math:`\X{st}` be the :ref:`value type <syntax-valtype>` :math:`t`. -6. Assert: due to :ref:`validation <valid-atomic-rmwn-cmpxchg>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack.+3. Assert: due to :ref:`validation <valid-atomic.rmwn>`, two values of :ref:`value type <syntax-valtype>` :math:`t` are on the top of the stack. -7. Pop the value :math:`t.\CONST~c_3` from the stack.+4. Pop the value :math:`t.\CONST~c_3` from the stack. -8. Assert: due to :ref:`validation <valid-atomic-rmwn-cmpxchg>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack.+5. Pop the value :math:`t.\CONST~c_2` from the stack. -9. Pop the value :math:`t.\CONST~c_2` from the stack.+6. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -10. Assert: due to :ref:`validation <valid-atomic-rmwn-cmpxchg>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+7. Pop the value :math:`\I32.\CONST~i` from the stack. -11. Pop the value :math:`\I32.\CONST~i` from the stack.+8. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`. -12. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`.+9. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then: -13. If :math:`N` is not part of the instruction, then:+   a. Trap. -    a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+10. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -14. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+11. Assert: due to :ref:`validation <valid-atomic.rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -    a. Trap.+12. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -15. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then:+13. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -    a. Trap.+    a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -16. Let :math:`b^\ast_r` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+    b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -17. Let :math:`c_1` be the integer for which :math:`bytes_{\iN}(m) = b^\ast_r`.+       a. Trap. -18. If :math:`N` is part of the instruction, then:+    c. Let :math:`b^\ast_{\F{r}}` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -    a. Let :math:`n` be the result of computing :math:`\wrap_{|t|,N}(c_3)`.+14. Else:++    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`.++    b. If :math:`n` is smaller than :math:`\X{ea} + N/8`, or :math:`\X{ea}` is not divisible by :math:`N/8`, then:++       i. Trap.++    c. Perform the atomic :ref:`action <syntax-act>` :math:`(\ARMW_{\SEQCST}~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)` to read the bytes :math:`b_{\F{r}}^\ast` from data offset :math:`\X{ea}` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a` and replace them with bytes :math:`b_{\F{w}}^\ast` (which are defined below).

Fixed.

rossberg

comment created time in 21 hours

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & \meminst = S.\SMEMS[a]) \\      \end{array}-   \\[1ex]+   \\    %+   ~\\+   \\    \begin{array}{lcl@{\qquad}l}-   S; F; (\I32.\CONST~i)~\MEMORYGROW-     &\stepto^{(\ARMW~a.\LLEN~n~(n+k))~(\AWR~a.\LDATA[n]~(0)^k)}&+   S; F; (\I32.\CONST~n)~\MEMORYGROW+     &\stepto^{(\ARMW~a.\LLEN~l~(l+k))~(\AWR~a.\LDATA[l]~(0)^k)}&      S; F; (\I32.\CONST~\X{sz})    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined} \\-     \wedge & n = \X{sz} \cdot 64\,\F{Ki} \\-     \wedge & k = i \cdot 64\,\F{Ki}) \\+     \wedge & \X{sz} = l / 64\,\F{Ki} \\+     \wedge & n = k / 64\,\F{Ki}) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}    S; F; (\I32.\CONST~n)~\MEMORYGROW-     &\stepto^{(\ARD~a.\LLEN~n)}&+     &\stepto^{(\ARD_{\SEQCST}~a.\LLEN~n)}&      S; F; (\I32.\CONST~{-1})    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined}) \\      \end{array}    \end{array}-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}    (\where & a = F.\AMODULE.\MIMEMS[0]) \\    \end{array}    \end{array}  .. note::-   The |MEMORYGROW| instruction is non-deterministic.+   The |MEMORYGROW| instruction is non-deterministic, even on unshared memories.    It may either succeed, returning the old memory size :math:`\X{sz}`,    or fail, returning :math:`{-1}`.    Failure *must* occur if the referenced memory instance has a maximum size defined that would be exceeded.    However, failure *can* occur in other cases as well.    In practice, the choice depends on the :ref:`resources <impl-exec>` available to the :ref:`embedder <embedder>`.  -.. index:: atomic memory instruction, memory, frame, module++.. index:: atomic memory instruction, memory, frame, module, atomic operator    pair: execution; instruction    single: abstract syntax; instruction .. _exec-instr-atomic-memory:  Atomic Memory Instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~ -:math:`t\K{.}\ATOMICLOAD~\memarg` and :math:`t\K{.}\ATOMICLOAD{N}\K{\_u}~\memarg`-.................................................................................+.. _exec-atomic.load:+.. _exec-atomic.loadn: -See :ref:`above <exec-atomic-load>`.+:math:`t\K{.}\ATOMICLOAD({N}\K{\_u})^?~\memarg`+............................................... +The rules are identical to :ref:`non-atomic loads <exec-load>`, except that :math:`\ord = \SEQCST`. -:math:`t\K{.}\ATOMICSTORE~\memarg` and :math:`t\K{.}\ATOMICSTORE{N}~\memarg`-............................................................................ -See :ref:`above <exec-atomic-store>`.+.. _exec-atomic.store:+.. _exec-atomic.storen: +:math:`t\K{.}\ATOMICSTORE{N}^?~\memarg`+....................................... +The rules are identical to :ref:`non-atomic stores <exec-store>`, except that :math:`\ord = \SEQCST`. -.. _exec-atomic-rmw:-.. _exec-atomic-rmwn: -:math:`t\K{.}\ATOMICRMW{.}\atomicop~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\atomicop~\memarg`-.....................................................................................................+.. _exec-atomic.rmw:+.. _exec-atomic.rmwn: -.. todo:: update text to match formalism+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\atop~\memarg`+........................................................ -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+2. Else: -4. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`S.\SMEMS[a]` exists.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+   b. Let :math:`\X{st}` be the :ref:`value type <syntax-valtype>` :math:`t`. -6. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack.+3. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack. -7. Pop the value :math:`t.\CONST~c_2` from the stack.+4. Pop the value :math:`t.\CONST~c_2` from the stack. -8. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+5. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -9. Pop the value :math:`\I32.\CONST~i` from the stack.+6. Pop the value :math:`\I32.\CONST~i` from the stack. -10. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`.+7. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`. -11. If :math:`N` is not part of the instruction, then:+8. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then: -    a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+   a. Trap. -12. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+9. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -    a. Trap.+10. Assert: due to :ref:`validation <valid-atomic.rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -13. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then:+11. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -    a. Trap.+12. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -14. Let :math:`b^\ast_r` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+    a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -15. Let :math:`c_1` be the integer for which :math:`bytes_{\iN}(m) = b^\ast_r`.+    b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -16. Let :math:`m` be the result of computing :math:`\atomicop_t(c_1, c_2)`.+       a. Trap. -17. If :math:`N` is part of the instruction, then:+    c. Let :math:`b^\ast_{\F{r}}` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -    a. Let :math:`n` be the result of computing :math:`\wrap_{|t|,N}(m)`.+13. Else: -    b. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_{\iN}(n)`.+    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`. -18. Else:+    b. If :math:`n` is smaller than :math:`\X{ea} + N/8`, or :math:`\X{ea}` is not divisible by :math:`N/8`, then: -    a. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_t(m)`.+       i. Trap. -19. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_w`.+    c. Perform the atomic :ref:`action <syntax-act>` :math:`(\ARMW_{\SEQCST}~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)` to read the bytes :math:`b_{\F{r}}^\ast` from data offset :math:`\X{ea}` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a` and replace them with bytes :math:`b_{\F{w}}^\ast` (which are defined below). -20. Push the value :math:`t.\CONST~c_1` to the stack.+14. Let :math:`c_{\F{r}}` be the integer for which :math:`\bytes_{\X{st}}(n) = b_{\F{r}}^\ast`.++15. Let :math:`c_1` be the result of computing :math:`\extendtu_{\X{st},t}(c_{\F{r}})`.++16. Let :math:`c` be the result of computing :math:`\atop_t(c_1, c_2)`.++17. Let :math:`c_{\F{w}}` be the result of computing :math:`\wrapt_{t,\X{st}}(c)`.++18. Let :math:`b^\ast_{\F{w}}` be the byte sequence :math:`\bytes_{\X{st}}(c_{\F{w}})`.++19. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then:++    a. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_{\F{w}}`.++20. Push the value :math:`t.\CONST~c` to the stack.  .. math::    \begin{array}{l}    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)-     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_1^\ast~b^\ast)}&-     F; (t.\CONST~c_1)+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S'; F; (t.\CONST~c_1)    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}-     (\iff & \X{ea} + N/8 \leq n \\+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 \leq n \\      \wedge & \X{ea} \mod N/8 = 0 \\-     \wedge & b_1^\ast = \bytes_{\iN}(c_1) \\-     \wedge & b^\ast = \bytes_{\iN}(\wrap_{|t|,N}(\atomicop_t(c_1, c_2)))) \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(\meminst.\MIDATA[\X{ea} \slice N/8])) \\+     \wedge & S' = S \with \SMEMS[a].\MIDATA[\X{ea} \slice N/8] = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)+   S; F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S; F; \TRAP+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\+     \end{array}+   \\+   %+   ~\\+   \begin{array}{lcl@{\qquad}l}+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)}&+     S; F; (t.\CONST~c_1)+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & S.\SMEMS[a] ~\mbox{undefined} \\+     \wedge & \X{ea} + N/8 \leq n \\+     \wedge & \X{ea} \mod N/8 = 0 \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(b_{\F{r}}^\ast)) \\+     \wedge & b_{\F{r}}^\ast = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\+     \end{array}+   \\[1ex]+   \begin{array}{lcl@{\qquad}l}+   S; F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)      &\stepto^{(\ARD~a.\LLEN~n)}&-     F; \TRAP+     S; F; \TRAP    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}-     (\iff & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\+     (\iff & S.\SMEMS[a] ~\mbox{undefined} \\+     \wedge & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\      \end{array}-   \\[2ex]-   (\where N = |t| \iff ~\mbox{not present}) \\-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}-   (\where & N = |t| \iff ~\mbox{not present} \\+   (\where & N = |t| \iff N~\mbox{not present} \\+   \wedge & \X{st} = t \iff N~\mbox{not present}, ~\X{st} = \iN \otherwise \\    \wedge & a = F.\AMODULE.\MIMEMS[0] \\    \wedge & \X{ea} = i + \memarg.\OFFSET) \\    \end{array}    \end{array}  -.. _exec-atomic-rmw-cmpxchg:-.. _exec-atomic-rmwn-cmpxchg:+.. _exec-atomic.rmw.cmpxchg:+.. _exec-atomic.rmwn.cmpxchg: -:math:`t\K{.}\ATOMICRMW{.}\ATOMICCMPXCHG~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\ATOMICCMPXCHG~\memarg`-...............................................................................................................+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\ATCMPXCHG~\memarg`+............................................................. -.. todo:: update text to match formalism+.. todo:: should only emit |ARMW| if the condition is true? -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn-cmpxchg>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`.

Fixed.

rossberg

comment created time in 21 hours

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & \meminst = S.\SMEMS[a]) \\      \end{array}-   \\[1ex]+   \\    %+   ~\\+   \\    \begin{array}{lcl@{\qquad}l}-   S; F; (\I32.\CONST~i)~\MEMORYGROW-     &\stepto^{(\ARMW~a.\LLEN~n~(n+k))~(\AWR~a.\LDATA[n]~(0)^k)}&+   S; F; (\I32.\CONST~n)~\MEMORYGROW+     &\stepto^{(\ARMW~a.\LLEN~l~(l+k))~(\AWR~a.\LDATA[l]~(0)^k)}&      S; F; (\I32.\CONST~\X{sz})    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined} \\-     \wedge & n = \X{sz} \cdot 64\,\F{Ki} \\-     \wedge & k = i \cdot 64\,\F{Ki}) \\+     \wedge & \X{sz} = l / 64\,\F{Ki} \\+     \wedge & n = k / 64\,\F{Ki}) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}    S; F; (\I32.\CONST~n)~\MEMORYGROW-     &\stepto^{(\ARD~a.\LLEN~n)}&+     &\stepto^{(\ARD_{\SEQCST}~a.\LLEN~n)}&      S; F; (\I32.\CONST~{-1})    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined}) \\      \end{array}    \end{array}-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}    (\where & a = F.\AMODULE.\MIMEMS[0]) \\    \end{array}    \end{array}  .. note::-   The |MEMORYGROW| instruction is non-deterministic.+   The |MEMORYGROW| instruction is non-deterministic, even on unshared memories.    It may either succeed, returning the old memory size :math:`\X{sz}`,    or fail, returning :math:`{-1}`.    Failure *must* occur if the referenced memory instance has a maximum size defined that would be exceeded.    However, failure *can* occur in other cases as well.    In practice, the choice depends on the :ref:`resources <impl-exec>` available to the :ref:`embedder <embedder>`.  -.. index:: atomic memory instruction, memory, frame, module++.. index:: atomic memory instruction, memory, frame, module, atomic operator    pair: execution; instruction    single: abstract syntax; instruction .. _exec-instr-atomic-memory:  Atomic Memory Instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~ -:math:`t\K{.}\ATOMICLOAD~\memarg` and :math:`t\K{.}\ATOMICLOAD{N}\K{\_u}~\memarg`-.................................................................................+.. _exec-atomic.load:+.. _exec-atomic.loadn: -See :ref:`above <exec-atomic-load>`.+:math:`t\K{.}\ATOMICLOAD({N}\K{\_u})^?~\memarg`+............................................... +The rules are identical to :ref:`non-atomic loads <exec-load>`, except that :math:`\ord = \SEQCST`. -:math:`t\K{.}\ATOMICSTORE~\memarg` and :math:`t\K{.}\ATOMICSTORE{N}~\memarg`-............................................................................ -See :ref:`above <exec-atomic-store>`.+.. _exec-atomic.store:+.. _exec-atomic.storen: +:math:`t\K{.}\ATOMICSTORE{N}^?~\memarg`+....................................... +The rules are identical to :ref:`non-atomic stores <exec-store>`, except that :math:`\ord = \SEQCST`. -.. _exec-atomic-rmw:-.. _exec-atomic-rmwn: -:math:`t\K{.}\ATOMICRMW{.}\atomicop~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\atomicop~\memarg`-.....................................................................................................+.. _exec-atomic.rmw:+.. _exec-atomic.rmwn: -.. todo:: update text to match formalism+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\atop~\memarg`+........................................................ -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+2. Else: -4. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`S.\SMEMS[a]` exists.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+   b. Let :math:`\X{st}` be the :ref:`value type <syntax-valtype>` :math:`t`. -6. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack.+3. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack. -7. Pop the value :math:`t.\CONST~c_2` from the stack.+4. Pop the value :math:`t.\CONST~c_2` from the stack. -8. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+5. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -9. Pop the value :math:`\I32.\CONST~i` from the stack.+6. Pop the value :math:`\I32.\CONST~i` from the stack. -10. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`.+7. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`. -11. If :math:`N` is not part of the instruction, then:+8. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then: -    a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+   a. Trap. -12. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+9. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -    a. Trap.+10. Assert: due to :ref:`validation <valid-atomic.rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -13. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then:+11. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -    a. Trap.+12. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -14. Let :math:`b^\ast_r` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+    a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -15. Let :math:`c_1` be the integer for which :math:`bytes_{\iN}(m) = b^\ast_r`.+    b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -16. Let :math:`m` be the result of computing :math:`\atomicop_t(c_1, c_2)`.+       a. Trap. -17. If :math:`N` is part of the instruction, then:+    c. Let :math:`b^\ast_{\F{r}}` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -    a. Let :math:`n` be the result of computing :math:`\wrap_{|t|,N}(m)`.+13. Else: -    b. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_{\iN}(n)`.+    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`. -18. Else:+    b. If :math:`n` is smaller than :math:`\X{ea} + N/8`, or :math:`\X{ea}` is not divisible by :math:`N/8`, then: -    a. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_t(m)`.+       i. Trap. -19. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_w`.+    c. Perform the atomic :ref:`action <syntax-act>` :math:`(\ARMW_{\SEQCST}~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)` to read the bytes :math:`b_{\F{r}}^\ast` from data offset :math:`\X{ea}` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a` and replace them with bytes :math:`b_{\F{w}}^\ast` (which are defined below).

Fixed as above. (Yes, for b*_w this follows from the definition of bytes_st.)

rossberg

comment created time in 21 hours

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & \meminst = S.\SMEMS[a]) \\      \end{array}-   \\[1ex]+   \\    %+   ~\\+   \\    \begin{array}{lcl@{\qquad}l}-   S; F; (\I32.\CONST~i)~\MEMORYGROW-     &\stepto^{(\ARMW~a.\LLEN~n~(n+k))~(\AWR~a.\LDATA[n]~(0)^k)}&+   S; F; (\I32.\CONST~n)~\MEMORYGROW+     &\stepto^{(\ARMW~a.\LLEN~l~(l+k))~(\AWR~a.\LDATA[l]~(0)^k)}&      S; F; (\I32.\CONST~\X{sz})    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined} \\-     \wedge & n = \X{sz} \cdot 64\,\F{Ki} \\-     \wedge & k = i \cdot 64\,\F{Ki}) \\+     \wedge & \X{sz} = l / 64\,\F{Ki} \\+     \wedge & n = k / 64\,\F{Ki}) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}    S; F; (\I32.\CONST~n)~\MEMORYGROW-     &\stepto^{(\ARD~a.\LLEN~n)}&+     &\stepto^{(\ARD_{\SEQCST}~a.\LLEN~n)}&      S; F; (\I32.\CONST~{-1})    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined}) \\      \end{array}    \end{array}-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}    (\where & a = F.\AMODULE.\MIMEMS[0]) \\    \end{array}    \end{array}  .. note::-   The |MEMORYGROW| instruction is non-deterministic.+   The |MEMORYGROW| instruction is non-deterministic, even on unshared memories.    It may either succeed, returning the old memory size :math:`\X{sz}`,    or fail, returning :math:`{-1}`.    Failure *must* occur if the referenced memory instance has a maximum size defined that would be exceeded.    However, failure *can* occur in other cases as well.    In practice, the choice depends on the :ref:`resources <impl-exec>` available to the :ref:`embedder <embedder>`.  -.. index:: atomic memory instruction, memory, frame, module++.. index:: atomic memory instruction, memory, frame, module, atomic operator    pair: execution; instruction    single: abstract syntax; instruction .. _exec-instr-atomic-memory:  Atomic Memory Instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~ -:math:`t\K{.}\ATOMICLOAD~\memarg` and :math:`t\K{.}\ATOMICLOAD{N}\K{\_u}~\memarg`-.................................................................................+.. _exec-atomic.load:+.. _exec-atomic.loadn: -See :ref:`above <exec-atomic-load>`.+:math:`t\K{.}\ATOMICLOAD({N}\K{\_u})^?~\memarg`+............................................... +The rules are identical to :ref:`non-atomic loads <exec-load>`, except that :math:`\ord = \SEQCST`. -:math:`t\K{.}\ATOMICSTORE~\memarg` and :math:`t\K{.}\ATOMICSTORE{N}~\memarg`-............................................................................ -See :ref:`above <exec-atomic-store>`.+.. _exec-atomic.store:+.. _exec-atomic.storen: +:math:`t\K{.}\ATOMICSTORE{N}^?~\memarg`+....................................... +The rules are identical to :ref:`non-atomic stores <exec-store>`, except that :math:`\ord = \SEQCST`. -.. _exec-atomic-rmw:-.. _exec-atomic-rmwn: -:math:`t\K{.}\ATOMICRMW{.}\atomicop~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\atomicop~\memarg`-.....................................................................................................+.. _exec-atomic.rmw:+.. _exec-atomic.rmwn: -.. todo:: update text to match formalism+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\atop~\memarg`+........................................................ -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+2. Else: -4. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`S.\SMEMS[a]` exists.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+   b. Let :math:`\X{st}` be the :ref:`value type <syntax-valtype>` :math:`t`. -6. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack.+3. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack. -7. Pop the value :math:`t.\CONST~c_2` from the stack.+4. Pop the value :math:`t.\CONST~c_2` from the stack. -8. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+5. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -9. Pop the value :math:`\I32.\CONST~i` from the stack.+6. Pop the value :math:`\I32.\CONST~i` from the stack. -10. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`.+7. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`. -11. If :math:`N` is not part of the instruction, then:+8. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then: -    a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+   a. Trap. -12. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+9. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -    a. Trap.+10. Assert: due to :ref:`validation <valid-atomic.rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -13. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then:+11. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -    a. Trap.+12. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -14. Let :math:`b^\ast_r` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+    a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -15. Let :math:`c_1` be the integer for which :math:`bytes_{\iN}(m) = b^\ast_r`.+    b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -16. Let :math:`m` be the result of computing :math:`\atomicop_t(c_1, c_2)`.+       a. Trap. -17. If :math:`N` is part of the instruction, then:+    c. Let :math:`b^\ast_{\F{r}}` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -    a. Let :math:`n` be the result of computing :math:`\wrap_{|t|,N}(m)`.+13. Else: -    b. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_{\iN}(n)`.+    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`. -18. Else:+    b. If :math:`n` is smaller than :math:`\X{ea} + N/8`, or :math:`\X{ea}` is not divisible by :math:`N/8`, then: -    a. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_t(m)`.+       i. Trap. -19. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_w`.+    c. Perform the atomic :ref:`action <syntax-act>` :math:`(\ARMW_{\SEQCST}~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)` to read the bytes :math:`b_{\F{r}}^\ast` from data offset :math:`\X{ea}` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a` and replace them with bytes :math:`b_{\F{w}}^\ast` (which are defined below). -20. Push the value :math:`t.\CONST~c_1` to the stack.+14. Let :math:`c_{\F{r}}` be the integer for which :math:`\bytes_{\X{st}}(n) = b_{\F{r}}^\ast`.++15. Let :math:`c_1` be the result of computing :math:`\extendtu_{\X{st},t}(c_{\F{r}})`.++16. Let :math:`c` be the result of computing :math:`\atop_t(c_1, c_2)`.++17. Let :math:`c_{\F{w}}` be the result of computing :math:`\wrapt_{t,\X{st}}(c)`.++18. Let :math:`b^\ast_{\F{w}}` be the byte sequence :math:`\bytes_{\X{st}}(c_{\F{w}})`.++19. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then:++    a. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_{\F{w}}`.++20. Push the value :math:`t.\CONST~c` to the stack.  .. math::    \begin{array}{l}    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)-     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_1^\ast~b^\ast)}&-     F; (t.\CONST~c_1)+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S'; F; (t.\CONST~c_1)    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}-     (\iff & \X{ea} + N/8 \leq n \\+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 \leq n \\      \wedge & \X{ea} \mod N/8 = 0 \\-     \wedge & b_1^\ast = \bytes_{\iN}(c_1) \\-     \wedge & b^\ast = \bytes_{\iN}(\wrap_{|t|,N}(\atomicop_t(c_1, c_2)))) \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(\meminst.\MIDATA[\X{ea} \slice N/8])) \\+     \wedge & S' = S \with \SMEMS[a].\MIDATA[\X{ea} \slice N/8] = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)+   S; F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S; F; \TRAP+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\+     \end{array}+   \\+   %+   ~\\+   \begin{array}{lcl@{\qquad}l}+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)}&+     S; F; (t.\CONST~c_1)+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & S.\SMEMS[a] ~\mbox{undefined} \\+     \wedge & \X{ea} + N/8 \leq n \\+     \wedge & \X{ea} \mod N/8 = 0 \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(b_{\F{r}}^\ast)) \\+     \wedge & b_{\F{r}}^\ast = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\

Fixed.

rossberg

comment created time in 21 hours

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & \meminst = S.\SMEMS[a]) \\      \end{array}-   \\[1ex]+   \\    %+   ~\\+   \\    \begin{array}{lcl@{\qquad}l}-   S; F; (\I32.\CONST~i)~\MEMORYGROW-     &\stepto^{(\ARMW~a.\LLEN~n~(n+k))~(\AWR~a.\LDATA[n]~(0)^k)}&+   S; F; (\I32.\CONST~n)~\MEMORYGROW+     &\stepto^{(\ARMW~a.\LLEN~l~(l+k))~(\AWR~a.\LDATA[l]~(0)^k)}&      S; F; (\I32.\CONST~\X{sz})    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined} \\-     \wedge & n = \X{sz} \cdot 64\,\F{Ki} \\-     \wedge & k = i \cdot 64\,\F{Ki}) \\+     \wedge & \X{sz} = l / 64\,\F{Ki} \\+     \wedge & n = k / 64\,\F{Ki}) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}    S; F; (\I32.\CONST~n)~\MEMORYGROW-     &\stepto^{(\ARD~a.\LLEN~n)}&+     &\stepto^{(\ARD_{\SEQCST}~a.\LLEN~n)}&      S; F; (\I32.\CONST~{-1})    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined}) \\      \end{array}    \end{array}-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}    (\where & a = F.\AMODULE.\MIMEMS[0]) \\    \end{array}    \end{array}  .. note::-   The |MEMORYGROW| instruction is non-deterministic.+   The |MEMORYGROW| instruction is non-deterministic, even on unshared memories.    It may either succeed, returning the old memory size :math:`\X{sz}`,    or fail, returning :math:`{-1}`.    Failure *must* occur if the referenced memory instance has a maximum size defined that would be exceeded.    However, failure *can* occur in other cases as well.    In practice, the choice depends on the :ref:`resources <impl-exec>` available to the :ref:`embedder <embedder>`.  -.. index:: atomic memory instruction, memory, frame, module++.. index:: atomic memory instruction, memory, frame, module, atomic operator    pair: execution; instruction    single: abstract syntax; instruction .. _exec-instr-atomic-memory:  Atomic Memory Instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~ -:math:`t\K{.}\ATOMICLOAD~\memarg` and :math:`t\K{.}\ATOMICLOAD{N}\K{\_u}~\memarg`-.................................................................................+.. _exec-atomic.load:+.. _exec-atomic.loadn: -See :ref:`above <exec-atomic-load>`.+:math:`t\K{.}\ATOMICLOAD({N}\K{\_u})^?~\memarg`+............................................... +The rules are identical to :ref:`non-atomic loads <exec-load>`, except that :math:`\ord = \SEQCST`. -:math:`t\K{.}\ATOMICSTORE~\memarg` and :math:`t\K{.}\ATOMICSTORE{N}~\memarg`-............................................................................ -See :ref:`above <exec-atomic-store>`.+.. _exec-atomic.store:+.. _exec-atomic.storen: +:math:`t\K{.}\ATOMICSTORE{N}^?~\memarg`+....................................... +The rules are identical to :ref:`non-atomic stores <exec-store>`, except that :math:`\ord = \SEQCST`. -.. _exec-atomic-rmw:-.. _exec-atomic-rmwn: -:math:`t\K{.}\ATOMICRMW{.}\atomicop~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\atomicop~\memarg`-.....................................................................................................+.. _exec-atomic.rmw:+.. _exec-atomic.rmwn: -.. todo:: update text to match formalism+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\atop~\memarg`+........................................................ -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`.

Fixed.

rossberg

comment created time in 21 hours

Pull request review commentWebAssembly/threads

Spec basic instructions

 Index of Instructions --------------------- -===========================================================  =========================  =============================================  =============================================  ===============================================================-Instruction                                                  Binary Opcode              Type                                           Validation                                     Execution                                                      -===========================================================  =========================  =============================================  =============================================  ===============================================================-:math:`\UNREACHABLE`                                         :math:`\hex{00}`           :math:`[t_1^\ast] \to [t_2^\ast]`              :ref:`validation <valid-unreachable>`          :ref:`execution <exec-unreachable>`                            -:math:`\NOP`                                                 :math:`\hex{01}`           :math:`[] \to []`                              :ref:`validation <valid-nop>`                  :ref:`execution <exec-nop>`                                    -:math:`\BLOCK~\X{bt}`                                        :math:`\hex{02}`           :math:`[t_1^\ast] \to [t_2^\ast]`              :ref:`validation <valid-block>`                :ref:`execution <exec-block>`                                  -:math:`\LOOP~\X{bt}`                                         :math:`\hex{03}`           :math:`[t_1^\ast] \to [t_2^\ast]`              :ref:`validation <valid-loop>`                 :ref:`execution <exec-loop>`                                   -:math:`\IF~\X{bt}`                                           :math:`\hex{04}`           :math:`[t_1^\ast] \to [t_2^\ast]`              :ref:`validation <valid-if>`                   :ref:`execution <exec-if>`                                     -:math:`\ELSE`                                                :math:`\hex{05}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{06}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{07}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{08}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{09}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{0A}`                                                                                                                                                                        -:math:`\END`                                                 :math:`\hex{0B}`                                                                                                                                                                        -:math:`\BR~l`                                                :math:`\hex{0C}`           :math:`[t_1^\ast~t^\ast] \to [t_2^\ast]`       :ref:`validation <valid-br>`                   :ref:`execution <exec-br>`                                     -:math:`\BRIF~l`                                              :math:`\hex{0D}`           :math:`[t^\ast~\I32] \to [t^\ast]`             :ref:`validation <valid-br_if>`                :ref:`execution <exec-br_if>`                                  -:math:`\BRTABLE~l^\ast~l`                                    :math:`\hex{0E}`           :math:`[t_1^\ast~t^\ast~\I32] \to [t_2^\ast]`  :ref:`validation <valid-br_table>`             :ref:`execution <exec-br_table>`                               -:math:`\RETURN`                                              :math:`\hex{0F}`           :math:`[t_1^\ast~t^\ast] \to [t_2^\ast]`       :ref:`validation <valid-return>`               :ref:`execution <exec-return>`                                 -:math:`\CALL~x`                                              :math:`\hex{10}`           :math:`[t_1^\ast] \to [t_2^\ast]`              :ref:`validation <valid-call>`                 :ref:`execution <exec-call>`                                   -:math:`\CALLINDIRECT~x`                                      :math:`\hex{11}`           :math:`[t_1^\ast~\I32] \to [t_2^\ast]`         :ref:`validation <valid-call_indirect>`        :ref:`execution <exec-call_indirect>`                          -(reserved)                                                   :math:`\hex{12}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{13}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{14}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{15}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{16}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{17}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{18}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{19}`                                                                                                                                                                        -:math:`\DROP`                                                :math:`\hex{1A}`           :math:`[t] \to []`                             :ref:`validation <valid-drop>`                 :ref:`execution <exec-drop>`                                   -:math:`\SELECT`                                              :math:`\hex{1B}`           :math:`[t~t~\I32] \to [t]`                     :ref:`validation <valid-select>`               :ref:`execution <exec-select>`                                 -(reserved)                                                   :math:`\hex{1C}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{1D}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{1E}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{1F}`                                                                                                                                                                        -:math:`\LOCALGET~x`                                          :math:`\hex{20}`           :math:`[] \to [t]`                             :ref:`validation <valid-local.get>`            :ref:`execution <exec-local.get>`                              -:math:`\LOCALSET~x`                                          :math:`\hex{21}`           :math:`[t] \to []`                             :ref:`validation <valid-local.set>`            :ref:`execution <exec-local.set>`                              -:math:`\LOCALTEE~x`                                          :math:`\hex{22}`           :math:`[t] \to [t]`                            :ref:`validation <valid-local.tee>`            :ref:`execution <exec-local.tee>`                              -:math:`\GLOBALGET~x`                                         :math:`\hex{23}`           :math:`[] \to [t]`                             :ref:`validation <valid-global.get>`           :ref:`execution <exec-global.get>`                             -:math:`\GLOBALSET~x`                                         :math:`\hex{24}`           :math:`[t] \to []`                             :ref:`validation <valid-global.set>`           :ref:`execution <exec-global.set>`                             -(reserved)                                                   :math:`\hex{25}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{26}`                                                                                                                                                                        -(reserved)                                                   :math:`\hex{27}`                                                                                                                                                                        -:math:`\I32.\LOAD~\memarg`                                   :math:`\hex{28}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-load>`                 :ref:`execution <exec-load>`                                   -:math:`\I64.\LOAD~\memarg`                                   :math:`\hex{29}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-load>`                 :ref:`execution <exec-load>`                                   -:math:`\F32.\LOAD~\memarg`                                   :math:`\hex{2A}`           :math:`[\I32] \to [\F32]`                      :ref:`validation <valid-load>`                 :ref:`execution <exec-load>`                                   -:math:`\F64.\LOAD~\memarg`                                   :math:`\hex{2B}`           :math:`[\I32] \to [\F64]`                      :ref:`validation <valid-load>`                 :ref:`execution <exec-load>`                                   -:math:`\I32.\LOAD\K{8\_s}~\memarg`                           :math:`\hex{2C}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-loadn>`                :ref:`execution <exec-loadn>`                                  -:math:`\I32.\LOAD\K{8\_u}~\memarg`                           :math:`\hex{2D}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-loadn>`                :ref:`execution <exec-loadn>`                                  -:math:`\I32.\LOAD\K{16\_s}~\memarg`                          :math:`\hex{2E}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-loadn>`                :ref:`execution <exec-loadn>`                                  -:math:`\I32.\LOAD\K{16\_u}~\memarg`                          :math:`\hex{2F}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-loadn>`                :ref:`execution <exec-loadn>`                                  -:math:`\I64.\LOAD\K{8\_s}~\memarg`                           :math:`\hex{30}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-loadn>`                :ref:`execution <exec-loadn>`                                  -:math:`\I64.\LOAD\K{8\_u}~\memarg`                           :math:`\hex{31}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-loadn>`                :ref:`execution <exec-loadn>`                                  -:math:`\I64.\LOAD\K{16\_s}~\memarg`                          :math:`\hex{32}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-loadn>`                :ref:`execution <exec-loadn>`                                  -:math:`\I64.\LOAD\K{16\_u}~\memarg`                          :math:`\hex{33}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-loadn>`                :ref:`execution <exec-loadn>`                                  -:math:`\I64.\LOAD\K{32\_s}~\memarg`                          :math:`\hex{34}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-loadn>`                :ref:`execution <exec-loadn>`                                  -:math:`\I64.\LOAD\K{32\_u}~\memarg`                          :math:`\hex{35}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-loadn>`                :ref:`execution <exec-loadn>`                                  -:math:`\I32.\STORE~\memarg`                                  :math:`\hex{36}`           :math:`[\I32~\I32] \to []`                     :ref:`validation <valid-store>`                :ref:`execution <exec-store>`                                  -:math:`\I64.\STORE~\memarg`                                  :math:`\hex{37}`           :math:`[\I32~\I64] \to []`                     :ref:`validation <valid-store>`                :ref:`execution <exec-store>`                                  -:math:`\F32.\STORE~\memarg`                                  :math:`\hex{38}`           :math:`[\I32~\F32] \to []`                     :ref:`validation <valid-store>`                :ref:`execution <exec-store>`                                  -:math:`\F64.\STORE~\memarg`                                  :math:`\hex{39}`           :math:`[\I32~\F64] \to []`                     :ref:`validation <valid-store>`                :ref:`execution <exec-store>`                                  -:math:`\I32.\STORE\K{8}~\memarg`                             :math:`\hex{3A}`           :math:`[\I32~\I32] \to []`                     :ref:`validation <valid-storen>`               :ref:`execution <exec-storen>`                                 -:math:`\I32.\STORE\K{16}~\memarg`                            :math:`\hex{3B}`           :math:`[\I32~\I32] \to []`                     :ref:`validation <valid-storen>`               :ref:`execution <exec-storen>`                                 -:math:`\I64.\STORE\K{8}~\memarg`                             :math:`\hex{3C}`           :math:`[\I32~\I64] \to []`                     :ref:`validation <valid-storen>`               :ref:`execution <exec-storen>`                                 -:math:`\I64.\STORE\K{16}~\memarg`                            :math:`\hex{3D}`           :math:`[\I32~\I64] \to []`                     :ref:`validation <valid-storen>`               :ref:`execution <exec-storen>`                                 -:math:`\I64.\STORE\K{32}~\memarg`                            :math:`\hex{3E}`           :math:`[\I32~\I64] \to []`                     :ref:`validation <valid-storen>`               :ref:`execution <exec-storen>`                                 -:math:`\MEMORYSIZE`                                          :math:`\hex{3F}`           :math:`[] \to [\I32]`                          :ref:`validation <valid-memory.size>`          :ref:`execution <exec-memory.size>`                            -:math:`\MEMORYGROW`                                          :math:`\hex{40}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-memory.grow>`          :ref:`execution <exec-memory.grow>`                            -:math:`\I32.\CONST~\i32`                                     :math:`\hex{41}`           :math:`[] \to [\I32]`                          :ref:`validation <valid-const>`                :ref:`execution <exec-const>`                                  -:math:`\I64.\CONST~\i64`                                     :math:`\hex{42}`           :math:`[] \to [\I64]`                          :ref:`validation <valid-const>`                :ref:`execution <exec-const>`                                  -:math:`\F32.\CONST~\f32`                                     :math:`\hex{43}`           :math:`[] \to [\F32]`                          :ref:`validation <valid-const>`                :ref:`execution <exec-const>`                                  -:math:`\F64.\CONST~\f64`                                     :math:`\hex{44}`           :math:`[] \to [\F64]`                          :ref:`validation <valid-const>`                :ref:`execution <exec-const>`                                  -:math:`\I32.\EQZ`                                            :math:`\hex{45}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-testop>`               :ref:`execution <exec-testop>`, :ref:`operator <op-ieqz>`      -:math:`\I32.\EQ`                                             :math:`\hex{46}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ieq>`        -:math:`\I32.\NE`                                             :math:`\hex{47}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ine>`        -:math:`\I32.\LT\K{\_s}`                                      :math:`\hex{48}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ilt_s>`      -:math:`\I32.\LT\K{\_u}`                                      :math:`\hex{49}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ilt_u>`      -:math:`\I32.\GT\K{\_s}`                                      :math:`\hex{4A}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-igt_s>`      -:math:`\I32.\GT\K{\_u}`                                      :math:`\hex{4B}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-igt_u>`      -:math:`\I32.\LE\K{\_s}`                                      :math:`\hex{4C}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ile_s>`      -:math:`\I32.\LE\K{\_u}`                                      :math:`\hex{4D}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ile_u>`      -:math:`\I32.\GE\K{\_s}`                                      :math:`\hex{4E}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ige_s>`      -:math:`\I32.\GE\K{\_u}`                                      :math:`\hex{4F}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ige_u>`      -:math:`\I64.\EQZ`                                            :math:`\hex{50}`           :math:`[\I64] \to [\I32]`                      :ref:`validation <valid-testop>`               :ref:`execution <exec-testop>`, :ref:`operator <op-ieqz>`      -:math:`\I64.\EQ`                                             :math:`\hex{51}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ieq>`        -:math:`\I64.\NE`                                             :math:`\hex{52}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ine>`        -:math:`\I64.\LT\K{\_s}`                                      :math:`\hex{53}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ilt_s>`      -:math:`\I64.\LT\K{\_u}`                                      :math:`\hex{54}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ilt_u>`      -:math:`\I64.\GT\K{\_s}`                                      :math:`\hex{55}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-igt_s>`      -:math:`\I64.\GT\K{\_u}`                                      :math:`\hex{56}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-igt_u>`      -:math:`\I64.\LE\K{\_s}`                                      :math:`\hex{57}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ile_s>`      -:math:`\I64.\LE\K{\_u}`                                      :math:`\hex{58}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ile_u>`      -:math:`\I64.\GE\K{\_s}`                                      :math:`\hex{59}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ige_s>`      -:math:`\I64.\GE\K{\_u}`                                      :math:`\hex{5A}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-ige_u>`      -:math:`\F32.\EQ`                                             :math:`\hex{5B}`           :math:`[\F32~\F32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-feq>`        -:math:`\F32.\NE`                                             :math:`\hex{5C}`           :math:`[\F32~\F32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-fne>`        -:math:`\F32.\LT`                                             :math:`\hex{5D}`           :math:`[\F32~\F32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-flt>`        -:math:`\F32.\GT`                                             :math:`\hex{5E}`           :math:`[\F32~\F32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-fgt>`        -:math:`\F32.\LE`                                             :math:`\hex{5F}`           :math:`[\F32~\F32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-fle>`        -:math:`\F32.\GE`                                             :math:`\hex{60}`           :math:`[\F32~\F32] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-fge>`        -:math:`\F64.\EQ`                                             :math:`\hex{61}`           :math:`[\F64~\F64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-feq>`        -:math:`\F64.\NE`                                             :math:`\hex{62}`           :math:`[\F64~\F64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-fne>`        -:math:`\F64.\LT`                                             :math:`\hex{63}`           :math:`[\F64~\F64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-flt>`        -:math:`\F64.\GT`                                             :math:`\hex{64}`           :math:`[\F64~\F64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-fgt>`        -:math:`\F64.\LE`                                             :math:`\hex{65}`           :math:`[\F64~\F64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-fle>`        -:math:`\F64.\GE`                                             :math:`\hex{66}`           :math:`[\F64~\F64] \to [\I32]`                 :ref:`validation <valid-relop>`                :ref:`execution <exec-relop>`, :ref:`operator <op-fge>`        -:math:`\I32.\CLZ`                                            :math:`\hex{67}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-iclz>`        -:math:`\I32.\CTZ`                                            :math:`\hex{68}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-ictz>`        -:math:`\I32.\POPCNT`                                         :math:`\hex{69}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-ipopcnt>`     -:math:`\I32.\ADD`                                            :math:`\hex{6A}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-iadd>`       -:math:`\I32.\SUB`                                            :math:`\hex{6B}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-isub>`       -:math:`\I32.\MUL`                                            :math:`\hex{6C}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-imul>`       -:math:`\I32.\DIV\K{\_s}`                                     :math:`\hex{6D}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-idiv_s>`     -:math:`\I32.\DIV\K{\_u}`                                     :math:`\hex{6E}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-idiv_u>`     -:math:`\I32.\REM\K{\_s}`                                     :math:`\hex{6F}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-irem_s>`     -:math:`\I32.\REM\K{\_u}`                                     :math:`\hex{70}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-irem_u>`     -:math:`\I32.\AND`                                            :math:`\hex{71}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-iand>`       -:math:`\I32.\OR`                                             :math:`\hex{72}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-ior>`        -:math:`\I32.\XOR`                                            :math:`\hex{73}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-ixor>`       -:math:`\I32.\SHL`                                            :math:`\hex{74}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-ishl>`       -:math:`\I32.\SHR\K{\_s}`                                     :math:`\hex{75}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-ishr_s>`     -:math:`\I32.\SHR\K{\_u}`                                     :math:`\hex{76}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-ishr_u>`     -:math:`\I32.\ROTL`                                           :math:`\hex{77}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-irotl>`      -:math:`\I32.\ROTR`                                           :math:`\hex{78}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-irotr>`      -:math:`\I64.\CLZ`                                            :math:`\hex{79}`           :math:`[\I64] \to [\I64]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-iclz>`        -:math:`\I64.\CTZ`                                            :math:`\hex{7A}`           :math:`[\I64] \to [\I64]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-ictz>`        -:math:`\I64.\POPCNT`                                         :math:`\hex{7B}`           :math:`[\I64] \to [\I64]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-ipopcnt>`     -:math:`\I64.\ADD`                                            :math:`\hex{7C}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-iadd>`       -:math:`\I64.\SUB`                                            :math:`\hex{7D}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-isub>`       -:math:`\I64.\MUL`                                            :math:`\hex{7E}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-imul>`       -:math:`\I64.\DIV\K{\_s}`                                     :math:`\hex{7F}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-idiv_s>`     -:math:`\I64.\DIV\K{\_u}`                                     :math:`\hex{80}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-idiv_u>`     -:math:`\I64.\REM\K{\_s}`                                     :math:`\hex{81}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-irem_s>`     -:math:`\I64.\REM\K{\_u}`                                     :math:`\hex{82}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-irem_u>`     -:math:`\I64.\AND`                                            :math:`\hex{83}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-iand>`       -:math:`\I64.\OR`                                             :math:`\hex{84}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-ior>`        -:math:`\I64.\XOR`                                            :math:`\hex{85}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-ixor>`       -:math:`\I64.\SHL`                                            :math:`\hex{86}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-ishl>`       -:math:`\I64.\SHR\K{\_s}`                                     :math:`\hex{87}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-ishr_s>`     -:math:`\I64.\SHR\K{\_u}`                                     :math:`\hex{88}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-ishr_u>`     -:math:`\I64.\ROTL`                                           :math:`\hex{89}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-irotl>`      -:math:`\I64.\ROTR`                                           :math:`\hex{8A}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-irotr>`      -:math:`\F32.\ABS`                                            :math:`\hex{8B}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-fabs>`        -:math:`\F32.\NEG`                                            :math:`\hex{8C}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-fneg>`        -:math:`\F32.\CEIL`                                           :math:`\hex{8D}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-fceil>`       -:math:`\F32.\FLOOR`                                          :math:`\hex{8E}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-ffloor>`      -:math:`\F32.\TRUNC`                                          :math:`\hex{8F}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-ftrunc>`      -:math:`\F32.\NEAREST`                                        :math:`\hex{90}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-fnearest>`    -:math:`\F32.\SQRT`                                           :math:`\hex{91}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-fsqrt>`       -:math:`\F32.\ADD`                                            :math:`\hex{92}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fadd>`       -:math:`\F32.\SUB`                                            :math:`\hex{93}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fsub>`       -:math:`\F32.\MUL`                                            :math:`\hex{94}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fmul>`       -:math:`\F32.\DIV`                                            :math:`\hex{95}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fdiv>`       -:math:`\F32.\FMIN`                                           :math:`\hex{96}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fmin>`       -:math:`\F32.\FMAX`                                           :math:`\hex{97}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fmax>`       -:math:`\F32.\COPYSIGN`                                       :math:`\hex{98}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fcopysign>`  -:math:`\F64.\ABS`                                            :math:`\hex{99}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-fabs>`        -:math:`\F64.\NEG`                                            :math:`\hex{9A}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-fneg>`        -:math:`\F64.\CEIL`                                           :math:`\hex{9B}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-fceil>`       -:math:`\F64.\FLOOR`                                          :math:`\hex{9C}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-ffloor>`      -:math:`\F64.\TRUNC`                                          :math:`\hex{9D}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-ftrunc>`      -:math:`\F64.\NEAREST`                                        :math:`\hex{9E}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-fnearest>`    -:math:`\F64.\SQRT`                                           :math:`\hex{9F}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-fsqrt>`       -:math:`\F64.\ADD`                                            :math:`\hex{A0}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fadd>`       -:math:`\F64.\SUB`                                            :math:`\hex{A1}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fsub>`       -:math:`\F64.\MUL`                                            :math:`\hex{A2}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fmul>`       -:math:`\F64.\DIV`                                            :math:`\hex{A3}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fdiv>`       -:math:`\F64.\FMIN`                                           :math:`\hex{A4}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fmin>`       -:math:`\F64.\FMAX`                                           :math:`\hex{A5}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fmax>`       -:math:`\F64.\COPYSIGN`                                       :math:`\hex{A6}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                :ref:`execution <exec-binop>`, :ref:`operator <op-fcopysign>`  -:math:`\I32.\WRAP\K{\_}\I64`                                 :math:`\hex{A7}`           :math:`[\I64] \to [\I32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-wrap>`       -:math:`\I32.\TRUNC\K{\_}\F32\K{\_s}`                         :math:`\hex{A8}`           :math:`[\F32] \to [\I32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_s>`    -:math:`\I32.\TRUNC\K{\_}\F32\K{\_u}`                         :math:`\hex{A9}`           :math:`[\F32] \to [\I32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_u>`    -:math:`\I32.\TRUNC\K{\_}\F64\K{\_s}`                         :math:`\hex{AA}`           :math:`[\F64] \to [\I32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_s>`    -:math:`\I32.\TRUNC\K{\_}\F64\K{\_u}`                         :math:`\hex{AB}`           :math:`[\F64] \to [\I32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_u>`    -:math:`\I64.\EXTEND\K{\_}\I32\K{\_s}`                        :math:`\hex{AC}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-extend_s>`   -:math:`\I64.\EXTEND\K{\_}\I32\K{\_u}`                        :math:`\hex{AD}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-extend_u>`   -:math:`\I64.\TRUNC\K{\_}\F32\K{\_s}`                         :math:`\hex{AE}`           :math:`[\F32] \to [\I64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_s>`    -:math:`\I64.\TRUNC\K{\_}\F32\K{\_u}`                         :math:`\hex{AF}`           :math:`[\F32] \to [\I64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_u>`    -:math:`\I64.\TRUNC\K{\_}\F64\K{\_s}`                         :math:`\hex{B0}`           :math:`[\F64] \to [\I64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_s>`    -:math:`\I64.\TRUNC\K{\_}\F64\K{\_u}`                         :math:`\hex{B1}`           :math:`[\F64] \to [\I64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_u>`    -:math:`\F32.\CONVERT\K{\_}\I32\K{\_s}`                       :math:`\hex{B2}`           :math:`[\I32] \to [\F32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_s>`  -:math:`\F32.\CONVERT\K{\_}\I32\K{\_u}`                       :math:`\hex{B3}`           :math:`[\I32] \to [\F32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_u>`  -:math:`\F32.\CONVERT\K{\_}\I64\K{\_s}`                       :math:`\hex{B4}`           :math:`[\I64] \to [\F32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_s>`  -:math:`\F32.\CONVERT\K{\_}\I64\K{\_u}`                       :math:`\hex{B5}`           :math:`[\I64] \to [\F32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_u>`  -:math:`\F32.\DEMOTE\K{\_}\F64`                               :math:`\hex{B6}`           :math:`[\F64] \to [\F32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-demote>`     -:math:`\F64.\CONVERT\K{\_}\I32\K{\_s}`                       :math:`\hex{B7}`           :math:`[\I32] \to [\F64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_s>`  -:math:`\F64.\CONVERT\K{\_}\I32\K{\_u}`                       :math:`\hex{B8}`           :math:`[\I32] \to [\F64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_u>`  -:math:`\F64.\CONVERT\K{\_}\I64\K{\_s}`                       :math:`\hex{B9}`           :math:`[\I64] \to [\F64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_s>`  -:math:`\F64.\CONVERT\K{\_}\I64\K{\_u}`                       :math:`\hex{BA}`           :math:`[\I64] \to [\F64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_u>`  -:math:`\F64.\PROMOTE\K{\_}\F32`                              :math:`\hex{BB}`           :math:`[\F32] \to [\F64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-promote>`    -:math:`\I32.\REINTERPRET\K{\_}\F32`                          :math:`\hex{BC}`           :math:`[\F32] \to [\I32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-reinterpret>`-:math:`\I64.\REINTERPRET\K{\_}\F64`                          :math:`\hex{BD}`           :math:`[\F64] \to [\I64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-reinterpret>`-:math:`\F32.\REINTERPRET\K{\_}\I32`                          :math:`\hex{BE}`           :math:`[\I32] \to [\F32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-reinterpret>`-:math:`\F64.\REINTERPRET\K{\_}\I64`                          :math:`\hex{BF}`           :math:`[\I64] \to [\F64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-reinterpret>`-:math:`\I32.\EXTEND\K{8\_s}`                                 :math:`\hex{C0}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-iextendn_s>`  -:math:`\I32.\EXTEND\K{16\_s}`                                :math:`\hex{C1}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-iextendn_s>`  -:math:`\I64.\EXTEND\K{8\_s}`                                 :math:`\hex{C2}`           :math:`[\I64] \to [\I64]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-iextendn_s>`  -:math:`\I64.\EXTEND\K{16\_s}`                                :math:`\hex{C3}`           :math:`[\I64] \to [\I64]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-iextendn_s>`  -:math:`\I64.\EXTEND\K{32\_s}`                                :math:`\hex{C4}`           :math:`[\I64] \to [\I64]`                      :ref:`validation <valid-unop>`                 :ref:`execution <exec-unop>`, :ref:`operator <op-iextendn_s>`  -:math:`\I32.\TRUNC\K{\_sat\_}\F32\K{\_s}`                    :math:`\hex{FC}~~0`        :math:`[\F32] \to [\I32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_s>`-:math:`\I32.\TRUNC\K{\_sat\_}\F32\K{\_u}`                    :math:`\hex{FC}~~1`        :math:`[\F32] \to [\I32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_u>`-:math:`\I32.\TRUNC\K{\_sat\_}\F64\K{\_s}`                    :math:`\hex{FC}~~2`        :math:`[\F64] \to [\I32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_s>`-:math:`\I32.\TRUNC\K{\_sat\_}\F64\K{\_u}`                    :math:`\hex{FC}~~3`        :math:`[\F64] \to [\I32]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_u>`-:math:`\I64.\TRUNC\K{\_sat\_}\F32\K{\_s}`                    :math:`\hex{FC}~~4`        :math:`[\F32] \to [\I64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_s>`-:math:`\I64.\TRUNC\K{\_sat\_}\F32\K{\_u}`                    :math:`\hex{FC}~~5`        :math:`[\F32] \to [\I64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_u>`-:math:`\I64.\TRUNC\K{\_sat}\_\F64\K{\_s}`                    :math:`\hex{FC}~~6`        :math:`[\F64] \to [\I64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_s>`-:math:`\I64.\TRUNC\K{\_sat\_}\F64\K{\_u}`                    :math:`\hex{FC}~~7`        :math:`[\F64] \to [\I64]`                      :ref:`validation <valid-cvtop>`                :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_u>`-(reserved)                                                   :math:`\hex{FD}`                                                                                                                                                                        -:math:`\MEMORYATOMICNOTIFY~\memarg`                          :math:`\hex{FE}~\hex{00}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-notify>`                                                                       -:math:`\MEMORYATOMICWAIT\K{32}~\memarg`                      :math:`\hex{FE}~\hex{01}`  :math:`[\I32~\I32~\I64] \to [\I32]`            :ref:`validation <valid-atomic-wait>`                                                                         -:math:`\MEMORYATOMICWAIT\K{64}~\memarg`                      :math:`\hex{FE}~\hex{02}`  :math:`[\I32~\I64~\I64] \to [\I32]`            :ref:`validation <valid-atomic-wait>`                                                                         -:math:`\I32.\ATOMICLOAD~\memarg`                             :math:`\hex{FE}~\hex{10}`  :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-atomic-load>`          :ref:`execution <exec-atomic-load>`                            -:math:`\I64.\ATOMICLOAD~\memarg`                             :math:`\hex{FE}~\hex{11}`  :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-atomic-load>`          :ref:`execution <exec-atomic-load>`                            -:math:`\I32.\ATOMICLOAD\K{8\_u}~\memarg`                     :math:`\hex{FE}~\hex{12}`  :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-atomic-loadn>`         :ref:`execution <exec-atomic-loadn>`                           -:math:`\I32.\ATOMICLOAD\K{16\_u}~\memarg`                    :math:`\hex{FE}~\hex{13}`  :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-atomic-loadn>`         :ref:`execution <exec-atomic-loadn>`                           -:math:`\I64.\ATOMICLOAD\K{8\_u}~\memarg`                     :math:`\hex{FE}~\hex{14}`  :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-atomic-loadn>`         :ref:`execution <exec-atomic-loadn>`                           -:math:`\I64.\ATOMICLOAD\K{16\_u}~\memarg`                    :math:`\hex{FE}~\hex{15}`  :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-atomic-loadn>`         :ref:`execution <exec-atomic-loadn>`                           -:math:`\I64.\ATOMICLOAD\K{32\_u}~\memarg`                    :math:`\hex{FE}~\hex{16}`  :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-atomic-loadn>`         :ref:`execution <exec-atomic-loadn>`                           -:math:`\I32.\ATOMICSTORE~\memarg`                            :math:`\hex{FE}~\hex{17}`  :math:`[\I32~\I32] \to []`                     :ref:`validation <valid-atomic-store>`         :ref:`execution <exec-atomic-store>`                           -:math:`\I64.\ATOMICSTORE~\memarg`                            :math:`\hex{FE}~\hex{18}`  :math:`[\I32~\I64] \to []`                     :ref:`validation <valid-atomic-store>`         :ref:`execution <exec-atomic-store>`                           -:math:`\I32.\ATOMICSTORE\K{8\_u}~\memarg`                    :math:`\hex{FE}~\hex{19}`  :math:`[\I32~\I32] \to []`                     :ref:`validation <valid-atomic-storen>`        :ref:`execution <exec-atomic-storen>`                          -:math:`\I32.\ATOMICSTORE\K{16\_u}~\memarg`                   :math:`\hex{FE}~\hex{1A}`  :math:`[\I32~\I32] \to []`                     :ref:`validation <valid-atomic-storen>`        :ref:`execution <exec-atomic-storen>`                          -:math:`\I64.\ATOMICSTORE\K{8\_u}~\memarg`                    :math:`\hex{FE}~\hex{1B}`  :math:`[\I32~\I64] \to []`                     :ref:`validation <valid-atomic-storen>`        :ref:`execution <exec-atomic-storen>`                          -:math:`\I64.\ATOMICSTORE\K{16\_u}~\memarg`                   :math:`\hex{FE}~\hex{1C}`  :math:`[\I32~\I64] \to []`                     :ref:`validation <valid-atomic-storen>`        :ref:`execution <exec-atomic-storen>`                          -:math:`\I64.\ATOMICSTORE\K{32\_u}~\memarg`                   :math:`\hex{FE}~\hex{1D}`  :math:`[\I32~\I64] \to []`                     :ref:`validation <valid-atomic-storen>`        :ref:`execution <exec-atomic-storen>`                          -:math:`\I32.\ATOMICRMW.\ATOMICADD~\memarg`                   :math:`\hex{FE}~\hex{1E}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmw>`           :ref:`execution <exec-atomic-rmw>`, :ref:`operator <op-iadd>`  -:math:`\I64.\ATOMICRMW.\ATOMICADD~\memarg`                   :math:`\hex{FE}~\hex{1F}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmw>`           :ref:`execution <exec-atomic-rmw>`, :ref:`operator <op-iadd>`  -:math:`\I32.\ATOMICRMW\K{8}.\ATOMICADD\K{\_u}~\memarg`       :math:`\hex{FE}~\hex{20}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-iadd>` -:math:`\I32.\ATOMICRMW\K{16}.\ATOMICADD\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{21}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-iadd>` -:math:`\I64.\ATOMICRMW\K{8}.\ATOMICADD\K{\_u}~\memarg`       :math:`\hex{FE}~\hex{22}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-iadd>` -:math:`\I64.\ATOMICRMW\K{16}.\ATOMICADD\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{23}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-iadd>` -:math:`\I64.\ATOMICRMW\K{32}.\ATOMICADD\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{24}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-iadd>` -:math:`\I32.\ATOMICRMW.\ATOMICSUB~\memarg`                   :math:`\hex{FE}~\hex{25}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmw>`           :ref:`execution <exec-atomic-rmw>`, :ref:`operator <op-isub>`  -:math:`\I64.\ATOMICRMW.\ATOMICSUB~\memarg`                   :math:`\hex{FE}~\hex{26}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmw>`           :ref:`execution <exec-atomic-rmw>`, :ref:`operator <op-isub>`  -:math:`\I32.\ATOMICRMW\K{8}.\ATOMICSUB\K{\_u}~\memarg`       :math:`\hex{FE}~\hex{27}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-isub>` -:math:`\I32.\ATOMICRMW\K{16}.\ATOMICSUB\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{28}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-isub>` -:math:`\I64.\ATOMICRMW\K{8}.\ATOMICSUB\K{\_u}~\memarg`       :math:`\hex{FE}~\hex{29}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-isub>` -:math:`\I64.\ATOMICRMW\K{16}.\ATOMICSUB\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{2A}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-isub>` -:math:`\I64.\ATOMICRMW\K{32}.\ATOMICSUB\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{2B}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-isub>` -:math:`\I32.\ATOMICRMW.\ATOMICAND~\memarg`                   :math:`\hex{FE}~\hex{2C}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmw>`           :ref:`execution <exec-atomic-rmw>`, :ref:`operator <op-iand>`  -:math:`\I64.\ATOMICRMW.\ATOMICAND~\memarg`                   :math:`\hex{FE}~\hex{2D}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmw>`           :ref:`execution <exec-atomic-rmw>`, :ref:`operator <op-iand>`  -:math:`\I32.\ATOMICRMW\K{8}.\ATOMICAND\K{\_u}~\memarg`       :math:`\hex{FE}~\hex{2E}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-iand>` -:math:`\I32.\ATOMICRMW\K{16}.\ATOMICAND\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{2F}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-iand>` -:math:`\I64.\ATOMICRMW\K{8}.\ATOMICAND\K{\_u}~\memarg`       :math:`\hex{FE}~\hex{30}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-iand>` -:math:`\I64.\ATOMICRMW\K{16}.\ATOMICAND\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{31}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-iand>` -:math:`\I64.\ATOMICRMW\K{32}.\ATOMICAND\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{32}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-iand>` -:math:`\I32.\ATOMICRMW.\ATOMICOR~\memarg`                    :math:`\hex{FE}~\hex{33}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmw>`           :ref:`execution <exec-atomic-rmw>`, :ref:`operator <op-ior>`   -:math:`\I64.\ATOMICRMW.\ATOMICOR~\memarg`                    :math:`\hex{FE}~\hex{34}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmw>`           :ref:`execution <exec-atomic-rmw>`, :ref:`operator <op-ior>`   -:math:`\I32.\ATOMICRMW\K{8}.\ATOMICOR\K{\_u}~\memarg`        :math:`\hex{FE}~\hex{35}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ior>`  -:math:`\I32.\ATOMICRMW\K{16}.\ATOMICOR\K{\_u}~\memarg`       :math:`\hex{FE}~\hex{36}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ior>`  -:math:`\I64.\ATOMICRMW\K{8}.\ATOMICOR\K{\_u}~\memarg`        :math:`\hex{FE}~\hex{37}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ior>`  -:math:`\I64.\ATOMICRMW\K{16}.\ATOMICOR\K{\_u}~\memarg`       :math:`\hex{FE}~\hex{38}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ior>`  -:math:`\I64.\ATOMICRMW\K{32}.\ATOMICOR\K{\_u}~\memarg`       :math:`\hex{FE}~\hex{39}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ior>`  -:math:`\I32.\ATOMICRMW.\ATOMICXOR~\memarg`                   :math:`\hex{FE}~\hex{3A}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmw>`           :ref:`execution <exec-atomic-rmw>`, :ref:`operator <op-ixor>`  -:math:`\I64.\ATOMICRMW.\ATOMICXOR~\memarg`                   :math:`\hex{FE}~\hex{3B}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmw>`           :ref:`execution <exec-atomic-rmw>`, :ref:`operator <op-ixor>`  -:math:`\I32.\ATOMICRMW\K{8}.\ATOMICXOR\K{\_u}~\memarg`       :math:`\hex{FE}~\hex{3C}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ixor>` -:math:`\I32.\ATOMICRMW\K{16}.\ATOMICXOR\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{3D}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ixor>` -:math:`\I64.\ATOMICRMW\K{8}.\ATOMICXOR\K{\_u}~\memarg`       :math:`\hex{FE}~\hex{3E}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ixor>` -:math:`\I64.\ATOMICRMW\K{16}.\ATOMICXOR\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{3F}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ixor>` -:math:`\I64.\ATOMICRMW\K{32}.\ATOMICXOR\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{40}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ixor>` -:math:`\I32.\ATOMICRMW.\ATOMICXCHG~\memarg`                  :math:`\hex{FE}~\hex{41}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmw>`           :ref:`execution <exec-atomic-rmw>`, :ref:`operator <op-ixchg>` -:math:`\I64.\ATOMICRMW.\ATOMICXCHG~\memarg`                  :math:`\hex{FE}~\hex{42}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmw>`           :ref:`execution <exec-atomic-rmw>`, :ref:`operator <op-ixchg>` -:math:`\I32.\ATOMICRMW\K{8}.\ATOMICXCHG\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{43}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ixchg>`-:math:`\I32.\ATOMICRMW\K{16}.\ATOMICXCHG\K{\_u}~\memarg`     :math:`\hex{FE}~\hex{44}`  :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ixchg>`-:math:`\I64.\ATOMICRMW\K{8}.\ATOMICXCHG\K{\_u}~\memarg`      :math:`\hex{FE}~\hex{45}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ixchg>`-:math:`\I64.\ATOMICRMW\K{16}.\ATOMICXCHG\K{\_u}~\memarg`     :math:`\hex{FE}~\hex{46}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ixchg>`-:math:`\I64.\ATOMICRMW\K{32}.\ATOMICXCHG\K{\_u}~\memarg`     :math:`\hex{FE}~\hex{47}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-atomic-rmwn>`          :ref:`execution <exec-atomic-rmwn>`, :ref:`operator <op-ixchg>`-:math:`\I32.\ATOMICRMW.\ATOMICCMPXCHG~\memarg`               :math:`\hex{FE}~\hex{48}`  :math:`[\I32~\I32~\I32] \to [\I32]`            :ref:`validation <valid-atomic-rmw-cmpxchg>`   :ref:`execution <exec-atomic-rmw-cmpxchg>`                     -:math:`\I64.\ATOMICRMW.\ATOMICCMPXCHG~\memarg`               :math:`\hex{FE}~\hex{49}`  :math:`[\I32~\I64~\I64] \to [\I64]`            :ref:`validation <valid-atomic-rmw-cmpxchg>`   :ref:`execution <exec-atomic-rmw-cmpxchg>`                     -:math:`\I32.\ATOMICRMW\K{8}.\ATOMICCMPXCHG\K{\_u}~\memarg`   :math:`\hex{FE}~\hex{4A}`  :math:`[\I32~\I32~\I32] \to [\I32]`            :ref:`validation <valid-atomic-rmwn-cmpxchg>`  :ref:`execution <exec-atomic-rmwn-cmpxchg>`                    -:math:`\I32.\ATOMICRMW\K{16}.\ATOMICCMPXCHG\K{\_u}~\memarg`  :math:`\hex{FE}~\hex{4B}`  :math:`[\I32~\I32~\I32] \to [\I32]`            :ref:`validation <valid-atomic-rmwn-cmpxchg>`  :ref:`execution <exec-atomic-rmwn-cmpxchg>`                    -:math:`\I64.\ATOMICRMW\K{8}.\ATOMICCMPXCHG\K{\_u}~\memarg`   :math:`\hex{FE}~\hex{4C}`  :math:`[\I32~\I64~\I64] \to [\I64]`            :ref:`validation <valid-atomic-rmwn-cmpxchg>`  :ref:`execution <exec-atomic-rmwn-cmpxchg>`                    -:math:`\I64.\ATOMICRMW\K{16}.\ATOMICCMPXCHG\K{\_u}~\memarg`  :math:`\hex{FE}~\hex{4D}`  :math:`[\I32~\I64~\I64] \to [\I64]`            :ref:`validation <valid-atomic-rmwn-cmpxchg>`  :ref:`execution <exec-atomic-rmwn-cmpxchg>`                    -:math:`\I64.\ATOMICRMW\K{32}.\ATOMICCMPXCHG\K{\_u}~\memarg`  :math:`\hex{FE}~\hex{4E}`  :math:`[\I32~\I64~\I64] \to [\I64]`            :ref:`validation <valid-atomic-rmwn-cmpxchg>`  :ref:`execution <exec-atomic-rmwn-cmpxchg>`                    -===========================================================  =========================  =============================================  =============================================  ===============================================================+=======================================================  =========================  =============================================  ==============================================  ===============================================================+Instruction                                              Binary Opcode              Type                                           Validation                                      Execution                                                      +=======================================================  =========================  =============================================  ==============================================  ===============================================================+:math:`\UNREACHABLE`                                     :math:`\hex{00}`           :math:`[t_1^\ast] \to [t_2^\ast]`              :ref:`validation <valid-unreachable>`           :ref:`execution <exec-unreachable>`                            +:math:`\NOP`                                             :math:`\hex{01}`           :math:`[] \to []`                              :ref:`validation <valid-nop>`                   :ref:`execution <exec-nop>`                                    +:math:`\BLOCK~\X{bt}`                                    :math:`\hex{02}`           :math:`[t_1^\ast] \to [t_2^\ast]`              :ref:`validation <valid-block>`                 :ref:`execution <exec-block>`                                  +:math:`\LOOP~\X{bt}`                                     :math:`\hex{03}`           :math:`[t_1^\ast] \to [t_2^\ast]`              :ref:`validation <valid-loop>`                  :ref:`execution <exec-loop>`                                   +:math:`\IF~\X{bt}`                                       :math:`\hex{04}`           :math:`[t_1^\ast] \to [t_2^\ast]`              :ref:`validation <valid-if>`                    :ref:`execution <exec-if>`                                     +:math:`\ELSE`                                            :math:`\hex{05}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{06}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{07}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{08}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{09}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{0A}`                                                                                                                                                                         +:math:`\END`                                             :math:`\hex{0B}`                                                                                                                                                                         +:math:`\BR~l`                                            :math:`\hex{0C}`           :math:`[t_1^\ast~t^\ast] \to [t_2^\ast]`       :ref:`validation <valid-br>`                    :ref:`execution <exec-br>`                                     +:math:`\BRIF~l`                                          :math:`\hex{0D}`           :math:`[t^\ast~\I32] \to [t^\ast]`             :ref:`validation <valid-br_if>`                 :ref:`execution <exec-br_if>`                                  +:math:`\BRTABLE~l^\ast~l`                                :math:`\hex{0E}`           :math:`[t_1^\ast~t^\ast~\I32] \to [t_2^\ast]`  :ref:`validation <valid-br_table>`              :ref:`execution <exec-br_table>`                               +:math:`\RETURN`                                          :math:`\hex{0F}`           :math:`[t_1^\ast~t^\ast] \to [t_2^\ast]`       :ref:`validation <valid-return>`                :ref:`execution <exec-return>`                                 +:math:`\CALL~x`                                          :math:`\hex{10}`           :math:`[t_1^\ast] \to [t_2^\ast]`              :ref:`validation <valid-call>`                  :ref:`execution <exec-call>`                                   +:math:`\CALLINDIRECT~x`                                  :math:`\hex{11}`           :math:`[t_1^\ast~\I32] \to [t_2^\ast]`         :ref:`validation <valid-call_indirect>`         :ref:`execution <exec-call_indirect>`                          +(reserved)                                               :math:`\hex{12}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{13}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{14}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{15}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{16}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{17}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{18}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{19}`                                                                                                                                                                         +:math:`\DROP`                                            :math:`\hex{1A}`           :math:`[t] \to []`                             :ref:`validation <valid-drop>`                  :ref:`execution <exec-drop>`                                   +:math:`\SELECT`                                          :math:`\hex{1B}`           :math:`[t~t~\I32] \to [t]`                     :ref:`validation <valid-select>`                :ref:`execution <exec-select>`                                 +(reserved)                                               :math:`\hex{1C}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{1D}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{1E}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{1F}`                                                                                                                                                                         +:math:`\LOCALGET~x`                                      :math:`\hex{20}`           :math:`[] \to [t]`                             :ref:`validation <valid-local.get>`             :ref:`execution <exec-local.get>`                              +:math:`\LOCALSET~x`                                      :math:`\hex{21}`           :math:`[t] \to []`                             :ref:`validation <valid-local.set>`             :ref:`execution <exec-local.set>`                              +:math:`\LOCALTEE~x`                                      :math:`\hex{22}`           :math:`[t] \to [t]`                            :ref:`validation <valid-local.tee>`             :ref:`execution <exec-local.tee>`                              +:math:`\GLOBALGET~x`                                     :math:`\hex{23}`           :math:`[] \to [t]`                             :ref:`validation <valid-global.get>`            :ref:`execution <exec-global.get>`                             +:math:`\GLOBALSET~x`                                     :math:`\hex{24}`           :math:`[t] \to []`                             :ref:`validation <valid-global.set>`            :ref:`execution <exec-global.set>`                             +(reserved)                                               :math:`\hex{25}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{26}`                                                                                                                                                                         +(reserved)                                               :math:`\hex{27}`                                                                                                                                                                         +:math:`\I32.\LOAD~\memarg`                               :math:`\hex{28}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-load>`                  :ref:`execution <exec-load>`                                   +:math:`\I64.\LOAD~\memarg`                               :math:`\hex{29}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-load>`                  :ref:`execution <exec-load>`                                   +:math:`\F32.\LOAD~\memarg`                               :math:`\hex{2A}`           :math:`[\I32] \to [\F32]`                      :ref:`validation <valid-load>`                  :ref:`execution <exec-load>`                                   +:math:`\F64.\LOAD~\memarg`                               :math:`\hex{2B}`           :math:`[\I32] \to [\F64]`                      :ref:`validation <valid-load>`                  :ref:`execution <exec-load>`                                   +:math:`\I32.\LOAD\K{8\_s}~\memarg`                       :math:`\hex{2C}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-loadn>`                 :ref:`execution <exec-loadn>`                                  +:math:`\I32.\LOAD\K{8\_u}~\memarg`                       :math:`\hex{2D}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-loadn>`                 :ref:`execution <exec-loadn>`                                  +:math:`\I32.\LOAD\K{16\_s}~\memarg`                      :math:`\hex{2E}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-loadn>`                 :ref:`execution <exec-loadn>`                                  +:math:`\I32.\LOAD\K{16\_u}~\memarg`                      :math:`\hex{2F}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-loadn>`                 :ref:`execution <exec-loadn>`                                  +:math:`\I64.\LOAD\K{8\_s}~\memarg`                       :math:`\hex{30}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-loadn>`                 :ref:`execution <exec-loadn>`                                  +:math:`\I64.\LOAD\K{8\_u}~\memarg`                       :math:`\hex{31}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-loadn>`                 :ref:`execution <exec-loadn>`                                  +:math:`\I64.\LOAD\K{16\_s}~\memarg`                      :math:`\hex{32}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-loadn>`                 :ref:`execution <exec-loadn>`                                  +:math:`\I64.\LOAD\K{16\_u}~\memarg`                      :math:`\hex{33}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-loadn>`                 :ref:`execution <exec-loadn>`                                  +:math:`\I64.\LOAD\K{32\_s}~\memarg`                      :math:`\hex{34}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-loadn>`                 :ref:`execution <exec-loadn>`                                  +:math:`\I64.\LOAD\K{32\_u}~\memarg`                      :math:`\hex{35}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-loadn>`                 :ref:`execution <exec-loadn>`                                  +:math:`\I32.\STORE~\memarg`                              :math:`\hex{36}`           :math:`[\I32~\I32] \to []`                     :ref:`validation <valid-store>`                 :ref:`execution <exec-store>`                                  +:math:`\I64.\STORE~\memarg`                              :math:`\hex{37}`           :math:`[\I32~\I64] \to []`                     :ref:`validation <valid-store>`                 :ref:`execution <exec-store>`                                  +:math:`\F32.\STORE~\memarg`                              :math:`\hex{38}`           :math:`[\I32~\F32] \to []`                     :ref:`validation <valid-store>`                 :ref:`execution <exec-store>`                                  +:math:`\F64.\STORE~\memarg`                              :math:`\hex{39}`           :math:`[\I32~\F64] \to []`                     :ref:`validation <valid-store>`                 :ref:`execution <exec-store>`                                  +:math:`\I32.\STORE\K{8}~\memarg`                         :math:`\hex{3A}`           :math:`[\I32~\I32] \to []`                     :ref:`validation <valid-storen>`                :ref:`execution <exec-storen>`                                 +:math:`\I32.\STORE\K{16}~\memarg`                        :math:`\hex{3B}`           :math:`[\I32~\I32] \to []`                     :ref:`validation <valid-storen>`                :ref:`execution <exec-storen>`                                 +:math:`\I64.\STORE\K{8}~\memarg`                         :math:`\hex{3C}`           :math:`[\I32~\I64] \to []`                     :ref:`validation <valid-storen>`                :ref:`execution <exec-storen>`                                 +:math:`\I64.\STORE\K{16}~\memarg`                        :math:`\hex{3D}`           :math:`[\I32~\I64] \to []`                     :ref:`validation <valid-storen>`                :ref:`execution <exec-storen>`                                 +:math:`\I64.\STORE\K{32}~\memarg`                        :math:`\hex{3E}`           :math:`[\I32~\I64] \to []`                     :ref:`validation <valid-storen>`                :ref:`execution <exec-storen>`                                 +:math:`\MEMORYSIZE`                                      :math:`\hex{3F}`           :math:`[] \to [\I32]`                          :ref:`validation <valid-memory.size>`           :ref:`execution <exec-memory.size>`                            +:math:`\MEMORYGROW`                                      :math:`\hex{40}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-memory.grow>`           :ref:`execution <exec-memory.grow>`                            +:math:`\I32.\CONST~\i32`                                 :math:`\hex{41}`           :math:`[] \to [\I32]`                          :ref:`validation <valid-const>`                 :ref:`execution <exec-const>`                                  +:math:`\I64.\CONST~\i64`                                 :math:`\hex{42}`           :math:`[] \to [\I64]`                          :ref:`validation <valid-const>`                 :ref:`execution <exec-const>`                                  +:math:`\F32.\CONST~\f32`                                 :math:`\hex{43}`           :math:`[] \to [\F32]`                          :ref:`validation <valid-const>`                 :ref:`execution <exec-const>`                                  +:math:`\F64.\CONST~\f64`                                 :math:`\hex{44}`           :math:`[] \to [\F64]`                          :ref:`validation <valid-const>`                 :ref:`execution <exec-const>`                                  +:math:`\I32.\EQZ`                                        :math:`\hex{45}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-testop>`                :ref:`execution <exec-testop>`, :ref:`operator <op-ieqz>`      +:math:`\I32.\EQ`                                         :math:`\hex{46}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ieq>`        +:math:`\I32.\NE`                                         :math:`\hex{47}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ine>`        +:math:`\I32.\LT\K{\_s}`                                  :math:`\hex{48}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ilt_s>`      +:math:`\I32.\LT\K{\_u}`                                  :math:`\hex{49}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ilt_u>`      +:math:`\I32.\GT\K{\_s}`                                  :math:`\hex{4A}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-igt_s>`      +:math:`\I32.\GT\K{\_u}`                                  :math:`\hex{4B}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-igt_u>`      +:math:`\I32.\LE\K{\_s}`                                  :math:`\hex{4C}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ile_s>`      +:math:`\I32.\LE\K{\_u}`                                  :math:`\hex{4D}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ile_u>`      +:math:`\I32.\GE\K{\_s}`                                  :math:`\hex{4E}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ige_s>`      +:math:`\I32.\GE\K{\_u}`                                  :math:`\hex{4F}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ige_u>`      +:math:`\I64.\EQZ`                                        :math:`\hex{50}`           :math:`[\I64] \to [\I32]`                      :ref:`validation <valid-testop>`                :ref:`execution <exec-testop>`, :ref:`operator <op-ieqz>`      +:math:`\I64.\EQ`                                         :math:`\hex{51}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ieq>`        +:math:`\I64.\NE`                                         :math:`\hex{52}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ine>`        +:math:`\I64.\LT\K{\_s}`                                  :math:`\hex{53}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ilt_s>`      +:math:`\I64.\LT\K{\_u}`                                  :math:`\hex{54}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ilt_u>`      +:math:`\I64.\GT\K{\_s}`                                  :math:`\hex{55}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-igt_s>`      +:math:`\I64.\GT\K{\_u}`                                  :math:`\hex{56}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-igt_u>`      +:math:`\I64.\LE\K{\_s}`                                  :math:`\hex{57}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ile_s>`      +:math:`\I64.\LE\K{\_u}`                                  :math:`\hex{58}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ile_u>`      +:math:`\I64.\GE\K{\_s}`                                  :math:`\hex{59}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ige_s>`      +:math:`\I64.\GE\K{\_u}`                                  :math:`\hex{5A}`           :math:`[\I64~\I64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-ige_u>`      +:math:`\F32.\EQ`                                         :math:`\hex{5B}`           :math:`[\F32~\F32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-feq>`        +:math:`\F32.\NE`                                         :math:`\hex{5C}`           :math:`[\F32~\F32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-fne>`        +:math:`\F32.\LT`                                         :math:`\hex{5D}`           :math:`[\F32~\F32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-flt>`        +:math:`\F32.\GT`                                         :math:`\hex{5E}`           :math:`[\F32~\F32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-fgt>`        +:math:`\F32.\LE`                                         :math:`\hex{5F}`           :math:`[\F32~\F32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-fle>`        +:math:`\F32.\GE`                                         :math:`\hex{60}`           :math:`[\F32~\F32] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-fge>`        +:math:`\F64.\EQ`                                         :math:`\hex{61}`           :math:`[\F64~\F64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-feq>`        +:math:`\F64.\NE`                                         :math:`\hex{62}`           :math:`[\F64~\F64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-fne>`        +:math:`\F64.\LT`                                         :math:`\hex{63}`           :math:`[\F64~\F64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-flt>`        +:math:`\F64.\GT`                                         :math:`\hex{64}`           :math:`[\F64~\F64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-fgt>`        +:math:`\F64.\LE`                                         :math:`\hex{65}`           :math:`[\F64~\F64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-fle>`        +:math:`\F64.\GE`                                         :math:`\hex{66}`           :math:`[\F64~\F64] \to [\I32]`                 :ref:`validation <valid-relop>`                 :ref:`execution <exec-relop>`, :ref:`operator <op-fge>`        +:math:`\I32.\CLZ`                                        :math:`\hex{67}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-iclz>`        +:math:`\I32.\CTZ`                                        :math:`\hex{68}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-ictz>`        +:math:`\I32.\POPCNT`                                     :math:`\hex{69}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-ipopcnt>`     +:math:`\I32.\ADD`                                        :math:`\hex{6A}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-iadd>`       +:math:`\I32.\SUB`                                        :math:`\hex{6B}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-isub>`       +:math:`\I32.\MUL`                                        :math:`\hex{6C}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-imul>`       +:math:`\I32.\DIV\K{\_s}`                                 :math:`\hex{6D}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-idiv_s>`     +:math:`\I32.\DIV\K{\_u}`                                 :math:`\hex{6E}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-idiv_u>`     +:math:`\I32.\REM\K{\_s}`                                 :math:`\hex{6F}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-irem_s>`     +:math:`\I32.\REM\K{\_u}`                                 :math:`\hex{70}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-irem_u>`     +:math:`\I32.\AND`                                        :math:`\hex{71}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-iand>`       +:math:`\I32.\OR`                                         :math:`\hex{72}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-ior>`        +:math:`\I32.\XOR`                                        :math:`\hex{73}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-ixor>`       +:math:`\I32.\SHL`                                        :math:`\hex{74}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-ishl>`       +:math:`\I32.\SHR\K{\_s}`                                 :math:`\hex{75}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-ishr_s>`     +:math:`\I32.\SHR\K{\_u}`                                 :math:`\hex{76}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-ishr_u>`     +:math:`\I32.\ROTL`                                       :math:`\hex{77}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-irotl>`      +:math:`\I32.\ROTR`                                       :math:`\hex{78}`           :math:`[\I32~\I32] \to [\I32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-irotr>`      +:math:`\I64.\CLZ`                                        :math:`\hex{79}`           :math:`[\I64] \to [\I64]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-iclz>`        +:math:`\I64.\CTZ`                                        :math:`\hex{7A}`           :math:`[\I64] \to [\I64]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-ictz>`        +:math:`\I64.\POPCNT`                                     :math:`\hex{7B}`           :math:`[\I64] \to [\I64]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-ipopcnt>`     +:math:`\I64.\ADD`                                        :math:`\hex{7C}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-iadd>`       +:math:`\I64.\SUB`                                        :math:`\hex{7D}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-isub>`       +:math:`\I64.\MUL`                                        :math:`\hex{7E}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-imul>`       +:math:`\I64.\DIV\K{\_s}`                                 :math:`\hex{7F}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-idiv_s>`     +:math:`\I64.\DIV\K{\_u}`                                 :math:`\hex{80}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-idiv_u>`     +:math:`\I64.\REM\K{\_s}`                                 :math:`\hex{81}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-irem_s>`     +:math:`\I64.\REM\K{\_u}`                                 :math:`\hex{82}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-irem_u>`     +:math:`\I64.\AND`                                        :math:`\hex{83}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-iand>`       +:math:`\I64.\OR`                                         :math:`\hex{84}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-ior>`        +:math:`\I64.\XOR`                                        :math:`\hex{85}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-ixor>`       +:math:`\I64.\SHL`                                        :math:`\hex{86}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-ishl>`       +:math:`\I64.\SHR\K{\_s}`                                 :math:`\hex{87}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-ishr_s>`     +:math:`\I64.\SHR\K{\_u}`                                 :math:`\hex{88}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-ishr_u>`     +:math:`\I64.\ROTL`                                       :math:`\hex{89}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-irotl>`      +:math:`\I64.\ROTR`                                       :math:`\hex{8A}`           :math:`[\I64~\I64] \to [\I64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-irotr>`      +:math:`\F32.\ABS`                                        :math:`\hex{8B}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-fabs>`        +:math:`\F32.\NEG`                                        :math:`\hex{8C}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-fneg>`        +:math:`\F32.\CEIL`                                       :math:`\hex{8D}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-fceil>`       +:math:`\F32.\FLOOR`                                      :math:`\hex{8E}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-ffloor>`      +:math:`\F32.\TRUNC`                                      :math:`\hex{8F}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-ftrunc>`      +:math:`\F32.\NEAREST`                                    :math:`\hex{90}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-fnearest>`    +:math:`\F32.\SQRT`                                       :math:`\hex{91}`           :math:`[\F32] \to [\F32]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-fsqrt>`       +:math:`\F32.\ADD`                                        :math:`\hex{92}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fadd>`       +:math:`\F32.\SUB`                                        :math:`\hex{93}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fsub>`       +:math:`\F32.\MUL`                                        :math:`\hex{94}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fmul>`       +:math:`\F32.\DIV`                                        :math:`\hex{95}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fdiv>`       +:math:`\F32.\FMIN`                                       :math:`\hex{96}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fmin>`       +:math:`\F32.\FMAX`                                       :math:`\hex{97}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fmax>`       +:math:`\F32.\COPYSIGN`                                   :math:`\hex{98}`           :math:`[\F32~\F32] \to [\F32]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fcopysign>`  +:math:`\F64.\ABS`                                        :math:`\hex{99}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-fabs>`        +:math:`\F64.\NEG`                                        :math:`\hex{9A}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-fneg>`        +:math:`\F64.\CEIL`                                       :math:`\hex{9B}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-fceil>`       +:math:`\F64.\FLOOR`                                      :math:`\hex{9C}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-ffloor>`      +:math:`\F64.\TRUNC`                                      :math:`\hex{9D}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-ftrunc>`      +:math:`\F64.\NEAREST`                                    :math:`\hex{9E}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-fnearest>`    +:math:`\F64.\SQRT`                                       :math:`\hex{9F}`           :math:`[\F64] \to [\F64]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-fsqrt>`       +:math:`\F64.\ADD`                                        :math:`\hex{A0}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fadd>`       +:math:`\F64.\SUB`                                        :math:`\hex{A1}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fsub>`       +:math:`\F64.\MUL`                                        :math:`\hex{A2}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fmul>`       +:math:`\F64.\DIV`                                        :math:`\hex{A3}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fdiv>`       +:math:`\F64.\FMIN`                                       :math:`\hex{A4}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fmin>`       +:math:`\F64.\FMAX`                                       :math:`\hex{A5}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fmax>`       +:math:`\F64.\COPYSIGN`                                   :math:`\hex{A6}`           :math:`[\F64~\F64] \to [\F64]`                 :ref:`validation <valid-binop>`                 :ref:`execution <exec-binop>`, :ref:`operator <op-fcopysign>`  +:math:`\I32.\WRAP\K{\_}\I64`                             :math:`\hex{A7}`           :math:`[\I64] \to [\I32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-wrap>`       +:math:`\I32.\TRUNC\K{\_}\F32\K{\_s}`                     :math:`\hex{A8}`           :math:`[\F32] \to [\I32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_s>`    +:math:`\I32.\TRUNC\K{\_}\F32\K{\_u}`                     :math:`\hex{A9}`           :math:`[\F32] \to [\I32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_u>`    +:math:`\I32.\TRUNC\K{\_}\F64\K{\_s}`                     :math:`\hex{AA}`           :math:`[\F64] \to [\I32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_s>`    +:math:`\I32.\TRUNC\K{\_}\F64\K{\_u}`                     :math:`\hex{AB}`           :math:`[\F64] \to [\I32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_u>`    +:math:`\I64.\EXTEND\K{\_}\I32\K{\_s}`                    :math:`\hex{AC}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-extend_s>`   +:math:`\I64.\EXTEND\K{\_}\I32\K{\_u}`                    :math:`\hex{AD}`           :math:`[\I32] \to [\I64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-extend_u>`   +:math:`\I64.\TRUNC\K{\_}\F32\K{\_s}`                     :math:`\hex{AE}`           :math:`[\F32] \to [\I64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_s>`    +:math:`\I64.\TRUNC\K{\_}\F32\K{\_u}`                     :math:`\hex{AF}`           :math:`[\F32] \to [\I64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_u>`    +:math:`\I64.\TRUNC\K{\_}\F64\K{\_s}`                     :math:`\hex{B0}`           :math:`[\F64] \to [\I64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_s>`    +:math:`\I64.\TRUNC\K{\_}\F64\K{\_u}`                     :math:`\hex{B1}`           :math:`[\F64] \to [\I64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_u>`    +:math:`\F32.\CONVERT\K{\_}\I32\K{\_s}`                   :math:`\hex{B2}`           :math:`[\I32] \to [\F32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_s>`  +:math:`\F32.\CONVERT\K{\_}\I32\K{\_u}`                   :math:`\hex{B3}`           :math:`[\I32] \to [\F32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_u>`  +:math:`\F32.\CONVERT\K{\_}\I64\K{\_s}`                   :math:`\hex{B4}`           :math:`[\I64] \to [\F32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_s>`  +:math:`\F32.\CONVERT\K{\_}\I64\K{\_u}`                   :math:`\hex{B5}`           :math:`[\I64] \to [\F32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_u>`  +:math:`\F32.\DEMOTE\K{\_}\F64`                           :math:`\hex{B6}`           :math:`[\F64] \to [\F32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-demote>`     +:math:`\F64.\CONVERT\K{\_}\I32\K{\_s}`                   :math:`\hex{B7}`           :math:`[\I32] \to [\F64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_s>`  +:math:`\F64.\CONVERT\K{\_}\I32\K{\_u}`                   :math:`\hex{B8}`           :math:`[\I32] \to [\F64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_u>`  +:math:`\F64.\CONVERT\K{\_}\I64\K{\_s}`                   :math:`\hex{B9}`           :math:`[\I64] \to [\F64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_s>`  +:math:`\F64.\CONVERT\K{\_}\I64\K{\_u}`                   :math:`\hex{BA}`           :math:`[\I64] \to [\F64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-convert_u>`  +:math:`\F64.\PROMOTE\K{\_}\F32`                          :math:`\hex{BB}`           :math:`[\F32] \to [\F64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-promote>`    +:math:`\I32.\REINTERPRET\K{\_}\F32`                      :math:`\hex{BC}`           :math:`[\F32] \to [\I32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-reinterpret>`+:math:`\I64.\REINTERPRET\K{\_}\F64`                      :math:`\hex{BD}`           :math:`[\F64] \to [\I64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-reinterpret>`+:math:`\F32.\REINTERPRET\K{\_}\I32`                      :math:`\hex{BE}`           :math:`[\I32] \to [\F32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-reinterpret>`+:math:`\F64.\REINTERPRET\K{\_}\I64`                      :math:`\hex{BF}`           :math:`[\I64] \to [\F64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-reinterpret>`+:math:`\I32.\EXTEND\K{8\_s}`                             :math:`\hex{C0}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-iextendn_s>`  +:math:`\I32.\EXTEND\K{16\_s}`                            :math:`\hex{C1}`           :math:`[\I32] \to [\I32]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-iextendn_s>`  +:math:`\I64.\EXTEND\K{8\_s}`                             :math:`\hex{C2}`           :math:`[\I64] \to [\I64]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-iextendn_s>`  +:math:`\I64.\EXTEND\K{16\_s}`                            :math:`\hex{C3}`           :math:`[\I64] \to [\I64]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-iextendn_s>`  +:math:`\I64.\EXTEND\K{32\_s}`                            :math:`\hex{C4}`           :math:`[\I64] \to [\I64]`                      :ref:`validation <valid-unop>`                  :ref:`execution <exec-unop>`, :ref:`operator <op-iextendn_s>`  +:math:`\I32.\TRUNC\K{\_sat\_}\F32\K{\_s}`                :math:`\hex{FC}~~0`        :math:`[\F32] \to [\I32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_s>`+:math:`\I32.\TRUNC\K{\_sat\_}\F32\K{\_u}`                :math:`\hex{FC}~~1`        :math:`[\F32] \to [\I32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_u>`+:math:`\I32.\TRUNC\K{\_sat\_}\F64\K{\_s}`                :math:`\hex{FC}~~2`        :math:`[\F64] \to [\I32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_s>`+:math:`\I32.\TRUNC\K{\_sat\_}\F64\K{\_u}`                :math:`\hex{FC}~~3`        :math:`[\F64] \to [\I32]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_u>`+:math:`\I64.\TRUNC\K{\_sat\_}\F32\K{\_s}`                :math:`\hex{FC}~~4`        :math:`[\F32] \to [\I64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_s>`+:math:`\I64.\TRUNC\K{\_sat\_}\F32\K{\_u}`                :math:`\hex{FC}~~5`        :math:`[\F32] \to [\I64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_u>`+:math:`\I64.\TRUNC\K{\_sat}\_\F64\K{\_s}`                :math:`\hex{FC}~~6`        :math:`[\F64] \to [\I64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_s>`+:math:`\I64.\TRUNC\K{\_sat\_}\F64\K{\_u}`                :math:`\hex{FC}~~7`        :math:`[\F64] \to [\I64]`                      :ref:`validation <valid-cvtop>`                 :ref:`execution <exec-cvtop>`, :ref:`operator <op-trunc_sat_u>`+(reserved)                                               :math:`\hex{FD}`                                                                                                                                                                         +:math:`\MEMORYATOMICNOTIFY~\memarg`                      :math:`\hex{FE}~\hex{00}`  :math:`[\I32~\I64] \to [\I64]`                 :ref:`validation <valid-memory.atomic.notify>`                                                                 

Fixed.

rossberg

comment created time in 21 hours

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions  .. _exec-store: .. _exec-storen:-.. _exec-atomic-store:-.. _exec-atomic-storen: -:math:`t\K{.}\ATOMIC^?.\STORE~\memarg` and :math:`t\K{.}\ATOMIC^?.\STORE{N}~\memarg`-....................................................................................+:math:`t\K{.}\STORE{N}^?~\memarg`+................................. -.. todo:: update text to match formalism+1. Let :math:`\ord` be :math:`\UNORD`. -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+2. If :math:`N` is part of the instruction, then: -2. Assert: due to :ref:`validation <valid-storen>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`.

Fixed.

rossberg

comment created time in 21 hours

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions  .. _exec-load: .. _exec-loadn:-.. _exec-atomic-load:-.. _exec-atomic-loadn: -:math:`t\K{.}\ATOMIC^?.\LOAD~\memarg` and :math:`t\K{.}\ATOMIC^?.\LOAD{N}\K{\_}\sx~\memarg`-...........................................................................................+:math:`t\K{.}\LOAD({N}\K{\_}\sx)^?~\memarg`+........................................... -.. todo:: update text to match formalism+1. Let :math:`\ord` be :math:`\UNORD`. -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+2. If :math:`N` and :math:`\sx` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-loadn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`.

Updated.

rossberg

comment created time in 21 hours

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions  .. _exec-load: .. _exec-loadn:-.. _exec-atomic-load:-.. _exec-atomic-loadn: -:math:`t\K{.}\ATOMIC^?.\LOAD~\memarg` and :math:`t\K{.}\ATOMIC^?.\LOAD{N}\K{\_}\sx~\memarg`-...........................................................................................+:math:`t\K{.}\LOAD({N}\K{\_}\sx)^?~\memarg`+........................................... -.. todo:: update text to match formalism+1. Let :math:`\ord` be :math:`\UNORD`. -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+2. If :math:`N` and :math:`\sx` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-loadn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+3. Else: -4. Assert: due to :ref:`validation <valid-loadn>`, :math:`S.\SMEMS[a]` exists.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+   b. Let :math:`\X{st}` be the :ref:`value type <syntax-valtype>` :math:`t`. -6. Assert: due to :ref:`validation <valid-loadn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+4. Assert: due to :ref:`validation <valid-loadn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -7. Pop the value :math:`\I32.\CONST~i` from the stack.+5. Pop the value :math:`\I32.\CONST~i` from the stack. -8. Let :math:`\X{ea}` be the integer :math:`i + \memarg.\OFFSET`.+6. Let :math:`\X{ea}` be the integer :math:`i + \memarg.\OFFSET`. -9. If :math:`N` is not part of the instruction, then:+7. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+8. Assert: due to :ref:`validation <valid-loadn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -10. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+9. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -    a. Trap.+10. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -11. Let :math:`b^\ast` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+   a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -12. If :math:`N` and :math:`\sx` are part of the instruction, then:+   b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -    a. Let :math:`n` be the integer for which :math:`\bytes_{\iN}(n) = b^\ast`.+      i. Trap. -    b. Let :math:`c` be the result of computing :math:`\extend\F{\_}\sx_{N,|t|}(n)`.+   c. Let :math:`b^\ast` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -13. Else:+11. Else:++    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`.

Made explicit in the prose. In the formal semantics that's implicit by the side conditions, particularly, its use as an argument to bytes^-1.

rossberg

comment created time in 21 hours

push eventWebAssembly/threads

Andreas Rossberg

commit sha ee78d2900065261102f0fc46069e551fc91916b4

More comments

view details

push time in 21 hours

issue commentn4ru/1vyrain

Lenovo Thinkpad L530 is compatible but require moded bios

@n4ru i still wait for a solution for my L530 with I7 3637qm, can you look that when you have time ^^ ?

snakeeater4526

comment created time in a day

issue commentnh2/static-haskell-nix

How do I actually use this?

The last green CI was october 6th, there seems to be a long backlog of pipelines that could probably be skipped.

Ah thanks, indeed an update seems to have sent the buildkite daemon into a crashloop due to permissions (probably because dir names changed due to https://github.com/NixOS/nixpkgs/pull/78373 and so the permissions were wrong).

I've fixed it now and cancelled the in-between unstable builds.

athas

comment created time in a day

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions  .. _exec-load: .. _exec-loadn:-.. _exec-atomic-load:-.. _exec-atomic-loadn: -:math:`t\K{.}\ATOMIC^?.\LOAD~\memarg` and :math:`t\K{.}\ATOMIC^?.\LOAD{N}\K{\_}\sx~\memarg`-...........................................................................................+:math:`t\K{.}\LOAD({N}\K{\_}\sx)^?~\memarg`+........................................... -.. todo:: update text to match formalism+1. Let :math:`\ord` be :math:`\UNORD`. -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+2. If :math:`N` and :math:`\sx` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-loadn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+3. Else: -4. Assert: due to :ref:`validation <valid-loadn>`, :math:`S.\SMEMS[a]` exists.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+   b. Let :math:`\X{st}` be the :ref:`value type <syntax-valtype>` :math:`t`. -6. Assert: due to :ref:`validation <valid-loadn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+4. Assert: due to :ref:`validation <valid-loadn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -7. Pop the value :math:`\I32.\CONST~i` from the stack.+5. Pop the value :math:`\I32.\CONST~i` from the stack. -8. Let :math:`\X{ea}` be the integer :math:`i + \memarg.\OFFSET`.+6. Let :math:`\X{ea}` be the integer :math:`i + \memarg.\OFFSET`. -9. If :math:`N` is not part of the instruction, then:+7. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+8. Assert: due to :ref:`validation <valid-loadn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -10. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+9. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -    a. Trap.+10. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -11. Let :math:`b^\ast` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+   a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -12. If :math:`N` and :math:`\sx` are part of the instruction, then:+   b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -    a. Let :math:`n` be the integer for which :math:`\bytes_{\iN}(n) = b^\ast`.+      i. Trap. -    b. Let :math:`c` be the result of computing :math:`\extend\F{\_}\sx_{N,|t|}(n)`.+   c. Let :math:`b^\ast` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -13. Else:+11. Else:++    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`.

sorry, this comment should have been at line 439 just below

rossberg

comment created time in 2 days

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & \meminst = S.\SMEMS[a]) \\      \end{array}-   \\[1ex]+   \\    %+   ~\\+   \\    \begin{array}{lcl@{\qquad}l}-   S; F; (\I32.\CONST~i)~\MEMORYGROW-     &\stepto^{(\ARMW~a.\LLEN~n~(n+k))~(\AWR~a.\LDATA[n]~(0)^k)}&+   S; F; (\I32.\CONST~n)~\MEMORYGROW+     &\stepto^{(\ARMW~a.\LLEN~l~(l+k))~(\AWR~a.\LDATA[l]~(0)^k)}&      S; F; (\I32.\CONST~\X{sz})    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined} \\-     \wedge & n = \X{sz} \cdot 64\,\F{Ki} \\-     \wedge & k = i \cdot 64\,\F{Ki}) \\+     \wedge & \X{sz} = l / 64\,\F{Ki} \\+     \wedge & n = k / 64\,\F{Ki}) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}    S; F; (\I32.\CONST~n)~\MEMORYGROW-     &\stepto^{(\ARD~a.\LLEN~n)}&+     &\stepto^{(\ARD_{\SEQCST}~a.\LLEN~n)}&      S; F; (\I32.\CONST~{-1})    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined}) \\      \end{array}    \end{array}-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}    (\where & a = F.\AMODULE.\MIMEMS[0]) \\    \end{array}    \end{array}  .. note::-   The |MEMORYGROW| instruction is non-deterministic.+   The |MEMORYGROW| instruction is non-deterministic, even on unshared memories.    It may either succeed, returning the old memory size :math:`\X{sz}`,    or fail, returning :math:`{-1}`.    Failure *must* occur if the referenced memory instance has a maximum size defined that would be exceeded.    However, failure *can* occur in other cases as well.    In practice, the choice depends on the :ref:`resources <impl-exec>` available to the :ref:`embedder <embedder>`.  -.. index:: atomic memory instruction, memory, frame, module++.. index:: atomic memory instruction, memory, frame, module, atomic operator    pair: execution; instruction    single: abstract syntax; instruction .. _exec-instr-atomic-memory:  Atomic Memory Instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~ -:math:`t\K{.}\ATOMICLOAD~\memarg` and :math:`t\K{.}\ATOMICLOAD{N}\K{\_u}~\memarg`-.................................................................................+.. _exec-atomic.load:+.. _exec-atomic.loadn: -See :ref:`above <exec-atomic-load>`.+:math:`t\K{.}\ATOMICLOAD({N}\K{\_u})^?~\memarg`+............................................... +The rules are identical to :ref:`non-atomic loads <exec-load>`, except that :math:`\ord = \SEQCST`. -:math:`t\K{.}\ATOMICSTORE~\memarg` and :math:`t\K{.}\ATOMICSTORE{N}~\memarg`-............................................................................ -See :ref:`above <exec-atomic-store>`.+.. _exec-atomic.store:+.. _exec-atomic.storen: +:math:`t\K{.}\ATOMICSTORE{N}^?~\memarg`+....................................... +The rules are identical to :ref:`non-atomic stores <exec-store>`, except that :math:`\ord = \SEQCST`. -.. _exec-atomic-rmw:-.. _exec-atomic-rmwn: -:math:`t\K{.}\ATOMICRMW{.}\atomicop~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\atomicop~\memarg`-.....................................................................................................+.. _exec-atomic.rmw:+.. _exec-atomic.rmwn: -.. todo:: update text to match formalism+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\atop~\memarg`+........................................................ -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+2. Else: -4. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`S.\SMEMS[a]` exists.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+   b. Let :math:`\X{st}` be the :ref:`value type <syntax-valtype>` :math:`t`. -6. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack.+3. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack. -7. Pop the value :math:`t.\CONST~c_2` from the stack.+4. Pop the value :math:`t.\CONST~c_2` from the stack. -8. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+5. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -9. Pop the value :math:`\I32.\CONST~i` from the stack.+6. Pop the value :math:`\I32.\CONST~i` from the stack. -10. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`.+7. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`. -11. If :math:`N` is not part of the instruction, then:+8. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then: -    a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+   a. Trap. -12. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+9. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -    a. Trap.+10. Assert: due to :ref:`validation <valid-atomic.rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -13. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then:+11. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -    a. Trap.+12. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -14. Let :math:`b^\ast_r` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+    a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -15. Let :math:`c_1` be the integer for which :math:`bytes_{\iN}(m) = b^\ast_r`.+    b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -16. Let :math:`m` be the result of computing :math:`\atomicop_t(c_1, c_2)`.+       a. Trap. -17. If :math:`N` is part of the instruction, then:+    c. Let :math:`b^\ast_{\F{r}}` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -    a. Let :math:`n` be the result of computing :math:`\wrap_{|t|,N}(m)`.+13. Else: -    b. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_{\iN}(n)`.+    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`. -18. Else:+    b. If :math:`n` is smaller than :math:`\X{ea} + N/8`, or :math:`\X{ea}` is not divisible by :math:`N/8`, then: -    a. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_t(m)`.+       i. Trap. -19. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_w`.+    c. Perform the atomic :ref:`action <syntax-act>` :math:`(\ARMW_{\SEQCST}~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)` to read the bytes :math:`b_{\F{r}}^\ast` from data offset :math:`\X{ea}` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a` and replace them with bytes :math:`b_{\F{w}}^\ast` (which are defined below). -20. Push the value :math:`t.\CONST~c_1` to the stack.+14. Let :math:`c_{\F{r}}` be the integer for which :math:`\bytes_{\X{st}}(n) = b_{\F{r}}^\ast`.++15. Let :math:`c_1` be the result of computing :math:`\extendtu_{\X{st},t}(c_{\F{r}})`.++16. Let :math:`c` be the result of computing :math:`\atop_t(c_1, c_2)`.++17. Let :math:`c_{\F{w}}` be the result of computing :math:`\wrapt_{t,\X{st}}(c)`.++18. Let :math:`b^\ast_{\F{w}}` be the byte sequence :math:`\bytes_{\X{st}}(c_{\F{w}})`.++19. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then:++    a. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_{\F{w}}`.++20. Push the value :math:`t.\CONST~c` to the stack.  .. math::    \begin{array}{l}    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)-     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_1^\ast~b^\ast)}&-     F; (t.\CONST~c_1)+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S'; F; (t.\CONST~c_1)    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}-     (\iff & \X{ea} + N/8 \leq n \\+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 \leq n \\      \wedge & \X{ea} \mod N/8 = 0 \\-     \wedge & b_1^\ast = \bytes_{\iN}(c_1) \\-     \wedge & b^\ast = \bytes_{\iN}(\wrap_{|t|,N}(\atomicop_t(c_1, c_2)))) \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(\meminst.\MIDATA[\X{ea} \slice N/8])) \\+     \wedge & S' = S \with \SMEMS[a].\MIDATA[\X{ea} \slice N/8] = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)+   S; F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S; F; \TRAP+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\+     \end{array}+   \\+   %+   ~\\+   \begin{array}{lcl@{\qquad}l}+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)}&+     S; F; (t.\CONST~c_1)+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & S.\SMEMS[a] ~\mbox{undefined} \\+     \wedge & \X{ea} + N/8 \leq n \\+     \wedge & \X{ea} \mod N/8 = 0 \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(b_{\F{r}}^\ast)) \\+     \wedge & b_{\F{r}}^\ast = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\+     \end{array}+   \\[1ex]+   \begin{array}{lcl@{\qquad}l}+   S; F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)      &\stepto^{(\ARD~a.\LLEN~n)}&-     F; \TRAP+     S; F; \TRAP    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}-     (\iff & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\+     (\iff & S.\SMEMS[a] ~\mbox{undefined} \\+     \wedge & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\      \end{array}-   \\[2ex]-   (\where N = |t| \iff ~\mbox{not present}) \\-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}-   (\where & N = |t| \iff ~\mbox{not present} \\+   (\where & N = |t| \iff N~\mbox{not present} \\+   \wedge & \X{st} = t \iff N~\mbox{not present}, ~\X{st} = \iN \otherwise \\    \wedge & a = F.\AMODULE.\MIMEMS[0] \\    \wedge & \X{ea} = i + \memarg.\OFFSET) \\    \end{array}    \end{array}  -.. _exec-atomic-rmw-cmpxchg:-.. _exec-atomic-rmwn-cmpxchg:+.. _exec-atomic.rmw.cmpxchg:+.. _exec-atomic.rmwn.cmpxchg: -:math:`t\K{.}\ATOMICRMW{.}\ATOMICCMPXCHG~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\ATOMICCMPXCHG~\memarg`-...............................................................................................................+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\ATCMPXCHG~\memarg`+............................................................. -.. todo:: update text to match formalism+.. todo:: should only emit |ARMW| if the condition is true? -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn-cmpxchg>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+2. Else: -4. Assert: due to :ref:`validation <valid-atomic-rmwn-cmpxchg>`, :math:`S.\SMEMS[a]` exists.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+   b. Let :math:`\X{st}` be the :ref:`value type <syntax-valtype>` :math:`t`. -6. Assert: due to :ref:`validation <valid-atomic-rmwn-cmpxchg>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack.+3. Assert: due to :ref:`validation <valid-atomic.rmwn>`, two values of :ref:`value type <syntax-valtype>` :math:`t` are on the top of the stack. -7. Pop the value :math:`t.\CONST~c_3` from the stack.+4. Pop the value :math:`t.\CONST~c_3` from the stack. -8. Assert: due to :ref:`validation <valid-atomic-rmwn-cmpxchg>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack.+5. Pop the value :math:`t.\CONST~c_2` from the stack. -9. Pop the value :math:`t.\CONST~c_2` from the stack.+6. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -10. Assert: due to :ref:`validation <valid-atomic-rmwn-cmpxchg>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+7. Pop the value :math:`\I32.\CONST~i` from the stack. -11. Pop the value :math:`\I32.\CONST~i` from the stack.+8. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`. -12. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`.+9. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then: -13. If :math:`N` is not part of the instruction, then:+   a. Trap. -    a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+10. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -14. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+11. Assert: due to :ref:`validation <valid-atomic.rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -    a. Trap.+12. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -15. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then:+13. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -    a. Trap.+    a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -16. Let :math:`b^\ast_r` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+    b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -17. Let :math:`c_1` be the integer for which :math:`bytes_{\iN}(m) = b^\ast_r`.+       a. Trap. -18. If :math:`N` is part of the instruction, then:+    c. Let :math:`b^\ast_{\F{r}}` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -    a. Let :math:`n` be the result of computing :math:`\wrap_{|t|,N}(c_3)`.+14. Else:++    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`.++    b. If :math:`n` is smaller than :math:`\X{ea} + N/8`, or :math:`\X{ea}` is not divisible by :math:`N/8`, then:++       i. Trap.++    c. Perform the atomic :ref:`action <syntax-act>` :math:`(\ARMW_{\SEQCST}~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)` to read the bytes :math:`b_{\F{r}}^\ast` from data offset :math:`\X{ea}` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a` and replace them with bytes :math:`b_{\F{w}}^\ast` (which are defined below).

same as above

rossberg

comment created time in 2 days

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions      (\iff & S.\SMEMS[a] ~\mbox{undefined}) \\      \end{array}    \end{array}-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}    (\where & a = F.\AMODULE.\MIMEMS[0]) \\    \end{array}    \end{array}  .. note::-   The |MEMORYGROW| instruction is non-deterministic.+   The |MEMORYGROW| instruction is non-deterministic, even on unshared memories.    It may either succeed, returning the old memory size :math:`\X{sz}`,    or fail, returning :math:`{-1}`.    Failure *must* occur if the referenced memory instance has a maximum size defined that would be exceeded.    However, failure *can* occur in other cases as well.    In practice, the choice depends on the :ref:`resources <impl-exec>` available to the :ref:`embedder <embedder>`.  -.. index:: atomic memory instruction, memory, frame, module++.. index:: atomic memory instruction, memory, frame, module, atomic operator    pair: execution; instruction    single: abstract syntax; instruction .. _exec-instr-atomic-memory:  Atomic Memory Instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~ -:math:`t\K{.}\ATOMICLOAD~\memarg` and :math:`t\K{.}\ATOMICLOAD{N}\K{\_u}~\memarg`-.................................................................................+.. _exec-atomic.load:+.. _exec-atomic.loadn: -See :ref:`above <exec-atomic-load>`.+:math:`t\K{.}\ATOMICLOAD({N}\K{\_u})^?~\memarg`+............................................... +The rules are identical to :ref:`non-atomic loads <exec-load>`, except that :math:`\ord = \SEQCST`. -:math:`t\K{.}\ATOMICSTORE~\memarg` and :math:`t\K{.}\ATOMICSTORE{N}~\memarg`-............................................................................ -See :ref:`above <exec-atomic-store>`.+.. _exec-atomic.store:+.. _exec-atomic.storen: +:math:`t\K{.}\ATOMICSTORE{N}^?~\memarg`+....................................... +The rules are identical to :ref:`non-atomic stores <exec-store>`, except that :math:`\ord = \SEQCST`. -.. _exec-atomic-rmw:-.. _exec-atomic-rmwn: -:math:`t\K{.}\ATOMICRMW{.}\atomicop~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\atomicop~\memarg`-.....................................................................................................+.. _exec-atomic.rmw:+.. _exec-atomic.rmwn: -.. todo:: update text to match formalism+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\atop~\memarg`+........................................................ -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack. -2. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+2. Pop the value :math:`t.\CONST~c_2` from the stack. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+3. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -4. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`S.\SMEMS[a]` exists.+4. Pop the value :math:`\I32.\CONST~i` from the stack. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+5. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`. -6. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack.+6. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then: -7. Pop the value :math:`t.\CONST~c_2` from the stack.+   a. Trap. -8. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+7. If :math:`N` is not part of the instruction, then: -9. Pop the value :math:`\I32.\CONST~i` from the stack.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -10. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`.+8. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -11. If :math:`N` is not part of the instruction, then:+9. Assert: due to :ref:`validation <valid-atomic.rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -    a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+10. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -12. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+11. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -    a. Trap.+    a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -13. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then:+    b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -    a. Trap.+       a. Trap. -14. Let :math:`b^\ast_r` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+    c. Let :math:`b^\ast_{\F{r}}` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -15. Let :math:`c_1` be the integer for which :math:`bytes_{\iN}(m) = b^\ast_r`.+12. Else: -16. Let :math:`m` be the result of computing :math:`\atomicop_t(c_1, c_2)`.+    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`. -17. If :math:`N` is part of the instruction, then:+    b. If :math:`n` is smaller than :math:`\X{ea} + N/8`, or :math:`\X{ea}` is not divisible by :math:`N/8`, then: -    a. Let :math:`n` be the result of computing :math:`\wrap_{|t|,N}(m)`.+       i. Trap. -    b. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_{\iN}(n)`.+    c. Perform the atomic :ref:`action <syntax-act>` :math:`(\ARMW_{\ord}~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{r}}^\ast)` to read the bytes :math:`b_{\F{r}}^\ast` from data offset :math:`\X{ea}` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a` and replace them with bytes :math:`b_{\F{w}}^\ast` (which are defined below). -18. Else:+13. If :math:`N` and :math:`\sx` are part of the instruction, then:++    a. Let :math:`c_{\F{r}}` be the integer for which :math:`\bytes_{\iN}(n) = b_{\F{r}}^\ast`.++    b. Let :math:`c_1` be the result of computing :math:`\extendsx_{N,|t|}(c_{\F{r}})`.++14. Else:++    a. Let :math:`c_1` be the constant for which :math:`\bytes_t(c_1) = b_{\F{r}}^\ast`. -    a. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_t(m)`.+15. Let :math:`c` be the result of computing :math:`\atop_t(c_1, c_2)`. -19. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_w`.+16. If :math:`N` is part of the instruction, then: -20. Push the value :math:`t.\CONST~c_1` to the stack.+    a. Let :math:`c_{\F{w}}` be the result of computing :math:`\wrap_{|t|,N}(c)`.++    b. Let :math:`b^\ast_{\F{w}}` be the byte sequence :math:`\bytes_{\iN}(c_{\F{w}})`.++17. Else:++    b. Let :math:`b^\ast_{\F{w}}` be the byte sequence :math:`\bytes_t(c_{\F{w}})`.++18. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then:++    a. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_{\F{w}}`.++19. Push the value :math:`t.\CONST~c` to the stack.  .. math::    \begin{array}{l}    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)-     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_1^\ast~b^\ast)}&-     F; (t.\CONST~c_1)+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S'; F; (t.\CONST~c_1)    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}-     (\iff & \X{ea} + N/8 \leq n \\+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 \leq n \\      \wedge & \X{ea} \mod N/8 = 0 \\-     \wedge & b_1^\ast = \bytes_{\iN}(c_1) \\-     \wedge & b^\ast = \bytes_{\iN}(\wrap_{|t|,N}(\atomicop_t(c_1, c_2)))) \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(\meminst.\MIDATA[\X{ea} \slice N/8])) \\+     \wedge & S' = S \with \SMEMS[a].\MIDATA[\X{ea} \slice N/8] = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)+   S; F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S; F; \TRAP+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\+     \end{array}+   \\+   %+   ~\\+   \begin{array}{lcl@{\qquad}l}+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)}&+     S; F; (t.\CONST~c_1)+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & S.\SMEMS[a] ~\mbox{undefined} \\+     \wedge & \X{ea} + N/8 \leq n \\+     \wedge & \X{ea} \mod N/8 = 0 \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(b_{\F{r}}^\ast)) \\+     \wedge & b_{\F{r}}^\ast = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\+     \end{array}+   \\[1ex]+   \begin{array}{lcl@{\qquad}l}+   S; F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)      &\stepto^{(\ARD~a.\LLEN~n)}&-     F; \TRAP+     S; F; \TRAP    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}-     (\iff & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\+     (\iff & S.\SMEMS[a] ~\mbox{undefined} \\+     \wedge & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\      \end{array}-   \\[2ex]-   (\where N = |t| \iff ~\mbox{not present}) \\-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}-   (\where & N = |t| \iff ~\mbox{not present} \\+   (\where & N = |t| \iff N~\mbox{not present} \\+   \wedge & \X{st} = t \iff N~\mbox{not present}, ~\X{st} = \iN \otherwise \\    \wedge & a = F.\AMODULE.\MIMEMS[0] \\    \wedge & \X{ea} = i + \memarg.\OFFSET) \\    \end{array}    \end{array}  -.. _exec-atomic-rmw-cmpxchg:-.. _exec-atomic-rmwn-cmpxchg:+.. _exec-atomic.rmw.cmpxchg:+.. _exec-atomic.rmwn.cmpxchg: -:math:`t\K{.}\ATOMICRMW{.}\ATOMICCMPXCHG~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\ATOMICCMPXCHG~\memarg`-...............................................................................................................+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\ATCMPXCHG~\memarg`

currently under discussion https://github.com/tc39/ecma262/issues/2231

rossberg

comment created time in 2 days

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & \meminst = S.\SMEMS[a]) \\      \end{array}-   \\[1ex]+   \\    %+   ~\\+   \\    \begin{array}{lcl@{\qquad}l}-   S; F; (\I32.\CONST~i)~\MEMORYGROW-     &\stepto^{(\ARMW~a.\LLEN~n~(n+k))~(\AWR~a.\LDATA[n]~(0)^k)}&+   S; F; (\I32.\CONST~n)~\MEMORYGROW+     &\stepto^{(\ARMW~a.\LLEN~l~(l+k))~(\AWR~a.\LDATA[l]~(0)^k)}&      S; F; (\I32.\CONST~\X{sz})    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined} \\-     \wedge & n = \X{sz} \cdot 64\,\F{Ki} \\-     \wedge & k = i \cdot 64\,\F{Ki}) \\+     \wedge & \X{sz} = l / 64\,\F{Ki} \\+     \wedge & n = k / 64\,\F{Ki}) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}    S; F; (\I32.\CONST~n)~\MEMORYGROW-     &\stepto^{(\ARD~a.\LLEN~n)}&+     &\stepto^{(\ARD_{\SEQCST}~a.\LLEN~n)}&      S; F; (\I32.\CONST~{-1})    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined}) \\      \end{array}    \end{array}-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}    (\where & a = F.\AMODULE.\MIMEMS[0]) \\    \end{array}    \end{array}  .. note::-   The |MEMORYGROW| instruction is non-deterministic.+   The |MEMORYGROW| instruction is non-deterministic, even on unshared memories.    It may either succeed, returning the old memory size :math:`\X{sz}`,    or fail, returning :math:`{-1}`.    Failure *must* occur if the referenced memory instance has a maximum size defined that would be exceeded.    However, failure *can* occur in other cases as well.    In practice, the choice depends on the :ref:`resources <impl-exec>` available to the :ref:`embedder <embedder>`.  -.. index:: atomic memory instruction, memory, frame, module++.. index:: atomic memory instruction, memory, frame, module, atomic operator    pair: execution; instruction    single: abstract syntax; instruction .. _exec-instr-atomic-memory:  Atomic Memory Instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~ -:math:`t\K{.}\ATOMICLOAD~\memarg` and :math:`t\K{.}\ATOMICLOAD{N}\K{\_u}~\memarg`-.................................................................................+.. _exec-atomic.load:+.. _exec-atomic.loadn: -See :ref:`above <exec-atomic-load>`.+:math:`t\K{.}\ATOMICLOAD({N}\K{\_u})^?~\memarg`+............................................... +The rules are identical to :ref:`non-atomic loads <exec-load>`, except that :math:`\ord = \SEQCST`. -:math:`t\K{.}\ATOMICSTORE~\memarg` and :math:`t\K{.}\ATOMICSTORE{N}~\memarg`-............................................................................ -See :ref:`above <exec-atomic-store>`.+.. _exec-atomic.store:+.. _exec-atomic.storen: +:math:`t\K{.}\ATOMICSTORE{N}^?~\memarg`+....................................... +The rules are identical to :ref:`non-atomic stores <exec-store>`, except that :math:`\ord = \SEQCST`. -.. _exec-atomic-rmw:-.. _exec-atomic-rmwn: -:math:`t\K{.}\ATOMICRMW{.}\atomicop~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\atomicop~\memarg`-.....................................................................................................+.. _exec-atomic.rmw:+.. _exec-atomic.rmwn: -.. todo:: update text to match formalism+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\atop~\memarg`+........................................................ -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+2. Else: -4. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`S.\SMEMS[a]` exists.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+   b. Let :math:`\X{st}` be the :ref:`value type <syntax-valtype>` :math:`t`. -6. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack.+3. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack. -7. Pop the value :math:`t.\CONST~c_2` from the stack.+4. Pop the value :math:`t.\CONST~c_2` from the stack. -8. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+5. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -9. Pop the value :math:`\I32.\CONST~i` from the stack.+6. Pop the value :math:`\I32.\CONST~i` from the stack. -10. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`.+7. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`. -11. If :math:`N` is not part of the instruction, then:+8. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then: -    a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+   a. Trap. -12. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+9. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -    a. Trap.+10. Assert: due to :ref:`validation <valid-atomic.rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -13. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then:+11. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -    a. Trap.+12. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -14. Let :math:`b^\ast_r` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+    a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -15. Let :math:`c_1` be the integer for which :math:`bytes_{\iN}(m) = b^\ast_r`.+    b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -16. Let :math:`m` be the result of computing :math:`\atomicop_t(c_1, c_2)`.+       a. Trap. -17. If :math:`N` is part of the instruction, then:+    c. Let :math:`b^\ast_{\F{r}}` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -    a. Let :math:`n` be the result of computing :math:`\wrap_{|t|,N}(m)`.+13. Else: -    b. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_{\iN}(n)`.+    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`. -18. Else:+    b. If :math:`n` is smaller than :math:`\X{ea} + N/8`, or :math:`\X{ea}` is not divisible by :math:`N/8`, then: -    a. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_t(m)`.+       i. Trap. -19. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_w`.+    c. Perform the atomic :ref:`action <syntax-act>` :math:`(\ARMW_{\SEQCST}~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)` to read the bytes :math:`b_{\F{r}}^\ast` from data offset :math:`\X{ea}` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a` and replace them with bytes :math:`b_{\F{w}}^\ast` (which are defined below). -20. Push the value :math:`t.\CONST~c_1` to the stack.+14. Let :math:`c_{\F{r}}` be the integer for which :math:`\bytes_{\X{st}}(n) = b_{\F{r}}^\ast`.++15. Let :math:`c_1` be the result of computing :math:`\extendtu_{\X{st},t}(c_{\F{r}})`.++16. Let :math:`c` be the result of computing :math:`\atop_t(c_1, c_2)`.++17. Let :math:`c_{\F{w}}` be the result of computing :math:`\wrapt_{t,\X{st}}(c)`.++18. Let :math:`b^\ast_{\F{w}}` be the byte sequence :math:`\bytes_{\X{st}}(c_{\F{w}})`.++19. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then:++    a. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_{\F{w}}`.++20. Push the value :math:`t.\CONST~c` to the stack.  .. math::    \begin{array}{l}    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)-     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_1^\ast~b^\ast)}&-     F; (t.\CONST~c_1)+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S'; F; (t.\CONST~c_1)    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}-     (\iff & \X{ea} + N/8 \leq n \\+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 \leq n \\      \wedge & \X{ea} \mod N/8 = 0 \\-     \wedge & b_1^\ast = \bytes_{\iN}(c_1) \\-     \wedge & b^\ast = \bytes_{\iN}(\wrap_{|t|,N}(\atomicop_t(c_1, c_2)))) \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(\meminst.\MIDATA[\X{ea} \slice N/8])) \\+     \wedge & S' = S \with \SMEMS[a].\MIDATA[\X{ea} \slice N/8] = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)+   S; F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S; F; \TRAP+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\+     \end{array}+   \\+   %+   ~\\+   \begin{array}{lcl@{\qquad}l}+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)}&+     S; F; (t.\CONST~c_1)+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & S.\SMEMS[a] ~\mbox{undefined} \\+     \wedge & \X{ea} + N/8 \leq n \\+     \wedge & \X{ea} \mod N/8 = 0 \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(b_{\F{r}}^\ast)) \\+     \wedge & b_{\F{r}}^\ast = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\

think this should be b_w*

rossberg

comment created time in 2 days

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & \meminst = S.\SMEMS[a]) \\      \end{array}-   \\[1ex]+   \\    %+   ~\\+   \\    \begin{array}{lcl@{\qquad}l}-   S; F; (\I32.\CONST~i)~\MEMORYGROW-     &\stepto^{(\ARMW~a.\LLEN~n~(n+k))~(\AWR~a.\LDATA[n]~(0)^k)}&+   S; F; (\I32.\CONST~n)~\MEMORYGROW+     &\stepto^{(\ARMW~a.\LLEN~l~(l+k))~(\AWR~a.\LDATA[l]~(0)^k)}&      S; F; (\I32.\CONST~\X{sz})    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined} \\-     \wedge & n = \X{sz} \cdot 64\,\F{Ki} \\-     \wedge & k = i \cdot 64\,\F{Ki}) \\+     \wedge & \X{sz} = l / 64\,\F{Ki} \\+     \wedge & n = k / 64\,\F{Ki}) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}    S; F; (\I32.\CONST~n)~\MEMORYGROW-     &\stepto^{(\ARD~a.\LLEN~n)}&+     &\stepto^{(\ARD_{\SEQCST}~a.\LLEN~n)}&      S; F; (\I32.\CONST~{-1})    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined}) \\      \end{array}    \end{array}-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}    (\where & a = F.\AMODULE.\MIMEMS[0]) \\    \end{array}    \end{array}  .. note::-   The |MEMORYGROW| instruction is non-deterministic.+   The |MEMORYGROW| instruction is non-deterministic, even on unshared memories.    It may either succeed, returning the old memory size :math:`\X{sz}`,    or fail, returning :math:`{-1}`.    Failure *must* occur if the referenced memory instance has a maximum size defined that would be exceeded.    However, failure *can* occur in other cases as well.    In practice, the choice depends on the :ref:`resources <impl-exec>` available to the :ref:`embedder <embedder>`.  -.. index:: atomic memory instruction, memory, frame, module++.. index:: atomic memory instruction, memory, frame, module, atomic operator    pair: execution; instruction    single: abstract syntax; instruction .. _exec-instr-atomic-memory:  Atomic Memory Instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~ -:math:`t\K{.}\ATOMICLOAD~\memarg` and :math:`t\K{.}\ATOMICLOAD{N}\K{\_u}~\memarg`-.................................................................................+.. _exec-atomic.load:+.. _exec-atomic.loadn: -See :ref:`above <exec-atomic-load>`.+:math:`t\K{.}\ATOMICLOAD({N}\K{\_u})^?~\memarg`+............................................... +The rules are identical to :ref:`non-atomic loads <exec-load>`, except that :math:`\ord = \SEQCST`. -:math:`t\K{.}\ATOMICSTORE~\memarg` and :math:`t\K{.}\ATOMICSTORE{N}~\memarg`-............................................................................ -See :ref:`above <exec-atomic-store>`.+.. _exec-atomic.store:+.. _exec-atomic.storen: +:math:`t\K{.}\ATOMICSTORE{N}^?~\memarg`+....................................... +The rules are identical to :ref:`non-atomic stores <exec-store>`, except that :math:`\ord = \SEQCST`. -.. _exec-atomic-rmw:-.. _exec-atomic-rmwn: -:math:`t\K{.}\ATOMICRMW{.}\atomicop~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\atomicop~\memarg`-.....................................................................................................+.. _exec-atomic.rmw:+.. _exec-atomic.rmwn: -.. todo:: update text to match formalism+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\atop~\memarg`+........................................................ -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+2. Else: -4. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`S.\SMEMS[a]` exists.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+   b. Let :math:`\X{st}` be the :ref:`value type <syntax-valtype>` :math:`t`. -6. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack.+3. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack. -7. Pop the value :math:`t.\CONST~c_2` from the stack.+4. Pop the value :math:`t.\CONST~c_2` from the stack. -8. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+5. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -9. Pop the value :math:`\I32.\CONST~i` from the stack.+6. Pop the value :math:`\I32.\CONST~i` from the stack. -10. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`.+7. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`. -11. If :math:`N` is not part of the instruction, then:+8. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then: -    a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+   a. Trap. -12. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+9. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -    a. Trap.+10. Assert: due to :ref:`validation <valid-atomic.rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -13. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then:+11. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -    a. Trap.+12. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -14. Let :math:`b^\ast_r` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+    a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -15. Let :math:`c_1` be the integer for which :math:`bytes_{\iN}(m) = b^\ast_r`.+    b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -16. Let :math:`m` be the result of computing :math:`\atomicop_t(c_1, c_2)`.+       a. Trap. -17. If :math:`N` is part of the instruction, then:+    c. Let :math:`b^\ast_{\F{r}}` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -    a. Let :math:`n` be the result of computing :math:`\wrap_{|t|,N}(m)`.+13. Else: -    b. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_{\iN}(n)`.+    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`. -18. Else:+    b. If :math:`n` is smaller than :math:`\X{ea} + N/8`, or :math:`\X{ea}` is not divisible by :math:`N/8`, then: -    a. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_t(m)`.+       i. Trap. -19. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_w`.+    c. Perform the atomic :ref:`action <syntax-act>` :math:`(\ARMW_{\SEQCST}~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)` to read the bytes :math:`b_{\F{r}}^\ast` from data offset :math:`\X{ea}` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a` and replace them with bytes :math:`b_{\F{w}}^\ast` (which are defined below). -20. Push the value :math:`t.\CONST~c_1` to the stack.+14. Let :math:`c_{\F{r}}` be the integer for which :math:`\bytes_{\X{st}}(n) = b_{\F{r}}^\ast`.++15. Let :math:`c_1` be the result of computing :math:`\extendtu_{\X{st},t}(c_{\F{r}})`.++16. Let :math:`c` be the result of computing :math:`\atop_t(c_1, c_2)`.++17. Let :math:`c_{\F{w}}` be the result of computing :math:`\wrapt_{t,\X{st}}(c)`.++18. Let :math:`b^\ast_{\F{w}}` be the byte sequence :math:`\bytes_{\X{st}}(c_{\F{w}})`.++19. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then:++    a. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_{\F{w}}`.++20. Push the value :math:`t.\CONST~c` to the stack.  .. math::    \begin{array}{l}    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)-     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_1^\ast~b^\ast)}&-     F; (t.\CONST~c_1)+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S'; F; (t.\CONST~c_1)    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}-     (\iff & \X{ea} + N/8 \leq n \\+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 \leq n \\      \wedge & \X{ea} \mod N/8 = 0 \\-     \wedge & b_1^\ast = \bytes_{\iN}(c_1) \\-     \wedge & b^\ast = \bytes_{\iN}(\wrap_{|t|,N}(\atomicop_t(c_1, c_2)))) \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(\meminst.\MIDATA[\X{ea} \slice N/8])) \\+     \wedge & S' = S \with \SMEMS[a].\MIDATA[\X{ea} \slice N/8] = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}-   F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atomicop~\memarg)+   S; F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto&+     S; F; \TRAP+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & \meminst = S.\SMEMS[a] \\+     \wedge & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\+     \end{array}+   \\+   %+   ~\\+   \begin{array}{lcl@{\qquad}l}+   S; F; (\I32.\CONST~i)~(t.\CONST~c_2)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)+     &\stepto^{(\ARD~a.\LLEN~n)~(\ARMW~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)}&+     S; F; (t.\CONST~c_1)+   \end{array}+   \\ \qquad+     \begin{array}[t]{@{}r@{~}l@{}}+     (\iff & S.\SMEMS[a] ~\mbox{undefined} \\+     \wedge & \X{ea} + N/8 \leq n \\+     \wedge & \X{ea} \mod N/8 = 0 \\+     \wedge & c_1 = \extendtu_{\X{st},t}(\bytes^{-1}_{\X{st}}(b_{\F{r}}^\ast)) \\+     \wedge & b_{\F{r}}^\ast = \bytes_{\X{st}}(\wrapt_{t,\X{st}}(\atop_t(c_1, c_2)))) \\+     \end{array}+   \\[1ex]+   \begin{array}{lcl@{\qquad}l}+   S; F; (\I32.\CONST~k)~(t.\CONST~c)~(t.\ATOMICRMW({N}\K{\_u})^?.\atop~\memarg)      &\stepto^{(\ARD~a.\LLEN~n)}&-     F; \TRAP+     S; F; \TRAP    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}-     (\iff & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\+     (\iff & S.\SMEMS[a] ~\mbox{undefined} \\+     \wedge & \X{ea} + N/8 > n \vee \X{ea} \mod N/8 \neq 0) \\      \end{array}-   \\[2ex]-   (\where N = |t| \iff ~\mbox{not present}) \\-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}-   (\where & N = |t| \iff ~\mbox{not present} \\+   (\where & N = |t| \iff N~\mbox{not present} \\+   \wedge & \X{st} = t \iff N~\mbox{not present}, ~\X{st} = \iN \otherwise \\    \wedge & a = F.\AMODULE.\MIMEMS[0] \\    \wedge & \X{ea} = i + \memarg.\OFFSET) \\    \end{array}    \end{array}  -.. _exec-atomic-rmw-cmpxchg:-.. _exec-atomic-rmwn-cmpxchg:+.. _exec-atomic.rmw.cmpxchg:+.. _exec-atomic.rmwn.cmpxchg: -:math:`t\K{.}\ATOMICRMW{.}\ATOMICCMPXCHG~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\ATOMICCMPXCHG~\memarg`-...............................................................................................................+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\ATCMPXCHG~\memarg`+............................................................. -.. todo:: update text to match formalism+.. todo:: should only emit |ARMW| if the condition is true? -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn-cmpxchg>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`.

same as above

rossberg

comment created time in 2 days

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & \meminst = S.\SMEMS[a]) \\      \end{array}-   \\[1ex]+   \\    %+   ~\\+   \\    \begin{array}{lcl@{\qquad}l}-   S; F; (\I32.\CONST~i)~\MEMORYGROW-     &\stepto^{(\ARMW~a.\LLEN~n~(n+k))~(\AWR~a.\LDATA[n]~(0)^k)}&+   S; F; (\I32.\CONST~n)~\MEMORYGROW+     &\stepto^{(\ARMW~a.\LLEN~l~(l+k))~(\AWR~a.\LDATA[l]~(0)^k)}&      S; F; (\I32.\CONST~\X{sz})    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined} \\-     \wedge & n = \X{sz} \cdot 64\,\F{Ki} \\-     \wedge & k = i \cdot 64\,\F{Ki}) \\+     \wedge & \X{sz} = l / 64\,\F{Ki} \\+     \wedge & n = k / 64\,\F{Ki}) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}    S; F; (\I32.\CONST~n)~\MEMORYGROW-     &\stepto^{(\ARD~a.\LLEN~n)}&+     &\stepto^{(\ARD_{\SEQCST}~a.\LLEN~n)}&      S; F; (\I32.\CONST~{-1})    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined}) \\      \end{array}    \end{array}-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}    (\where & a = F.\AMODULE.\MIMEMS[0]) \\    \end{array}    \end{array}  .. note::-   The |MEMORYGROW| instruction is non-deterministic.+   The |MEMORYGROW| instruction is non-deterministic, even on unshared memories.    It may either succeed, returning the old memory size :math:`\X{sz}`,    or fail, returning :math:`{-1}`.    Failure *must* occur if the referenced memory instance has a maximum size defined that would be exceeded.    However, failure *can* occur in other cases as well.    In practice, the choice depends on the :ref:`resources <impl-exec>` available to the :ref:`embedder <embedder>`.  -.. index:: atomic memory instruction, memory, frame, module++.. index:: atomic memory instruction, memory, frame, module, atomic operator    pair: execution; instruction    single: abstract syntax; instruction .. _exec-instr-atomic-memory:  Atomic Memory Instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~ -:math:`t\K{.}\ATOMICLOAD~\memarg` and :math:`t\K{.}\ATOMICLOAD{N}\K{\_u}~\memarg`-.................................................................................+.. _exec-atomic.load:+.. _exec-atomic.loadn: -See :ref:`above <exec-atomic-load>`.+:math:`t\K{.}\ATOMICLOAD({N}\K{\_u})^?~\memarg`+............................................... +The rules are identical to :ref:`non-atomic loads <exec-load>`, except that :math:`\ord = \SEQCST`. -:math:`t\K{.}\ATOMICSTORE~\memarg` and :math:`t\K{.}\ATOMICSTORE{N}~\memarg`-............................................................................ -See :ref:`above <exec-atomic-store>`.+.. _exec-atomic.store:+.. _exec-atomic.storen: +:math:`t\K{.}\ATOMICSTORE{N}^?~\memarg`+....................................... +The rules are identical to :ref:`non-atomic stores <exec-store>`, except that :math:`\ord = \SEQCST`. -.. _exec-atomic-rmw:-.. _exec-atomic-rmwn: -:math:`t\K{.}\ATOMICRMW{.}\atomicop~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\atomicop~\memarg`-.....................................................................................................+.. _exec-atomic.rmw:+.. _exec-atomic.rmwn: -.. todo:: update text to match formalism+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\atop~\memarg`+........................................................ -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+2. Else: -4. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`S.\SMEMS[a]` exists.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+   b. Let :math:`\X{st}` be the :ref:`value type <syntax-valtype>` :math:`t`. -6. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack.+3. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` :math:`t` is on the top of the stack. -7. Pop the value :math:`t.\CONST~c_2` from the stack.+4. Pop the value :math:`t.\CONST~c_2` from the stack. -8. Assert: due to :ref:`validation <valid-atomic-rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+5. Assert: due to :ref:`validation <valid-atomic.rmwn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -9. Pop the value :math:`\I32.\CONST~i` from the stack.+6. Pop the value :math:`\I32.\CONST~i` from the stack. -10. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`.+7. Let :math:`\X{ea}` be :math:`i + \memarg.\OFFSET`. -11. If :math:`N` is not part of the instruction, then:+8. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then: -    a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+   a. Trap. -12. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+9. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -    a. Trap.+10. Assert: due to :ref:`validation <valid-atomic.rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -13. If :math:`\X{ea}` modulo :math:`N/8` is not equal to :math:`0`, then:+11. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -    a. Trap.+12. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -14. Let :math:`b^\ast_r` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+    a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -15. Let :math:`c_1` be the integer for which :math:`bytes_{\iN}(m) = b^\ast_r`.+    b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -16. Let :math:`m` be the result of computing :math:`\atomicop_t(c_1, c_2)`.+       a. Trap. -17. If :math:`N` is part of the instruction, then:+    c. Let :math:`b^\ast_{\F{r}}` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -    a. Let :math:`n` be the result of computing :math:`\wrap_{|t|,N}(m)`.+13. Else: -    b. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_{\iN}(n)`.+    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`. -18. Else:+    b. If :math:`n` is smaller than :math:`\X{ea} + N/8`, or :math:`\X{ea}` is not divisible by :math:`N/8`, then: -    a. Let :math:`b^\ast_w` be the byte sequence :math:`\bytes_t(m)`.+       i. Trap. -19. Replace the bytes :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]` with :math:`b^\ast_w`.+    c. Perform the atomic :ref:`action <syntax-act>` :math:`(\ARMW_{\SEQCST}~a.\LDATA[\X{ea}]~b_{\F{r}}^\ast~b_{\F{w}}^\ast)` to read the bytes :math:`b_{\F{r}}^\ast` from data offset :math:`\X{ea}` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a` and replace them with bytes :math:`b_{\F{w}}^\ast` (which are defined below).

again, need to ensure that b_r* has the right length (does length of b_w* follow as numeric invariant?)

rossberg

comment created time in 2 days

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & \meminst = S.\SMEMS[a]) \\      \end{array}-   \\[1ex]+   \\    %+   ~\\+   \\    \begin{array}{lcl@{\qquad}l}-   S; F; (\I32.\CONST~i)~\MEMORYGROW-     &\stepto^{(\ARMW~a.\LLEN~n~(n+k))~(\AWR~a.\LDATA[n]~(0)^k)}&+   S; F; (\I32.\CONST~n)~\MEMORYGROW+     &\stepto^{(\ARMW~a.\LLEN~l~(l+k))~(\AWR~a.\LDATA[l]~(0)^k)}&      S; F; (\I32.\CONST~\X{sz})    \end{array}    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined} \\-     \wedge & n = \X{sz} \cdot 64\,\F{Ki} \\-     \wedge & k = i \cdot 64\,\F{Ki}) \\+     \wedge & \X{sz} = l / 64\,\F{Ki} \\+     \wedge & n = k / 64\,\F{Ki}) \\      \end{array}    \\[1ex]    \begin{array}{lcl@{\qquad}l}    S; F; (\I32.\CONST~n)~\MEMORYGROW-     &\stepto^{(\ARD~a.\LLEN~n)}&+     &\stepto^{(\ARD_{\SEQCST}~a.\LLEN~n)}&      S; F; (\I32.\CONST~{-1})    \\ \qquad      \begin{array}[t]{@{}r@{~}l@{}}      (\iff & S.\SMEMS[a] ~\mbox{undefined}) \\      \end{array}    \end{array}-   \\[2ex]+   \\+   %+   ~\\    \begin{array}[t]{@{}r@{~}l@{}}    (\where & a = F.\AMODULE.\MIMEMS[0]) \\    \end{array}    \end{array}  .. note::-   The |MEMORYGROW| instruction is non-deterministic.+   The |MEMORYGROW| instruction is non-deterministic, even on unshared memories.    It may either succeed, returning the old memory size :math:`\X{sz}`,    or fail, returning :math:`{-1}`.    Failure *must* occur if the referenced memory instance has a maximum size defined that would be exceeded.    However, failure *can* occur in other cases as well.    In practice, the choice depends on the :ref:`resources <impl-exec>` available to the :ref:`embedder <embedder>`.  -.. index:: atomic memory instruction, memory, frame, module++.. index:: atomic memory instruction, memory, frame, module, atomic operator    pair: execution; instruction    single: abstract syntax; instruction .. _exec-instr-atomic-memory:  Atomic Memory Instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~ -:math:`t\K{.}\ATOMICLOAD~\memarg` and :math:`t\K{.}\ATOMICLOAD{N}\K{\_u}~\memarg`-.................................................................................+.. _exec-atomic.load:+.. _exec-atomic.loadn: -See :ref:`above <exec-atomic-load>`.+:math:`t\K{.}\ATOMICLOAD({N}\K{\_u})^?~\memarg`+............................................... +The rules are identical to :ref:`non-atomic loads <exec-load>`, except that :math:`\ord = \SEQCST`. -:math:`t\K{.}\ATOMICSTORE~\memarg` and :math:`t\K{.}\ATOMICSTORE{N}~\memarg`-............................................................................ -See :ref:`above <exec-atomic-store>`.+.. _exec-atomic.store:+.. _exec-atomic.storen: +:math:`t\K{.}\ATOMICSTORE{N}^?~\memarg`+....................................... +The rules are identical to :ref:`non-atomic stores <exec-store>`, except that :math:`\ord = \SEQCST`. -.. _exec-atomic-rmw:-.. _exec-atomic-rmwn: -:math:`t\K{.}\ATOMICRMW{.}\atomicop~\memarg` and :math:`t\K{.}\ATOMICRMW{N}\K{\_u.}\atomicop~\memarg`-.....................................................................................................+.. _exec-atomic.rmw:+.. _exec-atomic.rmwn: -.. todo:: update text to match formalism+:math:`t\K{.}\ATOMICRMW({N}\K{\_u})^?\K{.}\atop~\memarg`+........................................................ -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+1. If :math:`N` and :math:`\K{\_u}` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-atomic-rmwn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`.

same here

rossberg

comment created time in 2 days

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions  .. _exec-store: .. _exec-storen:-.. _exec-atomic-store:-.. _exec-atomic-storen: -:math:`t\K{.}\ATOMIC^?.\STORE~\memarg` and :math:`t\K{.}\ATOMIC^?.\STORE{N}~\memarg`-....................................................................................+:math:`t\K{.}\STORE{N}^?~\memarg`+................................. -.. todo:: update text to match formalism+1. Let :math:`\ord` be :math:`\UNORD`. -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+2. If :math:`N` is part of the instruction, then: -2. Assert: due to :ref:`validation <valid-storen>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`.

same as above

rossberg

comment created time in 2 days

Pull request review commentWebAssembly/threads

Spec basic instructions

 Memory Instructions  .. _exec-load: .. _exec-loadn:-.. _exec-atomic-load:-.. _exec-atomic-loadn: -:math:`t\K{.}\ATOMIC^?.\LOAD~\memarg` and :math:`t\K{.}\ATOMIC^?.\LOAD{N}\K{\_}\sx~\memarg`-...........................................................................................+:math:`t\K{.}\LOAD({N}\K{\_}\sx)^?~\memarg`+........................................... -.. todo:: update text to match formalism+1. Let :math:`\ord` be :math:`\UNORD`. -1. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`.+2. If :math:`N` and :math:`\sx` are part of the instruction, then: -2. Assert: due to :ref:`validation <valid-loadn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists.+   a. Let :math:`\X{st}` be the :ref:`pro forma type <aux-bytes>` :math:`\iN`. -3. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`.+3. Else: -4. Assert: due to :ref:`validation <valid-loadn>`, :math:`S.\SMEMS[a]` exists.+   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`. -5. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`.+   b. Let :math:`\X{st}` be the :ref:`value type <syntax-valtype>` :math:`t`. -6. Assert: due to :ref:`validation <valid-loadn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack.+4. Assert: due to :ref:`validation <valid-loadn>`, a value of :ref:`value type <syntax-valtype>` |I32| is on the top of the stack. -7. Pop the value :math:`\I32.\CONST~i` from the stack.+5. Pop the value :math:`\I32.\CONST~i` from the stack. -8. Let :math:`\X{ea}` be the integer :math:`i + \memarg.\OFFSET`.+6. Let :math:`\X{ea}` be the integer :math:`i + \memarg.\OFFSET`. -9. If :math:`N` is not part of the instruction, then:+7. Let :math:`F` be the :ref:`current <exec-notation-textual>` :ref:`frame <syntax-frame>`. -   a. Let :math:`N` be the :ref:`bit width <syntax-valtype>` :math:`|t|` of :ref:`value type <syntax-valtype>` :math:`t`.+8. Assert: due to :ref:`validation <valid-loadn>`, :math:`F.\AMODULE.\MIMEMS[0]` exists. -10. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then:+9. Let :math:`a` be the :ref:`memory address <syntax-memaddr>` :math:`F.\AMODULE.\MIMEMS[0]`. -    a. Trap.+10. If the memory is local, i.e., :math:`S.\SMEMS[a]` exists, then: -11. Let :math:`b^\ast` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`.+   a. Let :math:`\X{mem}` be the :ref:`memory instance <syntax-meminst>` :math:`S.\SMEMS[a]`. -12. If :math:`N` and :math:`\sx` are part of the instruction, then:+   b. If :math:`\X{ea} + N/8` is larger than the length of :math:`\X{mem}.\MIDATA`, then: -    a. Let :math:`n` be the integer for which :math:`\bytes_{\iN}(n) = b^\ast`.+      i. Trap. -    b. Let :math:`c` be the result of computing :math:`\extend\F{\_}\sx_{N,|t|}(n)`.+   c. Let :math:`b^\ast` be the byte sequence :math:`\X{mem}.\MIDATA[\X{ea} \slice N/8]`. -13. Else:+11. Else:++    a. Perform the :ref:`action <syntax-act>` :math:`(\ARD~a.\LLEN~n)` to read the length :math:`n` of the shared :ref:`memory instance <syntax-meminst>` at :ref:`memory address <syntax-memaddr>` :math:`a`.

Need to make sure that the length of b* matches the width of the load (same in formal semantics).

rossberg

comment created time in 2 days

more