add absadd (unsigned) DRAFT
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 19 Jun 2022 19:34:30 +0000 (20:34 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 19 Jun 2022 19:34:30 +0000 (20:34 +0100)
https://bugs.libre-soc.org/show_bug.cgi?id=863

openpower/isa/av.mdwn
openpower/isatables/minor_22.csv
src/openpower/decoder/isa/caller.py
src/openpower/decoder/power_enums.py
src/openpower/sv/trans/svp64.py
src/openpower/test/bitmanip/av_cases.py

index 733369e3b6e76a4350fd7e12e32a7f35af155022..f4aea8e78c600f64c6a39a7f596c8deac93ec825 100644 (file)
@@ -70,8 +70,8 @@ Special Registers Altered:
 
 X-Form
 
-* avgadd RT,RA,RB (Rc=0)
-* avgadd.  RT,RA,RB (Rc=1)
+* avgadd  RT,RA,RB (Rc=0)
+* avgadd. RT,RA,RB (Rc=1)
 
 Pseudo-code:
 
@@ -90,8 +90,8 @@ Special Registers Altered:
 
 X-Form
 
-* absdu RT,RA,RB (Rc=0)
-* absdu.  RT,RA,RB (Rc=1)
+* absdu  RT,RA,RB (Rc=0)
+* absdu. RT,RA,RB (Rc=1)
 
 Pseudo-code:
 
@@ -101,3 +101,20 @@ Pseudo-code:
 Special Registers Altered:
 
     CR0                     (if Rc=1)
+
+# DRAFT Absolute Accumulate Unsigned Difference
+
+X-Form
+
+* absaddu  RT,RA,RB (Rc=0)
+* absaddu. RT,RA,RB (Rc=1)
+
+Pseudo-code:
+
+    if (RA) <u (RB) then r <- ¬(RA) + (RB) + 1
+    else                 r <- ¬(RB) + (RA) + 1
+    RT <- (RT) + r
+
+Special Registers Altered:
+
+    CR0                     (if Rc=1)
index fdb69c4b6fa1f1a0c64ad94a3f377bbc788f05d1..c432d601107ea3b2864b5c9a2da0e7e4aea40027 100644 (file)
@@ -9,3 +9,4 @@ opcode,unit,internal op,in1,in2,in3,out,CR in,CR out,inv A,inv out,cry in,cry ou
 0001001110-,ALU,OP_MINMAX,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,minu,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
 1101001110-,ALU,OP_AVGADD,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,avgadd,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
 1011110110-,ALU,OP_ABSDIFF,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,absdu,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
+1111110110-,ALU,OP_ABSADD,RA,RB,RT,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,absaddu,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
index 9fb5f727a3a01f5b2425934734d6f4c5a148156c..66d5196fb071d59822ba41cd087584a26924a389 100644 (file)
@@ -1284,6 +1284,11 @@ class ISACaller(ISACallerHelper, ISAFPHelpers):
             illegal = False
             ins_name = asmop
 
+        # and anything absadd
+        if asmop.startswith('absadd'):
+            illegal = False
+            ins_name = asmop
+
         # and anything ternlog
         if asmop.startswith('ternlog'):
             illegal = False
index 3d5b61b2259326920274f5a61ccc000d70798d87..b0aad76843741e97b129fc334251b90ac581021e 100644 (file)
@@ -261,6 +261,7 @@ _insns = [
     "and", "andc", "andi.", "andis.",
     "attn",
     "absdu",                                  # AV bitmanip
+    "absaddu", "absadds",                     # AV bitmanip
     "avgadd",                                 # AV bitmanip
     "b", "bc", "bcctr", "bclr", "bctar",
     "bpermd",
@@ -448,6 +449,7 @@ class MicrOp(Enum):
     OP_MINMAX = 89
     OP_AVGADD = 90
     OP_ABSDIFF = 91
+    OP_ABSADD = 92
 
 
 @unique
index b5fa9d7aef2ced82a7c96aecba0c0304c74c1574..6364449bd2363c5bd61775fbfb23e9e239718971 100644 (file)
@@ -441,28 +441,17 @@ class SVP64Asm:
             yield ".long 0x%x" % insn
             return
 
-        # and avgadd
+        # and avgadd, absdu, absaddu, absadds
         # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
-        if opcode in ['avgadd', ]:
-            if opcode[:6] == 'avgadd':
-                XO = 0b1101001110
-            fields = list(map(int, fields))
-            insn = 22 << (31-5)  # opcode 22, bits 0-5
-            insn |= fields[0] << (31-10)  # RT       , bits 6-10
-            insn |= fields[1] << (31-15)  # RA       , bits 11-15
-            insn |= fields[2] << (31-20)  # RB       , bits 16-20
-            insn |= XO        << (31-30)  # XO       , bits 21..30
-            if opcode.endswith('.'):
-                insn |= 1 << (31-31)     # Rc=1     , bit 31
-            log("avgadd", bin(insn))
-            yield ".long 0x%x" % insn
-            return
-
-        # and absdu
-        # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
-        if opcode in ['absdu', ]:
+        if opcode in ['avgadd', 'absdu', 'absaddu', 'absadds']:
             if opcode[:5] == 'absdu':
                 XO = 0b1011110110
+            elif opcode[:6] == 'avgadd':
+                XO = 0b1101001110
+            elif opcode[:7] == 'absaddu':
+                XO = 0b1111110110
+            elif opcode[:7] == 'absadds':
+                XO = 0b0111110110
             fields = list(map(int, fields))
             insn = 22 << (31-5)  # opcode 22, bits 0-5
             insn |= fields[0] << (31-10)  # RT       , bits 6-10
@@ -471,7 +460,7 @@ class SVP64Asm:
             insn |= XO        << (31-30)  # XO       , bits 21..30
             if opcode.endswith('.'):
                 insn |= 1 << (31-31)     # Rc=1     , bit 31
-            log("absdu", bin(insn))
+            log(opcode, bin(insn))
             yield ".long 0x%x" % insn
             return
 
@@ -1350,6 +1339,8 @@ if __name__ == '__main__':
         'maxs. 3,12,5',
         'avgadd 3,12,5',
         'absdu 3,12,5',
+        'absaddu 3,12,5',
+        'absadds 3,12,5',
     ]
     isa = SVP64Asm(lst, macros=macros)
     log("list", list(isa))
index b66928509725b308e51c26838ee8d701bf770905..a5da2fe084a7abca8d684319d27648dbf5215893 100644 (file)
@@ -260,3 +260,73 @@ class AVTestCase(TestAccumulatorBase):
         e.intregs[3] = 0x3
         self.add_case(Program(lst, bigendian), initial_regs, expected=e)
 
+    def case_0_absaddu(self):
+        lst = ["absaddu 3, 1, 2",
+               "absaddu 3, 4, 5",
+        ]
+        lst = list(SVP64Asm(lst, bigendian))
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x2
+        initial_regs[2] = 0x1
+        initial_regs[4] = 0x9
+        initial_regs[5] = 0x3
+        e = ExpectedState(pc=8)
+        e.intregs[1] = 0x2
+        e.intregs[2] = 0x1
+        e.intregs[3] = 0x7
+        e.intregs[4] = 0x9
+        e.intregs[5] = 0x3
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+    def case_1_absaddu(self):
+        lst = ["absaddu 3, 1, 2",
+               "absaddu 3, 4, 5",
+        ]
+        lst = list(SVP64Asm(lst, bigendian))
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x1
+        initial_regs[2] = 0x2
+        initial_regs[4] = 0x9
+        initial_regs[5] = 0x3
+        e = ExpectedState(pc=8)
+        e.intregs[1] = 0x1
+        e.intregs[2] = 0x2
+        e.intregs[3] = 0x7
+        e.intregs[4] = 0x9
+        e.intregs[5] = 0x3
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+    def case_2_absaddu(self):
+        """weird case where there's a negative number
+        * -1 is greater than 2 (as an unsigned number)
+          therefore difference is (-1)-(2) which is -3
+          RT=RT+-3
+            =0-3
+            =-3
+        * 9 is greater than 3
+          therefore differences is (9)-(3) which is 6
+          RT=RT+6
+            =-3+6
+            =3
+        * answer: RT=3
+        """
+        lst = ["absaddu 3, 1, 2",
+               "absaddu 3, 4, 5",
+        ]
+        lst = list(SVP64Asm(lst, bigendian))
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x2
+        initial_regs[2] = 0xffffffffffffffff
+        initial_regs[4] = 0x9
+        initial_regs[5] = 0x3
+        e = ExpectedState(pc=8)
+        e.intregs[1] = 0x2
+        e.intregs[2] = 0xffffffffffffffff
+        e.intregs[3] = 0x3 # ((-1)-(2)) + ((9)-(3))
+        e.intregs[4] = 0x9
+        e.intregs[5] = 0x3
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+