From: Luke Kenneth Casson Leighton Date: Thu, 6 Oct 2022 13:36:23 +0000 (+0100) Subject: starting to add sv.cmp support and failfirst, had to add X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=94c774a45685a1363ef39192280da4be504041a9;p=openpower-isa.git starting to add sv.cmp support and failfirst, had to add SVMode to SVP64RMModeDecode to identify the different RM modes first --- diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index ba681df3..19c966ff 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -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) diff --git a/src/openpower/decoder/power_decoder.py b/src/openpower/decoder/power_decoder.py index 90b83621..396a2d4f 100644 --- a/src/openpower/decoder/power_decoder.py +++ b/src/openpower/decoder/power_decoder.py @@ -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) diff --git a/src/openpower/decoder/power_decoder2.py b/src/openpower/decoder/power_decoder2.py index 4bafa456..2f981f35 100644 --- a/src/openpower/decoder/power_decoder2.py +++ b/src/openpower/decoder/power_decoder2.py @@ -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) diff --git a/src/openpower/decoder/power_enums.py b/src/openpower/decoder/power_enums.py index 2eef3758..aa2e2b3a 100644 --- a/src/openpower/decoder/power_enums.py +++ b/src/openpower/decoder/power_enums.py @@ -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() diff --git a/src/openpower/decoder/power_svp64.py b/src/openpower/decoder/power_svp64.py index 47693727..5c36f03e 100644 --- a/src/openpower/decoder/power_svp64.py +++ b/src/openpower/decoder/power_svp64.py @@ -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) diff --git a/src/openpower/decoder/power_svp64_rm.py b/src/openpower/decoder/power_svp64_rm.py index 155905a4..c46e39fb 100644 --- a/src/openpower/decoder/power_svp64_rm.py +++ b/src/openpower/decoder/power_svp64_rm.py @@ -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):