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:
print (" ptype", sv_ptype)
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
# update SVSTATE with new srcstep
self.svstate.srcstep[0:7] = srcstep
# 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
self.assertEqual(sim.gpr(9), SelectableInt(0x1234, 64))
self.assertEqual(sim.gpr(10), SelectableInt(0x1235, 64))
- def test_sv_extsw_intpred(self):
+ def tst_sv_extsw_intpred(self):
# extsb, integer twin-pred mask: source is ~r3 (0b01), dest r3 (0b10)
# works as follows, where any zeros indicate "skip element"
# - sources are 9 and 10
sim = self.run_tst_program(program, initial_regs, svstate)
self._check_regs(sim, expected_regs)
- def test_sv_add_intpred(self):
+ def test_sv_extsw_intpred_dz(self):
+ # extsb, integer twin-pred mask: dest is r3 (0b01), zeroing on dest
+ isa = SVP64Asm(['svextsb/m=r3/dz 5.v, 9.v'
+ ])
+ lst = list(isa)
+ print ("listing", lst)
+
+ # initial values in GPR regfile
+ initial_regs = [0] * 32
+ initial_regs[3] = 0b01 # predicate mask (dest)
+ initial_regs[5] = 0xfeed # going to be overwritten
+ initial_regs[6] = 0xbeef # going to be overwritten (with zero)
+ initial_regs[9] = 0x91 # dest r3 is 0b01 so this will be used
+ initial_regs[10] = 0x90 # this gets read but the output gets zero'd
+ # SVSTATE (in this case, VL=2)
+ svstate = SVP64State()
+ svstate.vl[0:7] = 2 # VL
+ svstate.maxvl[0:7] = 2 # MAXVL
+ print ("SVSTATE", bin(svstate.spr.asint()))
+ # copy before running
+ expected_regs = deepcopy(initial_regs)
+ expected_regs[5] = 0xffff_ffff_ffff_ff91 # dest r3 is 0b01: store
+ expected_regs[6] = 0 # 2nd bit of r3 is 1: zero
+
+ with Program(lst, bigendian=False) as program:
+ sim = self.run_tst_program(program, initial_regs, svstate)
+ self._check_regs(sim, expected_regs)
+
+ def tst_sv_add_intpred(self):
# adds, integer predicated mask r3=0b10
# 1 = 5 + 9 => not to be touched (skipped)
# 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
sim = self.run_tst_program(program, initial_regs, svstate)
self._check_regs(sim, expected_regs)
- def test_sv_add_cr_pred(self):
+ def tst_sv_add_cr_pred(self):
# adds, CR predicated mask CR4.eq = 1, CR5.eq = 0, invert (ne)
# 1 = 5 + 9 => not to be touched (skipped)
# 2 = 6 + 10 => 0x3334 = 0x2223+0x1111
# "normal" mode
if sv_mode is None:
- mode |= (src_zero << 3) | (dst_zero << 4) # predicate zeroing
+ mode |= (src_zero << 4) | (dst_zero << 3) # predicate zeroing
sv_mode = 0b00
# "mapreduce" modes
# bit of weird encoding to jam zero-pred or SVM mode in.
# SVM mode can be enabled only when SUBVL=2/3/4 (vec2/3/4)
if subvl == 0:
- mode |= (src_zero << 3) # predicate src-zeroing
+ mode |= (dst_zero << 3) # predicate src-zeroing
elif mapreduce_svm:
mode |= (1 << 3) # SVM mode
# "failfirst" modes
elif sv_mode == 0b01:
- assert dst_zero == 0, "dest-zero not allowed in failfirst mode"
+ assert src_zero == 0, "dest-zero not allowed in failfirst mode"
if failfirst == 'RC1':
mode |= (0b1<<4) # sets RC1 mode
- mode |= (src_zero << 3) # predicate src-zeroing
+ mode |= (dst_zero << 3) # predicate src-zeroing
assert rc_mode==False, "ffirst RC1 only possible when Rc=0"
elif failfirst == '~RC1':
mode |= (0b1<<4) # sets RC1 mode...
- mode |= (src_zero << 3) # predicate src-zeroing
+ mode |= (dst_zero << 3) # predicate src-zeroing
mode |= (0b1<<2) # ... with inversion
assert rc_mode==False, "ffirst RC1 only possible when Rc=0"
else:
- assert src_zero == 0, "src-zero not allowed in ffirst BO"
+ assert dst_zero == 0, "dst-zero not allowed in ffirst BO"
assert rc_mode, "ffirst BO only possible when Rc=1"
mode |= (failfirst << 2) # set BO
# "saturation" modes
elif sv_mode == 0b10:
- mode |= (src_zero << 3) | (dst_zero << 4) # predicate zeroing
+ mode |= (src_zero << 4) | (dst_zero << 3) # predicate zeroing
mode |= (saturation<<2) # sets signed/unsigned saturation
# "predicate-result" modes. err... code-duplication from ffirst
elif sv_mode == 0b11:
- assert dst_zero == 0, "dest-zero not allowed in predresult mode"
+ assert src_zero == 0, "dest-zero not allowed in predresult mode"
if predresult == 'RC1':
mode |= (0b1<<4) # sets RC1 mode
- mode |= (src_zero << 3) # predicate src-zeroing
+ mode |= (dst_zero << 3) # predicate src-zeroing
assert rc_mode==False, "pr-mode RC1 only possible when Rc=0"
elif predresult == '~RC1':
mode |= (0b1<<4) # sets RC1 mode...
- mode |= (src_zero << 3) # predicate src-zeroing
+ mode |= (dst_zero << 3) # predicate src-zeroing
mode |= (0b1<<2) # ... with inversion
assert rc_mode==False, "pr-mode RC1 only possible when Rc=0"
else:
- assert src_zero == 0, "src-zero not allowed in pr-mode BO"
+ assert dst_zero == 0, "dst-zero not allowed in pr-mode BO"
assert rc_mode, "pr-mode BO only possible when Rc=1"
mode |= (predresult << 2) # set BO