got sv.bc working for pospopcount
[openpower-isa.git] / src / openpower / decoder / power_svp64_extra.py
index 8a8a3f77bff1f66c4ecf587d01c2c164717e8003..71903f0a3d7df2b2e12eca09452b5b60f4077b8b 100644 (file)
@@ -6,9 +6,9 @@ from nmigen.cli import rtlil
 from nmutil.util import sel
 
 
-from openpower.decoder.power_enums import (SVEXTRA, SVEtype)
+from openpower.decoder.power_enums import (SVEXTRA, SVEType)
 from openpower.consts import (SPEC, EXTRA2, EXTRA3, SVP64P, field,
-                        SPEC_SIZE, SPECb, SPEC_AUG_SIZE, SVP64CROffs)
+                              SPEC_SIZE, SPECb, SPEC_AUG_SIZE, SVP64CROffs)
 
 
 class SVP64ExtraSpec(Elaboratable):
@@ -18,11 +18,12 @@ class SVP64ExtraSpec(Elaboratable):
 
     see https://libre-soc.org/openpower/sv/svp64/
     """
+
     def __init__(self):
-        self.extra   = Signal(9, reset_less=True)
-        self.etype   = Signal(SVEtype, reset_less=True) # 2 or 3 bits
-        self.idx     = Signal(SVEXTRA, reset_less=True) # which part of extra
-        self.spec  = Signal(3) # EXTRA spec for the register
+        self.extra = Signal(9, reset_less=True)
+        self.etype = Signal(SVEType, reset_less=True)  # 2 or 3 bits
+        self.idx = Signal(SVEXTRA, reset_less=True)  # which part of extra
+        self.spec = Signal(3)  # EXTRA spec for the register
 
     def elaborate(self, platform):
         m = Module()
@@ -36,22 +37,28 @@ class SVP64ExtraSpec(Elaboratable):
         # the register-extension information.  extract those now
         with m.Switch(self.etype):
             # 2-bit index selection mode
-            with m.Case(SVEtype.EXTRA2):
+            with m.Case(SVEType.EXTRA2):
+                extra2_lsb = Signal(1)
                 with m.Switch(self.idx):
                     with m.Case(SVEXTRA.Idx0):  # 1st 2 bits [0:1]
                         comb += spec[SPEC.VEC].eq(extra[EXTRA2.IDX0_VEC])
-                        comb += spec[SPEC.MSB].eq(extra[EXTRA2.IDX0_MSB])
+                        comb += extra2_lsb.eq(extra[EXTRA2.IDX0_MSB])
                     with m.Case(SVEXTRA.Idx1):  # 2nd 2 bits [2:3]
                         comb += spec[SPEC.VEC].eq(extra[EXTRA2.IDX1_VEC])
-                        comb += spec[SPEC.MSB].eq(extra[EXTRA2.IDX1_MSB])
+                        comb += extra2_lsb.eq(extra[EXTRA2.IDX1_MSB])
                     with m.Case(SVEXTRA.Idx2):  # 3rd 2 bits [4:5]
                         comb += spec[SPEC.VEC].eq(extra[EXTRA2.IDX2_VEC])
-                        comb += spec[SPEC.MSB].eq(extra[EXTRA2.IDX2_MSB])
+                        comb += extra2_lsb.eq(extra[EXTRA2.IDX2_MSB])
                     with m.Case(SVEXTRA.Idx3):  # 4th 2 bits [6:7]
                         comb += spec[SPEC.VEC].eq(extra[EXTRA2.IDX3_VEC])
-                        comb += spec[SPEC.MSB].eq(extra[EXTRA2.IDX3_MSB])
+                        comb += extra2_lsb.eq(extra[EXTRA2.IDX3_MSB])
+                with m.If(spec[SPEC.VEC]):  # vector mode
+                    # can express reg numbers range(0, 127, 2)
+                    comb += spec[SPEC.MSB].eq(extra2_lsb)
+                with m.Else():  # scalar mode: can express r0-63
+                    comb += spec[SPEC.LSB].eq(extra2_lsb)
             # 3-bit index selection mode
-            with m.Case(SVEtype.EXTRA3):
+            with m.Case(SVEType.EXTRA3):
                 with m.Switch(self.idx):
                     with m.Case(SVEXTRA.Idx0):  # 1st 3 bits [0:2]
                         extra3_idx0 = sel(m, extra, EXTRA3.IDX0)
@@ -78,14 +85,15 @@ class SVP64RegExtra(SVP64ExtraSpec):
 
     see https://libre-soc.org/openpower/sv/svp64/
     """
+
     def __init__(self):
         SVP64ExtraSpec.__init__(self)
-        self.reg_in  = Signal(5) # incoming reg number (5 bits, RA, RB)
-        self.reg_out = Signal(7) # extra-augmented output (7 bits)
-        self.isvec   = Signal(1) # reg is marked as vector if true
+        self.reg_in = Signal(5)  # incoming reg number (5 bits, RA, RB)
+        self.reg_out = Signal(7)  # extra-augmented output (7 bits)
+        self.isvec = Signal(1)  # reg is marked as vector if true
 
     def elaborate(self, platform):
-        m = super().elaborate(platform) # select required EXTRA2/3
+        m = super().elaborate(platform)  # select required EXTRA2/3
         comb = m.d.comb
 
         # first get the spec.  if not changed it's "scalar identity behaviour"
@@ -125,14 +133,15 @@ class SVP64CRExtra(SVP64ExtraSpec):
 
     see https://libre-soc.org/openpower/sv/svp64/appendix
     """
+
     def __init__(self):
         SVP64ExtraSpec.__init__(self)
-        self.cr_in  = Signal(3) # incoming CR number (3 bits, BA[0:2], BFA)
-        self.cr_out = Signal(7) # extra-augmented CR output (7 bits)
-        self.isvec  = Signal(1) # reg is marked as vector if true
+        self.cr_in = Signal(3)  # incoming CR number (3 bits, BA[0:2], BFA)
+        self.cr_out = Signal(7)  # extra-augmented CR output (7 bits)
+        self.isvec = Signal(1)  # reg is marked as vector if true
 
     def elaborate(self, platform):
-        m = super().elaborate(platform) # select required EXTRA2/3
+        m = super().elaborate(platform)  # select required EXTRA2/3
         comb = m.d.comb
 
         # first get the spec.  if not changed it's "scalar identity behaviour"