extract LDST mode from SVP64 RM
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 29 May 2021 17:13:56 +0000 (18:13 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 29 May 2021 17:13:56 +0000 (18:13 +0100)
src/openpower/decoder/power_enums.py
src/openpower/decoder/power_svp64_rm.py

index 429a1684872174ecf943527d1e47022592c8a9c6..21081a5b69f6e30fe2c5db3073dd549e62bc7e67 100644 (file)
@@ -208,9 +208,10 @@ class SVP64sat(Enum):
 
 @unique
 class SVP64LDSTmode(Enum):
-    NORMAL = 0
-    ELSTRIDE = 1
-    UNITSTRIDE = 2
+    NONE = 0
+    INDEXED = 1
+    ELSTRIDE = 2
+    UNITSTRIDE = 3
 
 
 # supported instructions: make sure to keep up-to-date with CSV files
index d1d65e309531191c853b23368cad804ccb1c688e..5d5a859de827c78954977fb8ca249338966ad263 100644 (file)
@@ -18,7 +18,7 @@ https://libre-soc.org/openpower/sv/svp64/
 
 from nmigen import Elaboratable, Module, Signal, Const
 from openpower.decoder.power_enums import (SVP64RMMode, Function, SVPtype,
-                                    SVP64PredMode, SVP64sat)
+                                    SVP64PredMode, SVP64sat, SVP64LDSTmode)
 from openpower.consts import EXTRA3, SVP64MODE
 from openpower.sv.svp64 import SVP64Rec
 from nmutil.util import sel
@@ -31,6 +31,7 @@ sv_input_record_layout = [
         ('sv_pred_sz', 1), # predicate source zeroing
         ('sv_pred_dz', 1), # predicate dest zeroing
         ('sv_saturate', SVP64sat),
+        ('sv_ldstmode', SVP64LDSTmode),
         ('SV_Ptype', SVPtype),
         #('sv_RC1', 1),
     ]
@@ -70,11 +71,15 @@ Arithmetic:
 
 class SVP64RMModeDecode(Elaboratable):
     def __init__(self, name=None):
+        ##### inputs #####
         self.rm_in = SVP64Rec(name=name)
         self.fn_in = Signal(Function) # LD/ST is different
         self.ptype_in = Signal(SVPtype)
         self.rc_in = Signal()
-        self.ldst_idx = Signal()
+        self.ldst_ra_vec = Signal() # set when RA is vec, indicate Index mode
+        self.ldst_imz_in = Signal() # set when LD/ST immediate is zero
+
+        ##### outputs #####
 
         # main mode (normal, reduce, saturate, ffirst, pred-result)
         self.mode = Signal(SVP64RMMode)
@@ -92,6 +97,7 @@ class SVP64RMModeDecode(Elaboratable):
         self.inv = Signal(1)
         self.map_evm = Signal(1)
         self.map_crm = Signal(1)
+        self.ldstmode = Signal(SVP64LDSTmode) # LD/ST Mode (strided type)
 
     def elaborate(self, platform):
         m = Module()
@@ -131,12 +137,12 @@ class SVP64RMModeDecode(Elaboratable):
                     comb += self.pred_dz.eq(mode[SVP64MODE.DZ])
             with m.Case(1, 3):
                 with m.If(is_ldst):
-                    with m.If(~self.ldst_idx):
+                    with m.If(~self.ldst_ra_vec):
                         comb += self.pred_dz.eq(mode[SVP64MODE.DZ])
                 with m.Elif(self.rc_in):
                     comb += self.pred_dz.eq(mode[SVP64MODE.DZ])
             with m.Case(2):
-                with m.If(is_ldst & ~self.ldst_idx):
+                with m.If(is_ldst & ~self.ldst_ra_vec):
                     comb += self.pred_dz.eq(mode[SVP64MODE.DZ])
                 with m.Else():
                     comb += self.pred_sz.eq(mode[SVP64MODE.SZ])
@@ -152,6 +158,30 @@ class SVP64RMModeDecode(Elaboratable):
             with m.Default():
                 comb += self.saturate.eq(SVP64sat.NONE)
 
+        # extract els (element strided mode bit)
+        # see https://libre-soc.org/openpower/sv/ldst/
+        els = Signal()
+        with m.If(is_ldst):
+            with m.Switch(mode2):
+                with m.Case(0):
+                    comb += els.eq(mode[SVP64MODE.ELS_NORMAL])
+                with m.Case(2):
+                    comb += els.eq(mode[SVP64MODE.ELS_SAT])
+                with m.Case(1, 3):
+                    with m.If(self.rc_in):
+                        comb += els.eq(mode[SVP64MODE.ELS_FFIRST_PRED])
+
+            # RA is vectorised
+            with m.If(self.ldst_ra_vec):
+                comb += self.ldstmode.eq(SVP64LDSTmode.INDEXED)
+            # not element-strided, therefore unit...
+            with m.Elif(~els):
+                comb += self.ldstmode.eq(SVP64LDSTmode.UNITSTRIDE)
+            # but if the LD/ST immediate is zero, allow cache-inhibited
+            # loads from same location, therefore don't do element-striding
+            with m.Elif(self.ldst_imz_in):
+                comb += self.ldstmode.eq(SVP64LDSTmode.ELSTRIDE)
+
         # extract src/dest predicate.  use EXTRA3.MASK because EXTRA2.MASK
         # is in exactly the same bits
         srcmask = sel(m, self.rm_in.extra, EXTRA3.MASK)