move ffadds to not conflict with fptrans -- makes space for min/max/fmod/remainder ops
[openpower-isa.git] / src / openpower / decoder / power_decoder2.py
index fdad739231d5aa1413c4f2d65b296141be12ce63..8cd7db702ba5be574173e704162f643317fefa05 100644 (file)
@@ -555,13 +555,9 @@ 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):
@@ -574,40 +570,15 @@ class DecodeOE(Elaboratable):
     def elaborate(self, platform):
         m = Module()
         comb = m.d.comb
-        op = self.op
-
-        # default: clear OE.
-        comb += self.oe_out.data.eq(0)
-        comb += self.oe_out.ok.eq(0)
 
-        with m.Switch(op.internal_op):
-
-            # mulhw, mulhwu, mulhd, mulhdu - these *ignore* OE
-            # also rotate.  and setvl and all other sv* management
-            # basically the HDL below bypasses normal decode and
-            # goes directly and explicitly to bit 30 (self.dec.OE).
-            # on the list of instructions below (really this should
-            # be in the CSV files) they must be told *not* to do that.
-            # 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_SETVL, MicrOp.OP_SVSHAPE,
-                        MicrOp.OP_SVINDEX, MicrOp.OP_SVREMAP,
-                        MicrOp.OP_SVSTEP,
-                        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(RCOE.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
 
@@ -824,7 +795,7 @@ class PowerDecodeSubset(Elaboratable):
         # amongst other things
         if svp64_en:
             conditions = {
-                          'SVP64FFT': self.use_svp64_fft,
+                          # XXX NO 'SVP64FFT': self.use_svp64_fft,
                           }
         else:
             conditions = None
@@ -1053,14 +1024,22 @@ 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.
+            # what this ultimately does is enable the 2nd implicit register
+            # (FRS) for SVP64-decoding.  all of these instructions are
+            # 3-in 2-out but there is not enough room either in the
+            # opcode *or* EXTRA2/3 to specify a 5th operand.
             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
-            comb += xo.eq(self.dec.opcode_in[1:6])
-            comb += self.use_svp64_fft.eq((major == 59) & (xo5 == 0b0) &
-                                          (xo != 0b01110))
+            xo = Signal(10)
+            comb += xo.eq(self.dec.opcode_in[1:11])
+            comb += self.use_svp64_fft.eq((major == 59) & xo.matches(
+                '-----00100',  # ffmsubs
+                '-----00101',  # ffmadds
+                '-----00110',  # ffnmsubs
+                '-----00111',  # ffnmadds
+                '1111100000',  # ffadds
+                '-----11011',  # fdmadds
+            ))
 
         # decoded/selected instruction flags
         comb += self.do_copy("data_len", self.op_get("ldst_len"))
@@ -1293,12 +1272,14 @@ class PowerDecode2(PowerDecodeSubset):
 
             # get SVSTATE srcstep (TODO: elwidth etc.) needed below
             vl = Signal.like(self.state.svstate.vl)
+            maxvl = Signal.like(self.state.svstate.maxvl)
             subvl = Signal.like(self.rm_dec.rm_in.subvl)
             srcstep = Signal.like(self.state.svstate.srcstep)
             dststep = Signal.like(self.state.svstate.dststep)
             ssubstep = Signal.like(self.state.svstate.ssubstep)
             dsubstep = Signal.like(self.state.svstate.ssubstep)
             comb += vl.eq(self.state.svstate.vl)
+            comb += maxvl.eq(self.state.svstate.maxvl)
             comb += subvl.eq(self.rm_dec.rm_in.subvl)
             comb += srcstep.eq(self.state.svstate.srcstep)
             comb += dststep.eq(self.state.svstate.dststep)
@@ -1339,7 +1320,7 @@ class PowerDecode2(PowerDecodeSubset):
                     with m.If(dec_o2.reg_out.ok & dec_o2.fp_madd_en):
                         with m.If(~self.remap_active[i]):
                             with m.If(svdec.isvec):
-                                comb += offs.eq(vl)  # VL for Vectors
+                                comb += offs.eq(maxvl)  # MAXVL for Vectors
                 # detect if Vectorised: add srcstep/dststep if yes.
                 # to_reg is 7-bits, outs get dststep added, ins get srcstep
                 with m.If(svdec.isvec):