starting to add sv.cmp support and failfirst, had to add
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 6 Oct 2022 13:36:23 +0000 (14:36 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 6 Oct 2022 13:36:23 +0000 (14:36 +0100)
SVMode to SVP64RMModeDecode to identify the different RM modes first

src/openpower/decoder/isa/caller.py
src/openpower/decoder/power_decoder.py
src/openpower/decoder/power_decoder2.py
src/openpower/decoder/power_enums.py
src/openpower/decoder/power_svp64.py
src/openpower/decoder/power_svp64_rm.py

index ba681df3296458afe89443afdf41829e0178fb24..19c966ffce542580e6b76b556a9a34ff30a217f2 100644 (file)
@@ -28,6 +28,7 @@ from openpower.decoder.power_enums import (spr_dict, spr_byname, XER_bits,
                                            insns, MicrOp,
                                            In1Sel, In2Sel, In3Sel,
                                            OutSel, CRInSel, CROutSel, LDSTMode,
+                                           SVMode,
                                            SVP64RMMode, SVP64PredMode,
                                            SVP64PredInt, SVP64PredCR,
                                            SVP64LDSTmode, FPTRANS_INSNS)
@@ -1844,7 +1845,9 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
         # check failfirst
         ffirst_hit = False
         if self.is_svp64_mode:
-            ffirst_hit = (yield from self.check_ffirst(rc_en, srcstep))
+            sv_mode = yield self.dec2.rm_dec.sv_mode
+            is_cr = sv_mode == SVMode.CROP.value
+            ffirst_hit = (yield from self.check_ffirst(rc_en or is_cr, srcstep))
 
         # any modified return results?
         yield from self.do_outregs_nia(asmop, ins_name, info, outs,
@@ -1863,6 +1866,7 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
         log("        RC1", RC1)
         log("        vli", vli)
         log("     cr_bit", cr_bit)
+        log("      rc_en", rc_en)
         if not rc_en or rm_mode != SVP64RMMode.FFIRST.value:
             return False
         # get the CR vevtor, do BO-test
@@ -2223,6 +2227,7 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
         pack = self.svstate.pack
         unpack = self.svstate.unpack
         vl = self.svstate.vl
+        sv_mode = yield self.dec2.rm_dec.sv_mode
         subvl = yield self.dec2.rm_dec.rm_in.subvl
         rm_mode = yield self.dec2.rm_dec.mode
         ff_inv = yield self.dec2.rm_dec.inv
@@ -2236,6 +2241,7 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
         log("         vl", vl)
         log("      subvl", subvl)
         log("    rm_mode", rm_mode)
+        log("    sv_mode", sv_mode)
         log("        inv", ff_inv)
         log("     cr_bit", cr_bit)
 
index 90b836215f3401a4f37f7b9ac44da754fa10de66..396a2d4f319eab94a403e72995a22c3f91ce9ba5 100644 (file)
@@ -93,7 +93,8 @@ from nmigen import Module, Elaboratable, Signal, Cat, Mux, Const
 from nmigen.cli import rtlil, verilog
 from openpower.decoder.power_enums import (Function, Form, MicrOp,
                                            In1Sel, In2Sel, In3Sel, OutSel,
-                                           SVEXTRA, SVEtype, SVPtype, # Simple-V
+                                           SVEXTRA, SVMode, # Simple-V
+                                           SVEtype, SVPtype, # Simple-V
                                            RCOE, LdstLen, LDSTMode, CryIn,
                                            single_bit_flags, CRInSel,
                                            CROutSel, get_signal_name,
@@ -125,6 +126,7 @@ power_op_types = {'function_unit': Function,
                   'asmcode': asmlen,
                   'SV_Etype': SVEtype,
                   'SV_Ptype': SVPtype,
+                  'SV_mode': SVMode,
                   'in1_sel': In1Sel,
                   'in2_sel': In2Sel,
                   'in3_sel': In3Sel,
@@ -160,6 +162,7 @@ power_op_csvmap = {'function_unit': 'unit',
                    'sv_cr_out': 'sv_cr_out',
                    'SV_Etype': 'SV_Etype',
                    'SV_Ptype': 'SV_Ptype',
+                   'SV_mode': 'SV_mode',
                    'cr_in': 'CR in',
                    'cr_out': 'CR out',
                    'ldst_len': 'ldst len',
@@ -248,7 +251,7 @@ class PowerOp:
             if field not in power_op_csvmap:
                 continue
             csvname = power_op_csvmap[field]
-            # log(field, ptype, csvname, row)
+            log("_eq", field, ptype, csvname, row)
             val = row[csvname]
             if csvname == 'upd' and isinstance(val, int):  # LDSTMode different
                 val = ptype(val)
index 4bafa456c1b3b96a3730a3cc7ff609c1a28cdc65..2f981f35fc786a1a140f32cfe872bb2893b3be69 100644 (file)
@@ -740,6 +740,7 @@ class DecodeCROut(Elaboratable):
 record_names = {'insn_type': 'internal_op',
                 'fn_unit': 'function_unit',
                 'SV_Ptype': 'SV_Ptype',
+                'SV_mode': 'SV_mode',
                 'rc': 'rc_sel',
                 'oe': 'rc_sel',
                 'zero_a': 'in1_sel',
@@ -1008,7 +1009,10 @@ class PowerDecodeSubset(Elaboratable):
             # quickly determined, and the Decoder result MUXed over to
             # the alternative decoder, svdecldst. what a mess... *sigh*
             sv_ptype = self.op_get("SV_Ptype")
+            sv_mode = self.op_get("SV_mode")
             fn = self.op_get("function_unit")
+            print ("sv_mode n", sv_mode)
+            comb += rm_dec.sv_mode.eq(sv_mode)  # BRANCH/CROP/LDST_IMM etc.
             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
@@ -1191,6 +1195,7 @@ class PowerDecode2(PowerDecodeSubset):
             subset.add("sv_cr_out")
             subset.add("SV_Etype")
             subset.add("SV_Ptype")
+            subset.add("SV_mode")
             # from SVP64RMModeDecode
             for (field, _) in sv_input_record_layout:
                 subset.add(field)
index 2eef375801e3aee0badac50711507da07c787506..aa2e2b3ae769e88f0df48e6c6b84510dfe7d7e94 100644 (file)
@@ -175,6 +175,7 @@ class Form(Enum):
 
 
 class SVMode(Enum):
+    NONE = 0          # for non-SV instructions only
     NORMAL = auto()
     LDST_IDX = auto()
     LDST_IMM = auto()
index 47693727e1bd59d9ddb87e7995cc77357300832d..5c36f03e1556ae5857e59c820fd1ec2600ee7ff9 100644 (file)
@@ -105,6 +105,7 @@ class SVP64RM:
             # dummy (blank) fields, first
             entry.update({'EXTRA0': '0', 'EXTRA1': '0', 'EXTRA2': '0',
                           'EXTRA3': '0',
+                          'SV_mode': 'NONE',
                           'SV_Ptype': 'NONE', 'SV_Etype': 'NONE',
                           'sv_cr_in': 'NONE', 'sv_cr_out': 'NONE'})
             for fname in ['in1', 'in2', 'in3', 'out', 'out2']:
@@ -119,6 +120,7 @@ class SVP64RM:
             svp64 = self.instrs[asmcode]
             for k, v in {'EXTRA0': '0', 'EXTRA1': '1', 'EXTRA2': '2',
                           'EXTRA3': '3',
+                          'SV_mode': 'mode',
                           'SV_Ptype': 'Ptype', 'SV_Etype': 'Etype'}.items():
                 entry[k] = svp64[v]
 
@@ -182,4 +184,5 @@ if __name__ == '__main__':
             print (entry)
     minor_31 = isa.get_svp64_csv("minor_31.csv")
     for entry in minor_31:
-        print (entry)
+        if entry['comment'].startswith('cmp'):
+            print ("cmp", entry)
index 155905a4b9a15c2272fa512ceed14749c04715b6..c46e39fb9b194ecb4719fe993d6a4755f87070c8 100644 (file)
@@ -18,6 +18,7 @@ https://libre-soc.org/openpower/sv/svp64/
 
 from nmigen import Elaboratable, Module, Signal, Const
 from openpower.decoder.power_enums import (SVP64RMMode, Function, SVPtype,
+                                    SVMode,
                                     SVP64PredMode, SVP64sat, SVP64LDSTmode,
                                     SVP64BCPredMode, SVP64BCVLSETMode,
                                     SVP64BCGate, SVP64BCCTRMode,
@@ -37,6 +38,7 @@ sv_input_record_layout = [
         ('sv_saturate', SVP64sat),
         ('sv_ldstmode', SVP64LDSTmode),
         ('SV_Ptype', SVPtype),
+        ('SV_mode', SVMode),
         #('sv_RC1', 1),
     ]
 
@@ -97,6 +99,7 @@ class SVP64RMModeDecode(Elaboratable):
         ##### inputs #####
         self.rm_in = SVP64Rec(name=name)
         self.fn_in = Signal(Function) # LD/ST and Branch is different
+        self.sv_mode = Signal(SVMode) # BRANCH/LDST_IMM/CROP etc.
         self.svp64_vf_in = Signal()  # Vertical-First Mode
         self.ptype_in = Signal(SVPtype)
         self.rc_in = Signal()
@@ -145,8 +148,10 @@ class SVP64RMModeDecode(Elaboratable):
         # decode pieces of mode
         is_ldst = Signal()
         is_bc = Signal()
+        is_cr = Signal()
         comb += is_ldst.eq(self.fn_in == Function.LDST)
-        comb += is_bc.eq(self.fn_in == Function.BRANCH)
+        comb += is_bc.eq(self.fn_in == Function.BRANCH) # XXX TODO use SV Mode
+        comb += is_cr.eq(self.sv_mode == SVMode.CROP.value)
         mode2 = sel(m, mode, SVP64MODE.MOD2)
         cr = sel(m, mode, SVP64MODE.CR)
 
@@ -165,6 +170,16 @@ class SVP64RMModeDecode(Elaboratable):
             comb += self.bc_lru.eq(self.rm_in.elwidth[0])
             comb += self.bc_vsb.eq(self.rm_in.ewsrc[0])
 
+        with m.Elif(is_cr):
+            with m.Switch(mode2):
+                with m.Case(0, 1): # needs further decoding (LDST no mapreduce)
+                    with m.If(mode[SVP64MODE.REDUCE]):
+                        comb += self.mode.eq(SVP64RMMode.MAPREDUCE)
+                    with m.Else():
+                        comb += self.mode.eq(SVP64RMMode.NORMAL)
+                with m.Case(2,3):
+                    comb += self.mode.eq(SVP64RMMode.FFIRST) # fail-first
+
         with m.Else():
             # combined arith / ldst decoding due to similarity
             with m.Switch(mode2):