add maxs DRAFT instruction
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 19 Jun 2022 16:10:21 +0000 (17:10 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 19 Jun 2022 16:10:21 +0000 (17:10 +0100)
https://libre-soc.org/openpower/sv/av_opcodes/

openpower/isa/av.mdwn [new file with mode: 0644]
openpower/isatables/minor_22.csv
src/openpower/decoder/isa/caller.py
src/openpower/decoder/isa/test_caller_bitmanip_av.py [new file with mode: 0644]
src/openpower/decoder/power_enums.py
src/openpower/sv/trans/svp64.py
src/openpower/test/bitmanip/av_cases.py [new file with mode: 0644]

diff --git a/openpower/isa/av.mdwn b/openpower/isa/av.mdwn
new file mode 100644 (file)
index 0000000..b4958b0
--- /dev/null
@@ -0,0 +1,18 @@
+<!-- DRAFT Instructions for PowerISA Version 3.0 B Book 1 -->
+
+# Fixed Point Signed Max
+
+X-Form
+
+* maxs  RT,RA,RB (Rc=0)
+* maxs. RT,RA,RB (Rc=1)
+
+Pseudo-code:
+
+    if   (RA) >= (RB) then RT <- (RA)
+    else                   RT <- (RB)
+
+Special Registers Altered:
+
+    CR0                     (if Rc=1)
+
index 6e2b0c64fce6f9f9174a5b6347bb0ff2628d109c..224eb1aec8dbbaa7ebe7ef040e7dc77d6f7a7733 100644 (file)
@@ -3,3 +3,4 @@ opcode,unit,internal op,in1,in2,in3,out,CR in,CR out,inv A,inv out,cry in,cry ou
 -----011001,VL,OP_SVSHAPE,NONE,NONE,NONE,NONE,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,svshape,SVM,,1,unofficial until submitted and approved/renumbered by the opf isa wg
 -----111001,VL,OP_SVREMAP,NONE,NONE,NONE,NONE,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,svremap,SVRM,,1,unofficial until submitted and approved/renumbered by the opf isa wg
 -----10011-,VL,OP_SVSTEP,NONE,NONE,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,svstep,SVL,,1,unofficial until submitted and approved/renumbered by the opf isa wg
+0111001110-,ALU,OP_MINMAX,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,maxs,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
index afa3f76e44b1b07f6216a3d61a7a6ca46ba9dc63..c8a60c4e421f35a46145c3a73db99827b23d2cba 100644 (file)
@@ -1268,7 +1268,19 @@ class ISACaller(ISACallerHelper, ISAFPHelpers):
             illegal = False
             ins_name = 'ffadds'
 
-        if re.fullmatch(r'ternlogi\.?|grevw?i?\.?', asmop or ''):
+        # and min/max/su
+        if asmop in ['mins', 'maxs', 'minu', 'maxu',
+                     'mins.', 'maxs.', 'minu.', 'maxu.']:
+            illegal = False
+            ins_name = asmop
+
+        # and anything ternlog
+        if asmop.startswith('ternlog'):
+            illegal = False
+            ins_name = asmop
+
+        # and anything grev
+        if asmop.startswith('grev'):
             illegal = False
             ins_name = asmop
 
diff --git a/src/openpower/decoder/isa/test_caller_bitmanip_av.py b/src/openpower/decoder/isa/test_caller_bitmanip_av.py
new file mode 100644 (file)
index 0000000..9c4788f
--- /dev/null
@@ -0,0 +1,38 @@
+""" Decoder tests
+
+related bugs:
+
+ *
+"""
+
+import unittest
+import sys
+
+# These tests utilize the run_hdl=False parameter to compare
+# simulator with expected states
+from soc.simple.test.test_runner import TestRunner
+from openpower.test.bitmanip.av_cases import AVTestCase
+
+
+if __name__ == "__main__":
+
+    # allow list of testing to be selected by command-line
+    testing = sys.argv[1:]
+    sys.argv = sys.argv[:1]
+
+    if not testing:
+        testing = ['bitmanipav']
+
+    unittest.main(exit=False)
+    suite = unittest.TestSuite()
+
+    # dictionary of data for tests
+    tests = {'bitmanipav': AVTestCase().test_data}
+
+    # walk through all tests, those requested get added
+    for tname, data in tests.items():
+        if tname in testing:
+            suite.addTest(TestRunner(data, run_hdl=False))
+
+    runner = unittest.TextTestRunner()
+    runner.run(suite)
index d5a97ccc1d7b38aaa96faf1564a920493ea359d2..a54cc270f1ead8399818454b680ffa1660548e27 100644 (file)
@@ -304,6 +304,7 @@ _insns = [
     "maddhd", "maddhdu", "maddld",                      # INT multiply-and-add
     "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf",           # CR mvs
     "mfmsr", "mfspr",
+    "mins", "maxs", "minu", "maxu",                     # AV bitmanip
     "modsd", "modsw", "modud", "moduw",
     "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
     "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
@@ -442,6 +443,7 @@ class MicrOp(Enum):
     OP_TERNLOG = 86
     OP_FETCH_FAILED = 87
     OP_GREV = 88
+    OP_MINMAX = 89
 
 
 @unique
index ef618b792b578c97c93bc2c0124f8fca9e374578..af13e7a78768882a08c9c6d934e473b269fa24a2 100644 (file)
@@ -417,6 +417,21 @@ class SVP64Asm:
             yield f".4byte {hex(instr)} # {asm}"
             return
 
+        # and maxs
+        # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
+        if opcode.startswith('maxs'):
+            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 |= 0b0111001110 << (31-30)  # XO       , bits 21..30
+            if opcode == 'maxs.':
+                insn |= 1 << (31-31)     # Rc=1     , bit 31
+            log("maxs", bin(insn))
+            yield ".long 0x%x" % insn
+            return
+
         # identify if is a svp64 mnemonic
         if not opcode.startswith('sv.'):
             yield insn  # unaltered
@@ -1287,6 +1302,10 @@ if __name__ == '__main__':
         'sv.ld 5.v, 4(1.v)',
         'sv.svstep. 2.v, 4, 0',
     ]
+    lst = [
+        'maxs 3,12,5',
+        'maxs. 3,12,5',
+    ]
     isa = SVP64Asm(lst, macros=macros)
     log("list", list(isa))
     asm_process()
diff --git a/src/openpower/test/bitmanip/av_cases.py b/src/openpower/test/bitmanip/av_cases.py
new file mode 100644 (file)
index 0000000..66161d7
--- /dev/null
@@ -0,0 +1,99 @@
+from openpower.sv.trans.svp64 import SVP64Asm
+import random
+from openpower.test.common import TestAccumulatorBase
+from openpower.endian import bigendian
+from openpower.simulator.program import Program
+from openpower.decoder.selectable_int import SelectableInt
+from openpower.decoder.power_enums import XER_bits
+from openpower.decoder.isa.caller import special_sprs
+from openpower.decoder.helpers import exts
+from openpower.test.state import ExpectedState
+import unittest
+
+
+class AVTestCase(TestAccumulatorBase):
+
+    def cse_0_maxs(self):
+        lst = ["maxs 3, 1, 2"]
+        lst = list(SVP64Asm(lst, bigendian))
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 0xc523e996a8ff6215
+        initial_regs[2] = 0xe1e5b9cc9864c4a8
+        e = ExpectedState(pc=4)
+        e.intregs[1] = 0xc523e996a8ff6215
+        e.intregs[2] = 0xe1e5b9cc9864c4a8
+        e.intregs[3] = 0xe1e5b9cc9864c4a8
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+    def cse_1_maxs(self):
+        lst = ["maxs 3, 1, 2"]
+        lst = list(SVP64Asm(lst, bigendian))
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 0xe1e5b9cc9864c4a8
+        initial_regs[2] = 0xc523e996a8ff6215
+        e = ExpectedState(pc=4)
+        e.intregs[1] = 0xe1e5b9cc9864c4a8
+        e.intregs[2] = 0xc523e996a8ff6215
+        e.intregs[3] = 0xe1e5b9cc9864c4a8
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+    def cse_2_maxs_(self):
+        lst = [f"maxs. 3, 1, 2"]
+        lst = list(SVP64Asm(lst, bigendian))
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 0xc523e996a8ff6215
+        initial_regs[2] = 0xe1e5b9cc9864c4a8
+        e = ExpectedState(pc=4)
+        e.intregs[1] = 0xc523e996a8ff6215
+        e.intregs[2] = 0xe1e5b9cc9864c4a8
+        e.intregs[3] = 0xe1e5b9cc9864c4a8
+        e.crregs[0] = 0x8
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+    def cse_3_maxs_(self):
+        lst = [f"maxs. 3, 1, 2"]
+        lst = list(SVP64Asm(lst, bigendian))
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 0xc523e996a8ff6215
+        initial_regs[2] = 0
+        e = ExpectedState(pc=4)
+        e.intregs[1] = 0xc523e996a8ff6215
+        e.intregs[2] = 0
+        e.intregs[3] = 0
+        e.crregs[0] = 0x2 # RT is zero
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+    def cse_4_maxs_(self):
+        lst = [f"maxs. 3, 1, 2"]
+        lst = list(SVP64Asm(lst, bigendian))
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 1
+        initial_regs[2] = 0
+        e = ExpectedState(pc=4)
+        e.intregs[1] = 1
+        e.intregs[2] = 0
+        e.intregs[3] = 1
+        e.crregs[0] = 0x4 # RT is +ve
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+    def case_5_maxs_(self):
+        """max negative number compared against +ve number
+        """
+        lst = [f"maxs. 3, 1, 2"]
+        lst = list(SVP64Asm(lst, bigendian))
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 1
+        initial_regs[2] = 0x8000_0000_0000_0000
+        e = ExpectedState(pc=4)
+        e.intregs[1] = 1
+        e.intregs[2] = 0x8000_0000_0000_0000
+        e.intregs[3] = 1
+        e.crregs[0] = 0x4 # RT is +ve
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+