(no commit message)
[libreriscv.git] / openpower / sv / twin_butterfly.mdwn
index 4ce57a779df3b1f4f20a0439b3e878f9f0e794e7..3bd36d897ffc18685d9c606856bec608c3a07a20 100644 (file)
@@ -1,6 +1,15 @@
-<https://bugs.libre-soc.org/show_bug.cgi?id=1074>
+# Introduction
 
-# [DRAFT] Twin Butterfly DCT Instruction(s)
+<!-- hide -->
+* <https://bugs.libre-soc.org/show_bug.cgi?id=1074>
+* <https://libre-soc.org/openpower/sv/biginteger/> for format and
+  information about implicit RS/FRS
+* <https://git.libre-soc.org/?p=openpower-isa.git;a=blob;f=src/openpower/decoder/isa/test_caller_svp64_dct.py;hb=HEAD>
+* [[openpower/isa/svfparith]]
+* [[openpower/isa/svfixedarith]]
+<!-- show -->
+
+# Twin Butterfly Integer DCT Instruction(s)
 
 The goal is to implement instructions that calculate the expression:
 
@@ -22,62 +31,116 @@ For the double-coefficient butterfly instruction.
 #define ROUND_POWER_OF_TWO(value, n) (((value) + (1 << ((n)-1))) >> (n))
 ```
 
+These instructions are at the core of **ALL** FDCT calculations in many major video codecs, including -but not limited to- VP8/VP9, AV1, etc.
+Arm includes special instructions to optimize these operations, although they are limited in precision: `vqrdmulhq_s16`/`vqrdmulhq_s32`.
+
 The suggestion is to have a single instruction to calculate both values `((a + b) * c) >> N`, and `((a - b) * c) >> N`.
 The instruction will run in accumulate mode, so in order to calculate the 2-coeff version one would just have to call the same instruction with different order a, b and a different constant c.
 
-```
-# [DRAFT] Integer Butterfly Multiply Add/Sub FFT/DCT
+## [DRAFT] Integer Butterfly Multiply Add/Sub FFT/DCT
 
-BF-Form
+A-Form
 
-* maddsubrs  RT,RA,RB,RC,SH
+* maddsubrs  RT,RA,SH,RB
 
 Pseudo-code:
 
-    RT2 <- RT + 1
-    sum <- (RA) + (RB)
-    diff <- (RA) - (RB)
-    prod1 <- MUL(RC, sum)
-    prod2 <- MUL(RC, diff)
-    res1 <- ROTL64(prod1, SH)
-    res2 <- ROTL64(prod2, SH)
-    RT <- (RT) + res1
-    RT2 <- (RT2) + res2
+```
+    n <- SH
+    sum <- (RT) + (RA)
+    diff <- (RT) - (RA)
+    prod1 <- MULS(RB, sum)[XLEN:(XLEN*2)-1]
+    prod2 <- MULS(RB, diff)[XLEN:(XLEN*2)-1]
+    res1 <- ROTL64(prod1, XLEN-n)
+    res2 <- ROTL64(prod2, XLEN-n)
+    m <- MASK(n, (XLEN-1))
+    signbit1 <- res1[0]
+    signbit2 <- res2[0]
+    smask1 <- ([signbit1]*XLEN) & ¬m
+    smask2 <- ([signbit2]*XLEN) & ¬m
+    s64_1 <- [0]*(XLEN-1) || signbit1
+    s64_2 <- [0]*(XLEN-1) || signbit2
+    RT <- (res1 & m | smask1) + s64_1
+    RS <- (res2 & m | smask2) + s64_2
+```
 
 Special Registers Altered:
 
+```
     None
 ```
 
-Where BF-Form is defined in fields.txt:
+Where we have added this variant in A-Form (defined in fields.txt):
+
+```
+# # 1.6.17 A-FORM
+    |0     |6     |11      |16     |21      |26    |31 |
+    | PO   |  RT  |   RA   |   RB  |   SH   |   XO |Rc |
+
+```
+
+The instruction has been added to `minor_22.csv`:
+
+```
+------01000,ALU,OP_MADDSUBRS,RT,CONST_SH,RB,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC_ONLY,0,0,maddsubrs,A,,1,unofficial until submitted and approved/renumbered by the opf isa wg
+```
+
+
+# Twin Butterfly Integer DCT Instruction(s)
+
+## [DRAFT] Floating Twin Multiply-Add DCT [Single]
+
+X-Form
+
+```
+    |0     |6     |11      |16     |21      |31 |
+    | PO   |  FRT |  FRA   |  FRB  |   XO   | Rc|
+```
+
+* fdmadds FRT,FRA,FRB (Rc=0)
+* fdmadds. FRT,FRA,FRB (Rc=1)
 
+Pseudo-code:
+
+```
+    FRS <- FPADD32(FRT, FRB)
+    sub <- FPSUB32(FRT, FRB)
+    FRT <- FPMUL32(FRA, sub)
 ```
-# 1.6.39 BF-FORM
-    |0     | 6   |11   |16   |21   | 25  |30  |31  |
-    | PO   | RT  | RA  | RB  | RC  | SH  | XO | Rc |
+
+Special Registers Altered:
 
 ```
+    FPRF FR FI
+    FX OX UX XX
+    VXSNAN VXISI VXIMZ
+    CR1          (if Rc=1)
+```
+
+## [DRAFT] Floating Multiply-Add FFT [Single]
 
-The resulting autogenerated code is:
+X-Form
 
 ```
-class butterfly:
-    @inject()
-    def op_maddsubrs(self, RA, RB, RC, RT):
-        RT2 = copy_assign_rhs(RT + 1)
-        sum = copy_assign_rhs(RA + RB)
-        diff = copy_assign_rhs(RA - RB)
-        prod1 = copy_assign_rhs(self.MUL(RC, sum))
-        prod2 = copy_assign_rhs(self.MUL(RC, diff))
-        res1 = copy_assign_rhs(self.ROTL64(prod1, SH))
-        res2 = copy_assign_rhs(self.ROTL64(prod2, SH))
-        RT = copy_assign_rhs(RT + res1)
-        RT2 = copy_assign_rhs(RT2 + res2)
-        return (RT,)
+    |0     |6     |11      |16     |21      |31 |
+    | PO   |  FRT |  FRA   |  FRB  |   XO   | Rc|
 ```
 
-The instruction has been added to `minor_59.csv`:
+* ffmadds FRT,FRA,FRB (Rc=0)
+* ffmadds. FRT,FRA,FRB (Rc=1)
+
+Pseudo-code:
+
 ```
-1111011111,ALU,OP_MADDSUBRS,RA,RB,RC,RT,NONE,CR1,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC_ONLY,0,0,maddsubrs,A,,1,unofficial until submitted and approved/renumbered by the opf isa wg
+    FRS <- FPMULADD32(FRT, FRA, FRB, -1, 1)
+    FRT <- FPMULADD32(FRT, FRA, FRB, 1, 1)
 ```
 
+Special Registers Altered:
+
+```
+    FPRF FR FI
+    FX OX UX XX
+    VXSNAN VXISI VXIMZ
+    CR1          (if Rc=1)
+```