2 from openpower
.test
.common
import TestAccumulatorBase
3 from openpower
.endian
import bigendian
4 from openpower
.simulator
.program
import Program
5 from openpower
.decoder
.selectable_int
import SelectableInt
6 from openpower
.decoder
.power_enums
import XER_bits
7 from openpower
.decoder
.isa
.caller
import special_sprs
8 from openpower
.decoder
.helpers
import exts
9 from openpower
.test
.state
import ExpectedState
10 from openpower
.util
import log
11 from pathlib
import Path
15 from hashlib
import sha256
16 from functools
import lru_cache
18 # output-for-v0.2.0-7-g95fdd1c.json.gz generated from:
19 # https://salsa.debian.org/Kazan-team/power-instruction-analyzer/-/commit/95fdd1c4edbd91c0a02b772ba02aa2045101d2b0
21 PIA_OUTPUT_URL
= "https://ftp.libre-soc.org/power-instruction-analyzer/output-for-v0.2.0-7-g95fdd1c.json.gz"
22 PIA_OUTPUT_SHA256
= "2ad50464eb6c9b6bf2dad2ee16b6820a34024bc008ea86818845cf14f7f457ad"
23 PIA_OUTPUT_PATH
= Path(__file__
).parent
/ PIA_OUTPUT_URL
.rpartition('/')[2]
26 def download_pia_output():
27 from urllib
.request
import urlopen
28 from shutil
import copyfileobj
29 with PIA_OUTPUT_PATH
.open("wb") as f
:
30 print(f
"downloading {PIA_OUTPUT_URL} to {PIA_OUTPUT_PATH}",
31 file=sys
.stderr
, flush
=True)
32 with
urlopen(PIA_OUTPUT_URL
) as response
:
33 copyfileobj(response
, f
)
36 @lru_cache(maxsize
=None)
37 def read_pia_output(filter_fn
=lambda _
: True):
38 tried_download
= False
41 file_bytes
= PIA_OUTPUT_PATH
.read_bytes()
42 digest
= sha256(file_bytes
).hexdigest()
43 if digest
!= PIA_OUTPUT_SHA256
:
44 raise Exception(f
"{PIA_OUTPUT_PATH} has wrong hash, expected "
45 f
"{PIA_OUTPUT_SHA256} got {digest}")
46 file_bytes
= gzip
.decompress(file_bytes
)
47 test_cases
= json
.loads(file_bytes
)['test_cases']
48 return list(filter(filter_fn
, test_cases
))
57 @lru_cache(maxsize
=None)
58 def get_addmeo_subfmeo_reference_cases():
59 return read_pia_output(lambda i
: i
['instr'] in ("addmeo", "subfmeo"))
62 def check_addmeo_subfmeo_matches_reference(instr
, case_filter
, out
):
65 'ra': '0x0', 'ca': False, 'ca32': False,
66 'so': False, 'ov': False, 'ov32': False,
69 for case
in get_addmeo_subfmeo_reference_cases():
71 for k
, v
in case_filter
.items():
77 reference_outputs
= case
['native_outputs']
78 for k
, v
in out
.items():
79 assert reference_outputs
[k
] == v
, (
80 f
"{instr} outputs don't match reference:\n"
81 f
"case_filter={case_filter}\nout={out}\n"
82 f
"reference_outputs={reference_outputs}")
83 log(f
"PIA reference successfully matched: {case_filter}")
85 log(f
"PIA reference not found: {case_filter}")
89 class ALUTestCase(TestAccumulatorBase
):
91 def case_1_regression(self
):
92 lst
= [f
"add. 3, 1, 2"]
93 initial_regs
= [0] * 32
94 initial_regs
[1] = 0xc523e996a8ff6215
95 initial_regs
[2] = 0xe1e5b9cc9864c4a8
96 e
= ExpectedState(pc
=4)
97 e
.intregs
[1] = 0xc523e996a8ff6215
98 e
.intregs
[2] = 0xe1e5b9cc9864c4a8
99 e
.intregs
[3] = 0xa709a363416426bd
101 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
103 def case_2_regression(self
):
104 lst
= [f
"extsw 3, 1"]
105 initial_regs
= [0] * 32
106 initial_regs
[1] = 0xb6a1fc6c8576af91
107 e
= ExpectedState(pc
=4)
108 e
.intregs
[1] = 0xb6a1fc6c8576af91
109 e
.intregs
[3] = 0xffffffff8576af91
110 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
112 lst
= [f
"subf 3, 1, 2"]
113 initial_regs
= [0] * 32
114 initial_regs
[1] = 0x3d7f3f7ca24bac7b
115 initial_regs
[2] = 0xf6b2ac5e13ee15c2
116 e
= ExpectedState(pc
=4)
117 e
.intregs
[1] = 0x3d7f3f7ca24bac7b
118 e
.intregs
[2] = 0xf6b2ac5e13ee15c2
119 e
.intregs
[3] = 0xb9336ce171a26947
120 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
122 lst
= [f
"subf 3, 1, 2"]
123 initial_regs
= [0] * 32
124 initial_regs
[1] = 0x833652d96c7c0058
125 initial_regs
[2] = 0x1c27ecff8a086c1a
126 e
= ExpectedState(pc
=4)
127 e
.intregs
[1] = 0x833652d96c7c0058
128 e
.intregs
[2] = 0x1c27ecff8a086c1a
129 e
.intregs
[3] = 0x98f19a261d8c6bc2
130 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
132 lst
= [f
"extsb 3, 1"]
133 initial_regs
= [0] * 32
134 initial_regs
[1] = 0x7f9497aaff900ea0
135 e
= ExpectedState(pc
=4)
136 e
.intregs
[1] = 0x7f9497aaff900ea0
137 e
.intregs
[3] = 0xffffffffffffffa0
138 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
140 lst
= [f
"add 3, 1, 2"]
141 initial_regs
= [0] * 32
142 initial_regs
[1] = 0x2e08ae202742baf8
143 initial_regs
[2] = 0x86c43ece9efe5baa
144 e
= ExpectedState(pc
=4)
145 e
.intregs
[1] = 0x2e08ae202742baf8
146 e
.intregs
[2] = 0x86c43ece9efe5baa
147 e
.intregs
[3] = 0xb4cceceec64116a2
148 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
151 insns
= ["add", "add.", "subf"]
153 choice
= random
.choice(insns
)
154 lst
= [f
"{choice} 3, 1, 2"]
155 initial_regs
= [0] * 32
156 initial_regs
[1] = random
.randint(0, (1 << 64)-1)
157 initial_regs
[2] = random
.randint(0, (1 << 64)-1)
159 e
= ExpectedState(pc
=4)
160 e
.intregs
[1] = initial_regs
[1]
161 e
.intregs
[2] = initial_regs
[2]
163 result
= initial_regs
[1] + initial_regs
[2]
164 e
.intregs
[3] = result
& ((2**64)-1)
165 elif choice
== "add.":
166 result
= initial_regs
[1] + initial_regs
[2]
167 e
.intregs
[3] = result
& ((2**64)-1)
171 if (e
.intregs
[3] & (1 << 63)) != 0:
173 elif e
.intregs
[3] == 0:
177 e
.crregs
[0] = (eq
<< 1) |
(gt
<< 2) |
(le
<< 3)
178 elif choice
== "subf":
179 result
= ~initial_regs
[1] + initial_regs
[2] + 1
180 e
.intregs
[3] = result
& ((2**64)-1)
182 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
184 def case_addme_ca_0(self
):
185 insns
= ["addme", "addme.", "addmeo", "addmeo."]
187 lst
= [f
"{choice} 6, 16"]
188 for value
in [0x7ffffffff,
190 initial_regs
= [0] * 32
191 initial_regs
[16] = value
193 xer
= SelectableInt(0, 64)
194 xer
[XER_bits
['CA']] = 0 # input carry is 0 (see test below)
195 initial_sprs
[special_sprs
['XER']] = xer
197 # create expected results. pc should be 4 (one instruction)
198 e
= ExpectedState(pc
=4)
199 # input value should not be modified
200 e
.intregs
[16] = value
201 # carry-out should always occur
203 # create output value
204 if value
== 0x7ffffffff:
205 e
.intregs
[6] = 0x7fffffffe
207 e
.intregs
[6] = 0xffff7ffff
208 # CR version needs an expected CR
211 self
.add_case(Program(lst
, bigendian
),
212 initial_regs
, initial_sprs
,
215 def case_addme_ca_1(self
):
216 insns
= ["addme", "addme.", "addmeo", "addmeo."]
218 lst
= [f
"{choice} 6, 16"]
219 for value
in [0x7ffffffff, # fails, bug #476
221 initial_regs
= [0] * 32
222 initial_regs
[16] = value
224 xer
= SelectableInt(0, 64)
225 # input carry is 1 (differs from above)
226 xer
[XER_bits
['CA']] = 1
227 initial_sprs
[special_sprs
['XER']] = xer
228 e
= ExpectedState(pc
=4)
229 e
.intregs
[16] = value
231 if value
== 0x7ffffffff:
232 e
.intregs
[6] = 0x7ffffffff
234 e
.intregs
[6] = 0xffff80000
237 self
.add_case(Program(lst
, bigendian
),
238 initial_regs
, initial_sprs
, expected
=e
)
240 def case_addme_ca_so_4(self
):
241 """test of SO being set
243 lst
= ["addmeo. 6, 16"]
244 initial_regs
= [0] * 32
245 initial_regs
[16] = 0x7fffffffffffffff
247 xer
= SelectableInt(0, 64)
248 xer
[XER_bits
['CA']] = 1
249 initial_sprs
[special_sprs
['XER']] = xer
250 e
= ExpectedState(pc
=4)
251 e
.intregs
[16] = 0x7fffffffffffffff
252 e
.intregs
[6] = 0x7fffffffffffffff
255 self
.add_case(Program(lst
, bigendian
),
256 initial_regs
, initial_sprs
, expected
=e
)
258 def case_addme_ca_so_3(self
):
259 """bug where SO does not get passed through to CR0
261 lst
= ["addme. 6, 16"]
262 initial_regs
= [0] * 32
263 initial_regs
[16] = 0x7ffffffff
265 xer
= SelectableInt(0, 64)
266 xer
[XER_bits
['CA']] = 1
267 xer
[XER_bits
['SO']] = 1
268 initial_sprs
[special_sprs
['XER']] = xer
269 e
= ExpectedState(pc
=4)
270 e
.intregs
[16] = 0x7ffffffff
271 e
.intregs
[6] = 0x7ffffffff
275 self
.add_case(Program(lst
, bigendian
),
276 initial_regs
, initial_sprs
, expected
=e
)
278 def case_addme_subfme_ca_propagation(self
):
279 for flags
in range(1 << 2):
280 ca_in
= bool(flags
& 1)
281 is_sub
= (flags
>> 1) & 1
283 prog
= Program(["subfmeo 3, 4"], bigendian
)
285 prog
= Program(["addmeo 3, 4"], bigendian
)
286 for i
in range(-2, 3):
288 with self
.subTest(ra
=hex(ra
), ca
=ca_in
, is_sub
=is_sub
):
289 initial_regs
= [0] * 32
292 xer
= SelectableInt(0, 64)
293 xer
[XER_bits
['CA']] = ca_in
294 initial_sprs
[special_sprs
['XER']] = xer
295 e
= ExpectedState(pc
=4)
297 rb
= 2 ** 64 - 1 # add 0xfff...fff *not* -1
298 expected
= ca_in
+ rb
299 expected32
= ca_in
+ (rb
% 2 ** 32)
303 inv_ra
= ~ra
% 2 ** 64
305 expected32
+= inv_ra
% 2 ** 32
306 rt_out
= expected
% 2 ** 64
307 e
.intregs
[3] = rt_out
308 ca
= bool(expected
>> 64)
309 ca32
= bool(expected32
>> 32)
310 e
.ca
= (ca32
<< 1) | ca
311 # use algorithm from microwatt's calc_ov
312 # https://github.com/antonblanchard/microwatt/blob/5c6d57de3056bd08fdc1f656bc8656635a77512b/execute1.vhdl#L284
314 emsb
= (expected
>> 63) & 1
315 ov
= ca ^ emsb
and not (axb
>> 63) & 1
316 e32msb
= (expected32
>> 31) & 1
317 ov32
= ca32 ^ e32msb
and not (axb
>> 31) & 1
318 e
.ov
= (ov32
<< 1) | ov
319 check_addmeo_subfmeo_matches_reference(
320 instr
='subfmeo' if is_sub
else 'addmeo',
322 'ra': f
'0x{ra:X}', 'ca': ca_in
,
324 'rt': f
'0x{rt_out:X}', 'ca': ca
,
325 'ca32': ca32
, 'ov': ov
, 'ov32': ov32
,
327 self
.add_case(prog
, initial_regs
, initial_sprs
,
330 def case_addze(self
):
331 insns
= ["addze", "addze.", "addzeo", "addzeo."]
333 lst
= [f
"{choice} 6, 16"]
334 initial_regs
= [0] * 32
335 initial_regs
[16] = 0x00ff00ff00ff0080
336 e
= ExpectedState(pc
=4)
337 e
.intregs
[16] = 0xff00ff00ff0080
338 e
.intregs
[6] = 0xff00ff00ff0080
341 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
343 def case_addis_nonzero_r0_regression(self
):
344 lst
= [f
"addis 3, 0, 1"]
346 initial_regs
= [0] * 32
348 e
= ExpectedState(initial_regs
, pc
=4)
349 e
.intregs
[3] = 0x10000
350 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
352 def case_addis_nonzero_r0(self
):
354 imm
= random
.randint(-(1 << 15), (1 << 15)-1)
355 lst
= [f
"addis 3, 0, {imm}"]
357 initial_regs
= [0] * 32
358 initial_regs
[0] = random
.randint(0, (1 << 64)-1)
359 e
= ExpectedState(pc
=4)
360 e
.intregs
[0] = initial_regs
[0]
361 e
.intregs
[3] = (imm
<< 16) & ((1 << 64)-1)
362 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
364 def case_rand_imm(self
):
365 insns
= ["addi", "addis", "subfic"]
367 choice
= random
.choice(insns
)
368 imm
= random
.randint(-(1 << 15), (1 << 15)-1)
369 lst
= [f
"{choice} 3, 1, {imm}"]
371 initial_regs
= [0] * 32
372 initial_regs
[1] = random
.randint(0, (1 << 64)-1)
374 e
= ExpectedState(pc
=4)
375 e
.intregs
[1] = initial_regs
[1]
377 result
= initial_regs
[1] + imm
378 e
.intregs
[3] = result
& ((2**64)-1)
379 elif choice
== "addis":
380 result
= initial_regs
[1] + (imm
<< 16)
381 e
.intregs
[3] = result
& ((2**64)-1)
382 elif choice
== "subfic":
383 result
= ~initial_regs
[1] + imm
+ 1
384 value
= (~initial_regs
[1]+2**64) + (imm
) + 1
387 carry_out
= value
& (1 << 64) != 0
388 value
= (~initial_regs
[1]+2**64 & 0xffff_ffff) + imm
+ 1
391 carry_out32
= value
& (1 << 32) != 0
392 e
.intregs
[3] = result
& ((2**64)-1)
393 e
.ca
= carry_out |
(carry_out32
<< 1)
395 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
397 def case_0_adde(self
):
398 lst
= ["adde. 5, 6, 7"]
400 initial_regs
= [0] * 32
401 initial_regs
[6] = random
.randint(0, (1 << 64)-1)
402 initial_regs
[7] = random
.randint(0, (1 << 64)-1)
404 xer
= SelectableInt(0, 64)
405 xer
[XER_bits
['CA']] = 1
406 initial_sprs
[special_sprs
['XER']] = xer
407 # calculate result *including carry* and mask it to 64-bit
408 # (if it overflows, we don't care, because this is not addeo)
409 result
= 1 + initial_regs
[6] + initial_regs
[7]
410 # detect 65th bit as carry-out?
411 carry_out
= result
& (1 << 64) != 0
412 carry_out32
= (initial_regs
[6] & 0xffff_ffff) + \
413 (initial_regs
[7] & 0xffff_ffff) & (1 << 32) != 0
414 result
= result
& ((1 << 64)-1) # round
418 if (result
& (1 << 63)) != 0:
424 # now construct the state
425 e
= ExpectedState(pc
=4)
426 e
.intregs
[6] = initial_regs
[6] # should be same as initial
427 e
.intregs
[7] = initial_regs
[7] # should be same as initial
428 e
.intregs
[5] = result
429 # carry_out goes into bit 0 of ca, carry_out32 into bit 1
430 e
.ca
= carry_out |
(carry_out32
<< 1)
431 # eq goes into bit 1 of CR0, gt into bit 2, le into bit 3.
432 # SO goes into bit 0 but overflow doesn't occur here [we hope]
433 e
.crregs
[0] = (eq
<< 1) |
(gt
<< 2) |
(le
<< 3)
435 self
.add_case(Program(lst
, bigendian
),
436 initial_regs
, initial_sprs
, expected
=e
)
439 lst
= ["subf. 1, 6, 7",
441 initial_regs
= [0] * 32
442 initial_regs
[6] = 0x10
443 initial_regs
[7] = 0x05
444 e
= ExpectedState(pc
=8)
447 e
.intregs
[1] = 0xfffffffffffffff5
450 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
453 lst
= ["cmp cr2, 0, 2, 3"]
454 initial_regs
= [0] * 32
455 initial_regs
[2] = 0xffffffffaaaaaaaa
456 initial_regs
[3] = 0x00000000aaaaaaaa
457 e
= ExpectedState(pc
=4)
458 e
.intregs
[2] = 0xffffffffaaaaaaaa
459 e
.intregs
[3] = 0xaaaaaaaa
461 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
463 lst
= ["cmp cr2, 0, 4, 5"]
464 initial_regs
= [0] * 32
465 initial_regs
[4] = 0x00000000aaaaaaaa
466 initial_regs
[5] = 0xffffffffaaaaaaaa
467 e
= ExpectedState(pc
=4)
468 e
.intregs
[4] = 0xaaaaaaaa
469 e
.intregs
[5] = 0xffffffffaaaaaaaa
471 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
474 lst
= ["cmp cr2, 1, 2, 3"]
475 initial_regs
= [0] * 32
476 initial_regs
[2] = 0xffffffffaaaaaaaa
477 initial_regs
[3] = 0x00000000aaaaaaaa
478 e
= ExpectedState(pc
=4)
479 e
.intregs
[2] = 0xffffffffaaaaaaaa
480 e
.intregs
[3] = 0xaaaaaaaa
482 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
484 lst
= ["cmp cr2, 1, 4, 5"]
485 initial_regs
= [0] * 32
486 initial_regs
[4] = 0x00000000aaaaaaaa
487 initial_regs
[5] = 0xffffffffaaaaaaaa
488 e
= ExpectedState(pc
=4)
489 e
.intregs
[4] = 0xaaaaaaaa
490 e
.intregs
[5] = 0xffffffffaaaaaaaa
492 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
494 def case_cmpl_microwatt_0(self
):
496 115b8: 40 50 d1 7c .long 0x7cd15040 # cmpl 6, 0, 17, 10
497 register_file.vhdl: Reading GPR 11 000000000001C026
498 register_file.vhdl: Reading GPR 0A FEDF3FFF0001C025
499 cr_file.vhdl: Reading CR 35055050
500 cr_file.vhdl: Writing 35055058 to CR mask 01 35055058
503 lst
= ["cmpl 6, 0, 17, 10"]
504 initial_regs
= [0] * 32
505 initial_regs
[0x11] = 0x1c026
506 initial_regs
[0xa] = 0xFEDF3FFF0001C025
510 e
= ExpectedState(pc
=4)
511 e
.intregs
[10] = 0xfedf3fff0001c025
512 e
.intregs
[17] = 0x1c026
522 self
.add_case(Program(lst
, bigendian
), initial_regs
,
523 initial_sprs
={'XER': XER
},
524 initial_cr
=CR
, expected
=e
)
526 def case_cmpl_microwatt_0_disasm(self
):
527 """microwatt 1.bin: disassembled version
528 115b8: 40 50 d1 7c .long 0x7cd15040 # cmpl 6, 0, 17, 10
529 register_file.vhdl: Reading GPR 11 000000000001C026
530 register_file.vhdl: Reading GPR 0A FEDF3FFF0001C025
531 cr_file.vhdl: Reading CR 35055050
532 cr_file.vhdl: Writing 35055058 to CR mask 01 35055058
535 dis
= ["cmpl 6, 0, 17, 10"]
536 lst
= bytes([0x40, 0x50, 0xd1, 0x7c]) # 0x7cd15040
537 initial_regs
= [0] * 32
538 initial_regs
[0x11] = 0x1c026
539 initial_regs
[0xa] = 0xFEDF3FFF0001C025
543 e
= ExpectedState(pc
=4)
544 e
.intregs
[10] = 0xfedf3fff0001c025
545 e
.intregs
[17] = 0x1c026
555 p
= Program(lst
, bigendian
)
556 p
.assembly
= '\n'.join(dis
)+'\n'
557 self
.add_case(p
, initial_regs
,
558 initial_sprs
={'XER': XER
},
559 initial_cr
=CR
, expected
=e
)
561 def case_cmplw_microwatt_1(self
):
563 10d94: 40 20 96 7c cmplw cr1,r22,r4
564 gpr: 00000000ffff6dc1 <- r4
565 gpr: 0000000000000000 <- r22
568 lst
= ["cmpl 1, 0, 22, 4"]
569 initial_regs
= [0] * 32
570 initial_regs
[4] = 0xffff6dc1
575 e
= ExpectedState(pc
=4)
576 e
.intregs
[4] = 0xffff6dc1
589 self
.add_case(Program(lst
, bigendian
), initial_regs
,
590 initial_sprs
={'XER': XER
},
591 initial_cr
=CR
, expected
=e
)
593 def case_cmpli_microwatt(self
):
594 """microwatt 1.bin: cmpli
595 123ac: 9c 79 8d 2a cmpli cr5,0,r13,31132
596 gpr: 00000000301fc7a7 <- r13
597 cr : 0000000090215393
598 xer: so 1 ca 0 32 0 ov 0 32 0
602 lst
= ["cmpli 5, 0, 13, 31132"]
603 initial_regs
= [0] * 32
604 initial_regs
[13] = 0x301fc7a7
608 e
= ExpectedState(pc
=4)
609 e
.intregs
[13] = 0x301fc7a7
621 self
.add_case(Program(lst
, bigendian
), initial_regs
,
622 initial_sprs
={'XER': XER
},
623 initial_cr
=CR
, expected
=e
)
625 def case_extsb(self
):
626 insns
= ["extsb", "extsh", "extsw"]
628 choice
= random
.choice(insns
)
629 lst
= [f
"{choice} 3, 1"]
631 initial_regs
= [0] * 32
632 initial_regs
[1] = random
.randint(0, (1 << 64)-1)
634 e
= ExpectedState(pc
=4)
635 e
.intregs
[1] = initial_regs
[1]
636 if choice
== "extsb":
637 e
.intregs
[3] = exts(initial_regs
[1], 8) & ((1 << 64)-1)
638 elif choice
== "extsh":
639 e
.intregs
[3] = exts(initial_regs
[1], 16) & ((1 << 64)-1)
641 e
.intregs
[3] = exts(initial_regs
[1], 32) & ((1 << 64)-1)
643 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
645 def case_cmpeqb(self
):
646 lst
= ["cmpeqb cr1, 1, 2"]
648 initial_regs
= [0] * 32
650 initial_regs
[2] = 0x0001030507090b0f
652 e
= ExpectedState(pc
=4)
654 e
.intregs
[2] = 0x1030507090b0f
655 matlst
= [0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0f]
660 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
662 def case_pia_ca_ov_cases(self
):
663 wanted_outputs
= 'ca', 'ca32', 'ov', 'ov32', 'so'
665 'addi', 'paddi', 'addis', 'add', 'addic', 'subf', 'subfic', 'addc',
666 'subfc', 'adde', 'subfe', 'addme', 'subfme', 'addze', 'subfze',
669 wanted_instrs |
= {i
+ 'o' for i
in wanted_instrs
}
670 # intentionally don't test Rc=1 instrs
673 '0xFFFFFFFFFFFFFFFF', '0xFFFFFFFFFFFFFFFE',
674 '0x7FFFFFFFFFFFFFFE', '0x7FFFFFFFFFFFFFFF',
675 '0x8000000000000000', '0x8000000000000001',
676 '0x123456787FFFFFFE', '0x123456787FFFFFFF',
677 '0x1234567880000000', '0x1234567880000001',
681 '0xFFFFFFFFFFFFFFFF', '0xFFFFFFFFFFFFFFFE',
682 '0xFFFFFFFFFFFF8000', '0xFFFFFFFFFFFF8001',
683 '0x7FFE', '0x7FFF', '0x8000', '0x8001',
687 '0x12345678FFFFFFFF', '0x12345678FFFFFFFE',
688 '0x123456787FFFFFFE', '0x123456787FFFFFFF',
689 '0x1234567880000000', '0x1234567880000001',
693 '0xFFFFFFFFFFFFFFFF', '0xFFFFFFFFFFFFFFFE',
694 '0x7FFFFFFFFFFFFFFE', '0x7FFFFFFFFFFFFFFF',
695 '0x8000000000000000', '0x8000000000000001',
698 def matches(case
, **kwargs
):
699 for k
, v
in kwargs
.items():
706 for case
in read_pia_output():
707 instr
= case
['instr']
708 if instr
not in wanted_instrs
:
710 if not any(i
in case
['native_outputs'] for i
in wanted_outputs
):
712 if case
.get('so') == True:
714 if case
.get('ov32') == True:
716 if case
.get('ca32') == True:
718 initial_regs
= [0] * 32
720 xer
= SelectableInt(0, 64)
721 xer
[XER_bits
['CA']] = case
.get('ca', False)
722 xer
[XER_bits
['OV']] = case
.get('ov', False)
723 initial_sprs
[special_sprs
['XER']] = xer
724 e
= ExpectedState(pc
=4)
725 e
.intregs
[3] = int(case
['native_outputs']['rt'], 0)
726 ca_out
= case
['native_outputs'].get('ca', False)
727 ca32_out
= case
['native_outputs'].get('ca32', False)
728 ov_out
= case
['native_outputs'].get('ov', False)
729 ov32_out
= case
['native_outputs'].get('ov32', False)
730 e
.ca
= ca_out |
(ca32_out
<< 1)
731 e
.ov
= ov_out |
(ov32_out
<< 1)
732 e
.so
= int(case
['native_outputs'].get('so', False))
733 if 'rb' in case
: # binary op
734 pass32
= matches(case
, ra
=binary_inputs32
, rb
=binary_inputs32
)
735 pass64
= matches(case
, ra
=binary_inputs64
, rb
=binary_inputs64
)
736 if not pass32
and not pass64
:
738 asm
= f
'{instr} 3, 4, 5'
741 e
.intregs
[4] = initial_regs
[4] = int(case
['ra'], 0)
742 e
.intregs
[5] = initial_regs
[5] = int(case
['rb'], 0)
743 elif 'immediate' in case
:
744 pass32
= matches(case
, ra
=binary_inputs32
,
745 immediate
=imm_inputs
)
746 pass64
= matches(case
, ra
=binary_inputs64
,
747 immediate
=imm_inputs
)
748 if not pass32
and not pass64
:
750 immediate
= int(case
['immediate'], 16)
753 asm
= f
'{instr} 3, 4, {immediate}'
754 e
.intregs
[4] = initial_regs
[4] = int(case
['ra'], 0)
756 if not matches(case
, ra
=unary_inputs
):
758 asm
= f
'{instr} 3, 4'
759 e
.intregs
[4] = initial_regs
[4] = int(case
['ra'], 0)
760 with self
.subTest(case
=repr(case
)):
761 if asm
not in programs
:
762 programs
[asm
] = Program([asm
], bigendian
)
763 self
.add_case(programs
[asm
], initial_regs
,
764 initial_sprs
=initial_sprs
, expected
=e
)