reduce code linecount slightly
[openpower-isa.git] / src / openpower / test / state.py
1 """ Power ISA test API
2
3 This module implements the creation, inspection and comparison
4 of test states from different sources.
5
6 The basic premise is to create a test state using the TestState method.
7 The TestState method returns a test state object initialized with a
8 basic set of registers pulled from the 'to_test' object. The
9 state created can then be tested against other test states using the
10 'compare' method.
11
12 The SimState class provides an example of needed registers and naming.
13
14 The TestState method relies on the 'state_factory' dictionary for lookup
15 of associated test class creation. The dictionary can be added to using
16 the state_add method.
17
18 Also note when creating and accessing test state classes and object
19 methods, the use of yield from/yield is required.
20
21
22 """
23
24
25 from openpower.decoder.power_enums import XER_bits
26 from openpower.util import log
27
28
29 class State:
30 def get_state(self):
31 yield from self.get_intregs()
32 yield from self.get_crregs()
33 yield from self.get_xregs()
34 yield from self.get_pc()
35
36 def compare(self, s2):
37 # Compare int registers
38 for i, (self.intregs, s2.intregs) in enumerate(
39 zip(self.intregs, s2.intregs)):
40 log("asserting...reg", i, self.intregs, s2.intregs)
41 log("code, frepr(code)", self.code, repr(self.code))
42 self.dut.assertEqual(self.intregs, s2.intregs,
43 "int reg %d (%s) not equal (%s) %s. got %x expected %x" %
44 (i, self.state_type, s2.state_type, repr(self.code),
45 self.intregs, s2.intregs))
46
47 # CR registers
48 for i, (self.crregs, s2.crregs) in enumerate(
49 zip(self.crregs, s2.crregs)):
50 log("asserting...cr", i, self.crregs, s2.crregs)
51 self.dut.assertEqual(self.crregs, s2.crregs,
52 "cr reg %d (%s) not equal (%s) %s. got %x expected %x" %
53 (i, self.state_type, s2.state_type, repr(self.code),
54 self.crregs, s2.crregs))
55
56 # XER
57 self.dut.assertEqual(self.so, s2.so, "so mismatch (%s != %s) %s" %
58 (self.state_type, s2.state_type, repr(self.code)))
59 self.dut.assertEqual(self.ov, s2.ov, "ov mismatch (%s != %s) %s" %
60 (self.state_type, s2.state_type, repr(self.code)))
61 self.dut.assertEqual(self.ca, s2.ca, "ca mismatch (%s != %s) %s" %
62 (self.state_type, s2.state_type, repr(self.code)))
63
64 # pc
65 self.dut.assertEqual(self.pc, s2.pc, "pc mismatch (%s != %s) %s" %
66 (self.state_type, s2.state_type, repr(self.code)))
67
68
69 class SimState(State):
70 def __init__(self, sim):
71 self.sim = sim
72
73 def get_intregs(self):
74 if False:
75 yield
76 self.intregs = []
77 for i in range(32):
78 simregval = self.sim.gpr[i].asint()
79 self.intregs.append(simregval)
80 log("class sim int regs", list(map(hex, self.intregs)))
81
82 def get_crregs(self):
83 if False:
84 yield
85 self.crregs = []
86 for i in range(8):
87 cri = self.sim.crl[7 - i].get_range().value
88 self.crregs.append(cri)
89 log("class sim cr regs", list(map(hex, self.crregs)))
90
91 def get_xregs(self):
92 if False:
93 yield
94 self.xregs = []
95 self.so = self.sim.spr['XER'][XER_bits['SO']].value
96 self.ov = self.sim.spr['XER'][XER_bits['OV']].value
97 self.ov32 = self.sim.spr['XER'][XER_bits['OV32']].value
98 self.ca = self.sim.spr['XER'][XER_bits['CA']].value
99 self.ca32 = self.sim.spr['XER'][XER_bits['CA32']].value
100 self.ov = self.ov | (self.ov32 << 1)
101 self.ca = self.ca | (self.ca32 << 1)
102 self.xregs.extend((self.so, self.ov, self.ca))
103 log("class sim xregs", list(map(hex, self.xregs)))
104
105 def get_pc(self):
106 if False:
107 yield
108 self.pcl = []
109 self.pc = self.sim.pc.CIA.value
110 self.pcl.append(self.pc)
111 log("class sim pc", hex(self.pc))
112
113
114 class ExpectedState(State):
115 def __init__(self, int_regs = None, pc = 0, crregs = None,
116 so = 0, ov = 0, ca=0):
117 if int_regs is None:
118 int_regs = 32
119 if isinstance(int_regs, int):
120 int_regs = [0] * int_regs
121 self.intregs = int_regs
122 self.pc = pc
123 if crregs is None:
124 crregs = 8
125 if isinstance(int_regs, int):
126 crregs = [0] * crregs
127 self.crregs = crregs
128 self.so = so
129 self.ov = ov
130 self.ca = ca
131
132 def get_intregs(self): if False: yield
133 def get_crregs(self): if False: yield
134 def get_xregs(self): if False: yield
135 def get_pc(self): if False: yield
136
137
138 global state_factory
139 state_factory = {'sim': SimState, 'expected': ExpectedState}
140
141
142 def state_add(name, kls):
143 log("state_add", name, kls)
144 state_factory[name] = kls
145
146
147 def TestState(state_type, to_test, dut, code = 0):
148 state_class = state_factory[state_type]
149 state = state_class(to_test)
150 state.to_test = to_test
151 state.dut = dut
152 state.state_type = state_type
153 state.code = code
154 yield from state.get_state()
155 return state
156
157
158 def teststate_check_regs(dut, states, test, code):
159 """teststate_check_regs: compares a set of Power ISA objects
160 to check if they have the same "state" (registers only, at the moment)
161 """
162 slist = []
163 # create one TestState per "thing"
164 for stype, totest in states.items():
165 state = yield from TestState(stype, totest, dut, code)
166 slist.append(state)
167 # compare each "thing" against the next "thing" in the list.
168 # (no need to do an O(N^2) comparison here, they *all* have to be the same
169 for i in range(len(slist)-1):
170 state, against = slist[i], slist[i+1]
171 state.compare(against)
172