diff options
Diffstat (limited to 'math/gen-libm-test.py')
-rwxr-xr-x | math/gen-libm-test.py | 75 |
1 files changed, 17 insertions, 58 deletions
diff --git a/math/gen-libm-test.py b/math/gen-libm-test.py index 397dbd3..1abc7fb 100755 --- a/math/gen-libm-test.py +++ b/math/gen-libm-test.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 # Generate tests for libm functions. -# Copyright (C) 2018-2024 Free Software Foundation, Inc. +# Copyright (C) 2018-2025 Free Software Foundation, Inc. # This file is part of the GNU C Library. # # The GNU C Library is free software; you can redistribute it and/or @@ -93,8 +93,7 @@ BEAUTIFY_MAP = {'minus_zero': '-0', # Flags in auto-libm-test-out that map directly to C flags. FLAGS_SIMPLE = {'ignore-zero-inf-sign': 'IGNORE_ZERO_INF_SIGN', - 'xfail': 'XFAIL_TEST', - 'no-mathvec': 'NO_TEST_MATHVEC'} + 'xfail': 'XFAIL_TEST'} # Exceptions in auto-libm-test-out, and their corresponding C flags # for being required, OK or required to be absent. @@ -103,7 +102,7 @@ EXC_EXPECTED = {'divbyzero': 'DIVBYZERO_EXCEPTION', 'invalid': 'INVALID_EXCEPTION', 'overflow': 'OVERFLOW_EXCEPTION', 'underflow': 'UNDERFLOW_EXCEPTION'} -EXC_OK = {'divbyzero': 'DIVBYZERO_EXCEPTION_OK', +EXC_OK = {'divbyzero': 'DIVIDE_BY_ZERO_EXCEPTION_OK', 'inexact': '0', 'invalid': 'INVALID_EXCEPTION_OK', 'overflow': 'OVERFLOW_EXCEPTION_OK', @@ -122,19 +121,20 @@ class Ulps(object): """Initialize an Ulps object.""" # normal[function][float_type] is the ulps value, and likewise # for real and imag. - self.normal = defaultdict(lambda: defaultdict(lambda: 0)) - self.real = defaultdict(lambda: defaultdict(lambda: 0)) - self.imag = defaultdict(lambda: defaultdict(lambda: 0)) + self.normal = defaultdict(lambda: defaultdict(lambda: -1)) + self.real = defaultdict(lambda: defaultdict(lambda: -1)) + self.imag = defaultdict(lambda: defaultdict(lambda: -1)) # List of ulps kinds, in the order in which they appear in # sorted ulps files. self.ulps_kinds = (('Real part of ', self.real), ('Imaginary part of ', self.imag), ('', self.normal)) + self.ulps_file = [] self def read(self, ulps_file): """Read ulps from a file into an Ulps object.""" - self.ulps_file = ulps_file + self.ulps_file.append(ulps_file) with open(ulps_file, 'r') as f: ulps_dict = None ulps_fn = None @@ -166,10 +166,7 @@ class Ulps(object): if line_first not in ALL_FLOATS: raise ValueError('bad ulps line: %s' % line) ulps_val = int(line_second) - if ulps_val > 0: - ulps_dict[ulps_fn][line_first] = max( - ulps_dict[ulps_fn][line_first], - ulps_val) + ulps_dict[ulps_fn][line_first] = ulps_val def all_functions(self): """Return the set of functions with ulps and whether they are @@ -182,27 +179,6 @@ class Ulps(object): complex[f] = True if k_prefix else False return funcs, complex - def write(self, ulps_file): - """Write ulps back out as a sorted ulps file.""" - # Output is sorted first by function name, then by (real, - # imag, normal), then by float type. - out_data = {} - for order, (prefix, d) in enumerate(self.ulps_kinds): - for fn in d.keys(): - fn_data = ['%s: %d' % (f, d[fn][f]) - for f in sorted(d[fn].keys())] - fn_text = 'Function: %s"%s":\n%s' % (prefix, fn, - '\n'.join(fn_data)) - out_data[(fn, order)] = fn_text - out_list = [out_data[fn_order] for fn_order in sorted(out_data.keys())] - out_text = ('# Begin of automatic generation\n\n' - '# Maximal error of functions:\n' - '%s\n\n' - '# end of automatic generation\n' - % '\n\n'.join(out_list)) - with open(ulps_file, 'w') as f: - f.write(out_text) - @staticmethod def ulps_table(name, ulps_dict): """Return text of a C table of ulps.""" @@ -221,14 +197,14 @@ class Ulps(object): """Write header file with ulps data.""" header_text_1 = ('/* This file is automatically generated\n' ' from %s with gen-libm-test.py.\n' - ' Don\'t change it - change instead the master ' + ' Don\'t change it - change the original source ' 'files. */\n\n' 'struct ulp_data\n' '{\n' ' const char *name;\n' ' FLOAT max_ulp[%d];\n' '};' - % (self.ulps_file, len(ALL_FLOATS))) + % (', '.join(self.ulps_file), len(ALL_FLOATS))) macro_list = [] for i, f in enumerate(ALL_FLOATS): if f.startswith('i'): @@ -252,18 +228,6 @@ class Ulps(object): f.write(header_text) -def read_all_ulps(srcdir): - """Read all platforms' libm-test-ulps files.""" - all_ulps = {} - for dirpath, dirnames, filenames in os.walk(srcdir): - if 'libm-test-ulps' in filenames: - with open(os.path.join(dirpath, 'libm-test-ulps-name')) as f: - name = f.read().rstrip() - all_ulps[name] = Ulps() - all_ulps[name].read(os.path.join(dirpath, 'libm-test-ulps')) - return all_ulps - - def read_auto_tests(test_file): """Read tests from auto-libm-test-out-<function> (possibly None).""" auto_tests = defaultdict(lambda: defaultdict(dict)) @@ -654,12 +618,8 @@ def main(): help='input file with automatically generated tests') parser.add_argument('-c', dest='inc_input', metavar='FILE', help='input file .inc file with tests') - parser.add_argument('-u', dest='ulps_file', metavar='FILE', - help='input file with ulps') - parser.add_argument('-s', dest='srcdir', metavar='DIR', - help='input source directory with all ulps') - parser.add_argument('-n', dest='ulps_output', metavar='FILE', - help='generate sorted ulps file FILE') + parser.add_argument('-u', dest='ulps_file', metavar='list', + help='input files with ulps (multiple input separated by colon') parser.add_argument('-C', dest='c_output', metavar='FILE', help='generate output C file FILE from .inc file') parser.add_argument('-H', dest='ulps_header', metavar='FILE', @@ -669,12 +629,11 @@ def main(): args = parser.parse_args() ulps = Ulps() if args.ulps_file is not None: - ulps.read(args.ulps_file) + # Iterate in reverse order so arch specific definitions can override + # the generic ones. + for ulp_file in reversed(args.ulps_file.split(':')): + ulps.read(ulp_file) auto_tests = read_auto_tests(args.auto_input) - if args.srcdir is not None: - all_ulps = read_all_ulps(args.srcdir) - if args.ulps_output is not None: - ulps.write(args.ulps_output) if args.ulps_header is not None: ulps.write_header(args.ulps_header) if args.c_output is not None: |