"CA32": 0,
"overflow": 7, # should definitely be last
+ "CR0": 8, # likewise
}
fregs = ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
out, o_isvec)
if upd == LDSTMode.update.value:
return out, o_isvec
+ if name == 'RS':
+ fft_en = yield dec2.implicit_rs
+ if fft_en:
+ log("get_pdecode_idx_out2", out_sel, OutSel.RS.value,
+ out, o_isvec)
+ return out, o_isvec
if name == 'FRS':
- int_op = yield dec2.dec.op.internal_op
- fft_en = yield dec2.use_svp64_fft
- # if int_op == MicrOp.OP_FP_MADD.value and fft_en:
+ fft_en = yield dec2.implicit_rs
if fft_en:
log("get_pdecode_idx_out2", out_sel, OutSel.FRS.value,
out, o_isvec)
return
# look up instruction in ISA.instrs, prepare namespace
- info = self.instrs[ins_name]
+ if ins_name == 'pcdec': # grrrr yes there are others ("stbcx." etc.)
+ info = self.instrs[ins_name+"."]
+ else:
+ info = self.instrs[ins_name]
yield from self.prep_namespace(ins_name, info.form, info.op_fields)
# preserve order of register names
if name == 'CA32':
already_done |= 2
- log("carry already done?", bin(already_done))
+ log("carry already done?", bin(already_done), output_names)
carry_en = yield self.dec2.e.do.output_carry
if carry_en:
yield from self.handle_carry_(inputs, results, already_done)
if name == 'overflow':
overflow = output
+ # and one called CR0
+ cr0 = None
+ if info.write_regs:
+ for name, output in zip(output_names, results):
+ if name == 'CR0':
+ cr0 = output
+
if not self.is_svp64_mode: # yeah just no. not in parallel processing
# detect if overflow was in return result
ov_en = yield self.dec2.e.do.oe.oe
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
+ # don't do Rc=1 for svstep it is handled explicitly.
+ # XXX TODO: now that CR0 is supported, sort out svstep's pseudocode
+ # to write directly to CR0 instead of in ISACaller. hooyahh.
if rc_en and ins_name not in ['svstep']:
- yield from self.do_rc_ov(ins_name, results, overflow)
+ yield from self.do_rc_ov(ins_name, results, overflow, cr0)
+
+ # check failfirst
+ rm_mode = yield self.dec2.rm_dec.mode
+ ff_inv = yield self.dec2.rm_dec.inv
+ cr_bit = yield self.dec2.rm_dec.cr_sel
+ log(" ff rm_mode", rc_en, rm_mode, SVP64RMMode.FFIRST.value)
+ log(" inv", ff_inv)
+ log(" cr_bit", cr_bit)
+ ffirst_hit = False
+ if rc_en and rm_mode == SVP64RMMode.FFIRST.value:
+ regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, "CR0")
+ crtest = self.crl[regnum]
+ ffirst_hit = crtest[cr_bit] != ff_inv
+ log("cr test", regnum, int(crtest), crtest, cr_bit, ff_inv)
+ log("cr test?", ffirst_hit)
+ if ffirst_hit:
+ self.svstate.vl = srcstep
+ yield self.dec2.state.svstate.eq(self.svstate.value)
+ yield Settle() # let decoder update
# any modified return results?
yield from self.do_outregs_nia(asmop, ins_name, info,
output_names, results,
- carry_en, rc_en)
+ carry_en, rc_en, ffirst_hit)
- def do_rc_ov(self, ins_name, results, overflow):
+ def do_rc_ov(self, ins_name, results, overflow, cr0):
if ins_name.startswith("f"):
rc_reg = "CR1" # not calculated correctly yet (not FP compares)
else:
cmps = (SelectableInt(vl, 64), overflow,)
else:
overflow = None # do not override overflow except in setvl
- self.handle_comparison(cmps, regnum, overflow, no_so=is_setvl)
+
+ # if there was not an explicit CR0 in the pseudocode, do implicit Rc=1
+ if cr0 is None:
+ self.handle_comparison(cmps, regnum, overflow, no_so=is_setvl)
+ else:
+ # otherwise we just blat CR0 into the required regnum
+ log("explicit rc0", cr0)
+ self.crl[regnum].eq(cr0)
def do_outregs_nia(self, asmop, ins_name, info, output_names, results,
- carry_en, rc_en):
+ carry_en, rc_en, ffirst_hit):
# write out any regs for this instruction
if info.write_regs:
for name, output in zip(output_names, results):
yield from self.check_write(info, name, output, carry_en)
- # check advancement of src/dst/sub-steps and if PC needs updating
- nia_update = (yield from self.check_step_increment(results, rc_en,
+ if ffirst_hit:
+ self.svp64_reset_loop()
+ nia_update = True
+ else:
+ # check advancement of src/dst/sub-steps and if PC needs updating
+ nia_update = (yield from self.check_step_increment(results, rc_en,
asmop, ins_name))
if nia_update:
self.update_pc_next()
def check_write(self, info, name, output, carry_en):
if name == 'overflow': # ignore, done already (above)
return
+ if name == 'CR0': # ignore, done already (above)
+ return
if isinstance(output, int):
output = SelectableInt(output, 256)
# write carry flafs
unpack = self.svstate.unpack
vl = self.svstate.vl
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
+ cr_bit = yield self.dec2.rm_dec.cr_sel
log(" srcstep", srcstep)
log(" dststep", dststep)
log(" pack", pack)
log(" dsubstep", dsubstep)
log(" vl", vl)
log(" subvl", subvl)
+ log(" rm_mode", rm_mode)
+ log(" inv", ff_inv)
+ log(" cr_bit", cr_bit)
# check if end reached (we let srcstep overrun, above)
# nothing needs doing (TODO zeroing): just do next instruction