(root)/
glibc-2.38/
math/
gen-fromfp-tests.py
       1  #!/usr/bin/python3
       2  # Expand test inputs for fromfp functions into text to edit into libm-test.inc.
       3  # Copyright (C) 2016-2023 Free Software Foundation, Inc.
       4  # This file is part of the GNU C Library.
       5  #
       6  # The GNU C Library is free software; you can redistribute it and/or
       7  # modify it under the terms of the GNU Lesser General Public
       8  # License as published by the Free Software Foundation; either
       9  # version 2.1 of the License, or (at your option) any later version.
      10  #
      11  # The GNU C Library is distributed in the hope that it will be useful,
      12  # but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14  # Lesser General Public License for more details.
      15  #
      16  # You should have received a copy of the GNU Lesser General Public
      17  # License along with the GNU C Library; if not, see
      18  # <https://www.gnu.org/licenses/>.
      19  
      20  # Take test inputs on stdin, in format:
      21  #
      22  # i <value>:width [int-value]
      23  #
      24  # for integer inputs, or
      25  #
      26  # t <value> <pos> <z> <a>
      27  #
      28  # for noninteger inputs, where <pos> is "a" for fractional part
      29  # between 0 and 0.5, "be" for 0.5 with even integer part, "bo" for 0.5
      30  # with odd integer part and "c" for between 0.5 and 1; <z> is the
      31  # value truncated towards zero, <a> is the value rounded away from
      32  # zero, both being in the form <value>:<width>.  Width values are for
      33  # the smallest type that can hold the value; for positive values, this
      34  # is an unsigned type.
      35  #
      36  # Command-line argument is function to generate tests for.  Any input
      37  # lines not of the above form are just passed through unchanged.
      38  #
      39  # Note that the output of this script forms the largest part of the
      40  # tests for the fromfp functions, but not the whole of those tests.
      41  
      42  import sys
      43  
      44  func = sys.argv[1]
      45  
      46  invalid_res = 'IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION|ERRNO_EDOM'
      47  exact_res = 'NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED'
      48  if func == 'fromfpx' or func == 'ufromfpx':
      49      inexact_res = 'INEXACT_EXCEPTION|ERRNO_UNCHANGED'
      50  else:
      51      inexact_res = exact_res
      52  unsigned = func.startswith('ufromfp')
      53  rm_list = ['FP_INT_UPWARD', 'FP_INT_DOWNWARD', 'FP_INT_TOWARDZERO',
      54             'FP_INT_TONEARESTFROMZERO', 'FP_INT_TONEAREST']
      55  rm_away_pos = {'FP_INT_UPWARD': 'a',
      56                 'FP_INT_DOWNWARD': 'z',
      57                 'FP_INT_TOWARDZERO': 'z',
      58                 'FP_INT_TONEARESTFROMZERO': 'be',
      59                 'FP_INT_TONEAREST': 'bo'}
      60  rm_away_neg = {'FP_INT_UPWARD': 'z',
      61                 'FP_INT_DOWNWARD': 'a',
      62                 'FP_INT_TOWARDZERO': 'z',
      63                 'FP_INT_TONEARESTFROMZERO': 'be',
      64                 'FP_INT_TONEAREST': 'bo'}
      65  if unsigned:
      66      test_macro = 'TEST_fiu_U'
      67  else:
      68      test_macro = 'TEST_fiu_M'
      69  
      70  for line in sys.stdin:
      71      if line.startswith('i'):
      72          data = line.split()
      73          val_width = data[1]
      74          val, width = val_width.split(':')
      75          negative = val.startswith('-')
      76          if unsigned and negative:
      77              continue
      78          width = int(width)
      79          if not unsigned and not negative:
      80              width += 1
      81          width_list = [0, 1]
      82          if width > 2:
      83              width_list.append(width - 1)
      84          if width > 1 and width <= 64:
      85              width_list.append(width)
      86          if width < 64:
      87              width_list.append(width + 1)
      88          if width < 63:
      89              width_list.append(64)
      90          width_list = [(w, str(w)) for w in width_list]
      91          width_list.append((64, 'UINT_MAX'))
      92          for rm in rm_list:
      93              for we in width_list:
      94                  w, ws = we
      95                  if w < width:
      96                      print('    %s (%s, %s, %s, %s, %s),' %
      97                            (test_macro, func, val, rm, ws, invalid_res))
      98                  else:
      99                      print('    %s (%s, %s, %s, %s, %s, %s),' %
     100                            (test_macro, func, val, rm, ws, val, exact_res))
     101      elif line.startswith('t'):
     102          data = line.split()
     103          val = data[1]
     104          pos = data[2]
     105          z, z_width = data[3].split(':')
     106          z_width = int(z_width)
     107          a, a_width = data[4].split(':')
     108          a_width = int(a_width)
     109          if unsigned and z.startswith('-'):
     110              continue
     111          negative = val.startswith('-')
     112          if negative:
     113              rm_away = rm_away_neg
     114          else:
     115              rm_away = rm_away_pos
     116          for rm in rm_list:
     117              if pos >= rm_away[rm]:
     118                  res, width = a, a_width
     119              else:
     120                  res, width = z, z_width
     121              if not unsigned and not negative and res != '0':
     122                  width += 1
     123              width_list = [0, 1]
     124              if width > 2:
     125                  width_list.append(width - 1)
     126              if width > 1 and width <= 64:
     127                  width_list.append(width)
     128              if width < 64:
     129                  width_list.append(width + 1)
     130              if width < 63:
     131                  width_list.append(64)
     132              width_list = [(w, str(w)) for w in width_list]
     133              width_list.append((64, 'UINT_MAX'))
     134              for we in width_list:
     135                  w, ws = we
     136                  if w < width or (unsigned and res.startswith('-')):
     137                      print('    %s (%s, %s, %s, %s, %s),' %
     138                            (test_macro, func, val, rm, ws, invalid_res))
     139                  else:
     140                      print('    %s (%s, %s, %s, %s, %s, %s),' %
     141                            (test_macro, func, val, rm, ws, res, inexact_res))
     142      else:
     143          print(line.rstrip())