From 5b457f75cbbf4c43168d898286d103ab1bb926a5 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Mon, 19 Sep 2022 08:02:48 +0100 Subject: [PATCH] move two big step/loop functions into separate class out of ISACaller --- src/openpower/decoder/isa/caller.py | 318 ++++++++++++++-------------- 1 file changed, 163 insertions(+), 155 deletions(-) diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index 7c19928a..3fe5e284 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -523,7 +523,169 @@ def get_pdecode_idx_out2(dec2, name): return None, False -class ISACaller(ISACallerHelper, ISAFPHelpers): +class StepLoop: + """deals with svstate looping. + """ + + def __init__(self): + pass + + def advance_svstate_steps(self, end_src=False, end_dst=False): + """ advance sub/steps. note that Pack/Unpack *INVERTS* the order. + TODO when Pack/Unpack is set, substep becomes the *outer* loop + """ + subvl = yield self.dec2.rm_dec.rm_in.subvl + pack = self.svstate.pack + unpack = self.svstate.unpack + ssubstep = self.svstate.ssubstep + dsubstep = self.svstate.dsubstep + end_ssub = ssubstep == subvl + end_dsub = dsubstep == subvl + log(" pack/unpack/subvl", pack, unpack, subvl, + "end", end_src, end_dst, + "sub", end_ssub, end_dsub) + # first source step + srcstep = self.svstate.srcstep + if pack: + # pack advances subvl in *outer* loop + if end_src: + if not end_ssub: + self.svstate.ssubstep += SelectableInt(1, 2) + self.svstate.srcstep = SelectableInt(0, 7) # reset + else: + self.svstate.srcstep += SelectableInt(1, 7) # advance srcstep + else: + # advance subvl in *inner* loop + if end_ssub: + if not end_src: + self.svstate.srcstep += SelectableInt(1, 7) + self.svstate.ssubstep = SelectableInt(0, 2) # reset + else: + self.svstate.ssubstep += SelectableInt(1, 2) # advance ssubstep + + # now dest step + if unpack: + # unpack advances subvl in *outer* loop + if end_dst: + if not end_dsub: + self.svstate.dsubstep += SelectableInt(1, 2) + self.svstate.dststep = SelectableInt(0, 7) # reset + else: + self.svstate.dststep += SelectableInt(1, 7) # advance dststep + else: + # advance subvl in *inner* loop + if end_dsub: + if not end_dst: + self.svstate.dststep += SelectableInt(1, 7) + self.svstate.dsubstep = SelectableInt(0, 2) # reset + else: + self.svstate.dsubstep += SelectableInt(1, 2) # advance ssubstep + log(" advance", self.svstate.srcstep, self.svstate.ssubstep, + "dst", self.svstate.dststep, self.svstate.dsubstep) + + def svstate_pre_inc(self): + """check if srcstep/dststep need to skip over masked-out predicate bits + note that this is not supposed to do anything to substep, + it is purely for skipping masked-out bits + """ + # get SVSTATE VL (oh and print out some debug stuff) + # yield Delay(1e-10) # make changes visible + vl = self.svstate.vl + subvl = yield self.dec2.rm_dec.rm_in.subvl + srcstep = self.svstate.srcstep + dststep = self.svstate.dststep + ssubstep = self.svstate.ssubstep + dsubstep = self.svstate.dsubstep + pack = self.svstate.pack + unpack = self.svstate.unpack + sv_a_nz = yield self.dec2.sv_a_nz + fft_mode = yield self.dec2.use_svp64_fft + in1 = yield self.dec2.e.read_reg1.data + log("SVP64: VL, subvl, srcstep, dststep, ssubstep, dsybstep, sv_a_nz, " + "in1 fft, svp64", + vl, subvl, srcstep, dststep, ssubstep, dsubstep, + sv_a_nz, in1, fft_mode, + self.is_svp64_mode) + + # get predicate mask (all 64 bits) + srcmask = dstmask = 0xffff_ffff_ffff_ffff + + pmode = yield self.dec2.rm_dec.predmode + reverse_gear = yield self.dec2.rm_dec.reverse_gear + sv_ptype = yield self.dec2.dec.op.SV_Ptype + srcpred = yield self.dec2.rm_dec.srcpred + dstpred = yield self.dec2.rm_dec.dstpred + pred_src_zero = yield self.dec2.rm_dec.pred_sz + pred_dst_zero = yield self.dec2.rm_dec.pred_dz + if pmode == SVP64PredMode.INT.value: + srcmask = dstmask = get_predint(self.gpr, dstpred) + if sv_ptype == SVPtype.P2.value: + srcmask = get_predint(self.gpr, srcpred) + elif pmode == SVP64PredMode.CR.value: + srcmask = dstmask = get_predcr(self.crl, dstpred, vl) + if sv_ptype == SVPtype.P2.value: + srcmask = get_predcr(self.crl, srcpred, vl) + # work out if the ssubsteps are completed + ssubstart = ssubstep == 0 + dsubstart = dsubstep == 0 + log(" pmode", pmode) + log(" pack/unpack", pack, unpack) + log(" reverse", reverse_gear) + log(" ptype", sv_ptype) + log(" srcpred", bin(srcpred)) + log(" dstpred", bin(dstpred)) + log(" srcmask", bin(srcmask)) + log(" dstmask", bin(dstmask)) + log(" pred_sz", bin(pred_src_zero)) + log(" pred_dz", bin(pred_dst_zero)) + log(" ssubstart", ssubstart) + log(" dsubstart", dsubstart) + + # okaaay, so here we simply advance srcstep (TODO dststep) + # this can ONLY be done at the beginning of the "for" loop + # (this is all actually a FSM so it's hell to keep track sigh) + srcstep_skip = False + if ssubstart: + # until the predicate mask has a "1" bit... or we run out of VL + # let srcstep==VL be the indicator to move to next instruction + if not pred_src_zero: + srcstep_skip = True + + # srcstep-skipping opportunity identified + if srcstep_skip: + while (((1 << srcstep) & srcmask) == 0) and (srcstep != vl): + log(" sskip", bin(1 << srcstep)) + srcstep += 1 + + dststep_skip = False + if dsubstart: + # same for dststep + if not pred_dst_zero: + dststep_skip = True + + # dststep-skipping opportunity identified + if dststep_skip: + while (((1 << dststep) & dstmask) == 0) and (dststep != vl): + log(" dskip", bin(1 << dststep)) + dststep += 1 + + # now work out if the relevant mask bits require zeroing + if pred_dst_zero: + pred_dst_zero = ((1 << dststep) & dstmask) == 0 + if pred_src_zero: + pred_src_zero = ((1 << srcstep) & srcmask) == 0 + + # store new srcstep / dststep + self.new_srcstep, self.new_dststep = (srcstep, dststep) + self.new_ssubstep, self.new_dsubstep = (ssubstep, dsubstep) + self.pred_dst_zero, self.pred_src_zero = (pred_dst_zero, pred_src_zero) + log(" new srcstep", srcstep) + log(" new dststep", dststep) + log(" new ssubstep", ssubstep) + log(" new dsubstep", dsubstep) + + +class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop): # decoder2 - an instance of power_decoder2 # regfile - a list of initial values for the registers # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR @@ -1681,107 +1843,6 @@ class ISACaller(ISACallerHelper, ISAFPHelpers): return SelectableInt(self.svstate.dststep, 7) return SelectableInt(0, 7) - def svstate_pre_inc(self): - """check if srcstep/dststep need to skip over masked-out predicate bits - note that this is not supposed to do anything to substep, - it is purely for skipping masked-out bits - """ - # get SVSTATE VL (oh and print out some debug stuff) - # yield Delay(1e-10) # make changes visible - vl = self.svstate.vl - subvl = yield self.dec2.rm_dec.rm_in.subvl - srcstep = self.svstate.srcstep - dststep = self.svstate.dststep - ssubstep = self.svstate.ssubstep - dsubstep = self.svstate.dsubstep - pack = self.svstate.pack - unpack = self.svstate.unpack - sv_a_nz = yield self.dec2.sv_a_nz - fft_mode = yield self.dec2.use_svp64_fft - in1 = yield self.dec2.e.read_reg1.data - log("SVP64: VL, subvl, srcstep, dststep, ssubstep, dsybstep, sv_a_nz, " - "in1 fft, svp64", - vl, subvl, srcstep, dststep, ssubstep, dsubstep, - sv_a_nz, in1, fft_mode, - self.is_svp64_mode) - - # get predicate mask (all 64 bits) - srcmask = dstmask = 0xffff_ffff_ffff_ffff - - pmode = yield self.dec2.rm_dec.predmode - reverse_gear = yield self.dec2.rm_dec.reverse_gear - sv_ptype = yield self.dec2.dec.op.SV_Ptype - srcpred = yield self.dec2.rm_dec.srcpred - dstpred = yield self.dec2.rm_dec.dstpred - pred_src_zero = yield self.dec2.rm_dec.pred_sz - pred_dst_zero = yield self.dec2.rm_dec.pred_dz - if pmode == SVP64PredMode.INT.value: - srcmask = dstmask = get_predint(self.gpr, dstpred) - if sv_ptype == SVPtype.P2.value: - srcmask = get_predint(self.gpr, srcpred) - elif pmode == SVP64PredMode.CR.value: - srcmask = dstmask = get_predcr(self.crl, dstpred, vl) - if sv_ptype == SVPtype.P2.value: - srcmask = get_predcr(self.crl, srcpred, vl) - # work out if the ssubsteps are completed - ssubstart = ssubstep == 0 - dsubstart = dsubstep == 0 - log(" pmode", pmode) - log(" pack/unpack", pack, unpack) - log(" reverse", reverse_gear) - log(" ptype", sv_ptype) - log(" srcpred", bin(srcpred)) - log(" dstpred", bin(dstpred)) - log(" srcmask", bin(srcmask)) - log(" dstmask", bin(dstmask)) - log(" pred_sz", bin(pred_src_zero)) - log(" pred_dz", bin(pred_dst_zero)) - log(" ssubstart", ssubstart) - log(" dsubstart", dsubstart) - - # okaaay, so here we simply advance srcstep (TODO dststep) - # this can ONLY be done at the beginning of the "for" loop - # (this is all actually a FSM so it's hell to keep track sigh) - srcstep_skip = False - if ssubstart: - # until the predicate mask has a "1" bit... or we run out of VL - # let srcstep==VL be the indicator to move to next instruction - if not pred_src_zero: - srcstep_skip = True - - # srcstep-skipping opportunity identified - if srcstep_skip: - while (((1 << srcstep) & srcmask) == 0) and (srcstep != vl): - log(" sskip", bin(1 << srcstep)) - srcstep += 1 - - dststep_skip = False - if dsubstart: - # same for dststep - if not pred_dst_zero: - dststep_skip = True - - # dststep-skipping opportunity identified - if dststep_skip: - while (((1 << dststep) & dstmask) == 0) and (dststep != vl): - log(" dskip", bin(1 << dststep)) - dststep += 1 - - # now work out if the relevant mask bits require zeroing - if pred_dst_zero: - pred_dst_zero = ((1 << dststep) & dstmask) == 0 - if pred_src_zero: - pred_src_zero = ((1 << srcstep) & srcmask) == 0 - - # store new srcstep / dststep - self.new_srcstep, self.new_dststep = (srcstep, dststep) - self.new_ssubstep, self.new_dsubstep = (ssubstep, dsubstep) - self.pred_dst_zero, self.pred_src_zero = (pred_dst_zero, pred_src_zero) - log(" new srcstep", srcstep) - log(" new dststep", dststep) - log(" new ssubstep", ssubstep) - log(" new dsubstep", dsubstep) - def get_src_dststeps(self): """gets srcstep, dststep, and ssubstep, dsubstep """ @@ -1903,59 +1964,6 @@ class ISACaller(ISACallerHelper, ISAFPHelpers): log("end of sub-pc call", self.namespace['CIA'], self.namespace['NIA']) return False # DO NOT allow PC update whilst Sub-PC loop running - def advance_svstate_steps(self, end_src=False, end_dst=False): - """ advance sub/steps. note that Pack/Unpack *INVERTS* the order. - TODO when Pack/Unpack is set, substep becomes the *outer* loop - """ - subvl = yield self.dec2.rm_dec.rm_in.subvl - pack = self.svstate.pack - unpack = self.svstate.unpack - ssubstep = self.svstate.ssubstep - dsubstep = self.svstate.dsubstep - end_ssub = ssubstep == subvl - end_dsub = dsubstep == subvl - log(" pack/unpack/subvl", pack, unpack, subvl, - "end", end_src, end_dst, - "sub", end_ssub, end_dsub) - # first source step - srcstep = self.svstate.srcstep - if pack: - # pack advances subvl in *outer* loop - if end_src: - if not end_ssub: - self.svstate.ssubstep += SelectableInt(1, 2) - self.svstate.srcstep = SelectableInt(0, 7) # reset - else: - self.svstate.srcstep += SelectableInt(1, 7) # advance srcstep - else: - # advance subvl in *inner* loop - if end_ssub: - if not end_src: - self.svstate.srcstep += SelectableInt(1, 7) - self.svstate.ssubstep = SelectableInt(0, 2) # reset - else: - self.svstate.ssubstep += SelectableInt(1, 2) # advance ssubstep - - # now dest step - if unpack: - # unpack advances subvl in *outer* loop - if end_dst: - if not end_dsub: - self.svstate.dsubstep += SelectableInt(1, 2) - self.svstate.dststep = SelectableInt(0, 7) # reset - else: - self.svstate.dststep += SelectableInt(1, 7) # advance dststep - else: - # advance subvl in *inner* loop - if end_dsub: - if not end_dst: - self.svstate.dststep += SelectableInt(1, 7) - self.svstate.dsubstep = SelectableInt(0, 2) # reset - else: - self.svstate.dsubstep += SelectableInt(1, 2) # advance ssubstep - log(" advance", self.svstate.srcstep, self.svstate.ssubstep, - "dst", self.svstate.dststep, self.svstate.dsubstep) - def update_pc_next(self): # UPDATE program counter self.pc.update(self.namespace, self.is_svp64_mode) -- 2.30.2