add spr-to-state conversion, and support for state1 in PowerDecoder2
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 19 Jan 2022 15:55:30 +0000 (15:55 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 19 Jan 2022 15:55:30 +0000 (15:55 +0000)
src/openpower/consts.py
src/openpower/decoder/decode2execute1.py
src/openpower/decoder/power_decoder2.py
src/openpower/decoder/power_enums.py
src/openpower/decoder/power_regspec_map.py
src/openpower/util.py

index 42788d5f35229326221eb38e61f52bc3d89bcbc2..12c6ef7cb91d157b76f6c5143f884f97aa7bd290 100644 (file)
@@ -296,20 +296,29 @@ class StateRegsEnum:
     PC = 0
     MSR = 1
     SVSTATE = 2
-    N_REGS = 3 # maximum number of regs
+    DEC = 3
+    TB = 4
+    N_REGS = 5 # maximum number of regs
 
 # Fast SPRs Regfile
 class FastRegsEnum:
-    CTR = 0
-    LR = 1
-    TAR = 2
-    SRR0 = 3
-    SRR1 = 4
-    XER = 5 # non-XER bits
-    DEC = 6
-    TB = 7
-    SVSRR0 = 8
-    N_REGS = 9 # maximum number of regs
+    LR = 0
+    CTR = 1
+    SRR0 = 2
+    SRR1 = 3
+    HSRR0 = 4
+    HSRR1 = 5
+    SPRG0 = 6
+    SPRG1 = 7
+    SPRG2 = 8
+    SPRG3 = 9
+    HSPRG0 = 10
+    HSPRG1 = 11
+    XER = 12 # non-XER bits
+    TAR = 13
+    SVSRR0 = 14
+    # only one spare!
+    N_REGS = 15 # maximum number of regs
 
 # XER Regfile
 class XERRegsEnum:
index d0f37d2e062a242bc2bfdb9ba03cbb5cce81ad5e..767d84967ff40b6e86ae4d89ded535ad5998427a 100644 (file)
@@ -120,12 +120,15 @@ class Decode2ToExecute1Type(RecordObject):
         self.xer_out = Signal(reset_less=True)  # xer might be written
 
         # for the FAST regs (SRR1, SRR2, SVSRR0, CTR, LR etc.)
-        self.read_fast1 = Data(3, name="fast1")
-        self.read_fast2 = Data(3, name="fast2")
-        self.read_fast3 = Data(3, name="fast3")   # really only for SVSRR0
-        self.write_fast1 = Data(3, name="fasto1")
-        self.write_fast2 = Data(3, name="fasto2")
-        self.write_fast3 = Data(3, name="fasto3") # likewise
+        self.read_fast1 = Data(4, name="fast1")
+        self.read_fast2 = Data(4, name="fast2")
+        self.read_fast3 = Data(4, name="fast3")   # really only for SVSRR0
+        self.write_fast1 = Data(4, name="fasto1")
+        self.write_fast2 = Data(4, name="fasto2")
+        self.write_fast3 = Data(4, name="fasto3") # likewise
+        # and STATE regs (DEC, TB)
+        self.read_state1 = Data(3, name="state1")  # really only for DEC/TB
+        self.write_state1 = Data(3, name="state1")
 
         self.read_cr1 = Data(7, name="cr_in1")
         self.read_cr2 = Data(7, name="cr_in2")
index cb054735fbcb33dd2403c0bb6c1dbb288e95d30f..d7154e17a4be9268ad82729abd289cfc1e7df5d0 100644 (file)
@@ -41,7 +41,7 @@ from openpower.consts import (MSR, SPEC, EXTRA2, EXTRA3, SVP64P, field,
                               FastRegsEnum, XERRegsEnum, TT)
 
 from openpower.state import CoreState
-from openpower.util import (spr_to_fast, log)
+from openpower.util import (spr_to_fast, spr_to_state, log)
 
 
 def decode_spr_num(spr):
@@ -78,7 +78,8 @@ class SPRMap(Elaboratable):
 
         self.spr_i = Signal(10, reset_less=True)
         self.spr_o = Data(SPR, name="spr_o")
-        self.fast_o = Data(3, name="fast_o")
+        self.fast_o = Data(4, name="fast_o")
+        self.state_o = Data(3, name="state_o")
 
     def elaborate(self, platform):
         m = Module()
@@ -95,6 +96,10 @@ class SPRMap(Elaboratable):
                 with m.Case(x.value):
                     m.d.comb += self.fast_o.data.eq(v)
                     m.d.comb += self.fast_o.ok.eq(1)
+            for x, v in spr_to_state.items():
+                with m.Case(x.value):
+                    m.d.comb += self.state_o.data.eq(v)
+                    m.d.comb += self.state_o.ok.eq(1)
         return m
 
 
@@ -116,7 +121,8 @@ class DecodeA(Elaboratable):
         self.insn_in = Signal(32, reset_less=True)
         self.reg_out = Data(5, name="reg_a")
         self.spr_out = Data(SPR, "spr_a")
-        self.fast_out = Data(3, "fast_a")
+        self.fast_out = Data(4, "fast_a")
+        self.state_out = Data(3, "state_a")
         self.sv_nz = Signal(1)
 
     def elaborate(self, platform):
@@ -181,6 +187,7 @@ class DecodeA(Elaboratable):
                 comb += sprmap.spr_i.eq(spr)
                 comb += self.spr_out.eq(sprmap.spr_o)
                 comb += self.fast_out.eq(sprmap.fast_o)
+                comb += self.state_out.eq(sprmap.state_o)
 
         return m
 
@@ -229,7 +236,7 @@ class DecodeB(Elaboratable):
         self.insn_in = Signal(32, reset_less=True)
         self.reg_out = Data(7, "reg_b")
         self.reg_isvec = Signal(1, name="reg_b_isvec")  # TODO: in reg_out
-        self.fast_out = Data(3, "fast_b")
+        self.fast_out = Data(4, "fast_b")
 
     def elaborate(self, platform):
         m = Module()
@@ -393,7 +400,8 @@ class DecodeOut(Elaboratable):
         self.insn_in = Signal(32, reset_less=True)
         self.reg_out = Data(5, "reg_o")
         self.spr_out = Data(SPR, "spr_o")
-        self.fast_out = Data(3, "fast_o")
+        self.fast_out = Data(4, "fast_o")
+        self.state_out = Data(3, "state_o")
 
     def elaborate(self, platform):
         m = Module()
@@ -421,6 +429,7 @@ class DecodeOut(Elaboratable):
                     comb += sprmap.spr_i.eq(spr)
                     comb += self.spr_out.eq(sprmap.spr_o)
                     comb += self.fast_out.eq(sprmap.fast_o)
+                    comb += self.state_out.eq(sprmap.state_o)
 
         # determine Fast Reg
         with m.Switch(op.internal_op):
@@ -463,8 +472,8 @@ class DecodeOut2(Elaboratable):
         self.insn_in = Signal(32, reset_less=True)
         self.reg_out = Data(5, "reg_o2")
         self.fp_madd_en = Signal(reset_less=True)  # FFT instruction detected
-        self.fast_out = Data(3, "fast_o2")
-        self.fast_out3 = Data(3, "fast_o3")
+        self.fast_out = Data(4, "fast_o2")
+        self.fast_out3 = Data(4, "fast_o3")
 
     def elaborate(self, platform):
         m = Module()
@@ -1470,6 +1479,9 @@ class PowerDecode2(PowerDecodeSubset):
         comb += e.write_fast1.eq(dec_o.fast_out)   # SRR0 (OP_RFID)
         comb += e.write_fast2.eq(dec_o2.fast_out)  # SRR1 (ditto)
         comb += e.write_fast3.eq(dec_o2.fast_out3)  # SVSRR0 (ditto)
+        # and State regs (DEC, TB)
+        comb += e.read_state1.eq(dec_a.state_out)    # DEC/TB
+        comb += e.write_state1.eq(dec_o.state_out)   # DEC/TB
 
         # sigh this is exactly the sort of thing for which the
         # decoder is designed to not need.  MTSPR, MFSPR and others need
index a0f85b586b28e2ef1a5e5d71ad8195ef0ad982df..f68746a796848bc887f0e3bb440f83ed04bbd149 100644 (file)
@@ -565,9 +565,10 @@ def get_spr_enum(full_file):
     short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
                   'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
                   'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
-                  'SPRG3',
+                  'SPRG0', 'SPRG1', 'SPRG2', 'SPRG3',
                   # hmmm should not be including these, they are FAST regs
                   'CTR', 'LR', 'TAR', 'SRR0', 'SRR1', 'XER', 'DEC', 'TB', 'TBU',
+                  'HSRR0', 'HSRR1', 'HSPRG0', 'HSPRG1',
                   }
     spr_csv = []
     for row in get_csv("sprs.csv"):
index 151cb7ee19ab912c39178f189179ee2d9c42b201..6e93376d46708ff69a16ba7a81b6434d9e7af5c1 100644 (file)
@@ -111,6 +111,8 @@ def regspec_decode_read(m, e, regfile, name):
         if name == 'svstate':
             # TODO: detect read-conditions
             rd = RegDecodeInfo(Const(1), SVSTATE, 3)
+        if name == 'state1':
+            rd = RegDecodeInfo(e.read_state1.ok, 1<<e.read_state1.data, 3)
 
     # FAST regfile
 
@@ -199,6 +201,8 @@ def regspec_decode_write(m, e, regfile, name):
             wr = RegDecodeInfo(None, MSR, 3) # hmmm
         if name == 'svstate':
             wr = RegDecodeInfo(None, SVSTATE, 3) # hmmm
+        if name == 'state1':
+            wr = RegDecodeInfo(e.write_state1.ok, 1<<e.write_state1.data, 3)
 
     # FAST regfile
 
index 9be902dbd8721f32667cc054cc789514976f089d..cae6dcfef0bbd228f9954ec5a50f77e1fd753b20 100644 (file)
@@ -1,22 +1,49 @@
 import os
 import random
-from openpower.consts import FastRegsEnum
+from openpower.consts import FastRegsEnum, StateRegsEnum
 from openpower.decoder.power_enums import SPRfull as SPR, spr_dict
 
 
 # note that we can get away with using SPRfull here because the values
 # (numerical values) are what is used for lookup.
-spr_to_fast = { SPR.CTR: FastRegsEnum.CTR,
+spr_to_fast = {
                 SPR.LR: FastRegsEnum.LR,
-                SPR.TAR: FastRegsEnum.TAR,
+                SPR.CTR: FastRegsEnum.CTR,
                 SPR.SRR0: FastRegsEnum.SRR0,
                 SPR.SRR1: FastRegsEnum.SRR1,
+                SPR.HSRR0: FastRegsEnum.HSRR0,
+                SPR.HSRR1: FastRegsEnum.HSRR1,
+                SPR.SPRG0_priv: FastRegsEnum.SPRG0,
+                SPR.SPRG1_priv: FastRegsEnum.SPRG1,
+                SPR.SPRG2_priv: FastRegsEnum.SPRG2,
+                SPR.SPRG3: FastRegsEnum.SPRG3,
+                SPR.HSPRG0: FastRegsEnum.HSPRG0,
+                SPR.HSPRG1: FastRegsEnum.HSPRG1,
                 SPR.XER: FastRegsEnum.XER,
-                SPR.DEC: FastRegsEnum.DEC,
-                SPR.TB: FastRegsEnum.TB,
+                SPR.TAR: FastRegsEnum.TAR,
                 SPR.SVSRR0: FastRegsEnum.SVSRR0,
                }
 
+spr_to_state = { SPR.DEC: StateRegsEnum.DEC,
+                 SPR.TB: StateRegsEnum.TB,
+               }
+
+sprstr_to_state = {}
+state_to_spr = {}
+for (k, v) in spr_to_state.items():
+    sprstr_to_state[k.name] = v
+    state_to_spr[v] = k
+
+def state_reg_to_spr(spr_num):
+    return state_to_spr[spr_num].value
+
+
+def spr_to_state_reg(spr_num):
+    if not isinstance(spr_num, str):
+        spr_num = spr_dict[spr_num].SPR
+    return sprstr_to_state.get(spr_num, None)
+
+
 sprstr_to_fast = {}
 fast_to_spr = {}
 for (k, v) in spr_to_fast.items():