(no commit message)
[libreriscv.git] / simple_v_extension / vector_ops.mdwn
index b6fa7648b5b65b91a50fd259be3ac0fec15ccef2..5294cbdb5012e5dfde9f2c84ae89f871553beb50 100644 (file)
@@ -1,18 +1,24 @@
-[[!tag standards]]
+[[!tag oldstandards]]
+
+**OBSOLETE**, see [[openpower/sv/3d_vector_ops]]
 
 # Vector Operations Extension to SV
 
+This extension defines vector operations that would otherwise take several cycles to complete in software. With 3D priorities being to compute as many pixels per clock as possible, the normal RISC rules (reduce opcode count and make heavy use of macro op fusion) do not necessarily apply. 
+
 This extension is usually dependent on SV SUBVL being implemented. When SUBVL is set to define the length of a subvector the operations in this extension interpret the elements as a single vector.
 
 Normally in SV all operations are scalar and independent, and the operations on them may inherently be independently parallelised, with the result being a vector of length exactly equal to the input vectors.
 
 In this extension, the subvector itself is typically the unit, although some operations will work on scalars or standard vectors as well, or the result is a scalar that is dependent on all elements within the vector arguments.
 
+However given that some of the parameters are vectors (with and without SUBVL set), and some are scalars (where SUBVL will not apply), some clear rules need to be defined as to how the operations work.
+
 Examples which can require SUBVL include cross product and may in future involve complex numbers.
 
 ## CORDIC
 
-SUBVL=2, vd, vs; SUBVL=1, beta.
+6 opcode options (fmt3):
 
 * CORDIC.lin.rot vd, vs, beta
 * CORDIC.cir.rot vd, vs, beta
@@ -21,6 +27,17 @@ SUBVL=2, vd, vs; SUBVL=1, beta.
 * CORDIC.cir.vec vd, vs, beta
 * CORDIC.hyp.vec vd, vs, beta
 
+
+| Instr | result | src1 | src2 | SUBVL | VL | Notes |
+| ------------------ | ------ | ---- | ---- | ----- | -- | ------ |
+| CORDIC.x.t vd, vs1, rs2 | vec2 | vec2 | scal | 2 | any | src2 ignores SUBVL |
+
+SUBVL must be set to 2 and applies to vd and vs. SUBVL is *ignored* on beta.  vd and vs must be marked as vectors.
+
+VL may be applied.  beta as a scalar is ok (applies across all vectors vd and vs). Predication is also ok (single predication) sourced from vd. Use of swizzle is also ok.
+
+Non vector args vd, vs are reserved encodings.
+
 CORDIC is an extremely general-purpose algorithm useful for a huge number
 of diverse purposes.  In its full form it does however require quite a
 few parameters, one of which is a vector, making it awkward to include in
@@ -31,48 +48,28 @@ may also be run in either "vector" mode or "rotation" mode.  See [[discussion]]
 CORDIC can also be used for performing DCT.  See
 <https://arxiv.org/abs/1606.02424>
 
-vx, vy = CORDIC(vx, vy, coordinate\_mode, beta)
-
-     int i = 0;
-     int iterations = 0; // Number of times to run the algorithm
-     float arctanTable[iterations]; // in Radians
-     float K = 0.6073; // K
-     float v_x,v_y; // Vector v; x and y components
-
-     for(i=0; i < iterations; i++) {
-        arctanTable[i] = atan(pow(2,-i));
-     }
-
-     float vnew_x;   // To store the new value of x;
-     for(i = 0; i < iterations; i++) {
-         // If beta is negative, we need to do a counter-clockwise rotation:
-         if( beta < 0) {
-            vnew_x = v_x + (v_y*pow(2,-i)); 
-            v_y -= (v_x*pow(2,-i));  
-            beta += arctanTable[i]; 
-         }
-         // If beta is positive, we need to do a clockwise rotation:
-         else {
-            vnew_x = v_x - (v_y*pow(2,-i));
-            v_y += (v_x*pow(2,-i));
-            beta -= arctanTable[i];
-         }
-         v_x = vnew_x;
-     }
-     v_x *= K;
-     v_y *= K;
+CORDIC has several RADIX-4 papers for efficient pipelining.  Each stage requires its own ROM tables which can get costly.  Two combinatorial blocks may be chained together to double the RADIX and halve the pipeline depth, at the cost of doubling the latency.
+
+Also, to get good accuracy, particularly at the limits of CORDIC input range, requires double the bitwidth of the output in internal computations. This similar to how MUL requires double the bitwidth to compute.
 
 Links:
 
 * <http://www.myhdl.org/docs/examples/sinecomp/>
+* <https://www.atlantis-press.com/proceedings/jcis2006/232>
 
 ## Vector cross product
 
-SUBVL=2,3,4 all regs
-
 * VCROSS vd, vs1, vs1
 
-Result is the cross product of x and y, i.e., the resulting components are, in order:
+Result is the cross product of x and y.
+
+SUBVL must be set to 3, and all regs must be vectors. VL nonzero produces multiple results in vd.
+
+| Instr | result | src1 | src2 | SUBVL | VL |
+| ------------------ | ------ | ---- | ---- | ----- | -- |
+| VCROSS vd, vs1, vs2 | vec3 | vec3 | vec3 | 3 | any |
+
+The resulting components are, in order:
 
     x[1] * y[2] - y[1] * x[2]
     x[2] * y[0] - y[2] * x[0]
@@ -91,16 +88,33 @@ Pseudocode:
     vec3 p = t3 * t4;
     vec3 cross = t1 * t2 - p;
 
-## Vector dot product
+Assembler:
+
+    fswizzlei,2130 F4, F1
+    fswizzlei,1320 F5, F1
+    fswizzlei,2130 F6, F2
+    fswizzlei,1320 F7, F2
+    fmul F8, F5, F6
+    fmulsub F3, F4, F7, F8
 
-* SUBVL=1, rd SUBVL=2,3,4 vs1,vs2
-* rd=scalar, SUBVL=default, vs1, vs2=vec
+## Vector dot product
 
 * VDOT rd, vs1, vs2
 
 Computes the dot product of two vectors. Internal accuracy must be
 greater than the input vectors and the result.
 
+There are two possible argument options:
+
+* SUBVL=2,3,4 vs1 and vs2 set as vectors,  multiple results are generated. When VL is set, only the first (unpredicated) SUBVector is used to create a result, if rd is scalar (standard behaviour for single predication). Otherwise, if rd is a vector, multiple scalar results are calculated (i.e. SUBVL is always ignored for rd). Swizzling may be applied.
+* When rd=scalar, SUBVL=1 and vs1=vec, vs2=vec, one scalar result is generated from the entire src vectors.  Predication is allowed on the src vectors.
+
+
+| Instr | result | src1 | src2 | SUBVL | VL |
+| ------------------ | ------ | ---- | ---- | ----- | -- |
+| VDOT rd, vs1, vs2 | scal | vec  | vec | 2-4 | any |
+| VDOT rd, vs1, vs2 | scal | vec  | vec | 1 | any |
+
 Pseudocode in python:
 
     from operator import mul
@@ -116,11 +130,22 @@ Pseudocode in c:
         return result;
     }
 
+## Vector Normalisation (not included)
+
+Vector normalisation may be performed through dot product, recip square root and multiplication:
+
+    fdot F3, F1, F1 # vector dot with self
+    rcpsqrta F3, F3
+    fscale,0 F2, F3, F1
+
+Or it may be performed through VLEN (Vector length) and division.
+
 ## Vector length
 
-* rd=scalar, vs1=vec (SUBVL=default)
-* rd=scalar, vs1=vec (SUBVL=2,3,4) only 1
-* rd=vec, SUBVL=1; vs1=vec, SUBVL=any
+* rd=scalar, vs1=vec (SUBVL=1)
+* rd=scalar, vs1=vec (SUBVL=2,3,4) only 1 (predication rules apply)
+* rd=vec, SUBVL ignored; vs1=vec, SUBVL=2,3,4
+* rd=vec, SUBVL ignored; vs1=vec, SUBVL=1: reserved encoding.
 
 * VLEN rd, vs1
 
@@ -128,6 +153,8 @@ The scalar length of a vector:
 
     sqrt(x[0]^2 + x[1]^2 + ...).
 
+One option is for this to be a macro op fusion sequence, with inverse-sqrt also being a second macro op sequence suitable for normalisation.
+
 ## Vector distance
 
 * VDIST rd, vs1, vs2
@@ -139,7 +166,11 @@ other and returns length:
 
 ## Vector LERP
 
-* VLERP rd, vs1, rs2 # SUBVL=2: vs1.v0 vs1.v1
+* VLERP vd, vs1, rs2 # SUBVL=2: vs1.v0 vs1.v1
+
+| Instr | result | src1 | src2 | SUBVL | VL |
+| ------------------ | ------ | ---- | ---- | ----- | -- |
+| VLERP vd, vs1, rs2 | vec2 | vec2 | scal | 2 | any |
 
 Known as **fmix** in GLSL.
 
@@ -165,7 +196,7 @@ Pseudocode:
 * VSLERP vd, vs1, vs2, rs3
 
 Not recommended as it is not commonly used and has several trigonometric
-functions. Also a costly 4 arg operation.
+functions, although CORDIC in vector rotate circular mode is designed for this purpose. Also a costly 4 arg operation.
 
 <https://en.m.wikipedia.org/wiki/Slerp>
 
@@ -314,3 +345,13 @@ Another is to overwrite one of the src registers.
 # Opcode Table
 
 TODO
+
+# Links
+
+* <http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-September/002736.html>
+* <http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-September/002733.html>
+* <http://bugs.libre-riscv.org/show_bug.cgi?id=142>
+
+Research Papers
+
+* <https://www.researchgate.net/publication/2938554_PLX_FP_An_Efficient_Floating-Point_Instruction_Set_for_3D_Graphics>