1
0
mirror of https://github.com/bitdefender/bddisasm.git synced 2024-11-25 08:58:09 +00:00
bddisasm/bddisasm_test/test_all.py
BITDEFENDER\vlutas 9ba1e6a2f9 Added support for new Intel instructions, per Intel ISA extensions document #319433-046 (September 2022): PREFETCHITI, RAO-INT, CMPCCXADD, WRMSRNS, MSRLIST, AMX-FP16, AVX-IFMA, AVX-NE-CONVERT, AVX-VNNI-INT8.
Multiple minor fixes to existing instructions.
Moved x86 decoding tests in a separate directory & improved the test script.
2022-10-04 12:22:59 +03:00

142 lines
3.8 KiB
Python

#
# Copyright (c) 2020 Bitdefender
# SPDX-License-Identifier: Apache-2.0
#
import os
import sys
import glob
total_tests = 0
failed_tests = 0
def get_dict(ins):
d = {}
prefix = ""
# Remove lines that don't contain tokens.
lines = ins.split("\n")
# Main disassembly.
d["disasm"] = lines[0]
for line in lines[1:]:
tokens = line.split(",")
for t in tokens:
val = t.split(":")
if len(val) != 2:
continue
a = val[0].strip(" ")
b = val[1].strip(" ")
if a == "Operand":
prefix = "op%s_" % b
a = prefix + a
d[a] = b
return d
def compare_instruction(i1, i2):
x1 = get_dict(i1)
x2 = get_dict(i2)
for t in x1:
if not t in x2:
print(" ! ERROR: Token '%s', value '%s' missing from output!" % (t, x1[t]))
return False
if x1[t] != x2[t]:
print(" ! ERROR: Token '%s' value mismatch: expected '%s', got '%s'!" % (t, x1[t], x2[t]))
return False
for t in x2:
if not t in x1:
print(" ! WARNING: Extra token in result: '%s', value '%s'!" % (t, x2[t]))
return True
def compare_results(data1, data2):
ins1 = data1.split("\n\n")
ins2 = data2.split("\n\n")
if len(ins1) != len(ins2):
print(" ! Different number of instructions in output: expected %d, got %d!" % (len(ins1), len(ins2)))
return False
for i in range(0, len(ins1)):
if not compare_instruction(ins1[i], ins2[i]):
print(" ! ERROR: Instruction mismatch at %d!" % (i))
return False
return True
def test_dir(dir):
global total_tests
global failed_tests
for f in glob.glob('%s\\*.test' % dir):
base, _ = os.path.splitext(f)
tst_file = f
res_file = base + '.result'
tmp_file = base + '.temp'
if 0 < f.find('_16'):
mod = '-b16'
elif 0 < f.find('_32'):
mod = '-b32'
else:
mod = '-b64'
if 0 < f.find('_r0'):
mod += ' -k'
if 0 < f.find('_skip'):
mod += ' -skip16'
print(' * Running test case %s...' % f)
os.system('disasm -exi %s -f %s >%s' % (mod, tst_file, tmp_file))
try:
res = open(res_file).read()
except:
print(' ! No result file provided for test %s!' % tst_file)
try:
tmp = open(tmp_file).read()
except:
print(' ! No result produced by test %s!' % tst_file)
total_tests += 1
if not compare_results(res, tmp):
print(' **** FAILED! ****')
failed_tests += 1
else:
print(' * Passed.')
# Cleanup.
os.remove(tmp_file)
def regenerate(dir):
for f in glob.glob('%s\\*.test' % dir):
base, _ = os.path.splitext(f)
tst_file = f
res_file = base + '.result'
if 0 < f.find('_16'):
mod = '-b16'
elif 0 < f.find('_32'):
mod = '-b32'
else:
mod = '-b64'
if 0 < f.find('_r0'):
mod += ' -k'
if 0 < f.find('_skip'):
mod += ' -skip16'
print(' * Regenerating test case %s...' % tst_file)
os.system('disasm -exi %s -f %s >%s' % (mod, tst_file, res_file))
if __name__ == "__main__":
for dn in glob.glob("x86\\*"):
if not os.path.isdir(dn):
continue
if "regenerate" in sys.argv:
print('Regenerating %s...' % dn)
regenerate(dn)
else:
print('Testing %s...' % dn)
test_dir(dn)
print("Ran %d tests, %d failed" % (total_tests, failed_tests))