add svremap manual instruction (Primary Opcode 22, sandbox)
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 5 Jul 2021 16:28:31 +0000 (17:28 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Mon, 5 Jul 2021 16:28:31 +0000 (17:28 +0100)
openpower/isa/simplev.mdwn
openpower/isatables/fields.text
src/openpower/decoder/isa/caller.py
src/openpower/decoder/isa/test_caller_svp64_matrix.py [new file with mode: 0644]
src/openpower/decoder/power_enums.py
src/openpower/decoder/pseudo/parser.py
src/openpower/sv/trans/svp64.py

index bb84625e2f829ef9e0897784c202a511018798a5..ec47d0f758973c62eb38663e613bf0ce08d01ee8 100644 (file)
@@ -37,7 +37,7 @@ Special Registers Altered:
 
 SVM-Form
 
-* svstate SVxd, SVyd, SVzd, SVRM
+* svremap SVxd, SVyd, SVzd, SVRM
 
 Pseudo-code:
 
@@ -46,13 +46,21 @@ Pseudo-code:
     SVSHAPE1[0:31] <- [0] * 32
     SVSHAPE2[0:31] <- [0] * 32
     SVSHAPE3[0:31] <- [0] * 32
-    # set up FRT and FRB
+    # set up template in SVSHAPE0, then copy to 1-3
     SVSHAPE0[0:5] <- (0b0 || SVxd)   # xdim
-    SVSHAPE3[0:5] <- (0b0 || SVxd)   # xdim
+    SVSHAPE0[6:11] <- (0b0 || SVyd)   # ydim
+    SVSHAPE0[12:17] <- (0b0 || SVzd)   # zdim
+    SVSHAPE0[28:29] <- 0b11           # skip z
+    # copy
+    SVSHAPE1[0:31] <- SVSHAPE0[0:31]
+    SVSHAPE2[0:31] <- SVSHAPE0[0:31]
+    SVSHAPE3[0:31] <- SVSHAPE0[0:31]
     # set up FRA
-    SVSHAPE0[0:5] <- (0b0 || SVxd)   # xdim
-    SVSHAPE0[6:11] <- (0b0 || SVyd)  # ydim
-    SVSHAPE0[18:20] <- 0b010          # permute y,x,z
+    SVSHAPE1[18:20] <- 0b001          # permute x,z,y
+    SVSHAPE1[28:29] <- 0b01           # skip z
+    # FRC
+    SVSHAPE2[18:20] <- 0b001          # permute x,z,y
+    SVSHAPE2[28:29] <- 0b11           # skip y
 
 Special Registers Altered:
 
index a46299e81625873122bc6a099c1ecc2ce62537e4..542429dcaab8b715f24c0b8ac5e27c66de1a7c97 100644 (file)
     SVyd (11:15)
          Simple-V "REMAP" y-dimension size
          Formats: SVM
+    SVzd (16:20)
+         Simple-V "REMAP" z-dimension size
+         Formats: SVM
     SX,S (28,6:10)
          Fields SX and S are concatenated to specify a
          VSR to be used as a source.
index f7561a78349e2cf3f851632397edd69847a37a70..06abbf281f53468bb6111b490df4ddcf1554758f 100644 (file)
@@ -74,6 +74,10 @@ REG_SORT_ORDER = {
     "TAR": 0,
     "MSR": 0,
     "SVSTATE": 0,
+    "SVSHAPE0": 0,
+    "SVSHAPE1": 0,
+    "SVSHAPE2": 0,
+    "SVSHAPE3": 0,
 
     "CA": 0,
     "CA32": 0,
@@ -584,6 +588,11 @@ class ISACaller:
         self.gpr = GPR(decoder2, self, self.svstate, regfile)
         self.fpr = GPR(decoder2, self, self.svstate, fpregfile)
         self.spr = SPR(decoder2, initial_sprs) # initialise SPRs before MMU
+        for i in range(4):
+            sname = 'SVSHAPE%d' % i
+            if sname not in self.spr:
+                self.spr[sname] = SVSHAPE(0)
+
         # "raw" memory
         self.mem = Mem(row_bytes=8, initial_mem=initial_mem)
         self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
@@ -623,6 +632,10 @@ class ISACaller:
                                'NIA': self.pc.NIA,
                                'CIA': self.pc.CIA,
                                'SVSTATE': self.svstate.spr,
+                               'SVSHAPE0': self.spr['SVSHAPE0'],
+                               'SVSHAPE1': self.spr['SVSHAPE1'],
+                               'SVSHAPE2': self.spr['SVSHAPE2'],
+                               'SVSHAPE3': self.spr['SVSHAPE3'],
                                'CR': self.cr,
                                'MSR': self.msr,
                                'undefined': undefined,
@@ -1054,6 +1067,11 @@ class ISACaller:
             illegal = False
             name = 'setvl'
 
+        # and svremap not being supported by binutils (.long)
+        if asmop.startswith('svremap'):
+            illegal = False
+            name = 'svremap'
+
         # sigh also deal with ffmadds not being supported by binutils (.long)
         if asmop == 'ffmadds':
             illegal = False
diff --git a/src/openpower/decoder/isa/test_caller_svp64_matrix.py b/src/openpower/decoder/isa/test_caller_svp64_matrix.py
new file mode 100644 (file)
index 0000000..4a9c3f3
--- /dev/null
@@ -0,0 +1,91 @@
+from nmigen import Module, Signal
+from nmigen.back.pysim import Simulator, Delay, Settle
+from nmutil.formaltest import FHDLTestCase
+import unittest
+from openpower.decoder.isa.caller import ISACaller
+from openpower.decoder.power_decoder import (create_pdecode)
+from openpower.decoder.power_decoder2 import (PowerDecode2)
+from openpower.simulator.program import Program
+from openpower.decoder.isa.caller import ISACaller, SVP64State
+from openpower.decoder.selectable_int import SelectableInt
+from openpower.decoder.orderedset import OrderedSet
+from openpower.decoder.isa.all import ISA
+from openpower.decoder.isa.test_caller import Register, run_tst
+from openpower.sv.trans.svp64 import SVP64Asm
+from openpower.consts import SVP64CROffs
+from copy import deepcopy
+from openpower.decoder.helpers import fp64toselectable
+from openpower.decoder.isafunctions.double2single import DOUBLE2SINGLE
+
+class DecoderTestCase(FHDLTestCase):
+
+    def _check_regs(self, sim, expected):
+        for i in range(32):
+            self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
+
+    def test_sv_remap(self):
+        """>>> lst = ["svremap 2, 2, 3, 0"
+                        ]
+        """
+        lst = SVP64Asm(["svremap 2, 2, 3, 0"
+                        ])
+        lst = list(lst)
+
+        fprs = [0] * 32
+        if False:
+            av = [7.0, -9.8, 2.0, -32.3] # first half of array 0..3
+            bv = [-2.0, 2.0, -9.8, 32.3] # second half of array 4..7
+            coe = [-1.0, 4.0, 3.1, 6.2]  # coefficients
+            res = []
+            # work out the results with the twin mul/add-sub
+            for i, (a, b, c) in enumerate(zip(av, bv, coe)):
+                fprs[i+2] = fp64toselectable(a)
+                fprs[i+6] = fp64toselectable(b)
+                fprs[i+10] = fp64toselectable(c)
+                mul = a * c
+                t = a + mul
+                u = b - mul
+                t = DOUBLE2SINGLE(fp64toselectable(t)) # convert to Power single
+                u = DOUBLE2SINGLE(fp64toselectable(u)) # from double
+                res.append((t, u))
+                print ("FFT", i, "in", a, b, "coeff", c, "mul",
+                       mul, "res", t, u)
+
+        # SVSTATE (in this case, VL=12, to cover all of matrix)
+        svstate = SVP64State()
+        svstate.vl[0:7] = 12 # VL
+        svstate.maxvl[0:7] = 12 # MAXVL
+        print ("SVSTATE", bin(svstate.spr.asint()))
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, svstate=svstate,
+                                       initial_fprs=fprs)
+            print ("spr svshape0", sim.spr['SVSHAPE0'])
+            print ("spr svshape1", sim.spr['SVSHAPE1'])
+            print ("spr svshape2", sim.spr['SVSHAPE2'])
+            print ("spr svshape3", sim.spr['SVSHAPE3'])
+            # confirm that the results are as expected
+            #for i, (t, u) in enumerate(res):
+            #    self.assertEqual(sim.fpr(i+2), t)
+            #    self.assertEqual(sim.fpr(i+6), u)
+
+    def run_tst_program(self, prog, initial_regs=None,
+                              svstate=None,
+                              initial_mem=None,
+                              initial_fprs=None):
+        if initial_regs is None:
+            initial_regs = [0] * 32
+        simulator = run_tst(prog, initial_regs, mem=initial_mem,
+                                                initial_fprs=initial_fprs,
+                                                svstate=svstate)
+
+        print ("GPRs")
+        simulator.gpr.dump()
+        print ("FPRs")
+        simulator.fpr.dump()
+
+        return simulator
+
+
+if __name__ == "__main__":
+    unittest.main()
index 1b6586395cb5cf414d25727856b7558a0b768f31..67f81c3bc6b3265104bab56d9ab59ca24d96abd6 100644 (file)
@@ -505,6 +505,7 @@ def get_spr_enum(full_file):
     this saves drastically on the size of the regfile
     """
     short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
+                  'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
                   'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
                   'SPRG3'
                  }
index ed9fae793903fab942c89f0ec2feab218634ef40..6b11359cb850d63c8c57ba355eec99c877a8053d 100644 (file)
@@ -726,7 +726,8 @@ class PowerParser:
         if self.include_ca_in_write:
             if name in ['CA', 'CA32']:
                 self.write_regs.add(name)
-        if name in ['CR', 'LR', 'CTR', 'TAR', 'FPSCR', 'MSR', 'SVSTATE']:
+        if name in ['CR', 'LR', 'CTR', 'TAR', 'FPSCR', 'MSR',
+                     'SVSTATE', 'SVSHAPE0', 'SVSHAPE1', 'SVSHAPE2', 'SVSHAPE3']:
             self.special_regs.add(name)
             self.write_regs.add(name)  # and add to list to write
         p[0] = ast.Name(id=name, ctx=ast.Load())
index 64888594edca1f737010a5f7faa7335f03083a82..bf192028d971b85a7b3f4016b54d4c77c94b448b 100644 (file)
@@ -196,6 +196,19 @@ class SVP64Asm:
             yield ".long 0x%x" % insn
             return
 
+        # and svremap
+        if opcode == 'svremap':
+            insn = 22 << (31-5)          # opcode 22, bits 0-5
+            fields = list(map(int, fields))
+            insn |= fields[0] << (31-10) # SVxd       , bits 6-10
+            insn |= fields[1] << (31-15) # SVyd       , bits 11-15
+            insn |= fields[2] << (31-16) # SVzd       , bits 16-20
+            insn |= fields[3] << (31-21) # SVRM       , bits 21-25
+            insn |= 0b00001   << (31-30) # XO       , bits 26..30
+            log ("svremap", bin(insn))
+            yield ".long 0x%x" % insn
+            return
+
         # identify if is a svp64 mnemonic
         if not opcode.startswith('sv.'):
             yield insn  # unaltered
@@ -890,7 +903,8 @@ def asm_process():
     for line in lines:
         ls = line.split("#")
         # identify macros
-        if ls[0].strip().startswith("setvl"):
+        op = ls[0].strip()
+        if op.startswith("setvl") or op.startswith("svremap"):
             ws, line = get_ws(ls[0])
             lst = list(isa.translate_one(ls[0].strip(), macros))
             lst = '; '.join(lst)
@@ -953,6 +967,7 @@ if __name__ == '__main__':
              #'sv.lhzbr 5.v, 11(9.v), 15',
              #'sv.lwzbr 5.v, 11(9.v), 15',
              'sv.ffmadds 6.v, 2.v, 4.v, 6.v',
+             'svremap 2, 2, 3, 0',
     ]
     isa = SVP64Asm(lst, macros=macros)
     print ("list", list(isa))