Blame math/gen-fromfp-tests.py

Packit 6c4009
#!/usr/bin/python3
Packit 6c4009
# Expand test inputs for fromfp functions into text to edit into libm-test.inc.
Packit 6c4009
# Copyright (C) 2016-2018 Free Software Foundation, Inc.
Packit 6c4009
# This file is part of the GNU C Library.
Packit 6c4009
#
Packit 6c4009
# The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
# modify it under the terms of the GNU Lesser General Public
Packit 6c4009
# License as published by the Free Software Foundation; either
Packit 6c4009
# version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
#
Packit 6c4009
# The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
# Lesser General Public License for more details.
Packit 6c4009
#
Packit 6c4009
# You should have received a copy of the GNU Lesser General Public
Packit 6c4009
# License along with the GNU C Library; if not, see
Packit 6c4009
# <http://www.gnu.org/licenses/>.
Packit 6c4009
Packit 6c4009
# Take test inputs on stdin, in format:
Packit 6c4009
#
Packit 6c4009
# i <value>:width [int-value]
Packit 6c4009
#
Packit 6c4009
# for integer inputs, or
Packit 6c4009
#
Packit 6c4009
# t <value> <pos> <z> 
Packit 6c4009
#
Packit 6c4009
# for noninteger inputs, where <pos> is "a" for fractional part
Packit 6c4009
# between 0 and 0.5, "be" for 0.5 with even integer part, "bo" for 0.5
Packit 6c4009
# with odd integer part and "c" for between 0.5 and 1; <z> is the
Packit 6c4009
# value truncated towards zero,  is the value rounded away from
Packit 6c4009
# zero, both being in the form <value>:<width>.  Width values are for
Packit 6c4009
# the smallest type that can hold the value; for positive values, this
Packit 6c4009
# is an unsigned type.
Packit 6c4009
#
Packit 6c4009
# Command-line argument is function to generate tests for.  Any input
Packit 6c4009
# lines not of the above form are just passed through unchanged.
Packit 6c4009
#
Packit 6c4009
# Note that the output of this script forms the largest part of the
Packit 6c4009
# tests for the fromfp functions, but not the whole of those tests.
Packit 6c4009
Packit 6c4009
import sys
Packit 6c4009
Packit 6c4009
func = sys.argv[1]
Packit 6c4009
Packit 6c4009
invalid_res = 'IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM'
Packit 6c4009
exact_res = 'NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED'
Packit 6c4009
if func == 'fromfpx' or func == 'ufromfpx':
Packit 6c4009
    inexact_res = 'INEXACT_EXCEPTION|ERRNO_UNCHANGED'
Packit 6c4009
else:
Packit 6c4009
    inexact_res = exact_res
Packit 6c4009
unsigned = func.startswith('ufromfp')
Packit 6c4009
rm_list = ['FP_INT_UPWARD', 'FP_INT_DOWNWARD', 'FP_INT_TOWARDZERO',
Packit 6c4009
           'FP_INT_TONEARESTFROMZERO', 'FP_INT_TONEAREST']
Packit 6c4009
rm_away_pos = {'FP_INT_UPWARD': 'a',
Packit 6c4009
               'FP_INT_DOWNWARD': 'z',
Packit 6c4009
               'FP_INT_TOWARDZERO': 'z',
Packit 6c4009
               'FP_INT_TONEARESTFROMZERO': 'be',
Packit 6c4009
               'FP_INT_TONEAREST': 'bo'}
Packit 6c4009
rm_away_neg = {'FP_INT_UPWARD': 'z',
Packit 6c4009
               'FP_INT_DOWNWARD': 'a',
Packit 6c4009
               'FP_INT_TOWARDZERO': 'z',
Packit 6c4009
               'FP_INT_TONEARESTFROMZERO': 'be',
Packit 6c4009
               'FP_INT_TONEAREST': 'bo'}
Packit 6c4009
if unsigned:
Packit 6c4009
    test_macro = 'TEST_fiu_U'
Packit 6c4009
else:
Packit 6c4009
    test_macro = 'TEST_fiu_M'
Packit 6c4009
Packit 6c4009
for line in sys.stdin:
Packit 6c4009
    if line.startswith('i'):
Packit 6c4009
        data = line.split()
Packit 6c4009
        val_width = data[1]
Packit 6c4009
        val, width = val_width.split(':')
Packit 6c4009
        negative = val.startswith('-')
Packit 6c4009
        if unsigned and negative:
Packit 6c4009
            continue
Packit 6c4009
        width = int(width)
Packit 6c4009
        if not unsigned and not negative:
Packit 6c4009
            width += 1
Packit 6c4009
        width_list = [0, 1]
Packit 6c4009
        if width > 2:
Packit 6c4009
            width_list.append(width - 1)
Packit 6c4009
        if width > 1 and width <= 64:
Packit 6c4009
            width_list.append(width)
Packit 6c4009
        if width < 64:
Packit 6c4009
            width_list.append(width + 1)
Packit 6c4009
        if width < 63:
Packit 6c4009
            width_list.append(64)
Packit 6c4009
        width_list = [(w, str(w)) for w in width_list]
Packit 6c4009
        width_list.append((64, 'UINT_MAX'))
Packit 6c4009
        for rm in rm_list:
Packit 6c4009
            for we in width_list:
Packit 6c4009
                w, ws = we
Packit 6c4009
                if w < width:
Packit 6c4009
                    print('    %s (%s, %s, %s, %s, %s),' %
Packit 6c4009
                          (test_macro, func, val, rm, ws, invalid_res))
Packit 6c4009
                else:
Packit 6c4009
                    print('    %s (%s, %s, %s, %s, %s, %s),' %
Packit 6c4009
                          (test_macro, func, val, rm, ws, val, exact_res))
Packit 6c4009
    elif line.startswith('t'):
Packit 6c4009
        data = line.split()
Packit 6c4009
        val = data[1]
Packit 6c4009
        pos = data[2]
Packit 6c4009
        z, z_width = data[3].split(':')
Packit 6c4009
        z_width = int(z_width)
Packit 6c4009
        a, a_width = data[4].split(':')
Packit 6c4009
        a_width = int(a_width)
Packit 6c4009
        if unsigned and z.startswith('-'):
Packit 6c4009
            continue
Packit 6c4009
        negative = val.startswith('-')
Packit 6c4009
        if negative:
Packit 6c4009
            rm_away = rm_away_neg
Packit 6c4009
        else:
Packit 6c4009
            rm_away = rm_away_pos
Packit 6c4009
        for rm in rm_list:
Packit 6c4009
            if pos >= rm_away[rm]:
Packit 6c4009
                res, width = a, a_width
Packit 6c4009
            else:
Packit 6c4009
                res, width = z, z_width
Packit 6c4009
            if not unsigned and not negative and res != '0':
Packit 6c4009
                width += 1
Packit 6c4009
            width_list = [0, 1]
Packit 6c4009
            if width > 2:
Packit 6c4009
                width_list.append(width - 1)
Packit 6c4009
            if width > 1 and width <= 64:
Packit 6c4009
                width_list.append(width)
Packit 6c4009
            if width < 64:
Packit 6c4009
                width_list.append(width + 1)
Packit 6c4009
            if width < 63:
Packit 6c4009
                width_list.append(64)
Packit 6c4009
            width_list = [(w, str(w)) for w in width_list]
Packit 6c4009
            width_list.append((64, 'UINT_MAX'))
Packit 6c4009
            for we in width_list:
Packit 6c4009
                w, ws = we
Packit 6c4009
                if w < width or (unsigned and res.startswith('-')):
Packit 6c4009
                    print('    %s (%s, %s, %s, %s, %s),' %
Packit 6c4009
                          (test_macro, func, val, rm, ws, invalid_res))
Packit 6c4009
                else:
Packit 6c4009
                    print('    %s (%s, %s, %s, %s, %s, %s),' %
Packit 6c4009
                          (test_macro, func, val, rm, ws, res, inexact_res))
Packit 6c4009
    else:
Packit 6c4009
        print(line.rstrip())