add spr decode to A
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 8 Mar 2020 13:17:31 +0000 (13:17 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 8 Mar 2020 13:17:31 +0000 (13:17 +0000)
src/decoder/power_decoder2.py
src/decoder/power_fields.py

index f3c7ddeda48b831d72581343c153bcd8aa501455..c8e98705e0ed0fca23fa278cf81137d59759bbf8 100644 (file)
@@ -5,7 +5,7 @@ based on Anton Blanchard microwatt decode2.vhdl
 """
 from nmigen import Module, Elaboratable, Signal
 from power_enums import (InternalOp, CryIn,
-                         In1Sel, In2Sel, In3Sel, OutSel)
+                         In1Sel, In2Sel, In3Sel, OutSel, SPR)
 
 class DecodeA(Elaboratable):
     def __init__(self, dec):
@@ -30,11 +30,48 @@ class DecodeA(Elaboratable):
 
         # decode SPR1 based on instruction type
         op = self.dec.op
+        # BC or BCREG: potential implicit register (CTR)
         with m.If(op.internal_op == InternalOP.OP_BC |
                   op.internal_op == InternalOP.OP_BCREG):
             with m.If(~self.dec.BO[2]): # 3.0B p38 BO2=0, use CTR reg
-                self.spr_out.eq(SPR_CTR)
+                self.spr_out.eq(SPR.CTR) # constant: CTR
                 self.sprok_out.eq(1)
+        # MFSPR or MTSPR: move-from / move-to SPRs
+        with m.If(op.internal_op == InternalOP.OP_MFSPR |
+                  op.internal_op == InternalOP.OP_MTSPR):
+            self.spr_out.eq(self.dec.SPR) # decode SPR field from XFX insn
+            self.sprok_out.eq(1)
+
+
+class DecodeB(Elaboratable):
+    def __init__(self, dec):
+        self.dec = dec
+        self.sel_in = Signal(In1Sel, reset_less=True)
+        self.insn_in = Signal(32, reset_less=True)
+        self.ispr1_in = Signal(10, reset_less=True)
+        self.reg_out = Signal(5, reset_less=True)
+        self.regok_out = Signal(reset_less=True)
+        self.spr_out = Signal(10, reset_less=True)
+        self.sprok_out = Signal(reset_less=True)
+
+    def elaborate(self, platform):
+        m = Module()
+        comb = m.d.comb
+
+        # select Register B field
+        comb += self.reg_out.eq(self.dec.RB)
+        with m.If((self.sel_in == In1Sel.RB) |
+                  ((self.sel_in == In1Sel.RB_OR_ZERO) & (ra == Const(0, 5))):
+            comb += self.regok_out.eq(1)
+
+        # decode SPR2 based on instruction type
+        op = self.dec.op
+        with m.If(op.internal_op == InternalOP.OP_BCREG):
+            with m.If(self.dec.FormXL.XO[10]): # 3.0B p38 top bit of XO
+                self.spr_out.eq(SPR.CTR)
+            with m.Else():
+                self.spr_out.eq(SPR.LR)
+            self.sprok_out.eq(1)
 
 
 class XerBits:
index 60337ad35b52ac7311641f5484118ead5dfd68c1..3457331ecee46632604bae7aec79917dc9291b91 100644 (file)
@@ -156,6 +156,7 @@ class DecodeFields:
         self.SH = self.FormX.SH
         self.ME = self.FormM.ME
         self.MB = self.FormM.MB
+        self.SPR = self.FormXFX.SPR
 
     def decode_fields(self):
         with open(self.fname) as f: