start on CRs in SVP64 mode
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 20 Feb 2021 20:49:26 +0000 (20:49 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 20 Feb 2021 20:49:29 +0000 (20:49 +0000)
src/soc/decoder/isa/caller.py
src/soc/decoder/isa/test_caller_svp64.py

index 886e7bcd2545af2eb21d31b4c44b205ea4843365..acdc57c311cbc3866a75dbb5e99f59d030c5cfc3 100644 (file)
@@ -21,7 +21,7 @@ from soc.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
                                         selectconcat)
 from soc.decoder.power_enums import (spr_dict, spr_byname, XER_bits,
                                      insns, MicrOp, In1Sel, In2Sel, In3Sel,
-                                     OutSel)
+                                     OutSel, CROutSel)
 from soc.decoder.helpers import exts, gtu, ltu, undefined
 from soc.consts import PIb, MSRb  # big-endian (PowerISA versions)
 from soc.decoder.power_svp64 import SVP64RM, decode_extra
@@ -360,6 +360,21 @@ def get_pdecode_idx_in(dec2, name):
     return None, False
 
 
+def get_pdecode_cr_out(dec2, name):
+    op = dec2.dec.op
+    out_sel = yield op.cr_out
+    # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
+    out = yield dec2.e.write_cr.data
+    o_isvec = yield dec2.o_isvec
+    print ("get_pdecode_cr_out", out_sel, CROutSel.CR0.value, out, o_isvec)
+    # identify which regnames map to out / o2
+    if name == 'CR0':
+        if out_sel == CROutSel.CR0.value:
+            return out, o_isvec
+    print ("get_pdecode_idx_out not found", name)
+    return None, False
+
+
 def get_pdecode_idx_out(dec2, name):
     op = dec2.dec.op
     out_sel = yield op.out_sel
@@ -643,7 +658,7 @@ class ISACaller:
         so = so | ov
         self.spr['XER'][XER_bits['SO']] = so
 
-    def handle_comparison(self, outputs):
+    def handle_comparison(self, outputs, cr_idx=0):
         out = outputs[0]
         assert isinstance(out, SelectableInt), \
             "out zero not a SelectableInt %s" % repr(outputs)
@@ -661,7 +676,7 @@ class ISACaller:
         SO = self.spr['XER'][XER_bits['SO']]
         print("handle_comparison SO", SO)
         cr_field = selectconcat(negative, positive, zero, SO)
-        self.crl[0].eq(cr_field)
+        self.crl[cr_idx].eq(cr_field)
 
     def set_pc(self, pc_val):
         self.namespace['NIA'] = SelectableInt(pc_val, 64)
@@ -686,7 +701,6 @@ class ISACaller:
         yield self.dec2.dec.bigendian.eq(self.bigendian)
         yield self.dec2.state.msr.eq(self.msr.value)
         yield self.dec2.state.pc.eq(pc)
-        # sigh TODO
         yield self.dec2.state.svstate.eq(self.svstate.spr.value)
 
         # SVP64.  first, check if the opcode is EXT001, and SVP64 id bits set
@@ -963,7 +977,9 @@ class ISACaller:
         else:
             rc_en = False
         if rc_en:
-            self.handle_comparison(results)
+            regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, "CR0")
+            regnum = 0 # TODO fix
+            self.handle_comparison(results, regnum)
 
         # svp64 loop can end early if the dest is scalar
         svp64_dest_vector = False
index 89c6068e4023e0832082c52600ee9124bb591251..a5e93e472b67ed11a3674dbb5e1fbaca298a42f2 100644 (file)
@@ -106,6 +106,40 @@ class DecoderTestCase(FHDLTestCase):
             sim = self.run_tst_program(program, initial_regs, svstate)
             self._check_regs(sim, expected_regs)
 
+    def test_sv_add_cr(self):
+        # adds:
+        #       1 = 5 + 9   => 0x5555 = 0x4321+0x1234
+        #       2 = 6 + 10  => 0x3334 = 0x2223+0x1111
+        isa = SVP64Asm(['sv.add. 1.v, 5.v, 9.v'
+                       ])
+        lst = list(isa)
+        print ("listing", lst)
+
+        # initial values in GPR regfile
+        initial_regs = [0] * 32
+        initial_regs[9] = 0xffffffffffffffff
+        initial_regs[10] = 0x1111
+        initial_regs[5] = 0x1
+        initial_regs[6] = 0x2223
+        # SVSTATE (in this case, VL=2)
+        svstate = SVP64State()
+        svstate.vl[0:7] = 1 # VL
+        svstate.maxvl[0:7] = 1 # MAXVL
+        print ("SVSTATE", bin(svstate.spr.asint()))
+        # copy before running
+        expected_regs = deepcopy(initial_regs)
+        expected_regs[1] = 0
+        expected_regs[2] = 0x3334
+
+        with Program(lst, bigendian=False) as program:
+            sim = self.run_tst_program(program, initial_regs, svstate)
+            print ("CR0", sim.crl[0].get_range().value)
+            print ("CR1", sim.crl[1].get_range().value)
+            self._check_regs(sim, expected_regs)
+            self.assertEqual(sim.crl[0].get_range().value,
+                             SelectableInt(4, 4))
+
+
     def run_tst_program(self, prog, initial_regs=[0] * 32,
                               svstate=None):
         simulator = run_tst(prog, initial_regs, svstate=svstate)