+ # fpscr
+ if self.fpscr is not None and s2.fpscr is not None:
+ if self.fpscr != s2.fpscr:
+ # use FPSCRState.fsi since that's much easier to read than a
+ # decimal integer and since unittest has fancy dict diffs.
+
+ # use auto_update_summary_bits=False since HDL might
+ # mis-compute those summary bits and we want to show the
+ # actual bits, not the corrected bits
+ fpscr1 = FPSCRState(self.fpscr, auto_update_summary_bits=False)
+ fpscr2 = FPSCRState(s2.fpscr, auto_update_summary_bits=False)
+ # FieldSelectableInt.__repr__ is too long
+ fpscr1 = {k: hex(int(v)) for k, v in fpscr1.fsi.items()}
+ fpscr2 = {k: hex(int(v)) for k, v in fpscr2.fsi.items()}
+ old_max_diff = self.dut.maxDiff
+ self.dut.maxDiff = None # show full diff
+ try:
+ self.dut.assertEqual(
+ fpscr1, fpscr2, "fpscr mismatch (%s != %s) %s\n" %
+ (self.state_type, s2.state_type, repr(self.code)))
+ finally:
+ self.dut.maxDiff = old_max_diff
+
+ for spr in self.sprs:
+ spr1 = self.sprs[spr]
+ spr2 = s2.sprs[spr]
+
+ if spr1 == spr2:
+ continue
+
+ if spr1 is not None and spr2 is not None:
+ # if not explicitly ignored
+
+ self.dut.fail(
+ f"{spr1:#x} != {spr2:#x}: {spr} mismatch "
+ f"({self.state_type} != {s2.state_type}) {self.code!r}\n")
+
+ if self.msr is not None and s2.msr is not None:
+ self.dut.assertEqual(
+ hex(self.msr), hex(s2.msr), "msr mismatch (%s != %s) %s" %
+ (self.state_type, s2.state_type, repr(self.code)))
+
+ def compare_mem(self, s2):
+ # copy dics to preserve state mem then pad empty locs since
+ # different Power ISA objects may differ how theystore memory
+ s1mem, s2mem = self.mem.copy(), s2.mem.copy()
+ for i in set(self.mem).difference(set(s2.mem)):
+ s2mem[i] = 0
+ for i in set(s2.mem).difference(set(self.mem)):
+ s1mem[i] = 0
+ for i in s1mem:
+ self.dut.assertEqual(s1mem[i], s2mem[i],
+ "mem mismatch location %d %s" % (i, self.code))
+
+ def dump_state_tofile(self, testname=None, testfile=None):
+ """dump_state_tofile: Takes a passed in teststate object along
+ with a test name and generates a code file located at
+ /tmp/testfile/testname to set an expected state object
+ """
+ lindent = ' '*8 # indent for code
+ # create the path
+ if testname is not None:
+ path = "/tmp/expected/"
+ if testfile is not None:
+ path += testfile + '/'
+ os.makedirs(path, exist_ok=True)
+ sout = open("%s%s.py" % (path, testname), "a+")
+ else:
+ sout = sys.stdout
+
+ # pc and intregs
+ sout.write("%se = ExpectedState(pc=%d)\n" % (lindent, self.pc))
+ for i, reg in enumerate(self.intregs):
+ if(reg != 0):
+ msg = "%se.intregs[%d] = 0x%x\n"
+ sout.write( msg % (lindent, i, reg))
+ for i, reg in enumerate(self.fpregs):
+ if reg != 0:
+ msg = "%se.fpregs[%d] = 0x%x\n"
+ sout.write(msg % (lindent, i, reg))
+ # CR fields
+ for i in range(8):
+ cri = self.crregs[i]
+ if(cri != 0):
+ msg = "%se.crregs[%d] = 0x%x\n"
+ sout.write( msg % (lindent, i, cri))
+ # XER
+ if(self.so != 0):
+ sout.write("%se.so = 0x%x\n" % (lindent, self.so))
+ if(self.ov != 0):
+ sout.write("%se.ov = 0x%x\n" % (lindent, self.ov))
+ if(self.ca != 0):
+ sout.write("%se.ca = 0x%x\n" % (lindent, self.ca))
+ if self.xer_other != 0:
+ sout.write("%se.xer_other = 0x%x\n" % (lindent, self.xer_other))
+
+ # FPSCR
+ if self.fpscr != 0:
+ sout.write(f"{lindent}e.fpscr = {self.fpscr:#x}\n")
+
+ # SPRs
+ for k, v in self.sprs.nonzero().items():
+ sout.write(f"{lindent}e.sprs[{k.name!r}] = {v:#x}\n")
+
+ # MSR
+ if self.msr != 0:
+ sout.write(f"{lindent}e.msr = {self.msr:#x}\n")
+
+ if sout != sys.stdout:
+ sout.close()
+
+
+def _get_regs(regs, asint=lambda v: v.asint()):
+ retval = []
+ while True:
+ try:
+ retval.append(asint(regs[len(retval)]))
+ except (IndexError, KeyError):
+ break
+ return retval
+