xref: /netbsd-src/external/gpl3/gcc.old/dist/libquadmath/update-quadmath.py (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
1*627f7eb2Smrg#!/usr/bin/python3
2*627f7eb2Smrg# Update libquadmath code from glibc sources.
3*627f7eb2Smrg# Copyright (C) 2018 Free Software Foundation, Inc.
4*627f7eb2Smrg# This file is part of the libquadmath library.
5*627f7eb2Smrg#
6*627f7eb2Smrg# Libquadmath is free software; you can redistribute it and/or
7*627f7eb2Smrg# modify it under the terms of the GNU Lesser General Public
8*627f7eb2Smrg# License as published by the Free Software Foundation; either
9*627f7eb2Smrg# version 2.1 of the License, or (at your option) any later version.
10*627f7eb2Smrg#
11*627f7eb2Smrg# Libquadmath is distributed in the hope that it will be useful,
12*627f7eb2Smrg# but WITHOUT ANY WARRANTY; without even the implied warranty of
13*627f7eb2Smrg# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*627f7eb2Smrg# Lesser General Public License for more details.
15*627f7eb2Smrg#
16*627f7eb2Smrg# You should have received a copy of the GNU Lesser General Public
17*627f7eb2Smrg# License along with libquadmath; if not, see
18*627f7eb2Smrg# <https://www.gnu.org/licenses/>.
19*627f7eb2Smrg
20*627f7eb2Smrg# Usage: update-quadmath.py glibc_srcdir quadmath_srcdir
21*627f7eb2Smrg
22*627f7eb2Smrgimport argparse
23*627f7eb2Smrgfrom collections import defaultdict
24*627f7eb2Smrgimport os.path
25*627f7eb2Smrgimport re
26*627f7eb2Smrg
27*627f7eb2Smrg
28*627f7eb2Smrgdef replace_in_file(repl_map, extra_map, src, dest):
29*627f7eb2Smrg    """Apply the replacements in repl_map, then those in extra_map, to the
30*627f7eb2Smrg    file src, producing dest."""
31*627f7eb2Smrg    with open(src, 'r') as src_file:
32*627f7eb2Smrg        text = src_file.read()
33*627f7eb2Smrg    for re_src, re_repl in sorted(repl_map.items()):
34*627f7eb2Smrg        text = re.sub(re_src, re_repl, text)
35*627f7eb2Smrg    for re_src, re_repl in sorted(extra_map.items()):
36*627f7eb2Smrg        text = re.sub(re_src, re_repl, text)
37*627f7eb2Smrg    text = text.rstrip() + '\n'
38*627f7eb2Smrg    with open(dest, 'w') as dest_file:
39*627f7eb2Smrg        dest_file.write(text)
40*627f7eb2Smrg
41*627f7eb2Smrg
42*627f7eb2Smrgdef update_sources(glibc_srcdir, quadmath_srcdir):
43*627f7eb2Smrg    """Update libquadmath sources."""
44*627f7eb2Smrg    glibc_ldbl128 = os.path.join(glibc_srcdir, 'sysdeps/ieee754/ldbl-128')
45*627f7eb2Smrg    glibc_math = os.path.join(glibc_srcdir, 'math')
46*627f7eb2Smrg    quadmath_math = os.path.join(quadmath_srcdir, 'math')
47*627f7eb2Smrg    float128_h = os.path.join(glibc_srcdir,
48*627f7eb2Smrg                              'sysdeps/ieee754/float128/float128_private.h')
49*627f7eb2Smrg    repl_map = {}
50*627f7eb2Smrg    # Use float128_private.h to get an initial list of names to
51*627f7eb2Smrg    # replace for libquadmath.
52*627f7eb2Smrg    repl_names = {}
53*627f7eb2Smrg    with open(float128_h, 'r') as header:
54*627f7eb2Smrg        for line in header:
55*627f7eb2Smrg            line = line.strip()
56*627f7eb2Smrg            if not line.startswith('#define '):
57*627f7eb2Smrg                continue
58*627f7eb2Smrg            match = re.fullmatch('^#define[ \t]+([a-zA-Z0-9_]+)'
59*627f7eb2Smrg                                 '[ \t]+([a-zA-Z0-9_]+)', line)
60*627f7eb2Smrg            if not match:
61*627f7eb2Smrg                continue
62*627f7eb2Smrg            macro = match.group(1)
63*627f7eb2Smrg            result = match.group(2)
64*627f7eb2Smrg            result = result.replace('f128', 'q')
65*627f7eb2Smrg            result = result.replace('__ieee754_', '')
66*627f7eb2Smrg            if result not in ('__expq_table', '__sincosq_table',
67*627f7eb2Smrg                              '__builtin_signbit'):
68*627f7eb2Smrg                result = result.replace('__', '')
69*627f7eb2Smrg            result = result.replace('_do_not_use', '')
70*627f7eb2Smrg            if result in ('rem_pio2q', 'kernel_sincosq', 'kernel_sinq',
71*627f7eb2Smrg                          'kernel_cosq', 'kernel_tanq', 'gammaq_r',
72*627f7eb2Smrg                          'gamma_productq', 'lgamma_negq', 'lgamma_productq',
73*627f7eb2Smrg                          'lgammaq_r', 'x2y2m1q'):
74*627f7eb2Smrg                # Internal function names, for which the above removal
75*627f7eb2Smrg                # of leading '__' was inappropriate and a leading
76*627f7eb2Smrg                # '__quadmath_' needs adding instead.  In the
77*627f7eb2Smrg                # libquadmath context, lgammaq_r is an internal name.
78*627f7eb2Smrg                result = '__quadmath_' + result
79*627f7eb2Smrg            if result == 'ieee854_float128_shape_type':
80*627f7eb2Smrg                result = 'ieee854_float128'
81*627f7eb2Smrg            if result == 'HUGE_VAL_F128':
82*627f7eb2Smrg                result = 'HUGE_VALQ'
83*627f7eb2Smrg            repl_names[macro] = result
84*627f7eb2Smrg    # More such names that aren't simply defined as object-like macros
85*627f7eb2Smrg    # in float128_private.h.
86*627f7eb2Smrg    repl_names['_Float128'] = '__float128'
87*627f7eb2Smrg    repl_names['SET_RESTORE_ROUNDL'] = 'SET_RESTORE_ROUNDF128'
88*627f7eb2Smrg    repl_names['parts32'] = 'words32'
89*627f7eb2Smrg    for macro in ('GET_LDOUBLE_LSW64', 'GET_LDOUBLE_MSW64',
90*627f7eb2Smrg                  'GET_LDOUBLE_WORDS64', 'SET_LDOUBLE_LSW64',
91*627f7eb2Smrg                  'SET_LDOUBLE_MSW64', 'SET_LDOUBLE_WORDS64'):
92*627f7eb2Smrg        repl_names[macro] = macro.replace('LDOUBLE', 'FLT128')
93*627f7eb2Smrg    # The classication macros are replaced.
94*627f7eb2Smrg    for macro in ('FP_NAN', 'FP_INFINITE', 'FP_ZERO', 'FP_SUBNORMAL',
95*627f7eb2Smrg                  'FP_NORMAL'):
96*627f7eb2Smrg        repl_names[macro] = 'QUAD' + macro
97*627f7eb2Smrg    for macro in ('fpclassify', 'signbit', 'isnan', 'isinf', 'issignaling'):
98*627f7eb2Smrg        repl_names[macro] = macro + 'q'
99*627f7eb2Smrg    repl_names['isfinite'] = 'finiteq'
100*627f7eb2Smrg    # Map comparison macros to the __builtin forms.
101*627f7eb2Smrg    for macro in ('isgreater', 'isgreaterequal', 'isless', 'islessequal',
102*627f7eb2Smrg                  'islessgreater', 'isunordered'):
103*627f7eb2Smrg        repl_names[macro] = '__builtin_' + macro
104*627f7eb2Smrg    # Replace macros used in type-generic templates in glibc.
105*627f7eb2Smrg    repl_names['FLOAT'] = '__float128'
106*627f7eb2Smrg    repl_names['CFLOAT'] = '__complex128'
107*627f7eb2Smrg    repl_names['M_NAN'] = 'nanq ("")'
108*627f7eb2Smrg    repl_names['M_HUGE_VAL'] = 'HUGE_VALQ'
109*627f7eb2Smrg    repl_names['INFINITY'] = '__builtin_inf ()'
110*627f7eb2Smrg    for macro in ('MIN_EXP', 'MAX_EXP', 'MIN', 'MAX', 'MANT_DIG', 'EPSILON'):
111*627f7eb2Smrg        repl_names['M_%s' % macro] = 'FLT128_%s' % macro
112*627f7eb2Smrg    for macro in ('COPYSIGN', 'FABS', 'SINCOS', 'SCALBN', 'LOG1P', 'ATAN2',
113*627f7eb2Smrg                  'COSH', 'EXP', 'HYPOT', 'LOG', 'SINH', 'SQRT'):
114*627f7eb2Smrg        repl_names['M_%s' % macro] = macro.lower() + 'q'
115*627f7eb2Smrg    # Each such name is replaced when it appears as a whole word.
116*627f7eb2Smrg    for macro in repl_names:
117*627f7eb2Smrg        repl_map[r'\b%s\b' % macro] = repl_names[macro]
118*627f7eb2Smrg    # Also replace the L macro for constants; likewise M_LIT and M_MLIT.
119*627f7eb2Smrg    repl_map[r'\bL *\((.*?)\)'] = r'\1Q'
120*627f7eb2Smrg    repl_map[r'\bM_LIT *\((.*?)\)'] = r'\1Q'
121*627f7eb2Smrg    repl_map[r'\bM_MLIT *\((.*?)\)'] = r'\1q'
122*627f7eb2Smrg    # M_DECL_FUNC and M_SUF need similar replacements.
123*627f7eb2Smrg    repl_map[r'\bM_DECL_FUNC *\((?:__)?(?:ieee754_)?(.*?)\)'] = r'\1q'
124*627f7eb2Smrg    repl_map[r'\bM_SUF *\((?:__)?(?:ieee754_)?(.*?)\)'] = r'\1q'
125*627f7eb2Smrg    # Further adjustments are then needed for certain internal
126*627f7eb2Smrg    # functions called via M_SUF.
127*627f7eb2Smrg    repl_map[r'\bx2y2m1q\b'] = '__quadmath_x2y2m1q'
128*627f7eb2Smrg    repl_map[r'\bkernel_casinhq\b'] = '__quadmath_kernel_casinhq'
129*627f7eb2Smrg    # Replace calls to __set_errno.
130*627f7eb2Smrg    repl_map[r'\b__set_errno *\((.*?)\)'] = r'errno = \1'
131*627f7eb2Smrg    # Eliminate glibc diagnostic macros.
132*627f7eb2Smrg    repl_map[r' *\bDIAG_PUSH_NEEDS_COMMENT;'] = ''
133*627f7eb2Smrg    repl_map[r' *\bDIAG_IGNORE_NEEDS_COMMENT *\(.*?\);'] = ''
134*627f7eb2Smrg    repl_map[r' *\bDIAG_POP_NEEDS_COMMENT;'] = ''
135*627f7eb2Smrg    # Different names used in union.
136*627f7eb2Smrg    repl_map[r'\.d\b'] = '.value'
137*627f7eb2Smrg    repl_map[r'\bunion ieee854_float128\b'] = 'ieee854_float128'
138*627f7eb2Smrg    # Calls to alias and hidden_def macros are all eliminated.
139*627f7eb2Smrg    for macro in ('strong_alias', 'weak_alias', 'libm_alias_ldouble',
140*627f7eb2Smrg                  'declare_mgen_alias', 'declare_mgen_finite_alias',
141*627f7eb2Smrg                  'libm_hidden_def', 'mathx_hidden_def'):
142*627f7eb2Smrg        repl_map[r'\b%s *\(.*?\);?' % macro] = ''
143*627f7eb2Smrg    # Replace all #includes with a single include of quadmath-imp.h.
144*627f7eb2Smrg    repl_map['(\n+#include[^\n]*)+\n+'] = '\n\n#include "quadmath-imp.h"\n\n'
145*627f7eb2Smrg    # Omitted from this list because code comes from more than one
146*627f7eb2Smrg    # glibc source file: rem_pio2.
147*627f7eb2Smrg    ldbl_files = {
148*627f7eb2Smrg        'e_acoshl.c': 'acoshq.c', 'e_acosl.c': 'acosq.c',
149*627f7eb2Smrg        's_asinhl.c': 'asinhq.c', 'e_asinl.c': 'asinq.c',
150*627f7eb2Smrg        'e_atan2l.c': 'atan2q.c', 'e_atanhl.c': 'atanhq.c',
151*627f7eb2Smrg        's_atanl.c': 'atanq.c', 's_cbrtl.c': 'cbrtq.c', 's_ceill.c': 'ceilq.c',
152*627f7eb2Smrg        's_copysignl.c': 'copysignq.c', 'e_coshl.c': 'coshq.c',
153*627f7eb2Smrg        's_cosl.c': 'cosq.c', 'k_cosl.c': 'cosq_kernel.c',
154*627f7eb2Smrg        's_erfl.c': 'erfq.c', 's_expm1l.c': 'expm1q.c', 'e_expl.c': 'expq.c',
155*627f7eb2Smrg        't_expl.h': 'expq_table.h', 's_fabsl.c': 'fabsq.c',
156*627f7eb2Smrg        's_finitel.c': 'finiteq.c', 's_floorl.c': 'floorq.c',
157*627f7eb2Smrg        's_fmal.c': 'fmaq.c', 'e_fmodl.c': 'fmodq.c', 's_frexpl.c': 'frexpq.c',
158*627f7eb2Smrg        'e_lgammal_r.c': 'lgammaq.c', 'lgamma_negl.c': 'lgammaq_neg.c',
159*627f7eb2Smrg        'lgamma_productl.c': 'lgammaq_product.c', 'e_hypotl.c': 'hypotq.c',
160*627f7eb2Smrg        'e_ilogbl.c': 'ilogbq.c', 's_isinfl.c': 'isinfq.c',
161*627f7eb2Smrg        's_isnanl.c': 'isnanq.c', 's_issignalingl.c': 'issignalingq.c',
162*627f7eb2Smrg        'e_j0l.c': 'j0q.c', 'e_j1l.c': 'j1q.c', 'e_jnl.c': 'jnq.c',
163*627f7eb2Smrg        's_llrintl.c': 'llrintq.c', 's_llroundl.c': 'llroundq.c',
164*627f7eb2Smrg        'e_log10l.c': 'log10q.c', 's_log1pl.c': 'log1pq.c',
165*627f7eb2Smrg        'e_log2l.c': 'log2q.c', 's_logbl.c': 'logbq.c', 'e_logl.c': 'logq.c',
166*627f7eb2Smrg        's_lrintl.c': 'lrintq.c', 's_lroundl.c': 'lroundq.c',
167*627f7eb2Smrg        's_modfl.c': 'modfq.c', 's_nearbyintl.c': 'nearbyintq.c',
168*627f7eb2Smrg        's_nextafterl.c': 'nextafterq.c', 'e_powl.c': 'powq.c',
169*627f7eb2Smrg        'e_remainderl.c': 'remainderq.c', 's_remquol.c': 'remquoq.c',
170*627f7eb2Smrg        's_rintl.c': 'rintq.c', 's_roundl.c': 'roundq.c',
171*627f7eb2Smrg        's_scalblnl.c': 'scalblnq.c', 's_scalbnl.c': 'scalbnq.c',
172*627f7eb2Smrg        's_signbitl.c': 'signbitq.c', 't_sincosl.c': 'sincos_table.c',
173*627f7eb2Smrg        's_sincosl.c': 'sincosq.c', 'k_sincosl.c': 'sincosq_kernel.c',
174*627f7eb2Smrg        'e_sinhl.c': 'sinhq.c', 's_sinl.c': 'sinq.c',
175*627f7eb2Smrg        'k_sinl.c': 'sinq_kernel.c', 's_tanhl.c': 'tanhq.c',
176*627f7eb2Smrg        's_tanl.c': 'tanq.c', 'k_tanl.c': 'tanq_kernel.c',
177*627f7eb2Smrg        'e_gammal_r.c': 'tgammaq.c', 'gamma_productl.c': 'tgammaq_product.c',
178*627f7eb2Smrg        's_truncl.c': 'truncq.c', 'x2y2m1l.c': 'x2y2m1q.c'
179*627f7eb2Smrg        }
180*627f7eb2Smrg    template_files = {
181*627f7eb2Smrg        's_cacosh_template.c': 'cacoshq.c', 's_cacos_template.c': 'cacosq.c',
182*627f7eb2Smrg        's_casinh_template.c': 'casinhq.c',
183*627f7eb2Smrg        'k_casinh_template.c': 'casinhq_kernel.c',
184*627f7eb2Smrg        's_casin_template.c': 'casinq.c', 's_catanh_template.c': 'catanhq.c',
185*627f7eb2Smrg        's_catan_template.c': 'catanq.c', 's_ccosh_template.c': 'ccoshq.c',
186*627f7eb2Smrg        's_cexp_template.c': 'cexpq.c', 'cimag_template.c': 'cimagq.c',
187*627f7eb2Smrg        's_clog10_template.c': 'clog10q.c', 's_clog_template.c': 'clogq.c',
188*627f7eb2Smrg        'conj_template.c': 'conjq.c', 's_cproj_template.c': 'cprojq.c',
189*627f7eb2Smrg        'creal_template.c': 'crealq.c', 's_csinh_template.c': 'csinhq.c',
190*627f7eb2Smrg        's_csin_template.c': 'csinq.c', 's_csqrt_template.c': 'csqrtq.c',
191*627f7eb2Smrg        's_ctanh_template.c': 'ctanhq.c', 's_ctan_template.c': 'ctanq.c',
192*627f7eb2Smrg        'e_exp2_template.c': 'exp2q.c', 's_fdim_template.c': 'fdimq.c',
193*627f7eb2Smrg        's_fmax_template.c': 'fmaxq.c', 's_fmin_template.c': 'fminq.c',
194*627f7eb2Smrg        's_ldexp_template.c': 'ldexpq.c'
195*627f7eb2Smrg        }
196*627f7eb2Smrg    # Some files have extra substitutions to apply.
197*627f7eb2Smrg    extra_maps = defaultdict(dict)
198*627f7eb2Smrg    extra_maps['expq.c'] = {r'#include "quadmath-imp\.h"\n':
199*627f7eb2Smrg                            '#include "quadmath-imp.h"\n'
200*627f7eb2Smrg                            '#include "expq_table.h"\n'}
201*627f7eb2Smrg    extra_maps['ilogbq.c'] = {r'#include "quadmath-imp\.h"\n':
202*627f7eb2Smrg                              '#include <math.h>\n'
203*627f7eb2Smrg                              '#include "quadmath-imp.h"\n'
204*627f7eb2Smrg                              '#ifndef FP_ILOGB0\n'
205*627f7eb2Smrg                              '# define FP_ILOGB0 INT_MIN\n'
206*627f7eb2Smrg                              '#endif\n'
207*627f7eb2Smrg                              '#ifndef FP_ILOGBNAN\n'
208*627f7eb2Smrg                              '# define FP_ILOGBNAN INT_MAX\n'
209*627f7eb2Smrg                              '#endif\n',
210*627f7eb2Smrg                              r'return ([A-Z0-9_]+);':
211*627f7eb2Smrg                              r'{ errno = EDOM; feraiseexcept (FE_INVALID); '
212*627f7eb2Smrg                              r'return \1; }'}
213*627f7eb2Smrg    extra_maps['lgammaq.c'] = {r'#include "quadmath-imp\.h"\n':
214*627f7eb2Smrg                               '#include "quadmath-imp.h"\n'
215*627f7eb2Smrg                               '#ifdef HAVE_MATH_H_SIGNGAM\n'
216*627f7eb2Smrg                               '# include <math.h>\n'
217*627f7eb2Smrg                               '#endif\n'
218*627f7eb2Smrg                               '__float128\n'
219*627f7eb2Smrg                               'lgammaq (__float128 x)\n'
220*627f7eb2Smrg                               '{\n'
221*627f7eb2Smrg                               '#ifndef HAVE_MATH_H_SIGNGAM\n'
222*627f7eb2Smrg                               '  int signgam;\n'
223*627f7eb2Smrg                               '#endif\n'
224*627f7eb2Smrg                               '  return __quadmath_lgammaq_r (x, &signgam);\n'
225*627f7eb2Smrg                               '}\n'}
226*627f7eb2Smrg    extra_maps['tgammaq.c'] = {r'#include "quadmath-imp\.h"\n':
227*627f7eb2Smrg                               '#include "quadmath-imp.h"\n'
228*627f7eb2Smrg                               '__float128\n'
229*627f7eb2Smrg                               'tgammaq (__float128 x)\n'
230*627f7eb2Smrg                               '{\n'
231*627f7eb2Smrg                               '  int sign;\n'
232*627f7eb2Smrg                               '  __float128 ret;\n'
233*627f7eb2Smrg                               '  ret = __quadmath_gammaq_r (x, &sign);\n'
234*627f7eb2Smrg                               '  return sign < 0 ? -ret : ret;\n'
235*627f7eb2Smrg                               '}\n'}
236*627f7eb2Smrg    for src, dest in ldbl_files.items():
237*627f7eb2Smrg        replace_in_file(repl_map, extra_maps[dest],
238*627f7eb2Smrg                        os.path.join(glibc_ldbl128, src),
239*627f7eb2Smrg                        os.path.join(quadmath_math, dest))
240*627f7eb2Smrg    for src, dest in template_files.items():
241*627f7eb2Smrg        replace_in_file(repl_map, extra_maps[dest],
242*627f7eb2Smrg                        os.path.join(glibc_math, src),
243*627f7eb2Smrg                        os.path.join(quadmath_math, dest))
244*627f7eb2Smrg
245*627f7eb2Smrgdef main():
246*627f7eb2Smrg    parser = argparse.ArgumentParser(description='Update libquadmath code.')
247*627f7eb2Smrg    parser.add_argument('glibc_srcdir', help='glibc source directory')
248*627f7eb2Smrg    parser.add_argument('quadmath_srcdir', help='libquadmath source directory')
249*627f7eb2Smrg    args = parser.parse_args()
250*627f7eb2Smrg    update_sources(args.glibc_srcdir, args.quadmath_srcdir)
251*627f7eb2Smrg
252*627f7eb2Smrg
253*627f7eb2Smrgif __name__ == '__main__':
254*627f7eb2Smrg    main()
255