print("reg", "%2d" % i, s)
+class SPR(dict):
+ def __init__(self, dec2, initial_sprs={}):
+ self.sd = dec2
+ dict.__init__(self)
+ for key, v in initial_sprs.items():
+ if isinstance(key, SelectableInt):
+ key = key.value
+ key = special_sprs.get(key, key)
+ if isinstance(key, int):
+ info = spr_dict[key]
+ else:
+ info = spr_byname[key]
+ if not isinstance(v, SelectableInt):
+ v = SelectableInt(v, info.length)
+ self[key] = v
+
+ def __getitem__(self, key):
+ print("get spr", key)
+ print("dict", self.items())
+ # if key in special_sprs get the special spr, otherwise return key
+ if isinstance(key, SelectableInt):
+ key = key.value
+ if isinstance(key, int):
+ key = spr_dict[key].SPR
+ key = special_sprs.get(key, key)
+ if key == 'HSRR0': # HACK!
+ key = 'SRR0'
+ if key == 'HSRR1': # HACK!
+ key = 'SRR1'
+ if key in self:
+ res = dict.__getitem__(self, key)
+ else:
+ if isinstance(key, int):
+ info = spr_dict[key]
+ else:
+ info = spr_byname[key]
+ dict.__setitem__(self, key, SelectableInt(0, info.length))
+ res = dict.__getitem__(self, key)
+ print("spr returning", key, res)
+ return res
+
+ def __setitem__(self, key, value):
+ if isinstance(key, SelectableInt):
+ key = key.value
+ if isinstance(key, int):
+ key = spr_dict[key].SPR
+ print("spr key", key)
+ key = special_sprs.get(key, key)
+ if key == 'HSRR0': # HACK!
+ self.__setitem__('SRR0', value)
+ if key == 'HSRR1': # HACK!
+ self.__setitem__('SRR1', value)
+ print("setting spr", key, value)
+ dict.__setitem__(self, key, value)
+
+ def __call__(self, ridx):
+ return self[ridx]
+
+
class PC:
def __init__(self, pc_init=0):
self.CIA = SelectableInt(pc_init, 64)
def get_predint(gpr, mask):
r10 = gpr(10)
r30 = gpr(30)
+ print ("get_predint", mask, SVP64PredInt.ALWAYS.value)
if mask == SVP64PredInt.ALWAYS.value:
return 0xffff_ffff_ffff_ffff
if mask == SVP64PredInt.R3_UNARY.value:
if mask == SVP64PredInt.R30_N.value:
return ~gpr(30).value
-# decode SVP64 predicate CR to reg number and invert
+# decode SVP64 predicate CR to reg number and invert status
def _get_predcr(mask):
if mask == SVP64PredCR.LT.value:
return 0, 1
if mask == SVP64PredCR.NS.value:
return 3, 0
+# read individual CR fields (0..VL-1), extract the required bit
+# and construct the mask
def get_predcr(crl, mask, vl):
idx, noninv = _get_predcr(mask)
mask = 0
return mask
-class SPR(dict):
- def __init__(self, dec2, initial_sprs={}):
- self.sd = dec2
- dict.__init__(self)
- for key, v in initial_sprs.items():
- if isinstance(key, SelectableInt):
- key = key.value
- key = special_sprs.get(key, key)
- if isinstance(key, int):
- info = spr_dict[key]
- else:
- info = spr_byname[key]
- if not isinstance(v, SelectableInt):
- v = SelectableInt(v, info.length)
- self[key] = v
-
- def __getitem__(self, key):
- print("get spr", key)
- print("dict", self.items())
- # if key in special_sprs get the special spr, otherwise return key
- if isinstance(key, SelectableInt):
- key = key.value
- if isinstance(key, int):
- key = spr_dict[key].SPR
- key = special_sprs.get(key, key)
- if key == 'HSRR0': # HACK!
- key = 'SRR0'
- if key == 'HSRR1': # HACK!
- key = 'SRR1'
- if key in self:
- res = dict.__getitem__(self, key)
- else:
- if isinstance(key, int):
- info = spr_dict[key]
- else:
- info = spr_byname[key]
- dict.__setitem__(self, key, SelectableInt(0, info.length))
- res = dict.__getitem__(self, key)
- print("spr returning", key, res)
- return res
-
- def __setitem__(self, key, value):
- if isinstance(key, SelectableInt):
- key = key.value
- if isinstance(key, int):
- key = spr_dict[key].SPR
- print("spr key", key)
- key = special_sprs.get(key, key)
- if key == 'HSRR0': # HACK!
- self.__setitem__('SRR0', value)
- if key == 'HSRR1': # HACK!
- self.__setitem__('SRR1', value)
- print("setting spr", key, value)
- dict.__setitem__(self, key, value)
-
- def __call__(self, ridx):
- return self[ridx]
-
def get_pdecode_idx_in(dec2, name):
op = dec2.dec.op
in1_sel = yield op.in1_sel
self.mem = Mem(row_bytes=8, initial_mem=initial_mem)
self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
# MMU mode, redirect underlying Mem through RADIX
+ self.msr = SelectableInt(initial_msr, 64) # underlying reg
if mmu:
self.mem = RADIX(self.mem, self)
self.imem = RADIX(self.imem, self)
self.pc = PC()
- self.msr = SelectableInt(initial_msr, 64) # underlying reg
# TODO, needed here:
# FPR (same as GPR except for FP nums)
if self.is_svp64_mode:
vl = self.svstate.vl.asint(msb0=True)
srcstep = self.svstate.srcstep.asint(msb0=True)
- dststep = self.svstate.srcstep.asint(msb0=True)
+ dststep = self.svstate.dststep.asint(msb0=True)
sv_a_nz = yield self.dec2.sv_a_nz
in1 = yield self.dec2.e.read_reg1.data
print ("SVP64: VL, srcstep, dststep, sv_a_nz, in1",
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_predcr(self.crl, srcpred, vl)
print (" pmode", pmode)
print (" ptype", sv_ptype)
+ print (" srcpred", bin(srcpred))
+ print (" dstpred", bin(dstpred))
print (" srcmask", bin(srcmask))
print (" dstmask", bin(dstmask))
+ print (" pred_sz", bin(pred_src_zero))
+ print (" pred_dz", bin(pred_dst_zero))
# okaaay, so here we simply advance srcstep (TODO dststep)
# 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
- while (((1<<srcstep) & srcmask) == 0) and (srcstep != vl):
- print (" skip", bin(1<<srcstep))
- srcstep += 1
+ if not pred_src_zero:
+ while (((1<<srcstep) & srcmask) == 0) and (srcstep != vl):
+ print (" skip", bin(1<<srcstep))
+ srcstep += 1
# same for dststep
- while (((1<<dststep) & dstmask) == 0) and (dststep != vl):
- print (" skip", bin(1<<dststep))
- dststep += 1
+ if not pred_dst_zero:
+ while (((1<<dststep) & dstmask) == 0) and (dststep != vl):
+ print (" skip", 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
# update SVSTATE with new srcstep
self.svstate.srcstep[0:7] = srcstep
# check if end reached (we let srcstep overrun, above)
# nothing needs doing (TODO zeroing): just do next instruction
- if srcstep == vl:
+ if srcstep == vl or dststep == vl:
self.svp64_reset_loop()
self.update_pc_next()
return
# in case getting the register number is needed, _RA, _RB
regname = "_" + name
self.namespace[regname] = regnum
- print('reading reg %s %s' % (name, str(regnum)), is_vec)
- reg_val = self.gpr(regnum)
+ if not self.is_svp64_mode or not pred_src_zero:
+ print('reading reg %s %s' % (name, str(regnum)), is_vec)
+ reg_val = self.gpr(regnum)
+ else:
+ print('zero input reg %s %s' % (name, str(regnum)), is_vec)
+ reg_val = 0
inputs.append(reg_val)
# "special" registers
if carry_en:
yield from self.handle_carry_(inputs, results, already_done)
- # detect if overflow was in return result
- overflow = None
- if info.write_regs:
- for name, output in zip(output_names, results):
- if name == 'overflow':
- overflow = output
-
- if hasattr(self.dec2.e.do, "oe"):
- ov_en = yield self.dec2.e.do.oe.oe
- ov_ok = yield self.dec2.e.do.oe.ok
- else:
- ov_en = False
- ov_ok = False
- print("internal overflow", overflow, ov_en, ov_ok)
- if ov_en & ov_ok:
- yield from self.handle_overflow(inputs, results, overflow)
-
- if hasattr(self.dec2.e.do, "rc"):
- rc_en = yield self.dec2.e.do.rc.rc
- else:
- rc_en = False
+ if not self.is_svp64_mode: # yeah just no. not in parallel processing
+ # detect if overflow was in return result
+ overflow = None
+ if info.write_regs:
+ for name, output in zip(output_names, results):
+ if name == 'overflow':
+ overflow = output
+
+ if hasattr(self.dec2.e.do, "oe"):
+ ov_en = yield self.dec2.e.do.oe.oe
+ ov_ok = yield self.dec2.e.do.oe.ok
+ else:
+ ov_en = False
+ ov_ok = False
+ print("internal overflow", overflow, ov_en, ov_ok)
+ if ov_en & ov_ok:
+ yield from self.handle_overflow(inputs, results, overflow)
+
+ # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
+ rc_en = False
+ if not self.is_svp64_mode or not pred_dst_zero:
+ if hasattr(self.dec2.e.do, "rc"):
+ rc_en = yield self.dec2.e.do.rc.rc
if rc_en:
regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, "CR0")
self.handle_comparison(results, regnum)
# temporary hack for not having 2nd output
regnum = yield getattr(self.decoder, name)
is_vec = False
- print('writing reg %d %s' % (regnum, str(output)), is_vec)
+ if self.is_svp64_mode and pred_dst_zero:
+ print('zeroing reg %d %s' % (regnum, str(output)),
+ is_vec)
+ output = SelectableInt(0, 256)
+ else:
+ print('writing reg %d %s' % (regnum, str(output)),
+ is_vec)
if output.bits > 64:
output = SelectableInt(output.value, 64)
self.gpr[regnum] = output
vl = self.svstate.vl.asint(msb0=True)
mvl = self.svstate.maxvl.asint(msb0=True)
srcstep = self.svstate.srcstep.asint(msb0=True)
- dststep = self.svstate.srcstep.asint(msb0=True)
+ dststep = self.svstate.dststep.asint(msb0=True)
sv_ptype = yield self.dec2.dec.op.SV_Ptype
no_out_vec = not (yield self.dec2.no_out_vec)
no_in_vec = not (yield self.dec2.no_in_vec)
svp64_is_vector = (no_out_vec or no_in_vec)
else:
svp64_is_vector = no_out_vec
- if svp64_is_vector and srcstep != vl-1:
+ if svp64_is_vector and srcstep != vl-1 and dststep != vl-1:
self.svstate.srcstep += SelectableInt(1, 7)
self.svstate.dststep += SelectableInt(1, 7)
self.pc.NIA.value = self.pc.CIA.value