from openpower.decoder.power_enums import XER_bits
from openpower.util import log
+import os
+import sys
+
+global staterunner_factory
+staterunner_factory = {}
+
+
+def staterunner_add(name, kls):
+ log("staterunner_add", name, kls)
+ staterunner_factory[name] = kls
+
+
+# TBD an Abstract Base Class
+class StateRunner:
+ """StateRunner: an Abstract Base Class for preparing and running "State".
+ near-identical in concept to python unittest.TestCase
+ """
+ def __init__(self, name, kls):
+ staterunner_add(name, kls)
+ self.name = name
+
+ def setup_for_test(self):
+ if False: yield
+ def setup_during_test(self):
+ if False: yield
+ def prepare_for_test(self, test):
+ if False: yield
+ def run_test(self):
+ if False: yield
+ def end_test(self):
+ if False: yield
+ def cleanup(self):
+ if False: yield
class State:
+ """State: Base class for the "state" of the Power ISA object to be tested
+ including methods to compare various registers and memory between
+ them.
+
+ All methods implemented must be generators.
+
+ GPRs and CRs - stored as lists
+ XERs/PC - simple members
+ memory - stored as a dictionary {location: data}
+ """
def get_state(self):
yield from self.get_intregs()
yield from self.get_crregs()
def compare(self, s2):
# Compare int registers
- for i, (self.intregs, s2.intregs) in enumerate(
+ for i, (intreg, intreg2) in enumerate(
zip(self.intregs, s2.intregs)):
- log("asserting...reg", i, self.intregs, s2.intregs)
+ log("asserting...reg", i, intreg, intreg2)
log("code, frepr(code)", self.code, repr(self.code))
- self.dut.assertEqual(self.intregs, s2.intregs,
- "int reg %d (%s) not equal (%s) %s. got %x expected %x" %
+ self.dut.assertEqual(intreg, intreg2,
+ "int reg %d (%s) not equal (%s) %s. "
+ " got %x expected %x at pc %x %x\n" %
(i, self.state_type, s2.state_type, repr(self.code),
- self.intregs, s2.intregs))
+ intreg, intreg2, self.pc, s2.pc))
# CR registers
- for i, (self.crregs, s2.crregs) in enumerate(
+ for i, (crreg, crreg2) in enumerate(
+ zip(self.crregs, s2.crregs)):
+ log("asserting...cr", i, crreg, crreg2)
+
+ for i, (crreg, crreg2) in enumerate(
zip(self.crregs, s2.crregs)):
- log("asserting...cr", i, self.crregs, s2.crregs)
- self.dut.assertEqual(self.crregs, s2.crregs,
+ self.dut.assertEqual(crreg, crreg2,
"cr reg %d (%s) not equal (%s) %s. got %x expected %x" %
(i, self.state_type, s2.state_type, repr(self.code),
- self.crregs, s2.crregs))
+ crreg, crreg2))
# XER
self.dut.assertEqual(self.so, s2.so, "so mismatch (%s != %s) %s" %
(self.state_type, s2.state_type, repr(self.code)))
def compare_mem(self, s2):
- for i, (self.mem, s2.mem) in enumerate(
- zip(self.mem, s2.mem)):
- self.dut.assertEqual(self.mem, s2.mem,
- "mem mismatch %s %d %s %s" % (self.code, i,
- self.mem, s2.mem))
+ # 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))
+ # 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 sout != sys.stdout:
+ sout.close()
class SimState(State):
+ """SimState: Obtains registers and memory from an ISACaller object.
+ Note that yields are "faked" to maintain consistency and compatability
+ within the API.
+ """
def __init__(self, sim):
self.sim = sim
yield
self.crregs = []
for i in range(8):
- cri = self.sim.crl[7 - i].get_range().value
+ cri = self.sim.crl[i].get_range().value
self.crregs.append(cri)
log("class sim cr regs", list(map(hex, self.crregs)))
if False:
yield
keys = list(self.sim.mem.mem.keys())
- self.mem = []
+ self.mem = {}
+ # from each address in the underlying mem-simulated dictionary
+ # issue a 64-bit LD (with no byte-swapping)
for k in keys:
- self.mem.append(((k*8), self.sim.mem.mem[k]))
+ data = self.sim.mem.ld(k*8, 8, False)
+ self.mem[k*8] = data
class ExpectedState(State):
+ """ExpectedState: A user defined state set manually.
+ No methods, just pass into what expected values you want to test
+ with against other states.
+
+ see openpower/test/shift_rot/shift_rot_cases2.py for examples
+ """
def __init__(self, int_regs=None, pc=0, crregs=None,
so=0, ov=0, ca=0):
if int_regs is None:
def TestState(state_type, to_test, dut, code=0):
+ """TestState: Factory that returns a TestState object loaded with
+ registers and memory that can then be compared.
+
+ state_type: Type of state to create from global state_factory dictionary
+ to_test: The Power ISA object to test
+ dut: The unittest object
+ code: Actual machine code of what is being tested
+
+ The state_type can be added to the factory types using the state_add
+ function in this module.
+ """
state_class = state_factory[state_type]
state = state_class(to_test)
state.to_test = to_test
state, against = slist[i], slist[i+1]
state.compare(against)
+
+def teststate_check_mem(dut, states, test, code):
+ """teststate_check_mem: compares a set of Power ISA objects
+ to check if they have the same "state" (memory)
+ """
+ slist = []
+ # create one TestState per "thing"
+ for stype, totest in states.items():
+ state = yield from TestState(stype, totest, dut, code)
+ slist.append(state)
+ # compare each "thing" against the next "thing" in the list.
+ # (no need to do an O(N^2) comparison here, they *all* have to be the same
+ for i in range(len(slist)-1):
+ state, against = slist[i], slist[i+1]
+ state.compare_mem(against)