so = so | ov
self.spr['XER'][XER_bits['SO']] = so
- def handle_comparison(self, outputs, cr_idx=0):
+ def handle_comparison(self, outputs, cr_idx=0, overflow=None):
out = outputs[0]
assert isinstance(out, SelectableInt), \
"out zero not a SelectableInt %s" % repr(outputs)
positive = SelectableInt(out > 0, 1)
negative = SelectableInt(out < 0, 1)
SO = self.spr['XER'][XER_bits['SO']]
- log("handle_comparison SO", SO)
+ log("handle_comparison SO overflow", SO, overflow)
+ if overflow is not None and overflow == 1:
+ SO = SelectableInt(1, 1)
cr_field = selectconcat(negative, positive, zero, SO)
log("handle_comparison cr_field", self.cr, cr_idx, cr_field)
self.crl[cr_idx].eq(cr_field)
if carry_en:
yield from self.handle_carry_(inputs, results, already_done)
+ # check if one of the regs was named "overflow"
+ overflow = None
+ if info.write_regs:
+ for name, output in zip(output_names, results):
+ if name == 'overflow':
+ overflow = output
+
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
rc_en = yield self.dec2.e.do.rc.rc
if rc_en and ins_name not in ['svstep']:
regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, "CR0")
- self.handle_comparison(results, regnum)
+ self.handle_comparison(results, regnum, overflow)
# any modified return results?
if info.write_regs:
self.assertEqual(CR0[CRFields.GT], 1)
self.assertEqual(CR0[CRFields.SO], 0)
+ def test_3_setvl_overflow_rc1(self):
+ lst = SVP64Asm(["setvl. 5, 4, 5, 0, 1, 1",
+ ])
+ lst = list(lst)
+
+ # SVSTATE (in this case, MAXVL=5) which is going to get erased by setvl
+ # r4 (RA) is 4. and Rc=1. therefore, CR0 should be set to GT
+ svstate = SVP64State()
+ svstate.maxvl = 5 # MAXVL
+ print ("SVSTATE", bin(svstate.asint()))
+
+ initial_regs = [0] * 32
+ initial_regs[4] = 1000 # much greater than MAXVL
+
+ with Program(lst, bigendian=False) as program:
+ sim = self.run_tst_program(program, svstate=svstate,
+ initial_regs=initial_regs)
+ print ("SVSTATE after", bin(sim.svstate.asint()))
+ print (" vl", bin(sim.svstate.vl))
+ print (" mvl", bin(sim.svstate.maxvl))
+ print (" srcstep", bin(sim.svstate.srcstep))
+ print (" dststep", bin(sim.svstate.dststep))
+ print (" vfirst", bin(sim.svstate.vfirst))
+ self.assertEqual(sim.svstate.vl, 5)
+ self.assertEqual(sim.svstate.maxvl, 5)
+ self.assertEqual(sim.svstate.srcstep, 0)
+ self.assertEqual(sim.svstate.dststep, 0)
+ self.assertEqual(sim.svstate.vfirst, 0)
+ print(" gpr4", sim.gpr(4))
+ self.assertEqual(sim.gpr(4), SelectableInt(1000, 64)) # unmodified
+ print(" gpr5", sim.gpr(5))
+ self.assertEqual(sim.gpr(5), SelectableInt(5, 64)) # equal to MAXVL
+ CR0 = sim.crl[0]
+ print(" CR0", bin(CR0.get_range().value))
+ self.assertEqual(CR0[CRFields.EQ], 0)
+ self.assertEqual(CR0[CRFields.LT], 0)
+ self.assertEqual(CR0[CRFields.GT], 1)
+ self.assertEqual(CR0[CRFields.SO], 1)
+
+ def test_4_setvl_max_overflow_rc1(self):
+ """this should set overflow even though VL gets set to MAXVL
+ at its limit of 127 (0b1111111)
+ """
+ lst = SVP64Asm(["setvl. 5, 4, 127, 0, 1, 1",
+ ])
+ lst = list(lst)
+
+ # SVSTATE (in this case, MAXVL=5) which is going to get erased by setvl
+ # r4 (RA) is 4. and Rc=1. therefore, CR0 should be set to GT
+ svstate = SVP64State()
+ svstate.maxvl = 5 # MAXVL
+ print ("SVSTATE", bin(svstate.asint()))
+
+ initial_regs = [0] * 32
+ initial_regs[4] = 1000 # much greater than MAXVL
+
+ with Program(lst, bigendian=False) as program:
+ sim = self.run_tst_program(program, svstate=svstate,
+ initial_regs=initial_regs)
+ print ("SVSTATE after", bin(sim.svstate.asint()))
+ print (" vl", bin(sim.svstate.vl))
+ print (" mvl", bin(sim.svstate.maxvl))
+ print (" srcstep", bin(sim.svstate.srcstep))
+ print (" dststep", bin(sim.svstate.dststep))
+ print (" vfirst", bin(sim.svstate.vfirst))
+ self.assertEqual(sim.svstate.vl, 127)
+ self.assertEqual(sim.svstate.maxvl, 127)
+ self.assertEqual(sim.svstate.srcstep, 0)
+ self.assertEqual(sim.svstate.dststep, 0)
+ self.assertEqual(sim.svstate.vfirst, 0)
+ print(" gpr4", sim.gpr(4))
+ self.assertEqual(sim.gpr(4), SelectableInt(1000, 64)) # unmodified
+ print(" gpr5", sim.gpr(5))
+ self.assertEqual(sim.gpr(5), SelectableInt(127, 64)) # eq. MAXVL
+ CR0 = sim.crl[0]
+ print(" CR0", bin(CR0.get_range().value))
+ self.assertEqual(CR0[CRFields.EQ], 0)
+ self.assertEqual(CR0[CRFields.LT], 0)
+ self.assertEqual(CR0[CRFields.GT], 1)
+ self.assertEqual(CR0[CRFields.SO], 1)
+
+ def test_5_setvl_max_rc1(self):
+ """this should not set when VL gets set to MAXVL
+ at its limit of 127 (0b1111111)
+ """
+ lst = SVP64Asm(["setvl. 5, 4, 127, 0, 1, 1",
+ ])
+ lst = list(lst)
+
+ # SVSTATE (in this case, MAXVL=5) which is going to get erased by setvl
+ # r4 (RA) is 4. and Rc=1. therefore, CR0 should be set to GT
+ svstate = SVP64State()
+ svstate.maxvl = 5 # MAXVL
+ print ("SVSTATE", bin(svstate.asint()))
+
+ initial_regs = [0] * 32
+ initial_regs[4] = 127 # exactly equal to MAXVL
+
+ with Program(lst, bigendian=False) as program:
+ sim = self.run_tst_program(program, svstate=svstate,
+ initial_regs=initial_regs)
+ print ("SVSTATE after", bin(sim.svstate.asint()))
+ print (" vl", bin(sim.svstate.vl))
+ print (" mvl", bin(sim.svstate.maxvl))
+ print (" srcstep", bin(sim.svstate.srcstep))
+ print (" dststep", bin(sim.svstate.dststep))
+ print (" vfirst", bin(sim.svstate.vfirst))
+ self.assertEqual(sim.svstate.vl, 127)
+ self.assertEqual(sim.svstate.maxvl, 127)
+ self.assertEqual(sim.svstate.srcstep, 0)
+ self.assertEqual(sim.svstate.dststep, 0)
+ self.assertEqual(sim.svstate.vfirst, 0)
+ print(" gpr4", sim.gpr(4))
+ self.assertEqual(sim.gpr(4), SelectableInt(127, 64)) # unmodified
+ print(" gpr5", sim.gpr(5))
+ self.assertEqual(sim.gpr(5), SelectableInt(127, 64)) # eq. MAXVL
+ CR0 = sim.crl[0]
+ print(" CR0", bin(CR0.get_range().value))
+ self.assertEqual(CR0[CRFields.EQ], 0)
+ self.assertEqual(CR0[CRFields.LT], 0)
+ self.assertEqual(CR0[CRFields.GT], 1)
+ self.assertEqual(CR0[CRFields.SO], 0)
+
def test_svstep_1(self):
lst = SVP64Asm(["setvl 0, 0, 10, 1, 1, 1", # actual setvl (VF mode)
"setvl 0, 0, 1, 1, 0, 0", # svstep