power_insn: support PPC multi-records
[openpower-isa.git] / src / openpower / decoder / power_decoder2.py
index f2c4a0f661df9ffda6a19723269216796bc7166d..9312e7904908fcc89c323dbfd5c780a9eaac2fc5 100644 (file)
@@ -31,7 +31,7 @@ from openpower.decoder.power_enums import (MicrOp, CryIn, Function,
                                            CRInSel, CROutSel,
                                            LdstLen, In1Sel, In2Sel, In3Sel,
                                            OutSel, SPRfull, SPRreduced,
-                                           RC, SVP64LDSTmode, LDSTMode,
+                                           RCOE, SVP64LDSTmode, LDSTMode,
                                            SVEXTRA, SVEtype, SVPtype)
 from openpower.decoder.decode2execute1 import (Decode2ToExecute1Type, Data,
                                                Decode2ToOperand)
@@ -529,7 +529,7 @@ class DecodeRC(Elaboratable):
 
     def __init__(self, dec):
         self.dec = dec
-        self.sel_in = Signal(RC, reset_less=True)
+        self.sel_in = Signal(RCOE, reset_less=True)
         self.insn_in = Signal(32, reset_less=True)
         self.rc_out = Data(1, "rc")
 
@@ -539,13 +539,13 @@ class DecodeRC(Elaboratable):
 
         # select Record bit out field
         with m.Switch(self.sel_in):
-            with m.Case(RC.RC):
+            with m.Case(RCOE.RC, RCOE.RC_ONLY):
                 comb += self.rc_out.data.eq(self.dec.Rc)
                 comb += self.rc_out.ok.eq(1)
-            with m.Case(RC.ONE):
+            with m.Case(RCOE.ONE):
                 comb += self.rc_out.data.eq(1)
                 comb += self.rc_out.ok.eq(1)
-            with m.Case(RC.NONE):
+            with m.Case(RCOE.NONE):
                 comb += self.rc_out.data.eq(0)
                 comb += self.rc_out.ok.eq(1)
 
@@ -555,48 +555,30 @@ class DecodeRC(Elaboratable):
 class DecodeOE(Elaboratable):
     """DecodeOE from instruction
 
-    decodes OE field: uses RC decode detection which might not be good
-
-    -- For now, use "rc" in the decode table to decide whether oe exists.
-    -- This is not entirely correct architecturally: For mulhd and
-    -- mulhdu, the OE field is reserved. It remains to be seen what an
-    -- actual POWER9 does if we set it on those instructions, for now we
-    -- test that further down when assigning to the multiplier oe input.
+    decodes OE field: uses RC decode detection which has now been
+    updated to separate out RC_ONLY.  all cases RC_ONLY are *NOT*
+    listening to the OE field, here.
     """
 
     def __init__(self, dec, op):
         self.dec = dec
         self.op = op
-        self.sel_in = Signal(RC, reset_less=True)
+        self.sel_in = Signal(RCOE, reset_less=True)
         self.insn_in = Signal(32, reset_less=True)
         self.oe_out = Data(1, "oe")
 
     def elaborate(self, platform):
         m = Module()
         comb = m.d.comb
-        op = self.op
 
-        with m.Switch(op.internal_op):
-
-            # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
-            # also rotate
-            # XXX ARGH! ignoring OE causes incompatibility with microwatt
-            # http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-August/000302.html
-            with m.Case(MicrOp.OP_MUL_H64, MicrOp.OP_MUL_H32,
-                        MicrOp.OP_EXTS, MicrOp.OP_CNTZ,
-                        MicrOp.OP_SHL, MicrOp.OP_SHR, MicrOp.OP_RLC,
-                        MicrOp.OP_LOAD, MicrOp.OP_STORE,
-                        MicrOp.OP_RLCL, MicrOp.OP_RLCR,
-                        MicrOp.OP_EXTSWSLI, MicrOp.OP_GREV, MicrOp.OP_TERNLOG):
-                pass
-
-            # all other ops decode OE field
+        with m.Switch(self.sel_in):
+            with m.Case(RCOE.RC):
+                comb += self.oe_out.data.eq(self.dec.OE)
+                comb += self.oe_out.ok.eq(1)
             with m.Default():
-                # select OE bit out field
-                with m.Switch(self.sel_in):
-                    with m.Case(RC.RC):
-                        comb += self.oe_out.data.eq(self.dec.OE)
-                        comb += self.oe_out.ok.eq(1)
+                # default: clear OE.
+                comb += self.oe_out.data.eq(0)
+                comb += self.oe_out.ok.eq(0)
 
         return m
 
@@ -1029,27 +1011,7 @@ class PowerDecodeSubset(Elaboratable):
             # the alternative decoder, svdecldst. what a mess... *sigh*
             sv_ptype = self.op_get("SV_Ptype")
             fn = self.op_get("function_unit")
-            # detect major opcode for LDs: include 58 here. from CSV files.
-            # BLECH! TODO: these should be done using "mini decoders",
-            # using row and column subsets
-            is_major_ld = Signal()
-            # bits... errr... MSB0 0..5 which is 26:32 python
-            major = Signal(6)
-            comb += major.eq(self.dec.opcode_in[26:32])
-            comb += is_major_ld.eq((major == 34) | (major == 35) |
-                                   (major == 50) | (major == 51) |
-                                   (major == 48) | (major == 49) |
-                                   (major == 42) | (major == 43) |
-                                   (major == 40) | (major == 41) |
-                                   (major == 32) | (major == 33) |
-                                   (major == 58))
-            with m.If(self.is_svp64_mode & is_major_ld):
-                # straight-up: "it's a LD".  this gives enough info
-                # for SVP64 RM Mode decoding to detect LD/ST, and
-                # consequently detect the SHIFT mode. sigh
-                comb += rm_dec.fn_in.eq(Function.LDST)
-            with m.Else():
-                comb += rm_dec.fn_in.eq(fn)  # decode needs to know Fn type
+            comb += rm_dec.fn_in.eq(fn)  # decode needs to know Fn type
             comb += rm_dec.ptype_in.eq(sv_ptype)  # Single/Twin predicated
             comb += rm_dec.rc_in.eq(rc_out)  # Rc=1
             comb += rm_dec.rm_in.eq(self.sv_rm)  # SVP64 RM mode
@@ -1062,6 +1024,8 @@ class PowerDecodeSubset(Elaboratable):
             # exclude fcfids and others
             # XXX this is a REALLY bad hack, REALLY has to be done better.
             # likely with a sub-decoder.
+            major = Signal(6)
+            comb += major.eq(self.dec.opcode_in[26:32])
             xo5 = Signal(1)  # 1 bit from Minor 59 XO field == 0b0XXXX
             comb += xo5.eq(self.dec.opcode_in[5])
             xo = Signal(5)  # 5 bits from Minor 59 fcfids == 0b01110