On Wed, 24 Oct 2018, Jakub Jelinek wrote:

> On Tue, Oct 23, 2018 at 09:45:13PM -0400, Ed Smith-Rowland wrote:
> > Greetings,
> > 
> > This is an almost trivial patch to get the correct sign for tgammaq.
> 
> Doesn't look trivial to me.  What happens if x is a NaN?  Or if x is outside
> of the range of int?
> 
> Generally, libquadmath follows what glibc does, I don't see such a change in
> there.  So, the right fix is probably port all the upstream glibc *gamma*
> changes, in PR65757 as the 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65757#c18
> comment and my patch submission says, I've left those out because they were
> too large and I didn't have spare cycles for that.

I think it would be best to move to having a script to generate 
libquadmath sources automatically from glibc sources by appropriate 
substitutions, so that while you might need to update the script or 
quadmath-imp.h as part of updating libquadmath from glibc, you don't need 
to merge lots of changes manually.

Specifically, any comments on the patch below (quadmath-imp.h changes and 
new script shown, 6000 lines of diffs from running the script not shown)?  
It doesn't yet update the *gamma* sources, but could be extended to do so.  
(It also doesn't do anything with the parts of libquadmath outside of 
libquadmath/math/, but again could be extended for that.)  Specifically, 
the following files in libquadmath/math/ aren't yet updated by the script 
(a few of these, e.g. sqrtq.c, aren't actually based on glibc sources at 
all, while others just need the script to gain new features, or additional 
source files to be added to libquadmath): cacoshq.c cacosq.c casinhq.c 
complex.c expq.c fmaq.c ilogbq.c isinf_nsq.c lgammaq.c nanq.c rem_pio2q.c 
sqrtq.c tanq.c tgammaq.c x2y2m1q.c.

(The script does not aim to match formatting, comments etc. with the 
existing libquadmath code in all cases, but the results should be similar 
enough for comparison to be reasonable, especially if you ignore 
whitespace; an important question is whether it's losing deliberate local 
changes in the libquadmath code, that are either relevant for portability 
or affect the generated code.)

Index: libquadmath/quadmath-imp.h
===================================================================
--- libquadmath/quadmath-imp.h  (revision 265724)
+++ libquadmath/quadmath-imp.h  (working copy)
@@ -21,10 +21,15 @@
 #ifndef QUADMATH_IMP_H
 #define QUADMATH_IMP_H
 
+#include <errno.h>
+#include <limits.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include "quadmath.h"
 #include "config.h"
+#ifdef HAVE_FENV_H
+# include <fenv.h>
+#endif
 
 
 /* Under IEEE 754, an architecture may determine tininess of
@@ -36,6 +41,8 @@
 
 #define TININESS_AFTER_ROUNDING   1
 
+#define FIX_FLT128_LONG_CONVERT_OVERFLOW 0
+#define FIX_FLT128_LLONG_CONVERT_OVERFLOW 0
 
 /* Prototypes for internal functions.  */
 extern int32_t __quadmath_rem_pio2q (__float128, __float128 *);
@@ -227,4 +234,50 @@
     }                                                          \
   while (0)
 
+/* Likewise, for both real and imaginary parts of a complex
+   result.  */
+#define math_check_force_underflow_complex(x)                          \
+  do                                                                   \
+    {                                                                  \
+      __typeof (x) force_underflow_complex_tmp = (x);                  \
+      math_check_force_underflow (__real__ force_underflow_complex_tmp); \
+      math_check_force_underflow (__imag__ force_underflow_complex_tmp); \
+    }                                                                  \
+  while (0)
+
+#ifndef HAVE_FENV_H
+# define feraiseexcept(arg) ((void) 0)
+typedef int fenv_t;
+# define feholdexcept(arg) ((void) 0)
+# define fesetround(arg) ((void) 0)
+# define feupdateenv(arg) ((void) (arg))
+# define fesetenv(arg) ((void) (arg))
+# define fetestexcept(arg) 0
+# define feclearexcept(arg) ((void) 0)
+#else
+# ifndef HAVE_FEHOLDEXCEPT
+#  define feholdexcept(arg) ((void) 0)
+# endif
+# ifndef HAVE_FESETROUND
+#  define fesetround(arg) ((void) 0)
+# endif
+# ifndef HAVE_FEUPDATEENV
+#  define feupdateenv(arg) ((void) (arg))
+# endif
+# ifndef HAVE_FESETENV
+#  define fesetenv(arg) ((void) (arg))
+# endif
+# ifndef HAVE_FETESTEXCEPT
+#  define fetestexcept(arg) 0
+# endif
 #endif
+
+#ifndef __glibc_likely
+# define __glibc_likely(cond)  __builtin_expect ((cond), 1)
+#endif
+
+#ifndef __glibc_unlikely
+# define __glibc_unlikely(cond)        __builtin_expect ((cond), 0)
+#endif
+
+#endif
Index: libquadmath/update-quadmath.py
===================================================================
--- libquadmath/update-quadmath.py      (nonexistent)
+++ libquadmath/update-quadmath.py      (working copy)
@@ -0,0 +1,198 @@
+#!/usr/bin/python3
+# Update libquadmath code from glibc sources.
+# Copyright (C) 2018 Free Software Foundation, Inc.
+# This file is part of the libquadmath library.
+#
+# Libquadmath is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# Libquadmath is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with libquadmath; if not, see
+# <https://www.gnu.org/licenses/>.
+
+# Usage: update-quadmath.py glibc_srcdir quadmath_srcdir
+
+import argparse
+import os.path
+import re
+
+
+def replace_in_file(repl_map, src, dest):
+    """Apply the replacements in repl_map to the file src, producing dest."""
+    with open(src, 'r') as src_file:
+        text = src_file.read()
+    for re_src, re_repl in sorted(repl_map.items()):
+        text = re.sub(re_src, re_repl, text)
+    text = text.rstrip() + '\n'
+    with open(dest, 'w') as dest_file:
+        dest_file.write(text)
+
+
+def update_sources(glibc_srcdir, quadmath_srcdir):
+    """Update libquadmath sources."""
+    glibc_ldbl128 = os.path.join(glibc_srcdir, 'sysdeps/ieee754/ldbl-128')
+    glibc_math = os.path.join(glibc_srcdir, 'math')
+    quadmath_math = os.path.join(quadmath_srcdir, 'math')
+    float128_h = os.path.join(glibc_srcdir,
+                              'sysdeps/ieee754/float128/float128_private.h')
+    repl_map = {}
+    # Use float128_private.h to get an initial list of names to
+    # replace for libquadmath.
+    repl_names = {}
+    with open(float128_h, 'r') as header:
+        for line in header:
+            line = line.strip()
+            if not line.startswith('#define '):
+                continue
+            match = re.fullmatch('^#define[ \t]+([a-zA-Z0-9_]+)'
+                                 '[ \t]+([a-zA-Z0-9_]+)', line)
+            if not match:
+                continue
+            macro = match.group(1)
+            result = match.group(2)
+            result = result.replace('f128', 'q')
+            result = result.replace('__ieee754_', '')
+            if result not in ('__expq_table', '__sincosq_table',
+                              '__builtin_signbit'):
+                result = result.replace('__', '')
+            result = result.replace('_do_not_use', '')
+            if result in ('rem_pio2q', 'kernel_sincosq', 'kernel_sinq',
+                          'kernel_cosq', 'kernel_tanq', 'x2y2m1q'):
+                # Internal function names, for which the above removal
+                # of leading '__' was inappropriate and a leading
+                # '__quadmath_' needs adding instead.
+                result = '__quadmath_' + result
+            if result == 'ieee854_float128_shape_type':
+                result = 'ieee854_float128'
+            if result == 'HUGE_VAL_F128':
+                result = 'HUGE_VALQ'
+            repl_names[macro] = result
+    # More such names that aren't simply defined as object-like macros
+    # in float128_private.h.
+    repl_names['_Float128'] = '__float128'
+    repl_names['parts32'] = 'words32'
+    for macro in ('GET_LDOUBLE_LSW64', 'GET_LDOUBLE_MSW64',
+                  'GET_LDOUBLE_WORDS64', 'SET_LDOUBLE_LSW64',
+                  'SET_LDOUBLE_MSW64', 'SET_LDOUBLE_WORDS64'):
+        repl_names[macro] = macro.replace('LDOUBLE', 'FLT128')
+    # The classication macros are replaced.
+    for macro in ('FP_NAN', 'FP_INFINITE', 'FP_ZERO', 'FP_SUBNORMAL',
+                  'FP_NORMAL'):
+        repl_names[macro] = 'QUAD' + macro
+    for macro in ('fpclassify', 'signbit', 'isnan', 'isinf'):
+        repl_names[macro] = macro + 'q'
+    repl_names['isfinite'] = 'finiteq'
+    # Map comparison macros to the __builtin forms.
+    for macro in ('isgreater', 'isgreaterequal', 'isless', 'islessequal',
+                  'islessgreater', 'isunordered'):
+        repl_names[macro] = '__builtin_' + macro
+    # Replace macros used in type-generic templates in glibc.
+    repl_names['FLOAT'] = '__float128'
+    repl_names['CFLOAT'] = '__complex128'
+    repl_names['M_NAN'] = 'nanq ("")'
+    repl_names['M_HUGE_VAL'] = 'HUGE_VALQ'
+    repl_names['INFINITY'] = '__builtin_inf ()'
+    for macro in ('MIN_EXP', 'MAX_EXP', 'MIN', 'MAX', 'MANT_DIG', 'EPSILON'):
+        repl_names['M_%s' % macro] = 'FLT128_%s' % macro
+    for macro in ('COPYSIGN', 'FABS', 'SINCOS', 'SCALBN', 'LOG1P', 'ATAN2',
+                  'COSH', 'EXP', 'HYPOT', 'LOG', 'SINH', 'SQRT'):
+        repl_names['M_%s' % macro] = macro.lower() + 'q'
+    # Each such name is replaced when it appears as a whole word.
+    for macro in repl_names:
+        repl_map[r'\b%s\b' % macro] = repl_names[macro]
+    # issignalingq not yet defined in libquadmath.
+    repl_map[r'\bissignaling *\(.*?\)'] = '0'
+    # Likewise SET_RESTORE_ROUNDL (should map to SET_RESTORE_ROUNDF128
+    # above once supported).
+    repl_map[r'\bSET_RESTORE_ROUNDL *\(.*?\)'] = '(void) 0'
+    # Also replace the L macro for constants; likewise M_LIT and M_MLIT.
+    repl_map[r'\bL *\((.*?)\)'] = r'\1Q'
+    repl_map[r'\bM_LIT *\((.*?)\)'] = r'\1Q'
+    repl_map[r'\bM_MLIT *\((.*?)\)'] = r'\1q'
+    # M_DECL_FUNC and M_SUF need similar replacements.
+    repl_map[r'\bM_DECL_FUNC *\((?:__)?(.*?)\)'] = r'\1q'
+    repl_map[r'\bM_SUF *\((?:__)?(?:ieee754_)?(.*?)\)'] = r'\1q'
+    # Further adjustments are then needed for certain internal
+    # functions called via M_SUF.
+    repl_map[r'\bx2y2m1q\b'] = '__quadmath_x2y2m1q'
+    # Replace calls to __set_errno.
+    repl_map[r'\b__set_errno *\((.*?)\)'] = r'errno = \1'
+    # Different names used in union.
+    repl_map[r'\.d\b'] = '.value'
+    # Calls to alias and hidden_def macros are all eliminated.
+    for macro in ('strong_alias', 'weak_alias', 'libm_alias_ldouble',
+                  'declare_mgen_alias', 'libm_hidden_def', 'mathx_hidden_def'):
+        repl_map[r'\b%s *\(.*?\);?' % macro] = ''
+    # Replace all #includes with a single include of quadmath-imp.h.
+    repl_map['(\n+#include[^\n]*)+\n+'] = '\n\n#include "quadmath-imp.h"\n\n'
+    # Omitted from this list because code comes from more than one
+    # glibc source file: exp, rem_pio2, tan.  Omitted because of a
+    # union not currently provided in libquadmath: fma.  Omitted
+    # because of fallback macro definitions not currently handled
+    # here: ilogb.
+    ldbl_files = {
+        'e_acoshl.c': 'acoshq.c', 'e_acosl.c': 'acosq.c',
+        's_asinhl.c': 'asinhq.c', 'e_asinl.c': 'asinq.c',
+        'e_atan2l.c': 'atan2q.c', 'e_atanhl.c': 'atanhq.c',
+        's_atanl.c': 'atanq.c', 's_cbrtl.c': 'cbrtq.c', 's_ceill.c': 'ceilq.c',
+        's_copysignl.c': 'copysignq.c', 'e_coshl.c': 'coshq.c',
+        's_cosl.c': 'cosq.c', 'k_cosl.c': 'cosq_kernel.c',
+        's_erfl.c': 'erfq.c', 's_expm1l.c': 'expm1q.c', 's_fabsl.c': 'fabsq.c',
+        's_finitel.c': 'finiteq.c', 's_floorl.c': 'floorq.c',
+        'e_fmodl.c': 'fmodq.c', 's_frexpl.c': 'frexpq.c',
+        'e_hypotl.c': 'hypotq.c', 's_isinfl.c': 'isinfq.c',
+        's_isnanl.c': 'isnanq.c', 'e_j0l.c': 'j0q.c', 'e_j1l.c': 'j1q.c',
+        'e_jnl.c': 'jnq.c', 's_llrintl.c': 'llrintq.c',
+        's_llroundl.c': 'llroundq.c', 'e_log10l.c': 'log10q.c',
+        's_log1pl.c': 'log1pq.c', 'e_log2l.c': 'log2q.c',
+        's_logbl.c': 'logbq.c', 'e_logl.c': 'logq.c', 's_lrintl.c': 'lrintq.c',
+        's_lroundl.c': 'lroundq.c', 's_modfl.c': 'modfq.c',
+        's_nearbyintl.c': 'nearbyintq.c', 's_nextafterl.c': 'nextafterq.c',
+        'e_powl.c': 'powq.c', 'e_remainderl.c': 'remainderq.c',
+        's_remquol.c': 'remquoq.c', 's_rintl.c': 'rintq.c',
+        's_roundl.c': 'roundq.c', 's_scalblnl.c': 'scalblnq.c',
+        's_scalbnl.c': 'scalbnq.c', 's_signbitl.c': 'signbitq.c',
+        't_sincosl.c': 'sincos_table.c', 's_sincosl.c': 'sincosq.c',
+        'k_sincosl.c': 'sincosq_kernel.c', 'e_sinhl.c': 'sinhq.c',
+        's_sinl.c': 'sinq.c', 'k_sinl.c': 'sinq_kernel.c',
+        's_tanhl.c': 'tanhq.c', 's_truncl.c': 'truncq.c'
+        }
+    # Omitted from this list because of dependency on __kernel_casinh,
+    # not currently in libquadmath: cacosh cacos casinh.
+    template_files = {
+        's_casin_template.c': 'casinq.c',
+        's_catanh_template.c': 'catanhq.c', 's_catan_template.c': 'catanq.c',
+        's_ccosh_template.c': 'ccoshq.c', 's_cexp_template.c': 'cexpq.c',
+        'cimag_template.c': 'cimagq.c', 's_clog10_template.c': 'clog10q.c',
+        's_clog_template.c': 'clogq.c', 'conj_template.c': 'conjq.c',
+        's_cproj_template.c': 'cprojq.c', 'creal_template.c': 'crealq.c',
+        's_csinh_template.c': 'csinhq.c', 's_csin_template.c': 'csinq.c',
+        's_csqrt_template.c': 'csqrtq.c', 's_ctanh_template.c': 'ctanhq.c',
+        's_ctan_template.c': 'ctanq.c', 's_fdim_template.c': 'fdimq.c',
+        's_fmax_template.c': 'fmaxq.c', 's_fmin_template.c': 'fminq.c',
+        's_ldexp_template.c': 'ldexpq.c'
+        }
+    for src, dest in ldbl_files.items():
+        replace_in_file(repl_map, os.path.join(glibc_ldbl128, src),
+                        os.path.join(quadmath_math, dest))
+    for src, dest in template_files.items():
+        replace_in_file(repl_map, os.path.join(glibc_math, src),
+                        os.path.join(quadmath_math, dest))
+
+def main():
+    parser = argparse.ArgumentParser(description='Update libquadmath code.')
+    parser.add_argument('glibc_srcdir', help='glibc source directory')
+    parser.add_argument('quadmath_srcdir', help='libquadmath source directory')
+    args = parser.parse_args()
+    update_sources(args.glibc_srcdir, args.quadmath_srcdir)
+
+
+if __name__ == '__main__':
+    main()

Property changes on: libquadmath/update-quadmath.py
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property

-- 
Joseph S. Myers
jos...@codesourcery.com

Reply via email to