add absolute-difference DRAFT
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 19 Jun 2022 19:05:54 +0000 (20:05 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 19 Jun 2022 19:05:54 +0000 (20:05 +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 2dc0838d84f5949912fad0ffe33b1a8ce4a34b59..733369e3b6e76a4350fd7e12e32a7f35af155022 100644 (file)
@@ -86,3 +86,18 @@ Special Registers Altered:
 
     CR0                     (if Rc=1)
 
+# DRAFT Absolute Unsigned Difference
+
+X-Form
+
+* absdu RT,RA,RB (Rc=0)
+* absdu.  RT,RA,RB (Rc=1)
+
+Pseudo-code:
+
+    if (RA) < (RB) then RT <- ¬(RA) + (RB) + 1
+    else                RT <- ¬(RB) + (RA) + 1
+
+Special Registers Altered:
+
+    CR0                     (if Rc=1)
index 28d736b97f0df0b7c8d8208c5effcd0aef205f81..fdb69c4b6fa1f1a0c64ad94a3f377bbc788f05d1 100644 (file)
@@ -8,3 +8,4 @@ opcode,unit,internal op,in1,in2,in3,out,CR in,CR out,inv A,inv out,cry in,cry ou
 0101001110-,ALU,OP_MINMAX,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,mins,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
 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
index 2bad589f1f60f255a213eb62c2a6f41796d516f2..9fb5f727a3a01f5b2425934734d6f4c5a148156c 100644 (file)
@@ -1279,6 +1279,11 @@ class ISACaller(ISACallerHelper, ISAFPHelpers):
             illegal = False
             ins_name = asmop
 
+        # and anything absdu
+        if asmop.startswith('absdu'):
+            illegal = False
+            ins_name = asmop
+
         # and anything ternlog
         if asmop.startswith('ternlog'):
             illegal = False
index 90a861dafc38d3ca46d4af149c7c524425e0f0d4..3d5b61b2259326920274f5a61ccc000d70798d87 100644 (file)
@@ -259,8 +259,9 @@ _insns = [
     "addme", "addmeo", "addo", "addze", "addzeo",
     "addg6s",
     "and", "andc", "andi.", "andis.",
-    "attn",                                 # AV bitmanip
-    "avgadd",
+    "attn",
+    "absdu",                                  # AV bitmanip
+    "avgadd",                                 # AV bitmanip
     "b", "bc", "bcctr", "bclr", "bctar",
     "bpermd",
     "cbcdtd",
@@ -446,6 +447,7 @@ class MicrOp(Enum):
     OP_GREV = 88
     OP_MINMAX = 89
     OP_AVGADD = 90
+    OP_ABSDIFF = 91
 
 
 @unique
index 675d26b5e21e0d6f279cfd19bdd93057c0d3ae5d..b5fa9d7aef2ced82a7c96aecba0c0304c74c1574 100644 (file)
@@ -454,7 +454,24 @@ class SVP64Asm:
             insn |= XO        << (31-30)  # XO       , bits 21..30
             if opcode.endswith('.'):
                 insn |= 1 << (31-31)     # Rc=1     , bit 31
-            log("maxs", bin(insn))
+            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[:5] == 'absdu':
+                XO = 0b1011110110
+            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("absdu", bin(insn))
             yield ".long 0x%x" % insn
             return
 
@@ -1332,6 +1349,7 @@ if __name__ == '__main__':
         'maxs 3,12,5',
         'maxs. 3,12,5',
         'avgadd 3,12,5',
+        'absdu 3,12,5',
     ]
     isa = SVP64Asm(lst, macros=macros)
     log("list", list(isa))
index 5fabe7651379dafc2a17857e1db78fa385ff5882..b66928509725b308e51c26838ee8d701bf770905 100644 (file)
@@ -221,3 +221,42 @@ class AVTestCase(TestAccumulatorBase):
         e.intregs[3] = 0xffffffffffffffff
         self.add_case(Program(lst, bigendian), initial_regs, expected=e)
 
+    def case_0_absdu(self):
+        lst = ["absdu 3, 1, 2"]
+        lst = list(SVP64Asm(lst, bigendian))
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x1
+        initial_regs[2] = 0x2
+        e = ExpectedState(pc=4)
+        e.intregs[1] = 0x1
+        e.intregs[2] = 0x2
+        e.intregs[3] = 0x1
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+    def case_1_absdu(self):
+        lst = ["absdu 3, 1, 2"]
+        lst = list(SVP64Asm(lst, bigendian))
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 0xffffffffffffffff
+        initial_regs[2] = 0x2
+        e = ExpectedState(pc=4)
+        e.intregs[1] = 0xffffffffffffffff
+        e.intregs[2] = 0x2
+        e.intregs[3] = 0x3
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+    def case_2_absdu(self):
+        lst = ["absdu 3, 1, 2"]
+        lst = list(SVP64Asm(lst, bigendian))
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x2
+        initial_regs[2] = 0xffffffffffffffff
+        e = ExpectedState(pc=4)
+        e.intregs[1] = 0x2
+        e.intregs[2] = 0xffffffffffffffff
+        e.intregs[3] = 0x3
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+