3 This module implements the creation, inspection and comparison
4 of test states from different sources.
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
12 The SimState class provides an example of needed registers and naming.
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
18 Also note when creating and accessing test state classes and object
19 methods, the use of yield from/yield is required.
25 from openpower
.decoder
.power_enums
import XER_bits
26 from openpower
.util
import log
28 global staterunner_factory
29 staterunner_factory
= {}
32 def staterunner_add(name
, kls
):
33 log("staterunner_add", name
, kls
)
34 staterunner_factory
[name
] = kls
37 # TBD an Abstract Base Class
39 """StateRunner: an Abstract Base Class for preparing and running "State".
40 near-identical in concept to python unittest.TestCase
42 def __init__(self
, name
, kls
):
43 staterunner_add(name
, kls
)
46 def setup_for_test(self
):
48 def setup_during_test(self
):
50 def prepare_for_test(self
, test
):
61 """State: Base class for the "state" of the Power ISA object to be tested
62 including methods to compare various registers and memory between
65 All methods implemented must be generators.
67 GPRs and CRs - stored as lists
68 XERs/PC - simple members
69 memory - stored as a dictionary {location: data}
72 yield from self
.get_intregs()
73 yield from self
.get_crregs()
74 yield from self
.get_xregs()
75 yield from self
.get_pc()
76 yield from self
.get_mem()
78 def compare(self
, s2
):
79 # Compare int registers
80 for i
, (self
.intregs
, s2
.intregs
) in enumerate(
81 zip(self
.intregs
, s2
.intregs
)):
82 log("asserting...reg", i
, self
.intregs
, s2
.intregs
)
83 log("code, frepr(code)", self
.code
, repr(self
.code
))
84 self
.dut
.assertEqual(self
.intregs
, s2
.intregs
,
85 "int reg %d (%s) not equal (%s) %s. got %x expected %x" %
86 (i
, self
.state_type
, s2
.state_type
, repr(self
.code
),
87 self
.intregs
, s2
.intregs
))
90 for i
, (self
.crregs
, s2
.crregs
) in enumerate(
91 zip(self
.crregs
, s2
.crregs
)):
92 log("asserting...cr", i
, self
.crregs
, s2
.crregs
)
93 self
.dut
.assertEqual(self
.crregs
, s2
.crregs
,
94 "cr reg %d (%s) not equal (%s) %s. got %x expected %x" %
95 (i
, self
.state_type
, s2
.state_type
, repr(self
.code
),
96 self
.crregs
, s2
.crregs
))
99 self
.dut
.assertEqual(self
.so
, s2
.so
, "so mismatch (%s != %s) %s" %
100 (self
.state_type
, s2
.state_type
, repr(self
.code
)))
101 self
.dut
.assertEqual(self
.ov
, s2
.ov
, "ov mismatch (%s != %s) %s" %
102 (self
.state_type
, s2
.state_type
, repr(self
.code
)))
103 self
.dut
.assertEqual(self
.ca
, s2
.ca
, "ca mismatch (%s != %s) %s" %
104 (self
.state_type
, s2
.state_type
, repr(self
.code
)))
107 self
.dut
.assertEqual(self
.pc
, s2
.pc
, "pc mismatch (%s != %s) %s" %
108 (self
.state_type
, s2
.state_type
, repr(self
.code
)))
110 def compare_mem(self
, s2
):
111 # copy dics to preserve state mem then pad empty locs since
112 # different Power ISA objects may differ how theystore memory
113 s1mem
, s2mem
= self
.mem
.copy(), s2
.mem
.copy()
114 for i
in set(self
.mem
).difference(set(s2
.mem
)):
116 for i
in set(s2
.mem
).difference(set(self
.mem
)):
119 self
.dut
.assertEqual(s1mem
[i
], s2mem
[i
],
120 "mem mismatch location %d %s" % (i
, self
.code
))
123 class SimState(State
):
124 """SimState: Obtains registers and memory from an ISACaller object.
125 Note that yields are "faked" to maintain consistency and compatability
128 def __init__(self
, sim
):
131 def get_intregs(self
):
136 simregval
= self
.sim
.gpr
[i
].asint()
137 self
.intregs
.append(simregval
)
138 log("class sim int regs", list(map(hex, self
.intregs
)))
140 def get_crregs(self
):
145 cri
= self
.sim
.crl
[7 - i
].get_range().value
146 self
.crregs
.append(cri
)
147 log("class sim cr regs", list(map(hex, self
.crregs
)))
153 self
.so
= self
.sim
.spr
['XER'][XER_bits
['SO']].value
154 self
.ov
= self
.sim
.spr
['XER'][XER_bits
['OV']].value
155 self
.ov32
= self
.sim
.spr
['XER'][XER_bits
['OV32']].value
156 self
.ca
= self
.sim
.spr
['XER'][XER_bits
['CA']].value
157 self
.ca32
= self
.sim
.spr
['XER'][XER_bits
['CA32']].value
158 self
.ov
= self
.ov |
(self
.ov32
<< 1)
159 self
.ca
= self
.ca |
(self
.ca32
<< 1)
160 self
.xregs
.extend((self
.so
, self
.ov
, self
.ca
))
161 log("class sim xregs", list(map(hex, self
.xregs
)))
167 self
.pc
= self
.sim
.pc
.CIA
.value
168 self
.pcl
.append(self
.pc
)
169 log("class sim pc", hex(self
.pc
))
174 keys
= list(self
.sim
.mem
.mem
.keys())
176 # from each address in the underlying mem-simulated dictionary
177 # issue a 64-bit LD (with no byte-swapping)
179 data
= self
.sim
.mem
.ld(k
*8, 8, False)
183 class ExpectedState(State
):
184 """ExpectedState: A user defined state set manually.
185 No methods, just pass into what expected values you want to test
186 with against other states.
188 see openpower/test/shift_rot/shift_rot_cases2.py for examples
190 def __init__(self
, int_regs
=None, pc
=0, crregs
=None,
194 if isinstance(int_regs
, int):
195 int_regs
= [0] * int_regs
196 self
.intregs
= int_regs
200 if isinstance(crregs
, int):
201 crregs
= [0] * crregs
207 def get_intregs(self
):
209 def get_crregs(self
):
220 state_factory
= {'sim': SimState
, 'expected': ExpectedState
}
223 def state_add(name
, kls
):
224 log("state_add", name
, kls
)
225 state_factory
[name
] = kls
228 def TestState(state_type
, to_test
, dut
, code
=0):
229 """TestState: Factory that returns a TestState object loaded with
230 registers and memory that can then be compared.
232 state_type: Type of state to create from global state_factory dictionary
233 to_test: The Power ISA object to test
234 dut: The unittest object
235 code: Actual machine code of what is being tested
237 The state_type can be added to the factory types using the state_add
238 function in this module.
240 state_class
= state_factory
[state_type
]
241 state
= state_class(to_test
)
242 state
.to_test
= to_test
244 state
.state_type
= state_type
246 yield from state
.get_state()
250 def teststate_check_regs(dut
, states
, test
, code
):
251 """teststate_check_regs: compares a set of Power ISA objects
252 to check if they have the same "state" (registers only, at the moment)
255 # create one TestState per "thing"
256 for stype
, totest
in states
.items():
257 state
= yield from TestState(stype
, totest
, dut
, code
)
259 # compare each "thing" against the next "thing" in the list.
260 # (no need to do an O(N^2) comparison here, they *all* have to be the same
261 for i
in range(len(slist
)-1):
262 state
, against
= slist
[i
], slist
[i
+1]
263 state
.compare(against
)
266 def teststate_check_mem(dut
, states
, test
, code
):
267 """teststate_check_mem: compares a set of Power ISA objects
268 to check if they have the same "state" (memory)
271 # create one TestState per "thing"
272 for stype
, totest
in states
.items():
273 state
= yield from TestState(stype
, totest
, dut
, code
)
275 # compare each "thing" against the next "thing" in the list.
276 # (no need to do an O(N^2) comparison here, they *all* have to be the same
277 for i
in range(len(slist
)-1):
278 state
, against
= slist
[i
], slist
[i
+1]
279 state
.compare_mem(against
)