From 56496c875de59b736d6bbaaa2d4e77b0cc4a61ba Mon Sep 17 00:00:00 2001 From: Ng Zhi An Date: Wed, 22 Jul 2020 09:36:03 -0700 Subject: [PATCH] Add syntax for SIMD instructions --- document/core/syntax/instructions.rst | 152 ++++++++++++++++++++++++-- document/core/util/macros.def | 22 ++++ 2 files changed, 165 insertions(+), 9 deletions(-) diff --git a/document/core/syntax/instructions.rst b/document/core/syntax/instructions.rst index 4a21904f7..ad8381577 100644 --- a/document/core/syntax/instructions.rst +++ b/document/core/syntax/instructions.rst @@ -35,6 +35,16 @@ The following sections group instructions into a number of different categories. .. _syntax-fbinop: .. _syntax-ftestop: .. _syntax-frelop: +.. _syntax-vunop: +.. _syntax-vbinop: +.. _syntax-vternop: +.. _syntax-vtestop: +.. _syntax-vshiftop: +.. _syntax-viunop: +.. _syntax-vibinop: +.. _syntax-vsatbinop: +.. _syntax-vfunop: +.. _syntax-vfbinop: .. _syntax-instr-numeric: Numeric Instructions @@ -47,15 +57,27 @@ These operations closely match respective operations available in hardware. \begin{array}{llcl} \production{width} & \X{nn}, \X{mm} &::=& \K{32} ~|~ \K{64} \\ + \production{simdwidth} & \X{sss} &::=& + \K{128} \\ \production{signedness} & \sx &::=& \K{u} ~|~ \K{s} \\ + \production{ishape} & \X{ixx} &::=& + \K{i8x16} ~|~ \K{i16x8} ~|~ \K{i32x4} ~|~ \K{i64x2} \\ + \production{fshape} & \X{fxx} &::=& + \K{f32x4} ~|~ \K{f64x2} \\ + \production{vshape} & \X{vxx} &::=& + \X{ixx} ~|~ \X{fxx} \\ \production{instruction} & \instr &::=& \K{i}\X{nn}\K{.}\CONST~\xref{syntax/values}{syntax-int}{\iX{\X{nn}}} ~|~ - \K{f}\X{nn}\K{.}\CONST~\xref{syntax/values}{syntax-float}{\fX{\X{nn}}} \\&&|& + \K{f}\X{nn}\K{.}\CONST~\xref{syntax/values}{syntax-float}{\fX{\X{nn}}} ~|~ + \K{v}\X{sss}\K{.}\CONST~\xref{syntax/values}{syntax-simd}{\vX{\X{sss}}} \\&&|& \K{i}\X{nn}\K{.}\iunop ~|~ - \K{f}\X{nn}\K{.}\funop \\&&|& + \K{f}\X{nn}\K{.}\funop ~|~ + \K{v}\X{sss}\K{.}\vunop \\&&|& \K{i}\X{nn}\K{.}\ibinop ~|~ - \K{f}\X{nn}\K{.}\fbinop \\&&|& + \K{f}\X{nn}\K{.}\fbinop ~|~ + \K{v}\X{sss}\K{.}\vbinop \\&&|& + \K{v}\X{sss}\K{.}\vternop \\&&|& \K{i}\X{nn}\K{.}\itestop \\&&|& \K{i}\X{nn}\K{.}\irelop ~|~ \K{f}\X{nn}\K{.}\frelop \\&&|& @@ -71,6 +93,49 @@ These operations closely match respective operations available in hardware. \K{f}\X{nn}\K{.}\CONVERT\K{\_i}\X{mm}\K{\_}\sx \\&&|& \K{i}\X{nn}\K{.}\REINTERPRET\K{\_f}\X{nn} ~|~ \K{f}\X{nn}\K{.}\REINTERPRET\K{\_i}\X{nn} \\&&|& + \K{v8x16.}\SHUFFLE ~|~ \K{v8x16.}\SWIZZLE \\&&|& + \X{vxx}\K{.}\SPLAT \\&&|& + \K{i8x16.}\EXTRACTLANE\K{\_}\sx ~|~ + \K{i16x8.}\EXTRACTLANE\K{\_}\sx \\&&|& + \K{i32x4.}\EXTRACTLANE ~|~ + \K{i64x2.}\EXTRACTLANE \\&&|& + \X{fxx}\K{.}\EXTRACTLANE \\&&|& + \X{vxx}\K{.}\REPLACELANE \\&&|& + \X{ixx}\K{.}\irelop \\&&|& + \X{fxx}\K{.}\frelop \\&&|& + \K{i8x16.}\viunop ~|~ + \K{i16x8.}\viunop ~|~ + \K{i32x4.}\viunop \\&&|& + \K{i64x2.}\NEG \\&&|& + \X{fxx.}\vfunop \\&&|& + \K{i8x16.}\vtestop ~|~ + \K{i16x8.}\vtestop ~|~ + \K{i32x4.}\vtestop \\&&|& + \K{i8x16.}\BITMASK ~|~ + \K{i16x8.}\BITMASK ~|~ + \K{i32x4.}\BITMASK \\&&|& + \K{i8x16.}\NARROW\K{\_i16x8\_}\sx ~|~ + \K{i16x8.}\NARROW\K{\_i32x4\_}\sx \\&&|& + \K{i16x8.}\WIDEN\K{\_low}\K{\_i8x16\_}\sx ~|~ + \K{i32x4.}\WIDEN\K{\_low}\K{\_i16x8\_}\sx \\&&|& + \K{i16x8.}\WIDEN\K{\_high}\K{\_i8x16\_}\sx ~|~ + \K{i32x4.}\WIDEN\K{\_high}\K{\_i16x8\_}\sx \\&&|& + \X{ixx}\K{.}\vshiftop \\&&|& + \K{i8x16.}\vibinop ~|~ + \K{i16x8.}\vibinop ~|~ + \K{i32x4.}\vibinop \\&&|& + \K{i64x2.}\ADD ~|~ + \K{i64x2.}\SUB \\&&|& + \K{i8x16.}\vsatbinop ~|~ + \K{i16x8.}\vsatbinop \\&&|& + \K{i16x8.}\K{mul} ~|~ + \K{i32x4.}\K{mul} ~|~ + \K{i64x2.}\K{mul} \\&&|& + \K{i8x16.}\AVGRU ~|~ + \K{i16x8.}\AVGRU \\&&|& + \X{fxx.}\vfbinop \\&&|& + \K{i32x4.}\TRUNC\K{\_sat\_f32x4\_}\sx ~|~ + \K{f32x4.}\CONVERT\K{\_i32x4\_}\sx \\&&|& \dots \\ \production{integer unary operator} & \iunop &::=& \K{clz} ~|~ @@ -105,8 +170,20 @@ These operations closely match respective operations available in hardware. \K{min} ~|~ \K{max} ~|~ \K{copysign} \\ + \production{SIMD unary operator} & \vunop &::=& + \K{not} \\ + \production{SIMD binary operator} & \vbinop &::=& + \K{and} ~|~ + \K{andnot} ~|~ + \K{or} ~|~ + \K{xor} \\ + \production{SIMD unary operator} & \vternop &::=& + \K{bitselect} \\ \production{integer test operator} & \itestop &::=& \K{eqz} \\ + \production{SIMD test operator} & \vtestop &::=& + \K{any\_true} ~|~ + \K{all\_true} \\ \production{integer relational operator} & \irelop &::=& \K{eq} ~|~ \K{ne} ~|~ @@ -121,6 +198,32 @@ These operations closely match respective operations available in hardware. \K{gt} ~|~ \K{le} ~|~ \K{ge} \\ + \production{SIMD integer shift operator} & \vshiftop &::=& + \K{shl} ~|~ + \K{shr\_s} ~|~ + \K{shr\_u} \\ + \production{SIMD integer unary operator} & \viunop &::=& + \K{abs} ~|~ + \K{neg} \\ + \production{SIMD integer binary operator} & \vibinop &::=& + \K{add} ~|~ + \K{sub} ~|~ + \K{min\_}\sx ~|~ + \K{max\_}\sx \\ + \production{SIMD integer saturating binary operator} & \vsatbinop &::=& + \K{add\_sat\_}\sx ~|~ + \K{sub\_sat\_}\sx \\ + \production{SIMD floating-point unary operator} & \vfunop &::=& + \K{abs} ~|~ + \K{neg} ~|~ + \K{sqrt} \\ + \production{SIMD floating-point binary operator} & \vfbinop &::=& + \K{add} ~|~ + \K{sub} ~|~ + \K{mul} ~|~ + \K{div} ~|~ + \K{min} ~|~ + \K{max} \\ \end{array} Numeric instructions are divided by :ref:`value type `. @@ -134,15 +237,25 @@ For each type, several subcategories can be distinguished: * *Tests*: consume one operand of the respective type and produce a Boolean integer result. -* *Comparisons*: consume two operands of the respective type and produce a Boolean integer result. +* *Comparisons*: consume two operands of the respective type and produce a Boolean integer result or a result of the respective type. * *Conversions*: consume a value of one type and produce a result of another (the source type of the conversion is the one after the ":math:`\K{\_}`"). +.. todo:: + Do these subcategories have to cover every instruction? E.g. simd shifts don't fit anywhere here, since they take 128-bit int and a 32-bit int. + Some integer instructions come in two flavors, where a signedness annotation |sx| distinguishes whether the operands are to be :ref:`interpreted ` as :ref:`unsigned ` or :ref:`signed ` integers. For the other integer instructions, the use of two's complement for the signed interpretation means that they behave the same regardless of signedness. +Instructions that operate on |V128| operands have a naming convention that +determines how those operands will be interpreted. An instruction beginning with :math:`\K{i32x4}` +will interpret its operands as four |i32|, packed side-by-side into a |i128|. +Similarly, and instruction beginning with :math:`\K{f64x2}` interprets its operands as two |f64|, packed side-by-side into a |i128|. + +.. todo:: + write up runtime interpretation for the lane shapes Conventions ........... @@ -154,9 +267,22 @@ Occasionally, it is convenient to group operators together according to the foll \production{unary operator} & \unop &::=& \iunop ~|~ \funop ~|~ + \vunop ~|~ + \viunop ~|~ + \vfunop ~|~ \EXTEND{N}\K{\_s} \\ - \production{binary operator} & \binop &::=& \ibinop ~|~ \fbinop \\ - \production{test operator} & \testop &::=& \itestop \\ + \production{binary operator} & \binop &::=& + \ibinop ~|~ + \fbinop ~|~ + \vbinop ~|~ + \vibinop ~|~ + \vsatbinop ~|~ + \vfbinop ~|~ + \AVGRU + \\ + \production{test operator} & \testop &::=& + \itestop ~|~ + \vtestop \\ \production{relational operator} & \relop &::=& \irelop ~|~ \frelop \\ \production{conversion operator} & \cvtop &::=& \WRAP ~|~ @@ -166,7 +292,9 @@ Occasionally, it is convenient to group operators together according to the foll \CONVERT ~|~ \DEMOTE ~|~ \PROMOTE ~|~ - \REINTERPRET \\ + \REINTERPRET ~|~ + \NARROW ~|~ + \WIDEN \\ \end{array} @@ -235,15 +363,21 @@ Instructions in this group are concerned with linear :ref:`memory `. \production{instruction} & \instr &::=& \dots \\&&|& \K{i}\X{nn}\K{.}\LOAD~\memarg ~|~ - \K{f}\X{nn}\K{.}\LOAD~\memarg \\&&|& + \K{f}\X{nn}\K{.}\LOAD~\memarg ~|~ + \K{v}\X{sss}\K{.}\LOAD~\memarg \\&&|& \K{i}\X{nn}\K{.}\STORE~\memarg ~|~ - \K{f}\X{nn}\K{.}\STORE~\memarg \\&&|& + \K{f}\X{nn}\K{.}\STORE~\memarg ~|~ + \K{v}\X{sss}\K{.}\STORE~\memarg \\&&|& \K{i}\X{nn}\K{.}\LOAD\K{8\_}\sx~\memarg ~|~ \K{i}\X{nn}\K{.}\LOAD\K{16\_}\sx~\memarg ~|~ \K{i64.}\LOAD\K{32\_}\sx~\memarg \\&&|& \K{i}\X{nn}\K{.}\STORE\K{8}~\memarg ~|~ \K{i}\X{nn}\K{.}\STORE\K{16}~\memarg ~|~ \K{i64.}\STORE\K{32}~\memarg \\&&|& + \K{i16x8.}\LOAD\K{8x8}\_\sx ~|~ + \K{i32x4.}\LOAD\K{16x4}\_\sx ~|~ + \K{i64x2.}\LOAD\K{32x2}\_\sx \\&&|& + \K{v}\X{ixx}\K{.}\LOAD\K{\_splat} \\&&|& \MEMORYSIZE \\&&|& \MEMORYGROW \\ \end{array} diff --git a/document/core/util/macros.def b/document/core/util/macros.def index 8bd8a0caa..869644386 100644 --- a/document/core/util/macros.def +++ b/document/core/util/macros.def @@ -129,6 +129,7 @@ .. |sX#1| mathdef:: {\X{s#1}} .. |iX#1| mathdef:: {\X{i#1}} .. |fX#1| mathdef:: {\X{f#1}} +.. |vX#1| mathdef:: {\X{v#1}} .. |uN| mathdef:: \xref{syntax/values}{syntax-int}{\X{u}N} .. |uM| mathdef:: \xref{syntax/values}{syntax-int}{\X{u}M} @@ -378,6 +379,16 @@ .. |DEMOTE| mathdef:: \xref{syntax/instructions}{syntax-instr-numeric}{\K{demote}} .. |REINTERPRET| mathdef:: \xref{syntax/instructions}{syntax-instr-numeric}{\K{reinterpret}} +.. |SHUFFLE| mathdef:: \xref{syntax/instructions}{syntax-instr-numeric}{\K{shuffle}} +.. |SWIZZLE| mathdef:: \xref{syntax/instructions}{syntax-instr-numeric}{\K{swizzle}} +.. |SPLAT| mathdef:: \xref{syntax/instructions}{syntax-instr-numeric}{\K{splat}} +.. |EXTRACTLANE| mathdef:: \xref{syntax/instructions}{syntax-instr-numeric}{\K{extract\_lane}} +.. |REPLACELANE| mathdef:: \xref{syntax/instructions}{syntax-instr-numeric}{\K{replace\_lane}} +.. |BITMASK| mathdef:: \xref{syntax/instructions}{syntax-instr-numeric}{\K{bitmask}} +.. |NARROW| mathdef:: \xref{syntax/instructions}{syntax-instr-numeric}{\K{narrow}} +.. |WIDEN| mathdef:: \xref{syntax/instructions}{syntax-instr-numeric}{\K{widen}} +.. |AVGRU| mathdef:: \xref{syntax/instructions}{syntax-instr-numeric}{\K{avgr\_u}} + .. Instructions, non-terminals @@ -397,6 +408,17 @@ .. |ftestop| mathdef:: \xref{syntax/instructions}{syntax-ftestop}{\X{ftestop}} .. |frelop| mathdef:: \xref{syntax/instructions}{syntax-frelop}{\X{frelop}} +.. |vunop| mathdef:: \xref{syntax/instructions}{syntax-vunop}{\X{vunop}} +.. |vbinop| mathdef:: \xref{syntax/instructions}{syntax-vbinop}{\X{vbinop}} +.. |vternop| mathdef:: \xref{syntax/instructions}{syntax-vternop}{\X{vternop}} +.. |vtestop| mathdef:: \xref{syntax/instructions}{syntax-vtestop}{\X{vtestop}} +.. |vshiftop| mathdef:: \xref{syntax/instructions}{syntax-vshiftop}{\X{vshiftop}} +.. |viunop| mathdef:: \xref{syntax/instructions}{syntax-viunop}{\X{viunop}} +.. |vibinop| mathdef:: \xref{syntax/instructions}{syntax-vibinop}{\X{vibinop}} +.. |vsatbinop| mathdef:: \xref{syntax/instructions}{syntax-vsatbinop}{\X{vsatbinop}} +.. |vfunop| mathdef:: \xref{syntax/instructions}{syntax-vfunop}{\X{vfunop}} +.. |vfbinop| mathdef:: \xref{syntax/instructions}{syntax-vfbinop}{\X{vfbinop}} + .. |sx| mathdef:: \xref{syntax/instructions}{syntax-sx}{\X{sx}} .. |memarg| mathdef:: \xref{syntax/instructions}{syntax-memarg}{\X{memarg}}