-
Notifications
You must be signed in to change notification settings - Fork 5
/
gen_decoding_tests.py
executable file
·114 lines (99 loc) · 3.6 KB
/
gen_decoding_tests.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#! /usr/bin/env python
import sys
import os
import re
import subprocess
R_NSYMCHAR = re.compile('[^a-zA-Z0-9_]+')
R_UNDERSCORES = re.compile('[_]+')
R_LEADING_UNDERSCORE = re.compile('^_')
vasm = sys.argv[1]
infilename = sys.argv[2]
outfilename = sys.argv[3]
tests = []
with open(infilename, 'r') as f:
eof = False
while not eof:
asm_lines = []
result_lines = []
cpu = '68040'
while True:
l = f.readline()
if len(l) == 0:
eof = True
break
l = l.strip()
if len(l) == 0 or l.startswith('//'):
break
if l.startswith('> '):
asm_lines.append(l[1:])
elif l.startswith('# '):
result_lines.append(l[1:])
elif l.startswith('! '):
cpu = l[2:]
else:
stderr.write('bad input line: {}'.format(l))
if len(asm_lines) > 0 and len(result_lines) > 0:
with open('test.asm', 'w') as of:
of.write('start:\n')
for line in asm_lines:
of.write('\t')
of.write(line)
of.write('\n')
if subprocess.call([vasm, '-m' + cpu, 'test.asm', '-quiet', '-Fbin', '-o', 'test.out']) != 0:
sys.stderr.write('vasm failed for:')
for l in asm_lines:
sys.stderr.write(l)
sys.exit(1)
else:
with open('test.out', 'rb') as bf:
code_bytes = bytearray(bf.read())
tests.append((code_bytes, result_lines, asm_lines))
with open(outfilename, "w") as of:
of.write('// auto-generated from decoding_tests.txt by gen_decoding_tests.py\n')
of.write('mod tests {\n')
of.write(' use m68kdecode::*;\n')
of.write(' mod support;\n')
of.write(' use support::*;\n')
of.write(' use m68kdecode::DataRegister::*;\n')
of.write(' use m68kdecode::AddressRegister::*;\n')
of.write(' use m68kdecode::FloatingRegister::*;\n')
of.write(' use m68kdecode::MemoryIndirection::*;\n')
of.write(' use m68kdecode::FPConditionCode::*;\n')
of.write(' use m68kdecode::ConditionCode::*;\n')
of.write(' use m68kdecode::FPFormat::*;\n')
of.write(' use m68kdecode::Operand::*;\n')
of.write(' use m68kdecode::InstructionExtra::*;\n')
of.write(' use m68kdecode::BitfieldData::*;\n')
of.write(' use m68kdecode::Operation::*;\n')
testnum = 1
for t in tests:
code_bytes = t[0]
result_lines = t[1]
asm_lines = t[2]
for al in asm_lines:
of.write('// {}\n'.format(al))
name = re.sub(R_NSYMCHAR, '_', asm_lines[0].strip()).lower()
name = re.sub(R_UNDERSCORES, '_', name)
name = re.sub(R_LEADING_UNDERSCORE, '', name)
of.write('#[test]\n')
of.write('fn test_decode_{:04d}_{}() {{\n'.format(testnum, name))
if result_lines[0].find('Instruction {') == -1:
of.write('test_decoding_result_err(&[')
else:
of.write('test_decoding_result_ok(&[')
of.write(', '.join(['0x{0:02x}'.format(byt) for byt in code_bytes]))
of.write('], ')
for l in result_lines:
of.write(l)
of.write('\n')
of.write(', &[')
for al in asm_lines:
of.write('"{}",\n'.format(al))
of.write(']')
of.write(');}\n')
testnum = testnum + 1
of.write('}\n')
if subprocess.call(['rustfmt', outfilename]) != 0:
sys.exit(1)
os.remove('test.asm')
os.remove('test.out')