blob: e8576adf3ed4cdfe025645518ba16cb5315eada8 [file] [log] [blame]
#!/usr/bin/env python
# **********************************************************
# Copyright (c) 2022-2023 Arm Limited All rights reserved.
# **********************************************************
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of VMware, Inc. nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
# Script to check the order of operands in opnd_defs.txt and codec.c
# Usage: python aarch64_check_codec_order.py <path to core/ir/aarch64/> <path to build dir>
import sys
import subprocess
import os
import re
import difflib
def filter_lines(path, regex, ignore_until=''):
with open(path) as f:
patterns = []
ignore = True
for l in f.readlines():
ignore = ignore and l.find(ignore_until) == -1
if ignore:
continue
m = re.match(regex, l)
if not m:
continue
patterns.append(m.group(1))
return patterns
def check(l1, l2):
if len(l1) != len(l2):
raise Exception(
"Lists of different length.\n"
"In source 1, but not 2:\n"
"{} \n"
"In source 2, but not 1:\n"
"{} \n".format(
", ".join(set(l1) - set(l2)),
", ".join(set(l2) - set(l1))))
mismatches = [(i, a, b)
for (i, (a, b)) in enumerate(zip(l1, l2)) if a != b]
if mismatches:
for (i, a, b) in mismatches:
print('Lines {} differ: \n > {}\n < {}'.format(i, a, b))
sys.exit(1)
def normalise_plus(string):
return string.replace("+", "x")
def main():
src_dir = sys.argv[1]
bld_dir = sys.argv[2]
# Check if operand patterns in opnd_defs.txt are ordered by pattern.
patterns = filter_lines(
os.path.join(src_dir, 'opnd_defs.txt'),
re.compile(r'^([x\-\?\+]+) [a-z0-9A-Z_]+.+#.+'))
print('Checking if operand patterns in opnd_defs.txt are ordered by pattern')
check(patterns, sorted(patterns, key=normalise_plus))
print(' OK!')
# Check if operand order in opnd_defs.txt and codec.c matches.
op_names_txt = filter_lines(
os.path.join( src_dir, 'opnd_defs.txt'),
re.compile(r'^[x\-\?\+]+ ([a-z0-9A-Z_]+).+#.+'))
op_names_c = filter_lines(os.path.join(src_dir, 'codec.c'), re.compile(
r'^decode_opnd_([^\(]+).+'), ignore_until='each type of operand')
print('Checking if operand order in opnd_defs.txt matches codec.c')
check(op_names_txt, op_names_c)
print(' OK!')
# The Arm AArch64's architecture versions supported by the DynamoRIO codec.
# Currently, v8.0 is fully supported, while v8.1, v8.2, v8.3, v8.4, v8.6, SVE,
# and SVE2 are partially supported.
isa_versions = ['v80', 'v81', 'v82', 'v83', 'v84', 'v86', 'sve', 'sve2']
codecsort_py = os.path.join(src_dir, "codecsort.py")
print("Checking if instructions are in the correct order and format in each codec_<version>.txt file.")
codec_files = [os.path.join(src_dir, 'codec_' + isa_version + '.txt') for isa_version in isa_versions]
with open(os.devnull, 'wb') as dev_null:
needs_reorder = subprocess.call([codecsort_py] + codec_files, stdout=dev_null)
if needs_reorder:
print("codec file instructions are out of order, run:\n{} --rewrite {}".format(
codecsort_py, " ".join(codec_files)))
sys.exit(1)
print(", ".join(codec_files), "OK!")
print("Check there are no duplicate opcode enums across ALL codec_<version>.txt files.")
if __name__ == '__main__':
main()