An aggregation of algorithms, data structures and supporting crates
Notas de aula sobre linguagens de programação (baseado no livro "Concepts of Programming Languages")
Instances and solvers for the degree constrained minimum spanning tree problem
Some of my dotfiles
Notas de aula sobre o paradigma de programação funcional
Mirror of aports repository
Backtraces in Rust
The Rust package manager
Cargo subcommand to run kcov to get coverage report on Linux
Rust library for build scripts to compile C/C++ code into a Rust library
PR opened richfelker/musl-cross-make
0017-pr93402.diff was removed, as it was merged upstream.
pr created time in 6 hours
PR opened richfelker/musl-cross-make
0017-pr93402.diff was removed, as it was merged upstream.
pr created time in 7 hours
PR opened richfelker/musl-cross-make
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.
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.
comment created time in 12 hours
pull request commentWebAssembly/threads
@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.
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:
- add
caught-stack to the runtime and to validation contexts and remove catch-labels (which actually should have been called "caught" labels but anyway) - allow
trys withoutcatches - remove auxiliary
typeof labels and allowdelegateto reference any label
WDYT?
comment created time in 18 hours
pull request commentWebAssembly/threads
Thanks! No stress, I thought your thesis was already due in September.
yes
comment created time in 19 hours
Pull request review commentWebAssembly/threads
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.
comment created time in 21 hours
Pull request review commentWebAssembly/threads
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.
comment created time in 21 hours
Pull request review commentWebAssembly/threads
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.)
comment created time in 21 hours
Pull request review commentWebAssembly/threads
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.
comment created time in 21 hours
Pull request review commentWebAssembly/threads
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.
comment created time in 21 hours
Pull request review commentWebAssembly/threads
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.
comment created time in 21 hours
Pull request review commentWebAssembly/threads
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.
comment created time in 21 hours
Pull request review commentWebAssembly/threads
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.
comment created time in 21 hours
Pull request review commentWebAssembly/threads
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.
comment created time in 21 hours
push eventWebAssembly/threads
commit sha ee78d2900065261102f0fc46069e551fc91916b4
More comments
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 ^^ ?
comment created time in a day
issue commentnh2/static-haskell-nix
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.
comment created time in a day
Pull request review commentWebAssembly/threads
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
comment created time in 2 days
Pull request review commentWebAssembly/threads
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
comment created time in 2 days
Pull request review commentWebAssembly/threads
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
comment created time in 2 days
Pull request review commentWebAssembly/threads
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*
comment created time in 2 days
Pull request review commentWebAssembly/threads
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
comment created time in 2 days
Pull request review commentWebAssembly/threads
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?)
comment created time in 2 days
Pull request review commentWebAssembly/threads
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
comment created time in 2 days
Pull request review commentWebAssembly/threads
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
comment created time in 2 days
Pull request review commentWebAssembly/threads
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).
comment created time in 2 days