add ls001.po9 RFC
[libreriscv.git] / openpower / sv / mv.vec.mdwn
index e7f315a111895931cfbebaf447f35e2fa904ea66..9190fcdc7dc81f06a23b9c44da96422fd105d825 100644 (file)
 [[!tag standards]]
 
-# Vector mv operations
+# Vector Pack/Unpack operations
 
-In the SIMD VSX set, section 6.8.1 and 6.8.2 p254 of v3.0B has a series of pack and unpack operations. This page covers those and more.  [[svp64]] provides the Vector Context to also add saturation as well as predication.
+In the SIMD VSX set, section 6.8.1 and 6.8.2 p254 of v3.0B has a series of pack and unpack operations. Additional pixel pack/unpack instructions
+also exist.
 
-See <https://bugs.libre-soc.org/show_bug.cgi?id=230#c30>
+In SVP64, Pack and Unpack are achieved *in the abstract* for application on *all*
+Vectoriseable instructions.
 
-Note that some of these may be covered by [[remap]].
+* See <https://bugs.libre-soc.org/show_bug.cgi?id=230#c30>
+* <https://lists.libre-soc.org/pipermail/libre-soc-dev/2022-June/004911.html>
 
-# move to/from vec2/3/4
-
-Basic idea: mv operations where either the src or dest is specifically marked as having SUBVL apply to it, but, crucially, the *other* argument does *not*. Note that this is highly unusual in SimpleV, which normally only allows SUBVL to be applied uniformly across all dest and all src.
-
-     mv.srcvec  r3, r4.vec2
-     mv.destvec r2.vec4, r5
-
-TODO: evaluate whether this will fit with [[mv.swizzle]] involved as well
-(yes it probably will)
-
-* M=0 is mv.srcvec
-* M=1 is mv.destvec
-
-mv.srcvec (leaving out elwidths and chop):
-
-    for i in range(VL):
-        regs[rd+i] = regs[rs+i*SUBVL]
-
-mv.destvec (leaving out elwidths and chop):
-
-    for i in range(VL):
-        regs[rd+i*SUBVL] = regs[rs+i]
-
-Note that these mv operations only become significant when elwidth is set on the vector to a small value.  SUBVL=4, src elwidth=8, dest elwidth=32 for example.
-
-intended to cover:
-
-    rd = (rs >> 0 * 8) & (2^8 - 1)
-    rd+1 = (rs >> 1 * 8) & (2^8 - 1)
-    rd+2 = (rs >> 2 * 8) & (2^8 - 1)
-    rd+3 = (rs >> 3 * 8) & (2^8 - 1)
-
-and variants involving vec3 into 32 bit (4th byte set to zero).
-TODO: include this pseudocode which shows how the vecN can do that.
-in this example RA elwidth=32 and RB elwidth=8, RB is a vec4.
-
-    for i in range(VL):
-         if predicate_bit_not_set(i) continue
-         uint8_t *start_point = (uint8_t*)(int_regfile[RA].i[i])
-         for j in range(SUBVL): # vec4
-              start_point[j] = some_op(int_regfile[RB].b[i*SUBVL + j])
-
-## Twin Predication, saturation, swizzle, and elwidth overrides
-
-Note that mv is a twin-predicated operation, and is swizzlable.  This implies that from the vec2, vec3 or vec4, 1 to 8 bytes may be selected and re-ordered (XYZW), mixed with 0 and 1 constants, skipped by way of twin predicate pack and unpack, and a huge amount besides.
-
-Also saturation can be applied to individual elements, including the elements within a vec2/3/4.
-
-# mv.zip and unzip
-
-These are Scalar equivalents to VSX Pack and Unpack: v3.1
-Book I Section 6.8 p278.  Saturated variants do not need
-adding because SVP64 overrides add Saturation already.
-More detailed merging may be achieved with [[sv/bitmanip]]
-instructions.
-
-| 0.5 |6.10|11.15|16..20|21..25|26.....30|31|  name        |
-|-----|----|-----|------|------|---------|--|--------------|
-| 19  | RTp| RC  | RB/0 | RA/0 | XO[5:9] |Rc| mv.zip       |
-| 19  | RT | RC  | RS/0 | RA/0 | XO[5:9] |Rc| mv.unzip     |
-
-these are specialist operations that zip or unzip to/from multiple regs to/from one vector including vec2/3/4. when SUBVL!=1 the vec2/3/4 is the contiguous unit that is copied (as if one register).  different elwidths result in zero-extension or truncation except if saturation is enabled, where signed/unsigned may be applied as usual.
-
-mv.zip, RA=0, RB=0
-
-    for i in range(VL):
-        regs[rt+i] = regs[rc+i]
-
-mv.zip, RA=0, RB!=0
-
-    for i in range(VL):
-        regs[rt+i*2  ] = regs[rb+i]
-        regs[rt+i*2+1] = regs[rc+i]
-
-mv.zip, RA!=0, RB!=0
-
-    for i in range(VL):
-        regs[rt+i*3  ] = regs[rb+i]
-        regs[rt+i*3+1] = regs[rc+i]
-        regs[rt+i*3+2] = regs[ra+i]
-
-# REMAP concept for pack/unpack
-
-It may be possible to use one standard mv instruction to perform packing
-and unpacking: Matrix allows for both reordering and offsets. At the very least a predicate mask potentially can
-be used.
-
-* If a single src-dest mv is used, then it potentially requires
-  two separate REMAP and two separate sv.mvs: remap-even, sv.mv,
-  remap-odd, sv.mv
-* If adding twin-src and twin-dest that is a lot of instructions,
-  particularly if triple is added as well. FPR mv, GPR mv
-* Unless twin or triple is added, how is it possible to determine
-  the extra register(s) to be merged (or split)?
-
-How about instead relying on the implicit RS=MAXVL+RT trick and
-extending that to RS=MAXVL+RA as a source?  One spare bit in the
-EXTRA RM area says whether the sv.mv is a pack (RS-as-src=RA+MAXVL)
-or unpack (RS-as-dest=RT+MAXVL)
-
-Alternatively, given that Matrix is up to 3 Dimensions, not even
-be concerned about RS, just simply use one of those dimensions to
-span the packing:
-
-Example 1:
-
-* RA set to linear
-* RT set to YX, ydim=2, xdim=4
-* VL=MAXVL=8
-
-The indices match up as follows:
-
-    | RA | (0 1) (2 3) (4 5) (6 7) |
-    | RT |   0 2 4 8     1 3 5 7   |
-
-This results in a 2-element "unpack"
-
-Example 2:
-
-* RT set to linear
-* RT set to YX, ydim=3, xdim=3
-* VL=MAXVL=9
-
-The indices match up as follows:
-
-    | RA |  0 1 2   3 4 5   6 7 8  |
-    | RT | (0 3 6) (1 4 7) (2 5 8) |
-
-This results in a 3-element "pack"
-
-Both examples become particularly fun when Twin Predication is thrown
-into the mix.
+The effect of Pack and unpack could be covered by [[sv/remap]] by using Matrix 2D layouts on either source or destination but is quite expensive to do so.  Additionally,
+with pressure on the Scalar 32-bit opcode space it is more appropriate to
+compromise by adding required capability in SVP64 as a high priority
+(part of the Management Instructions).  [[sv/mv.swizzle]] is sufficiently
+unusual to justify a base Scalar 32-bit instruction but pack/unpack is not.
+What, ultimately, was decided, was to make Pack/Unpack part of the
+`SVSTATE` [[sv/spr]].
 
+# SVSTATE Pack/unpack Mode bits
 
+Described in [[svp64/appendix]] the Pack/Unpack Modes allow selective
+Transposition of Sub-vector elements, on both source and destination.
+[[sv/mv.swizzle]] is unique in that the Subvector length may be different
+for source and destination.