Skip to content

Commit

Permalink
Merge branch 'upstream'
Browse files Browse the repository at this point in the history
  • Loading branch information
rossberg committed Jan 17, 2024
2 parents a416865 + 724b3e7 commit 4c02753
Show file tree
Hide file tree
Showing 28 changed files with 266 additions and 210 deletions.
3 changes: 1 addition & 2 deletions document/core/appendix/index-instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ def RefWrap(s, kind):

def Instruction(name, opcode, type=None, validation=None, execution=None, operator=None):
if operator:
execution_str = ', '.join([RefWrap(execution, 'execution'),
RefWrap(operator, 'operator')])
execution_str = RefWrap(execution, 'execution') + ' (' + RefWrap(operator, 'operator') + ')'
else:
execution_str = RefWrap(execution, 'execution')

Expand Down
4 changes: 2 additions & 2 deletions document/core/appendix/properties.rst
Original file line number Diff line number Diff line change
Expand Up @@ -748,9 +748,9 @@ a store state :math:`S'` extends state :math:`S`, written :math:`S \extendsto S'

* For each :ref:`global instance <syntax-globalinst>` :math:`\globalinst_i` in the original :math:`S.\SGLOBALS`, the new global instance must be an :ref:`extension <extend-globalinst>` of the old.

* For each :ref:`element instance <syntax-eleminst>` :math:`\eleminst_i` in the original :math:`S.\SELEMS`, the new global instance must be an :ref:`extension <extend-eleminst>` of the old.
* For each :ref:`element instance <syntax-eleminst>` :math:`\eleminst_i` in the original :math:`S.\SELEMS`, the new element instance must be an :ref:`extension <extend-eleminst>` of the old.

* For each :ref:`data instance <syntax-datainst>` :math:`\datainst_i` in the original :math:`S.\SDATAS`, the new global instance must be an :ref:`extension <extend-datainst>` of the old.
* For each :ref:`data instance <syntax-datainst>` :math:`\datainst_i` in the original :math:`S.\SDATAS`, the new data instance must be an :ref:`extension <extend-datainst>` of the old.

.. math::
\frac{
Expand Down
102 changes: 54 additions & 48 deletions document/core/exec/instructions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,15 @@ The mapping of numeric instructions to their underlying operators is expressed b

.. math::
\begin{array}{lll@{\qquad}l}
\X{op}_{\IN}(i_1,\dots,i_k) &=& \F{i}\X{op}_N(i_1,\dots,i_k) \\
\X{op}_{\FN}(z_1,\dots,z_k) &=& \F{f}\X{op}_N(z_1,\dots,z_k) \\
\X{op}_{\VN}(i_1,\dots,i_k) &=& \F{i}\X{op}_N(i_1,\dots,i_k) \\
\X{op}_{\IN}(i_1,\dots,i_k) &=& \xref{exec/numerics}{int-ops}{\F{i}\X{op}}_N(i_1,\dots,i_k) \\
\X{op}_{\FN}(z_1,\dots,z_k) &=& \xref{exec/numerics}{float-ops}{\F{f}\X{op}}_N(z_1,\dots,z_k) \\
\end{array}
And for :ref:`conversion operators <exec-cvtop>`:

.. math::
\begin{array}{lll@{\qquad}l}
\X{cvtop}^{\sx^?}_{t_1,t_2}(c) &=& \X{cvtop}^{\sx^?}_{|t_1|,|t_2|}(c) \\
\cvtop^{\sx^?}_{t_1,t_2}(c) &=& \xref{exec/numerics}{convert-ops}{\X{cvtop}}^{\sx^?}_{|t_1|,|t_2|}(c) \\
\end{array}
Where the underlying operators are partial, the corresponding instruction will :ref:`trap <trap>` when the result is not defined.
Expand Down Expand Up @@ -64,9 +63,9 @@ Where the underlying operators are non-deterministic, because they may return on

2. Pop the value :math:`t.\CONST~c_1` from the stack.

3. If :math:`\unop_t(c_1)` is defined, then:
3. If :math:`\unopF_t(c_1)` is defined, then:

a. Let :math:`c` be a possible result of computing :math:`\unop_t(c_1)`.
a. Let :math:`c` be a possible result of computing :math:`\unopF_t(c_1)`.

b. Push the value :math:`t.\CONST~c` to the stack.

Expand All @@ -77,9 +76,9 @@ Where the underlying operators are non-deterministic, because they may return on
.. math::
\begin{array}{lcl@{\qquad}l}
(t\K{.}\CONST~c_1)~t\K{.}\unop &\stepto& (t\K{.}\CONST~c)
& (\iff c \in \unop_t(c_1)) \\
& (\iff c \in \unopF_t(c_1)) \\
(t\K{.}\CONST~c_1)~t\K{.}\unop &\stepto& \TRAP
& (\iff \unop_{t}(c_1) = \{\})
& (\iff \unopF_{t}(c_1) = \{\})
\end{array}
Expand All @@ -94,9 +93,9 @@ Where the underlying operators are non-deterministic, because they may return on

3. Pop the value :math:`t.\CONST~c_1` from the stack.

4. If :math:`\binop_t(c_1, c_2)` is defined, then:
4. If :math:`\binopF_t(c_1, c_2)` is defined, then:

a. Let :math:`c` be a possible result of computing :math:`\binop_t(c_1, c_2)`.
a. Let :math:`c` be a possible result of computing :math:`\binopF_t(c_1, c_2)`.

b. Push the value :math:`t.\CONST~c` to the stack.

Expand All @@ -107,9 +106,9 @@ Where the underlying operators are non-deterministic, because they may return on
.. math::
\begin{array}{lcl@{\qquad}l}
(t\K{.}\CONST~c_1)~(t\K{.}\CONST~c_2)~t\K{.}\binop &\stepto& (t\K{.}\CONST~c)
& (\iff c \in \binop_t(c_1,c_2)) \\
& (\iff c \in \binopF_t(c_1,c_2)) \\
(t\K{.}\CONST~c_1)~(t\K{.}\CONST~c_2)~t\K{.}\binop &\stepto& \TRAP
& (\iff \binop_{t}(c_1,c_2) = \{\})
& (\iff \binopF_{t}(c_1,c_2) = \{\})
\end{array}
Expand All @@ -122,14 +121,14 @@ Where the underlying operators are non-deterministic, because they may return on

2. Pop the value :math:`t.\CONST~c_1` from the stack.

3. Let :math:`c` be the result of computing :math:`\testop_t(c_1)`.
3. Let :math:`c` be the result of computing :math:`\testopF_t(c_1)`.

4. Push the value :math:`\I32.\CONST~c` to the stack.

.. math::
\begin{array}{lcl@{\qquad}l}
(t\K{.}\CONST~c_1)~t\K{.}\testop &\stepto& (\I32\K{.}\CONST~c)
& (\iff c = \testop_t(c_1)) \\
& (\iff c = \testopF_t(c_1)) \\
\end{array}
Expand All @@ -144,14 +143,14 @@ Where the underlying operators are non-deterministic, because they may return on

3. Pop the value :math:`t.\CONST~c_1` from the stack.

4. Let :math:`c` be the result of computing :math:`\relop_t(c_1, c_2)`.
4. Let :math:`c` be the result of computing :math:`\relopF_t(c_1, c_2)`.

5. Push the value :math:`\I32.\CONST~c` to the stack.

.. math::
\begin{array}{lcl@{\qquad}l}
(t\K{.}\CONST~c_1)~(t\K{.}\CONST~c_2)~t\K{.}\relop &\stepto& (\I32\K{.}\CONST~c)
& (\iff c = \relop_t(c_1,c_2)) \\
& (\iff c = \relopF_t(c_1,c_2)) \\
\end{array}
Expand Down Expand Up @@ -280,20 +279,27 @@ Reference Instructions
Vector Instructions
~~~~~~~~~~~~~~~~~~~

Most vector instructions are defined in terms of generic numeric operators applied lane-wise based on the :ref:`shape <syntax-vec-shape>`.
Vector instructions that operate bitwise are handled as integer operations of respective width.

.. math::
\begin{array}{lll@{\qquad}l}
\X{op}_{\VN}(i_1,\dots,i_k) &=& \xref{exec/numerics}{int-ops}{\F{i}\X{op}}_N(i_1,\dots,i_k) \\
\end{array}
Most other vector instructions are defined in terms of numeric operators that are applied lane-wise according to the given :ref:`shape <syntax-vec-shape>`.

.. math::
\begin{array}{llll}
\X{op}_{t\K{x}N}(n_1,\dots,n_k) &=&
\lanes^{-1}_{t\K{x}N}(op_t(\lanes_{t\K{x}N}(n_1) ~\dots~ \lanes_{t\K{x}N}(n_k))
\lanes^{-1}_{t\K{x}N}(\xref{exec/instructions}{exec-instr-numeric}{\X{op}}_t(i_1,\dots,i_k)^\ast) & \qquad(\iff i_1^\ast = \lanes_{t\K{x}N}(n_1) \land \dots \land i_k^\ast = \lanes_{t\K{x}N}(n_k) \\
\end{array}
.. note::
For example, the result of instruction :math:`\K{i32x4}.\ADD` applied to operands :math:`i_1, i_2`
invokes :math:`\ADD_{\K{i32x4}}(i_1, i_2)`, which maps to
:math:`\lanes^{-1}_{\K{i32x4}}(\ADD_{\I32}(i_1^+, i_2^+))`,
where :math:`i_1^+` and :math:`i_2^+` are sequences resulting from invoking
:math:`\lanes_{\K{i32x4}}(i_1)` and :math:`\lanes_{\K{i32x4}}(i_2)`
For example, the result of instruction :math:`\K{i32x4}.\ADD` applied to operands :math:`v_1, v_2`
invokes :math:`\ADD_{\K{i32x4}}(v_1, v_2)`, which maps to
:math:`\lanes^{-1}_{\K{i32x4}}(\ADD_{\I32}(i_1, i_2)^\ast)`,
where :math:`i_1^\ast` and :math:`i_2^\ast` are sequences resulting from invoking
:math:`\lanes_{\K{i32x4}}(v_1)` and :math:`\lanes_{\K{i32x4}}(v_2)`
respectively.


Expand Down Expand Up @@ -531,31 +537,31 @@ Most vector instructions are defined in terms of generic numeric operators appli

1. Assert: due to :ref:`validation <valid-vec-replace_lane>`, :math:`x < \dim(\shape)`.

2. Let :math:`t_1` be the type :math:`\unpacked(\shape)`.
2. Let :math:`t_2` be the type :math:`\unpacked(\shape)`.

3. Assert: due to :ref:`validation <valid-vec-replace_lane>`, a value of :ref:`value type <syntax-valtype>` :math:`t_1` is on the top of the stack.

4. Pop the value :math:`t_1.\CONST~c_1` from the stack.
4. Pop the value :math:`t_2.\CONST~c_2` from the stack.

5. Assert: due to :ref:`validation <valid-vec-replace_lane>`, a value of :ref:`value type <syntax-valtype>` |V128| is on the top of the stack.

6. Pop the value :math:`\V128.\VCONST~c_2` from the stack.
6. Pop the value :math:`\V128.\VCONST~c_1` from the stack.

7. Let :math:`i^\ast` be the result of computing :math:`\lanes_{\shape}(c_2)`.
7. Let :math:`i^\ast` be the result of computing :math:`\lanes_{\shape}(c_1)`.

8. Let :math:`c` be the result of computing :math:`\lanes^{-1}_{\shape}(i^\ast \with [x] = c_1)`.
8. Let :math:`c` be the result of computing :math:`\lanes^{-1}_{\shape}(i^\ast \with [x] = c_2)`.

9. Push :math:`\V128.\VCONST~c` on the stack.

.. math::
\begin{array}{l}
\begin{array}{lcl@{\qquad}l}
(t_1\K{.}\CONST~c_1)~(\V128\K{.}\VCONST~c_2)~(\shape\K{.}\REPLACELANE~x) &\stepto& (\V128\K{.}\VCONST~c)
(\V128\K{.}\VCONST~c_1)~(t_2\K{.}\CONST~c_2)~(\shape\K{.}\REPLACELANE~x) &\stepto& (\V128\K{.}\VCONST~c)
\end{array}
\\ \qquad
\begin{array}[t]{@{}r@{~}l@{}}
(\iff & i^\ast = \lanes_{\shape}(c_2) \\
\wedge & c = \lanes^{-1}_{\shape}(i^\ast \with [x] = c_1))
(\iff & i^\ast = \lanes_{\shape}(c_1) \\
\wedge & c = \lanes^{-1}_{\shape}(i^\ast \with [x] = c_2))
\end{array}
\end{array}
Expand Down Expand Up @@ -687,9 +693,9 @@ Most vector instructions are defined in terms of generic numeric operators appli

1. Assert: due to :ref:`validation <valid-vtestop>`, a value of :ref:`value type <syntax-valtype>` |V128| is on the top of the stack.

2. Pop the value :math:`\V128.\VCONST~c_1` from the stack.
2. Pop the value :math:`\V128.\VCONST~c` from the stack.

3. Let :math:`i_1^\ast` be the result of computing :math:`\lanes_{\shape}(c_1)`.
3. Let :math:`i_1^\ast` be the result of computing :math:`\lanes_{\shape}(c)`.

4. Let :math:`i` be the result of computing :math:`\bool(\bigwedge(i_1 \neq 0)^\ast)`.

Expand All @@ -699,7 +705,7 @@ Most vector instructions are defined in terms of generic numeric operators appli
.. math::
\begin{array}{l}
\begin{array}{lcl@{\qquad}l}
(\V128\K{.}\VCONST~c_1)~\shape\K{.}\ALLTRUE &\stepto& (\I32\K{.}\CONST~i)
(\V128\K{.}\VCONST~c)~\shape\K{.}\ALLTRUE &\stepto& (\I32\K{.}\CONST~i)
\end{array}
\\ \qquad
\begin{array}[t]{@{}r@{~}l@{}}
Expand All @@ -716,7 +722,7 @@ Most vector instructions are defined in terms of generic numeric operators appli

1. Assert: due to :ref:`validation <valid-vec-bitmask>`, a value of :ref:`value type <syntax-valtype>` |V128| is on the top of the stack.

2. Pop the value :math:`\V128.\VCONST~c_1` from the stack.
2. Pop the value :math:`\V128.\VCONST~c` from the stack.

3. Let :math:`i_1^N` be the result of computing :math:`\lanes_{t\K{x}N}(c)`.

Expand All @@ -726,14 +732,14 @@ Most vector instructions are defined in terms of generic numeric operators appli

6. Let :math:`j^\ast` be the concatenation of the two sequences :math:`i_2^N` and :math:`0^{32-N}`.

7. Let :math:`c` be the result of computing :math:`\ibits_{32}^{-1}(j^\ast)`.
7. Let :math:`i` be the result of computing :math:`\ibits_{32}^{-1}(j^\ast)`.

8. Push the value :math:`\I32.\CONST~c` onto the stack.
8. Push the value :math:`\I32.\CONST~i` onto the stack.

.. math::
\begin{array}{lcl@{\qquad}l}
(\V128\K{.}\VCONST~c_1)~t\K{x}N\K{.}\BITMASK &\stepto& (\I32\K{.}\CONST~c)
& (\iff c = \ibits_{32}^{-1}(\ilts_{|t|}(\lanes_{t\K{x}N}(c), 0^N)))
(\V128\K{.}\VCONST~c)~t\K{x}N\K{.}\BITMASK &\stepto& (\I32\K{.}\CONST~i)
& (\iff i = \ibits_{32}^{-1}(\ilts_{|t|}(\lanes_{t\K{x}N}(c), 0^N)))
\\
\end{array}
Expand Down Expand Up @@ -855,8 +861,8 @@ where:
\end{array}
:math:`t_2\K{x}N\K{.}\vcvtop\K{\_}t_1\K{x}M\K{\_}\sx\K{\_zero}`
...............................................................
:math:`t_2\K{x}N\K{.}\vcvtop\K{\_}t_1\K{x}M\K{\_}\sx^?\K{\_zero}`
.................................................................

1. Assert: due to :ref:`syntax <syntax-instr-vec>`, :math:`N = 2 \cdot M`.

Expand All @@ -866,7 +872,7 @@ where:

4. Let :math:`i^\ast` be the result of computing :math:`\lanes_{t_1\K{x}M}(c_1)`.

5. Let :math:`j^\ast` be the result of computing :math:`\vcvtop^{\sx}_{|t_1|,|t_2|}(i^\ast)`.
5. Let :math:`j^\ast` be the result of computing :math:`\vcvtop^{\sx^?}_{|t_1|,|t_2|}(i^\ast)`.

6. Let :math:`k^\ast` be the concatenation of the two sequences :math:`j^\ast` and :math:`0^M`.

Expand All @@ -877,11 +883,11 @@ where:
.. math::
\begin{array}{l}
\begin{array}{lcl@{\qquad}l}
(\V128\K{.}\VCONST~c_1)~t_2\K{x}N\K{.}\vcvtop\K{\_}t_1\K{x}M\K{\_}\sx\K{\_zero} &\stepto& (\V128\K{.}\VCONST~c) \\
(\V128\K{.}\VCONST~c_1)~t_2\K{x}N\K{.}\vcvtop\K{\_}t_1\K{x}M\K{\_}\sx^?\K{\_zero} &\stepto& (\V128\K{.}\VCONST~c) \\
\end{array}
\\ \qquad
\begin{array}[t]{@{}r@{~}l@{}}
(\iff & c = \lanes^{-1}_{t_2\K{x}N}(\vcvtop^{\sx}_{|t_1|,|t_2|}(\lanes_{t_1\K{x}M}(c_1))~0^M))
(\iff & c = \lanes^{-1}_{t_2\K{x}N}(\vcvtop^{\sx^?}_{|t_1|,|t_2|}(\lanes_{t_1\K{x}M}(c_1))~0^M))
\end{array}
\end{array}
Expand Down Expand Up @@ -960,7 +966,7 @@ where:

10. Let :math:`k_2^\ast` be the result of computing :math:`\extend^{\sx}_{|t_1|,|t_2|}(j_2^\ast)`.

11. Let :math:`k^\ast` be the result of computing :math:`\imul_{t_2\K{x}N}(k_1^\ast, k_2^\ast)`.
11. Let :math:`k^\ast` be the result of computing :math:`\imul_{|t_2|}(k_1^\ast, k_2^\ast)`.

12. Let :math:`c` be the result of computing :math:`\lanes^{-1}_{t_2\K{x}N}(k^\ast)`.

Expand All @@ -974,7 +980,7 @@ where:
\begin{array}[t]{@{}r@{~}l@{}}
(\iff & i^\ast = \lanes_{t_1\K{x}M}(c_1)[\half(0, N) \slice N] \\
\wedge & j^\ast = \lanes_{t_1\K{x}M}(c_2)[\half(0, N) \slice N] \\
\wedge & c = \lanes^{-1}_{t_2\K{x}N}(\imul_{t_2\K{x}N}(\extend^{\sx}_{|t_1|,|t_2|}(i^\ast), \extend^{\sx}_{|t_1|,|t_2|}(j^\ast))))
\wedge & c = \lanes^{-1}_{t_2\K{x}N}(\imul_{|t_2|}(\extend^{\sx}_{|t_1|,|t_2|}(i^\ast), \extend^{\sx}_{|t_1|,|t_2|}(j^\ast))))
\end{array}
where:
Expand All @@ -1001,7 +1007,7 @@ where:

5. Let :math:`(j_1~j_2)^\ast` be the result of computing :math:`\extend^{\sx}_{|t_1|,|t_2|}(i^\ast)`.

6. Let :math:`k^\ast` be the result of computing :math:`\iadd_{N}(j_1, j_2)^\ast`.
6. Let :math:`k^\ast` be the result of computing :math:`\iadd_{|t_2|}(j_1, j_2)^\ast`.

7. Let :math:`c` be the result of computing :math:`\lanes^{-1}_{t_2\K{x}N}(k^\ast)`.

Expand All @@ -1015,7 +1021,7 @@ where:
\\ \qquad
\begin{array}[t]{@{}r@{~}l@{}}
(\iff & (i_1~i_2)^\ast = \extend^{\sx}_{|t_1|,|t_2|}(\lanes_{t_1\K{x}M}(c_1)) \\
\wedge & j^\ast = \iadd_{N}(i_1, i_2)^\ast \\
\wedge & j^\ast = \iadd_{|t_2|}(i_1, i_2)^\ast \\
\wedge & c = \lanes^{-1}_{t_2\K{x}N}(j^\ast))
\end{array}
\end{array}
Expand Down
4 changes: 4 additions & 0 deletions document/core/exec/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,10 @@ Once the function has returned, the following steps are executed:

2. Pop :math:`\val_{\F{res}}^m` from the stack.

3. Assert: due to :ref:`validation <valid-module>`, the frame :math:`F` is now on the top of the stack.

4. Pop the frame :math:`F` from the stack.

The values :math:`\val_{\F{res}}^m` are returned as the results of the invocation.

.. math::
Expand Down
23 changes: 13 additions & 10 deletions document/core/exec/numerics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -169,24 +169,25 @@ where :math:`M = \significand(N)` and :math:`E = \exponent(N)`.
Vectors
.......

Numeric vectors have the same underlying representation as an |i128|.
They can also be interpreted as a sequence of numeric values packed into a |V128| with a particular |shape|.
Numeric vectors of type |VN| have the same underlying representation as an |IN|.
They can also be interpreted as a sequence of numeric values packed into a |VN| with a particular |shape| :math:`t\K{x}M`,
provided that :math:`N = |t|\cdot M`.

.. math::
\begin{array}{l}
\begin{array}{lll@{\qquad}l}
\lanes_{t\K{x}N}(c) &=&
c_0~\dots~c_{N-1} \\
\lanes_{t\K{x}M}(c) &=&
c_0~\dots~c_{M-1} \\
\end{array}
\\ \qquad
\begin{array}[t]{@{}r@{~}l@{}l@{~}l@{~}l}
(\where & B &=& |t| / 8 \\
\wedge & b^{16} &=& \bytes_{\i128}(c) \\
\wedge & c_i &=& \bytes_{t}^{-1}(b^{16}[i \cdot B \slice B]))
(\where & w &=& |t| / 8 \\
\wedge & b^\ast &=& \bytes_{\IN}(c) \\
\wedge & c_i &=& \bytes_{t}^{-1}(b^\ast[i \cdot w \slice w]))
\end{array}
\end{array}
These functions are bijections, so they are invertible.
This function is a bijection on |IN|, hence it is invertible.


.. index:: byte, little endian, memory
Expand Down Expand Up @@ -715,11 +716,13 @@ The integer result of predicates -- i.e., :ref:`tests <syntax-testop>` and :ref:
:math:`\iextendMs_N(i)`
.......................

* Return :math:`\extends_{M,N}(i)`.
* Let :math:`j` be the result of computing :math:`\wrap_{N,M}(i)`.

* Return :math:`\extends_{M,N}(j)`.

.. math::
\begin{array}{lll@{\qquad}l}
\iextendMs_{N}(i) &=& \extends_{M,N}(i) \\
\iextendMs_{N}(i) &=& \extends_{M,N}(\wrap_{N,M}(i)) \\
\end{array}
Expand Down
Loading

0 comments on commit 4c02753

Please sign in to comment.