radix: reading first page table entry
[soc.git] / src / soc / decoder / power_regspec_map.py
index 2d4f3fd9c89fd70ae23e188d10c8bd24834ed4f9..05ff4814e2504e3acbc5924b614031b460f8bd7c 100644 (file)
@@ -35,7 +35,7 @@ has to be "remapped" to internal SPR Enum indices (see SPRMap in PowerDecode2)
 see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
 """
 from nmigen import Const
-from soc.regfile.regfiles import XERRegs, FastRegs
+from soc.regfile.regfiles import XERRegs, FastRegs, StateRegs
 from soc.decoder.power_enums import CryIn
 
 
@@ -48,19 +48,18 @@ def regspec_decode_read(e, regfile, name):
     if regfile == 'INT':
         # Int register numbering is *unary* encoded
         if name == 'ra': # RA
-            return e.read_reg1.ok, 1<<e.read_reg1.data
+            return e.read_reg1.ok, e.read_reg1.data
         if name == 'rb': # RB
-            return e.read_reg2.ok, 1<<e.read_reg2.data
+            return e.read_reg2.ok, e.read_reg2.data
         if name == 'rc': # RS
-            return e.read_reg3.ok, 1<<e.read_reg3.data
+            return e.read_reg3.ok, e.read_reg3.data
 
     # CR regfile
 
     if regfile == 'CR':
         # CRRegs register numbering is *unary* encoded
-        # *sigh*.  numbering inverted on part-CRs.  because POWER.
-        if name == 'full_cr': # full CR
-            return e.read_cr_whole, 0b11111111
+        if name == 'full_cr': # full CR (from FXM field)
+            return e.do.read_cr_whole.ok, e.do.read_cr_whole.data
         if name == 'cr_a': # CR A
             return e.read_cr1.ok, 1<<(7-e.read_cr1.data)
         if name == 'cr_b': # CR B
@@ -76,32 +75,36 @@ def regspec_decode_read(e, regfile, name):
         CA = 1<<XERRegs.CA
         OV = 1<<XERRegs.OV
         if name == 'xer_so':
-            return (e.oe.oe[0] & e.oe.oe_ok) | e.xer_in, SO
+            # SO needs to be read for overflow *and* for creation
+            # of CR0 and also for MFSPR
+            return ((e.do.oe.oe[0] & e.do.oe.ok) | (e.xer_in & SO == SO)|
+                     (e.do.rc.rc & e.do.rc.ok)), SO
         if name == 'xer_ov':
-            return (e.oe.oe[0] & e.oe.oe_ok) | e.xer_in, OV
+            return ((e.do.oe.oe[0] & e.do.oe.ok) |
+                    (e.xer_in & CA == CA)), OV
         if name == 'xer_ca':
-            return (e.input_carry == CryIn.CA.value) | e.xer_in, CA
+            return ((e.do.input_carry == CryIn.CA.value) |
+                    (e.xer_in & OV == OV)), CA
 
-    # FAST regfile
+    # STATE regfile
 
-    if regfile == 'FAST':
-        # FAST register numbering is *unary* encoded
-        PC = 1<<FastRegs.PC
-        MSR = 1<<FastRegs.MSR
-        CTR = 1<<FastRegs.CTR
-        LR = 1<<FastRegs.LR
-        TAR = 1<<FastRegs.TAR
-        SRR0 = 1<<FastRegs.SRR0
-        SRR1 = 1<<FastRegs.SRR1
+    if regfile == 'STATE':
+        # STATE register numbering is *unary* encoded
+        PC = 1<<StateRegs.PC
+        MSR = 1<<StateRegs.MSR
         if name in ['cia', 'nia']:
             return Const(1), PC # TODO: detect read-conditions
         if name == 'msr':
             return Const(1), MSR # TODO: detect read-conditions
-        # TODO: remap the SPR numbers to FAST regs
+
+    # FAST regfile
+
+    if regfile == 'FAST':
+        # FAST register numbering is *unary* encoded
         if name == 'fast1':
-            return e.read_fast1.ok, 1<<e.read_fast1.data
+            return e.read_fast1.ok, e.read_fast1.data
         if name == 'fast2':
-            return e.read_fast2.ok, 1<<e.read_fast2.data
+            return e.read_fast2.ok, e.read_fast2.data
 
     # SPR regfile
 
@@ -122,17 +125,17 @@ def regspec_decode_write(e, regfile, name):
     if regfile == 'INT':
         # Int register numbering is *unary* encoded
         if name == 'o': # RT
-            return e.write_reg, 1<<e.write_reg.data
+            return e.write_reg, e.write_reg.data
         if name == 'o1': # RA (update mode: LD/ST EA)
-            return e.write_ea, 1<<e.write_ea.data
+            return e.write_ea, e.write_ea.data
 
     # CR regfile
 
     if regfile == 'CR':
         # CRRegs register numbering is *unary* encoded
         # *sigh*.  numbering inverted on part-CRs.  because POWER.
-        if name == 'full_cr': # full CR
-            return e.write_cr_whole, 0b11111111
+        if name == 'full_cr': # full CR (from FXM field)
+            return e.do.write_cr_whole.ok, e.do.write_cr_whole.data
         if name == 'cr_a': # CR A
             return e.write_cr, 1<<(7-e.write_cr.data)
 
@@ -150,26 +153,25 @@ def regspec_decode_write(e, regfile, name):
         if name == 'xer_ca':
             return e.xer_out, CA # hmmm
 
-    # FAST regfile
+    # STATE regfile
 
-    if regfile == 'FAST':
-        # FAST register numbering is *unary* encoded
-        PC = 1<<FastRegs.PC
-        MSR = 1<<FastRegs.MSR
-        CTR = 1<<FastRegs.CTR
-        LR = 1<<FastRegs.LR
-        TAR = 1<<FastRegs.TAR
-        SRR0 = 1<<FastRegs.SRR0
-        SRR1 = 1<<FastRegs.SRR1
+    if regfile == 'STATE':
+        # STATE register numbering is *unary* encoded
+        PC = 1<<StateRegs.PC
+        MSR = 1<<StateRegs.MSR
         if name in ['cia', 'nia']:
             return None, PC # hmmm
         if name == 'msr':
             return None, MSR # hmmm
-        # TODO: remap the SPR numbers to FAST regs
+
+    # FAST regfile
+
+    if regfile == 'FAST':
+        # FAST register numbering is *unary* encoded
         if name == 'fast1':
-            return e.write_fast1, 1<<e.write_fast1.data
+            return e.write_fast1, e.write_fast1.data
         if name == 'fast2':
-            return e.write_fast2, 1<<e.write_fast2.data
+            return e.write_fast2, e.write_fast2.data
 
     # SPR regfile