if rc_en and ins_name not in ['svstep']:
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, cr0):
if ins_name.startswith("f"):
# 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)
- return
- # otherwise we just blat CR0 into the required regnum
- log("explicit rc0", cr0)
- self.crl[regnum].eq(cr0)
+ 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()
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
--- /dev/null
+from nmigen import Module, Signal
+from nmigen.sim import Simulator, Delay, Settle
+from nmutil.formaltest import FHDLTestCase
+import unittest
+from openpower.decoder.isa.caller import ISACaller
+from openpower.decoder.power_decoder import (create_pdecode)
+from openpower.decoder.power_decoder2 import (PowerDecode2)
+from openpower.simulator.program import Program
+from openpower.decoder.isa.caller import ISACaller, SVP64State
+from openpower.decoder.selectable_int import SelectableInt
+from openpower.decoder.orderedset import OrderedSet
+from openpower.decoder.isa.all import ISA
+from openpower.decoder.isa.test_caller import Register, run_tst
+from openpower.sv.trans.svp64 import SVP64Asm
+from openpower.consts import SVP64CROffs
+from copy import deepcopy
+from openpower.decoder.helpers import fp64toselectable
+from openpower.decoder.isa.remap_preduce_yield import preduce_y
+from functools import reduce
+import operator
+
+
+class DecoderTestCase(FHDLTestCase):
+
+ def _check_regs(self, sim, expected):
+ for i in range(32):
+ self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
+
+ def test_sv_addi_ffirst(self):
+ lst = SVP64Asm([ "sv.subf./ff=eq *0,8,*0"
+ ])
+ lst = list(lst)
+
+ # SVSTATE
+ svstate = SVP64State()
+ svstate.vl = 4 # VL
+ svstate.maxvl = 4 # MAXVL
+ print ("SVSTATE", bin(svstate.asint()))
+
+ gprs = [0] * 64
+ gprs[8] = 3
+ vec = [9, 8, 3, 4]
+
+ res = []
+ # store GPRs
+ for i, x in enumerate(vec):
+ gprs[i] = x
+
+ with Program(lst, bigendian=False) as program:
+ sim = self.run_tst_program(program, initial_regs=gprs,
+ svstate=svstate)
+ for i in range(4):
+ val = sim.gpr(i).value
+ res.append(val)
+ print ("i", i, val)
+ # confirm that the results are as expected
+ expected = deepcopy(vec)
+ for i in range(4):
+ expected[i] -= gprs[8]
+ if expected[i] == 0:
+ break
+ for i, v in enumerate(res):
+ self.assertEqual(v, expected[i])
+
+
+ def run_tst_program(self, prog, initial_regs=None,
+ svstate=None,
+ initial_mem=None,
+ initial_fprs=None):
+ if initial_regs is None:
+ initial_regs = [0] * 32
+ simulator = run_tst(prog, initial_regs, mem=initial_mem,
+ initial_fprs=initial_fprs,
+ svstate=svstate)
+
+ print ("GPRs")
+ simulator.gpr.dump()
+ print ("FPRs")
+ simulator.fpr.dump()
+
+ return simulator
+
+
+if __name__ == "__main__":
+ unittest.main()