shorten words
[libreriscv.git] / openpower / sv / av_opcodes.mdwn
index 11ff00f93607c6b43d7505eece4097e4e5a22a65..ce4971fbfa1f4d53c485646039e7d23dc6759bc1 100644 (file)
@@ -4,11 +4,38 @@
 
 the fundamental principle of SV is a hardware for-loop. therefore the first (and in nearly 100% of cases only) place to put Vector operations is first and foremost in the *scalar* ISA.  However only by analysing those scalar opcodes *in* a SV Vectorisation context does it become clear why they are needed and how they may be designed.
 
-This page therefore has acompanying discussion at <https://bugs.libre-soc.org/show_bug.cgi?id=230> for evolution of suitable opcodes.
+This page therefore has accompanying discussion at <https://bugs.libre-soc.org/show_bug.cgi?id=230> for evolution of suitable opcodes.
 
 Links
 
+* <https://bugs.libre-soc.org/show_bug.cgi?id=915> add overflow to maxmin.
+* <https://bugs.libre-soc.org/show_bug.cgi?id=863> add pseudocode etc.
+* <https://bugs.libre-soc.org/show_bug.cgi?id=234> hardware implementation
+* <https://bugs.libre-soc.org/show_bug.cgi?id=910> mins/maxs zero-option?
 * [[vpu]]
+* [[sv/int_fp_mv]]
+* [[openpower/isa/av]] pseudocode
+* TODO review HP 1994-6 PA-RISC MAX <https://en.m.wikipedia.org/wiki/Multimedia_Acceleration_eXtensions>
+* <https://en.m.wikipedia.org/wiki/Sum_of_absolute_differences>
+* List of MMX instructions <https://cs.fit.edu/~mmahoney/cse3101/mmx.html>
+
+# Summary
+
+In-advance, the summary of base scalar operations that need to be added is:
+
+| instruction   | pseudocode               |
+| ------------  | ------------------------      |
+| average-add.  | result = (src1 + src2 + 1) >> 1 |
+| abs-diff      | result = abs (src1-src2) |
+| abs-accumulate| result += abs (src1-src2) |
+| (un)signed min| result = (src1 < src2) ? src1 : src2 use bitmanip |
+| (un)signed max| result = (src1 > src2) ? src1 : src2  use bitmanip |
+| bitwise sel   | (a ? b : c) - use [[sv/bitmanip]] ternary |
+| int/fp move   | covered by [[sv/int_fp_mv]] |
+
+Implemented at the [[openpower/isa/av]] pseudocode page.
+
+All other capabilities (saturate in particular) are achieved with [[sv/svp64]] modes and swizzle.  Note that minmax and ternary are added in bitmanip.
 
 # Audio
 
@@ -23,7 +50,7 @@ The fundamental principle for these instructions is:
 
 Thus for example, where OpenPOWER VSX has vpkswss, this would be achieved in SV with simply:
 
-* addition of a scalar ext/clamp instruction
+* applying saturation to minu (sv.minu/satu)
 * 1st op, swizzle-selection vec2 "select X only" from source to dest:
   dest.X = extclamp(src.X)
 * 2nd op, swizzle-select vec2 "select Y only" from source to dest
@@ -31,6 +58,14 @@ Thus for example, where OpenPOWER VSX has vpkswss, this would be achieved in SV
 
 Macro-op fusion may be used to detect that these two interleave cleanly, overlapping the vec2.X with vec2.Y to produce a single vec2.XY operation.
 
+Alternatively Twin-Predication may be applied, with every even bit set in
+the source mask and every odd bit set in the destination mask:
+
+    r3=0b10101010
+    r10=0b01010101
+    r0=0x00007fff # or other limit
+    sv.minu/satu/sm=r3/dm=r10/ew=32 *r20,*r20,r0
+
 ## Scalar element operations
 
 * clamping / saturation for signed and unsigned.  best done similar to FP rounding modes, i.e. with an SPR.
@@ -40,12 +75,12 @@ Macro-op fusion may be used to detect that these two interleave cleanly, overlap
 
 # Video
 
-TODO
+* DCT added as [[sv/remap]] <https://users.cs.cf.ac.uk/Dave.Marshall/Multimedia/node231.html>
+ <https://www.nayuki.io/page/fast-discrete-cosine-transform-algorithms>
+* Absolute-diff Accumulation, used in Motion Estimation, added,
+  see [[sv/bitmanip]] and opcodes in [[openpower/isa/av]]
 
-* DCT <https://users.cs.cf.ac.uk/Dave.Marshall/Multimedia/node231.html>
-* <https://www.nayuki.io/page/fast-discrete-cosine-transform-algorithms>
-
-# VSX SIMD
+# VSX SIMD analysis
 
 Useful parts of VSX, and how they might map.
 
@@ -55,7 +90,9 @@ signed and unsigned, these are N-to-M (N=64/32/16, M=32/16/8) chop/clamp/sign/ze
 
 The other direction, vec_unpack widening ops, may need some way to tell whether to sign-extend or zero-extend.
 
-*scalar extsw/b/h gives one set, mv gives another.  src elwidth override and dest rlwidth override provide the pack/unpack*
+*scalar extsw/b/h gives one set, mv gives another.  src elwidth override and dest elwidth override provide the pack/unpack*.
+
+implemented by Pack/Unpack. [[sv/normal]] arithmetic also has Pack-with-Saturate.
  
 ## vavgs\* (vec_avg)
 
@@ -74,6 +111,15 @@ unsigned 8/16/32: these are all of the form:
 
 *These do not exist in the scalar ISA and would need to be added*
 
+## abs-accumulate
+
+signed and unsigned variants needed:
+
+    result += (src1 > src2) ? truncate(src1-src2) :
+                              truncate(src2-src1)
+
+*These do not exist in the scalar ISA and would need to be added*
+
 ## vmaxs\* / vmaxu\* (and min)
 
 signed and unsigned, 8/16/32: these are all of the form:
@@ -81,7 +127,19 @@ signed and unsigned, 8/16/32: these are all of the form:
     result = (src1 > src2) ? src1 : src2 # max
     result = (src1 < src2) ? src1 : src2 # min
 
-*These do not exist in the scalar INTEGER ISA and would need to be added*
+*These do not exist in the scalar INTEGER ISA and would need to be added*.
+There are additionally no scalar FP min/max, either. These also
+need to be added.
+
+Also it makes sense for both the integer and FP variants
+to have Rc=1 modes, where those modes are based on the
+respective cmp (or fsel / isel) behaviour. In other words,
+the Rc=1 setting is based on the *comparison* of the
+two inputs, rather than on which of the two results was
+returned by the min/max opcode.
+
+    result = (src1 > src2) ? src1 : src2 # max
+    CR0 = CR_computr(src2-src1) # not based on result
 
 ## vmerge operations
 
@@ -158,6 +216,8 @@ For 8,16,32,64, resulting in 8,16,32,64,128.
 
 *All of these can be done with SV elwidth overrides, as long as the dest is no greater than 128.  SV specifically does not do 128 bit arithmetic. Instead, vec2.X mul-lo followed by vec2.Y mul-hi can be macro-op fused to get at the full 128 bit internal result.  Specifying e.g. src elwidth=8 and dest elwidth=16 will give a widening multiply*
 
+(Now added `madded` which is twin-half 64x64->HI64/LO64 in [[sv/biginteger]])
+
 ## vec_rl - rotate left
 
     (a << x) | (a >> (WIDTH - x))