From 781183595acba67a37c66f59a0c1d9b5fee7e248 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Mon, 22 Feb 2021 15:33:29 -0500 Subject: Add conversions between _Float128 and Decimal. This patch implements conversions between _Float128 and the 3 Decimal floating types. It does this by extendending the dfp-bit conversions to add a new binary floating point type (KF), and doing the conversions in the same manner as the other binary/decimal conversions. For conversions from _Float128 to Decimal, this patch uses a function (__sprintfkf) instead of the sprintf function to convert long double values to strings. The __sprintfkf function determines if GLIBC 2.32 or newer is used and calls the IEEE 128-bit version of sprintf (__sprintfieee128). If the GLIBC is earlier than 2.32, the code will convert _Float128 to __ibm128 and then use the normal sprintf to convert this value. For conversions from Decimal to _Float128, this patch uses a function (__strtokf) instead of strtold to convert the strings from the Decimal conversion to long double. The __strtokf function determines if GLIBC 2.32 or newer is used, and if it is, calls the IEEE 128-bit version (__strtoieee128). If the GLIBC is earlier than 2.32, the code will call strtold and convert the __ibm128 value to _Float128. These functions will primarily be used if/when the default PowerPC long double type is changed to IEEE 128-bit, but they could also be used if the user explicitly converts _Float128 to/from a Decimal type. libgcc/ 2021-02-22 Michael Meissner * config/rs6000/_dd_to_kf.c: New file. * config/rs6000/_kf_to_dd.c: New file. * config/rs6000/_kf_to_sd.c: New file. * config/rs6000/_kf_to_td.c: New file. * config/rs6000/_sd_to_kf.c: New file. * config/rs6000/_sprintfkf.c: New file. * config/rs6000/_sprintfkf.h: New file. * config/rs6000/_strtokf.h: New file. * config/rs6000/_strtokf.c: New file. * config/rs6000/_td_to_kf.c: New file. * config/rs6000/quad-float128.h: Add new declarations. * config/rs6000/t-float128 (fp128_dec_funcs): New macro. (fp128_decstr_funcs): New macro. (ibm128_dec_funcs): New macro. (fp128_ppc_funcs): Add the new conversions. (fp128_dec_objs): Force Decimal <-> __float128 conversions to be compiled with -mabi=ieeelongdouble. (fp128_decstr_objs): Force __float128 <-> string conversions to be compiled with -mabi=ibmlongdouble. (ibm128_dec_objs): Force Decimal <-> __float128 conversions to be compiled with -mabi=ieeelongdouble. (FP128_CFLAGS_DECIMAL): New macro. (IBM128_CFLAGS_DECIMAL): New macro. * dfp-bit.c (DFP_TO_BFP): Add PowerPC _Float128 support. (BFP_TO_DFP): Add PowerPC _Float128 support. * dfp-bit.h (BFP_KIND): Add new binary floating point kind for IEEE 128-bit floating point. (DFP_TO_BFP): Add PowerPC _Float128 support. (BFP_TO_DFP): Add PowerPC _Float128 support. (BFP_SPRINTF): New macro. --- libgcc/config/rs6000/_dd_to_kf.c | 37 +++++++++++++++++++++++ libgcc/config/rs6000/_kf_to_dd.c | 37 +++++++++++++++++++++++ libgcc/config/rs6000/_kf_to_sd.c | 37 +++++++++++++++++++++++ libgcc/config/rs6000/_kf_to_td.c | 37 +++++++++++++++++++++++ libgcc/config/rs6000/_sd_to_kf.c | 37 +++++++++++++++++++++++ libgcc/config/rs6000/_sprintfkf.c | 57 ++++++++++++++++++++++++++++++++++++ libgcc/config/rs6000/_sprintfkf.h | 28 ++++++++++++++++++ libgcc/config/rs6000/_strtokf.c | 53 +++++++++++++++++++++++++++++++++ libgcc/config/rs6000/_strtokf.h | 27 +++++++++++++++++ libgcc/config/rs6000/_td_to_kf.c | 37 +++++++++++++++++++++++ libgcc/config/rs6000/quad-float128.h | 8 +++++ libgcc/config/rs6000/t-float128 | 37 ++++++++++++++++++++++- libgcc/dfp-bit.c | 12 ++++++-- libgcc/dfp-bit.h | 26 ++++++++++++++++ 14 files changed, 467 insertions(+), 3 deletions(-) create mode 100644 libgcc/config/rs6000/_dd_to_kf.c create mode 100644 libgcc/config/rs6000/_kf_to_dd.c create mode 100644 libgcc/config/rs6000/_kf_to_sd.c create mode 100644 libgcc/config/rs6000/_kf_to_td.c create mode 100644 libgcc/config/rs6000/_sd_to_kf.c create mode 100644 libgcc/config/rs6000/_sprintfkf.c create mode 100644 libgcc/config/rs6000/_sprintfkf.h create mode 100644 libgcc/config/rs6000/_strtokf.c create mode 100644 libgcc/config/rs6000/_strtokf.h create mode 100644 libgcc/config/rs6000/_td_to_kf.c (limited to 'libgcc') diff --git a/libgcc/config/rs6000/_dd_to_kf.c b/libgcc/config/rs6000/_dd_to_kf.c new file mode 100644 index 0000000..6613c44 --- /dev/null +++ b/libgcc/config/rs6000/_dd_to_kf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* Decimal64 -> _Float128 conversion. */ + +/* FINE_GRAINED_LIBRARIES is used so we can isolate just to dd_to_tf conversion + function from dp-bits.c. */ +#define FINE_GRAINED_LIBRARIES 1 +#define L_dd_to_kf 1 +#define WIDTH 64 + +#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__) +#error "Long double is not IEEE 128-bit" +#endif + +/* Use dfp-bit.c to do the real work. */ +#include "dfp-bit.c" diff --git a/libgcc/config/rs6000/_kf_to_dd.c b/libgcc/config/rs6000/_kf_to_dd.c new file mode 100644 index 0000000..93a1043 --- /dev/null +++ b/libgcc/config/rs6000/_kf_to_dd.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* _Float128 -> Decimal64 conversion. */ + +/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_dd conversion + function from dp-bits.c. */ +#define FINE_GRAINED_LIBRARIES 1 +#define L_kf_to_dd 1 +#define WIDTH 64 + +#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__) +#error "Long double is not IEEE 128-bit" +#endif + +/* Use dfp-bit.c to do the real work. */ +#include "dfp-bit.c" diff --git a/libgcc/config/rs6000/_kf_to_sd.c b/libgcc/config/rs6000/_kf_to_sd.c new file mode 100644 index 0000000..01396da --- /dev/null +++ b/libgcc/config/rs6000/_kf_to_sd.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* _Float128 -> Decimal32 conversion. */ + +/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_sd conversion + function from dp-bits.c. */ +#define FINE_GRAINED_LIBRARIES 1 +#define L_kf_to_sd 1 +#define WIDTH 32 + +#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__) +#error "Long double is not IEEE 128-bit" +#endif + +/* Use dfp-bit.c to do the real work. */ +#include "dfp-bit.c" diff --git a/libgcc/config/rs6000/_kf_to_td.c b/libgcc/config/rs6000/_kf_to_td.c new file mode 100644 index 0000000..45bba92 --- /dev/null +++ b/libgcc/config/rs6000/_kf_to_td.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* _Float128 -> Decimal128 conversion. */ + +/* FINE_GRAINED_LIBRARIES is used so we can isolate just to tf_to_td conversion + function from dp-bits.c. */ +#define FINE_GRAINED_LIBRARIES 1 +#define L_kf_to_td 1 +#define WIDTH 128 + +#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__) +#error "Long double is not IEEE 128-bit" +#endif + +/* Use dfp-bit.c to do the real work. */ +#include "dfp-bit.c" diff --git a/libgcc/config/rs6000/_sd_to_kf.c b/libgcc/config/rs6000/_sd_to_kf.c new file mode 100644 index 0000000..9224444 --- /dev/null +++ b/libgcc/config/rs6000/_sd_to_kf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* Decimal32 -> _Float128 conversion. */ + +/* FINE_GRAINED_LIBRARIES is used so we can isolate just to sd_to_tf conversion + function from dp-bits.c. */ +#define FINE_GRAINED_LIBRARIES 1 +#define L_sd_to_kf 1 +#define WIDTH 32 + +#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__) +#error "Long double is not IEEE 128-bit" +#endif + +/* Use dfp-bit.c to do the real work. */ +#include "dfp-bit.c" diff --git a/libgcc/config/rs6000/_sprintfkf.c b/libgcc/config/rs6000/_sprintfkf.c new file mode 100644 index 0000000..a7fdfb4 --- /dev/null +++ b/libgcc/config/rs6000/_sprintfkf.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1989-2021 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* Conversion to IEEE 128-bit floating point from string using snprintf. */ + +#include +#include +#include +#include +#include + +/* This function must be built with IBM 128-bit as long double, so that we can + access the strfroml function if do not have an IEEE 128-bit version, and if + that is not available, use sprintf. */ +#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IBM128__) +#error "Long double is not IBM 128-bit" +#endif + +/* If the user is using GLIBC 2.32, we can use the __snprintfieee128 function. + + If we are linked against an earlier library, we will have fake it by + converting the value to long double, and using sprintf to do the conversion. + This isn't ideal, as IEEE 128-bit has more exponent range than IBM + 128-bit. */ + +extern int __sprintfieee128 (char *restrict, const char *restrict, ...) + __attribute__ ((__weak__)); + +int __sprintfkf (char *restrict string, + const char *restrict format, + _Float128 number) +{ + if (__sprintfieee128) + return __sprintfieee128 (string, format, number); + + return sprintf (string, format, (long double) number); +} diff --git a/libgcc/config/rs6000/_sprintfkf.h b/libgcc/config/rs6000/_sprintfkf.h new file mode 100644 index 0000000..637d104 --- /dev/null +++ b/libgcc/config/rs6000/_sprintfkf.h @@ -0,0 +1,28 @@ +/* Copyright (C) 1989-2021 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* Declaration of the conversion function to IEEE 128-bit floating point from + string using snprintf. */ + +extern int __sprintfkf (char *restrict, const char *restrict, ...); + diff --git a/libgcc/config/rs6000/_strtokf.c b/libgcc/config/rs6000/_strtokf.c new file mode 100644 index 0000000..dc13534 --- /dev/null +++ b/libgcc/config/rs6000/_strtokf.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1989-2021 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* Conversion to IEEE 128-bit floating point from string. */ + +#include +#include +#include +#include + +/* This function must be built with IBM 128-bit as long double, so that we can + access the strtold function if do not have an IEEE 128-bit version. */ +#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IBM128__) +#error "Long double is not IBM 128-bit" +#endif + +/* If the user is using GLIBC 2.32, we can use the __strtoieee128 function. + + If we are linked against an earlier library, we will have fake it by + converting the string to IBM 128-bit long double, and then converting that to + __float128. This isn't ideal, as IEEE 128-bit has more exponent range than + IBM 128-bit. */ + +extern _Float128 __strtoieee128 (const char *, char **) __attribute__ ((__weak__)); + +_Float128 +__strtokf (const char *string, char **endptr) +{ + if (__strtoieee128) + return __strtoieee128 (string, endptr); + + return strtold (string, endptr); +} diff --git a/libgcc/config/rs6000/_strtokf.h b/libgcc/config/rs6000/_strtokf.h new file mode 100644 index 0000000..a7ca8e0 --- /dev/null +++ b/libgcc/config/rs6000/_strtokf.h @@ -0,0 +1,27 @@ +/* Copyright (C) 1989-2021 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* Declaration of the conversion function to IEEE 128-bit floating point from + string. */ + +extern _Float128 __strtokf (const char *, char **); diff --git a/libgcc/config/rs6000/_td_to_kf.c b/libgcc/config/rs6000/_td_to_kf.c new file mode 100644 index 0000000..0134581 --- /dev/null +++ b/libgcc/config/rs6000/_td_to_kf.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC 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 General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* Decimal128 -> _Float128 conversion. */ + +/* FINE_GRAINED_LIBRARIES is used so we can isolate just to td_to_tf conversion + function from dp-bits.c. */ +#define FINE_GRAINED_LIBRARIES 1 +#define L_td_to_kf 1 +#define WIDTH 128 + +#if !defined(__LONG_DOUBLE_128__) || !defined(__LONG_DOUBLE_IEEE128__) +#error "Long double is not IEEE 128-bit" +#endif + +/* Use dfp-bit.c to do the real work. */ +#include "dfp-bit.c" diff --git a/libgcc/config/rs6000/quad-float128.h b/libgcc/config/rs6000/quad-float128.h index 0eb1d34..5beb153 100644 --- a/libgcc/config/rs6000/quad-float128.h +++ b/libgcc/config/rs6000/quad-float128.h @@ -49,6 +49,7 @@ typedef __complex float TCtype __attribute__ ((mode (TC))); #pragma GCC target ("vsx,float128") #endif +#include #include #define IBM128_TYPE __ibm128 @@ -171,6 +172,13 @@ extern TFtype __trunctfkf2 (IBM128_TYPE); extern TCtype __mulkc3 (TFtype, TFtype, TFtype, TFtype); extern TCtype __divkc3 (TFtype, TFtype, TFtype, TFtype); +/* Convert IEEE 128-bit floating point to/from string. We explicitly use + _Float128 instead of TFmode because _strtokf and _strfromkf must be compiled + with long double being IBM 128. */ +extern _Float128 __strtokf (const char *, char **); +extern int __strfromkf (char *restrict, size_t, const char *restrict, + _Float128); + /* Implementation of conversions between __ibm128 and __float128, to allow the same code to be used on systems with IEEE 128-bit emulation and with IEEE 128-bit hardware support. */ diff --git a/libgcc/config/rs6000/t-float128 b/libgcc/config/rs6000/t-float128 index d541344..6fb1a3d 100644 --- a/libgcc/config/rs6000/t-float128 +++ b/libgcc/config/rs6000/t-float128 @@ -22,10 +22,23 @@ fp128_softfp_static_obj = $(addsuffix -sw$(objext),$(fp128_softfp_funcs)) fp128_softfp_shared_obj = $(addsuffix -sw_s$(objext),$(fp128_softfp_funcs)) fp128_softfp_obj = $(fp128_softfp_static_obj) $(fp128_softfp_shared_obj) +# Decimal <-> _Float128 conversions +fp128_dec_funcs = _kf_to_sd _kf_to_dd _kf_to_td \ + _sd_to_kf _dd_to_kf _td_to_kf + +# _Float128 to/from string conversions that must be compiled with IBM 128-bit +# long double. +fp128_decstr_funcs = _strtokf _sprintfkf + +# Decimal <-> __ibm128 conversions +ibm128_dec_funcs = _tf_to_sd _tf_to_dd _tf_to_td \ + _sd_to_tf _dd_to_tf _td_to_tf + # New functions for software emulation fp128_ppc_funcs = floattikf floatuntikf fixkfti fixunskfti \ extendkftf2-sw trunctfkf2-sw \ - sfp-exceptions _mulkc3 _divkc3 _powikf2 + sfp-exceptions _mulkc3 _divkc3 _powikf2 \ + $(fp128_dec_funcs) $(fp128_decstr_funcs) fp128_ppc_src = $(addprefix $(srcdir)/config/rs6000/,$(addsuffix \ .c,$(fp128_ppc_funcs))) @@ -69,6 +82,28 @@ $(fp128_ppc_obj) : INTERNAL_CFLAGS += $(FP128_CFLAGS_SW) $(fp128_obj) : $(fp128_includes) $(fp128_obj) : $(srcdir)/config/rs6000/quad-float128.h +# Force the TF mode to/from decimal functions to be compiled with IBM long +# double. Add building the KF mode to/from decimal conversions with explict +# IEEE long double. +fp128_dec_objs = $(addsuffix $(objext),$(fp128_dec_funcs)) \ + $(addsuffix _s$(objext),$(fp128_dec_funcs)) + +fp128_decstr_objs = $(addsuffix $(objext),$(fp128_decstr_funcs)) \ + $(addsuffix _s$(objext),$(fp128_decstr_funcs)) + +ibm128_dec_objs = $(addsuffix $(objext),$(ibm128_dec_funcs)) \ + $(addsuffix _s$(objext),$(ibm128_dec_funcs)) + +FP128_CFLAGS_DECIMAL = -mno-gnu-attribute -Wno-psabi -mabi=ieeelongdouble +IBM128_CFLAGS_DECIMAL = -mno-gnu-attribute -Wno-psabi -mabi=ibmlongdouble + +$(fp128_dec_objs) : INTERNAL_CFLAGS += $(FP128_CFLAGS_DECIMAL) +$(fp128_decstr_objs) : INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL) +$(ibm128_dec_objs) : INTERNAL_CFLAGS += $(IBM128_CFLAGS_DECIMAL) + +$(fp128_decstr_objs) : $(srcdir)/config/rs6000/_strtokf.h \ + $(srcdir)/config/rs6000/_sprintfkf.h \ + $(fp128_softfp_src) : $(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@)) $(fp128_dep) @src="$(srcdir)/soft-fp/$(subst -sw,,$(subst kf,tf,$@))"; \ echo "Create $@"; \ diff --git a/libgcc/dfp-bit.c b/libgcc/dfp-bit.c index 17bca9c..0b0f9ac 100644 --- a/libgcc/dfp-bit.c +++ b/libgcc/dfp-bit.c @@ -606,6 +606,7 @@ INT_TO_DFP (INT_TYPE i) #if defined (L_sd_to_sf) || defined (L_dd_to_sf) || defined (L_td_to_sf) \ || defined (L_sd_to_df) || defined (L_dd_to_df) || defined (L_td_to_df) \ + || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \ || ((defined (L_sd_to_xf) || defined (L_dd_to_xf) || defined (L_td_to_xf)) \ && LONG_DOUBLE_HAS_XF_MODE) \ || ((defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf)) \ @@ -626,6 +627,7 @@ DFP_TO_BFP (DFP_C_TYPE f) #if defined (L_sf_to_sd) || defined (L_sf_to_dd) || defined (L_sf_to_td) \ || defined (L_df_to_sd) || defined (L_df_to_dd) || defined (L_df_to_td) \ + || defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td) \ || ((defined (L_xf_to_sd) || defined (L_xf_to_dd) || defined (L_xf_to_td)) \ && LONG_DOUBLE_HAS_XF_MODE) \ || ((defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)) \ @@ -641,8 +643,14 @@ BFP_TO_DFP (BFP_TYPE x) decContextDefault (&context, CONTEXT_INIT); DFP_INIT_ROUNDMODE (context.round); - /* Use a C library function to write the floating point value to a string. */ - sprintf (buf, BFP_FMT, (BFP_VIA_TYPE) x); + /* Use the sprintf library function to write the floating point value to a string. + + If we are handling the IEEE 128-bit floating point on PowerPC, use the + special function __sprintfkf instead of sprintf. This function allows us + to use __sprintfieee128 if we have a new enough GLIBC, and it can fall back + to using the traditional sprintf via conversion to IBM 128-bit if the glibc + is older. */ + BFP_SPRINTF (buf, BFP_FMT, (BFP_VIA_TYPE) x); /* Convert from the floating point string to a decimal* type. */ FROM_STRING (&s, buf, &context); diff --git a/libgcc/dfp-bit.h b/libgcc/dfp-bit.h index 1fa42ee..5e3bfa6 100644 --- a/libgcc/dfp-bit.h +++ b/libgcc/dfp-bit.h @@ -241,6 +241,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #elif defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf) \ || defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td) #define BFP_KIND 4 +#elif defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \ + || defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td) +#define BFP_KIND 5 #endif /* If BFP_KIND is defined, define additional macros: @@ -291,6 +294,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define BFP_VIA_TYPE long double #endif /* LONG_DOUBLE_HAS_TF_MODE */ +#elif BFP_KIND == 5 +#define BFP_TYPE _Float128 +#define BFP_FMT "%.36Le" +#define BFP_VIA_TYPE _Float128 +#define STR_TO_BFP __strtokf +#include <_strtokf.h> + #endif /* BFP_KIND */ #if WIDTH == 128 || WIDTH_TO == 128 @@ -490,6 +500,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #elif BFP_KIND == 4 #define BFP_TO_DFP DPD_BID_NAME(__dpd_trunctfsd,__bid_trunctfsd) #define DFP_TO_BFP DPD_BID_NAME(__dpd_extendsdtf,__bid_extendsdtf) +#elif BFP_KIND == 5 +#define BFP_TO_DFP DPD_BID_NAME(__dpd_trunckfsd,__bid_trunckfsd) +#define DFP_TO_BFP DPD_BID_NAME(__dpd_extendsdkf,__bid_extendsdkf) #endif /* BFP_KIND */ #elif WIDTH == 64 @@ -505,6 +518,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #elif BFP_KIND == 4 #define BFP_TO_DFP DPD_BID_NAME(__dpd_trunctfdd,__bid_trunctfdd) #define DFP_TO_BFP DPD_BID_NAME(__dpd_extendddtf,__bid_extendddtf) +#elif BFP_KIND == 5 +#define BFP_TO_DFP DPD_BID_NAME(__dpd_trunckfdd,__bid_trunckfdd) +#define DFP_TO_BFP DPD_BID_NAME(__dpd_extendddkf,__bid_extendddkf) #endif /* BFP_KIND */ #elif WIDTH == 128 @@ -520,6 +536,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #elif BFP_KIND == 4 #define BFP_TO_DFP DPD_BID_NAME(__dpd_extendtftd,__bid_extendtftd) #define DFP_TO_BFP DPD_BID_NAME(__dpd_trunctdtf,__bid_trunctdtf) +#elif BFP_KIND == 5 +#define BFP_TO_DFP DPD_BID_NAME(__dpd_extendkftd,__bid_extendkftd) +#define DFP_TO_BFP DPD_BID_NAME(__dpd_trunctdkf,__bid_trunctdkf) #endif /* BFP_KIND */ #endif /* WIDTH */ @@ -609,6 +628,7 @@ extern DFP_C_TYPE INT_TO_DFP (INT_TYPE); #if defined (L_sd_to_sf) || defined (L_dd_to_sf) || defined (L_td_to_sf) \ || defined (L_sd_to_df) || defined (L_dd_to_df) || defined (L_td_to_df) \ + || defined (L_sd_to_kf) || defined (L_dd_to_kf) || defined (L_td_to_kf) \ || ((defined (L_sd_to_xf) || defined (L_dd_to_xf) || defined (L_td_to_xf)) \ && LONG_DOUBLE_HAS_XF_MODE) \ || ((defined (L_sd_to_tf) || defined (L_dd_to_tf) || defined (L_td_to_tf)) \ @@ -623,6 +643,12 @@ extern BFP_TYPE DFP_TO_BFP (DFP_C_TYPE); || ((defined (L_tf_to_sd) || defined (L_tf_to_dd) || defined (L_tf_to_td)) \ && LONG_DOUBLE_HAS_TF_MODE) extern DFP_C_TYPE BFP_TO_DFP (BFP_TYPE); +#define BFP_SPRINTF sprintf + +#elif defined (L_kf_to_sd) || defined (L_kf_to_dd) || defined (L_kf_to_td) +extern DFP_C_TYPE BFP_TO_DFP (BFP_TYPE); +#include <_sprintfkf.h> +#define BFP_SPRINTF __sprintfkf #endif #endif /* _DFPBIT_H */ -- cgit v1.1 From 692ba083d9a22aaa08c8a3700d0237db8c922dc4 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Mon, 22 Feb 2021 15:54:39 -0500 Subject: Fix a comment line that was too long. libgcc/ 2021-02-22 Michael Meissner * dfp-bit.c (BFP_TO_DFP): Fix a comment line that was too long. --- libgcc/dfp-bit.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'libgcc') diff --git a/libgcc/dfp-bit.c b/libgcc/dfp-bit.c index 0b0f9ac..ed14b86 100644 --- a/libgcc/dfp-bit.c +++ b/libgcc/dfp-bit.c @@ -643,7 +643,8 @@ BFP_TO_DFP (BFP_TYPE x) decContextDefault (&context, CONTEXT_INIT); DFP_INIT_ROUNDMODE (context.round); - /* Use the sprintf library function to write the floating point value to a string. + /* Use the sprintf library function to write the floating point value to a + string. If we are handling the IEEE 128-bit floating point on PowerPC, use the special function __sprintfkf instead of sprintf. This function allows us -- cgit v1.1 From 2f5765cf25115fc8306806a913d90bed6edb420b Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Tue, 23 Feb 2021 00:16:34 +0000 Subject: Daily bump. --- libgcc/ChangeLog | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 90bea1b..0763765 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,40 @@ +2021-02-22 Michael Meissner + + * dfp-bit.c (BFP_TO_DFP): Fix a comment line that was too long. + +2021-02-22 Michael Meissner + + * config/rs6000/_dd_to_kf.c: New file. + * config/rs6000/_kf_to_dd.c: New file. + * config/rs6000/_kf_to_sd.c: New file. + * config/rs6000/_kf_to_td.c: New file. + * config/rs6000/_sd_to_kf.c: New file. + * config/rs6000/_sprintfkf.c: New file. + * config/rs6000/_sprintfkf.h: New file. + * config/rs6000/_strtokf.h: New file. + * config/rs6000/_strtokf.c: New file. + * config/rs6000/_td_to_kf.c: New file. + * config/rs6000/quad-float128.h: Add new declarations. + * config/rs6000/t-float128 (fp128_dec_funcs): New macro. + (fp128_decstr_funcs): New macro. + (ibm128_dec_funcs): New macro. + (fp128_ppc_funcs): Add the new conversions. + (fp128_dec_objs): Force Decimal <-> __float128 conversions to be + compiled with -mabi=ieeelongdouble. + (fp128_decstr_objs): Force __float128 <-> string conversions to be + compiled with -mabi=ibmlongdouble. + (ibm128_dec_objs): Force Decimal <-> __float128 conversions to be + compiled with -mabi=ieeelongdouble. + (FP128_CFLAGS_DECIMAL): New macro. + (IBM128_CFLAGS_DECIMAL): New macro. + * dfp-bit.c (DFP_TO_BFP): Add PowerPC _Float128 support. + (BFP_TO_DFP): Add PowerPC _Float128 support. + * dfp-bit.h (BFP_KIND): Add new binary floating point kind for + IEEE 128-bit floating point. + (DFP_TO_BFP): Add PowerPC _Float128 support. + (BFP_TO_DFP): Add PowerPC _Float128 support. + (BFP_SPRINTF): New macro. + 2021-01-27 Jakub Jelinek * config/i386/savms64.h: Add .note.GNU-stack section on Linux. -- cgit v1.1 From be30dd89926d5dd19d72f90c1586b0e2557fde43 Mon Sep 17 00:00:00 2001 From: Christophe Lyon Date: Wed, 24 Feb 2021 15:51:52 +0000 Subject: arm: Fix CMSE support detection in libgcc (PR target/99157) As discussed in the PR, the Makefile fragment lacks a double '$' to get the return-code from GCC invocation, resulting is CMSE support missing from multilibs. I checked that the simple patch proposed in the PR fixes the problem. 2021-02-23 Christophe Lyon Hau Hsu PR target/99157 libgcc/ * config/arm/t-arm: Fix cmse support detection. --- libgcc/config/arm/t-arm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libgcc') diff --git a/libgcc/config/arm/t-arm b/libgcc/config/arm/t-arm index 364f40e..3625a25 100644 --- a/libgcc/config/arm/t-arm +++ b/libgcc/config/arm/t-arm @@ -4,7 +4,7 @@ LIB1ASMFUNCS = _thumb1_case_sqi _thumb1_case_uqi _thumb1_case_shi \ HAVE_CMSE:=$(findstring __ARM_FEATURE_CMSE,$(shell $(gcc_compile_bare) -dM -E - /dev/null 2>/dev/null; echo $?),0) +ifeq ($(shell $(gcc_compile_bare) -E -mcmse - /dev/null 2>/dev/null; echo $$?),0) CMSE_OPTS:=-mcmse endif -- cgit v1.1 From 35da095d7e0614235cb0e241685c5e1a240dc882 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 24 Feb 2021 20:07:38 +0100 Subject: libgcc: Avoid signed negation overflow in __powi?f2 [PR99236] When these functions are called with integer minimum, there is UB on the libgcc side. Fixed in the obvious way, the code in the end wants ABSU_EXPR behavior. 2021-02-24 Jakub Jelinek PR libgcc/99236 * libgcc2.c (__powisf2, __powidf2, __powitf2, __powixf2): Perform negation of m in unsigned type. --- libgcc/libgcc2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libgcc') diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c index 960f594..17de0a7 100644 --- a/libgcc/libgcc2.c +++ b/libgcc/libgcc2.c @@ -1834,7 +1834,7 @@ __fixunssfSI (SFtype a) TYPE NAME (TYPE x, int m) { - unsigned int n = m < 0 ? -m : m; + unsigned int n = m < 0 ? -(unsigned int) m : (unsigned int) m; TYPE y = n % 2 ? x : 1; while (n >>= 1) { -- cgit v1.1 From 4028d01a050b478f245aab08702000976b7add2d Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 25 Feb 2021 00:16:29 +0000 Subject: Daily bump. --- libgcc/ChangeLog | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 0763765..9d03ff4 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,15 @@ +2021-02-24 Jakub Jelinek + + PR libgcc/99236 + * libgcc2.c (__powisf2, __powidf2, __powitf2, __powixf2): Perform + negation of m in unsigned type. + +2021-02-24 Christophe Lyon + Hau Hsu + + PR target/99157 + * config/arm/t-arm: Fix cmse support detection. + 2021-02-22 Michael Meissner * dfp-bit.c (BFP_TO_DFP): Fix a comment line that was too long. -- cgit v1.1 From 76c99cb1133334d2057b72aa5d5281ff7e71af74 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Mon, 1 Mar 2021 22:13:33 -0500 Subject: Fix __sprintfkf prototype in libgcc. The prototype of __sprintfkf in _sprintfkf.h did not match the function in _sprintfkf.c. This patch fixes the prototype. I also included the _sprintfkf.h file in _sprintfkf.c to make sure the prototype is correct and to eliminate a warning about declaring the function without a previous declaration. libgcc/ 2021-03-01 Michael Meissner * config/rs6000/_sprintfkf.h (__sprintfkf): Fix prototype to match the function. * config/rs6000/_sprintfkf.c: Include _sprintfkf.h. --- libgcc/config/rs6000/_sprintfkf.c | 1 + libgcc/config/rs6000/_sprintfkf.h | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'libgcc') diff --git a/libgcc/config/rs6000/_sprintfkf.c b/libgcc/config/rs6000/_sprintfkf.c index a7fdfb4..2d624f1 100644 --- a/libgcc/config/rs6000/_sprintfkf.c +++ b/libgcc/config/rs6000/_sprintfkf.c @@ -28,6 +28,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include #include #include +#include <_sprintfkf.h> /* This function must be built with IBM 128-bit as long double, so that we can access the strfroml function if do not have an IEEE 128-bit version, and if diff --git a/libgcc/config/rs6000/_sprintfkf.h b/libgcc/config/rs6000/_sprintfkf.h index 637d104..de9d713 100644 --- a/libgcc/config/rs6000/_sprintfkf.h +++ b/libgcc/config/rs6000/_sprintfkf.h @@ -24,5 +24,4 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* Declaration of the conversion function to IEEE 128-bit floating point from string using snprintf. */ -extern int __sprintfkf (char *restrict, const char *restrict, ...); - +extern int __sprintfkf (char *restrict, const char *restrict, _Float128); -- cgit v1.1 From d97a92dca90bb1badb68782c1293f3cd4ff911ea Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 3 Mar 2021 00:16:48 +0000 Subject: Daily bump. --- libgcc/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 9d03ff4..0a75105 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,9 @@ +2021-03-02 Michael Meissner + + * config/rs6000/_sprintfkf.h (__sprintfkf): Fix prototype to match + the function. + * config/rs6000/_sprintfkf.c: Include _sprintfkf.h. + 2021-02-24 Jakub Jelinek PR libgcc/99236 -- cgit v1.1 From 00d79dc4be0b86ec564cfa2b32c47de6c07449e6 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 13 Jan 2021 11:17:03 +0100 Subject: gcov: use mmap pools for KVP. gcc/ChangeLog: PR gcov-profile/97461 * gcov-io.h (GCOV_PREALLOCATED_KVP): Remove. libgcc/ChangeLog: PR gcov-profile/97461 * config.in: Regenerate. * configure: Likewise. * configure.ac: Check sys/mman.h header file * libgcov-driver.c (struct gcov_kvp): Remove static pre-allocated pool and use a dynamic one. * libgcov.h (MMAP_CHUNK_SIZE): New. (gcov_counter_add): Use mmap to allocate pool for struct gcov_kvp. --- libgcc/config.in | 3 +++ libgcc/configure | 4 ++-- libgcc/configure.ac | 2 +- libgcc/libgcov-driver.c | 11 +++++++---- libgcc/libgcov.h | 42 +++++++++++++++++++++++++++++++++--------- 5 files changed, 46 insertions(+), 16 deletions(-) (limited to 'libgcc') diff --git a/libgcc/config.in b/libgcc/config.in index 5be5321..f93c64a 100644 --- a/libgcc/config.in +++ b/libgcc/config.in @@ -49,6 +49,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_AUXV_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MMAN_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H diff --git a/libgcc/configure b/libgcc/configure index 78fc22a..dd3afb2 100755 --- a/libgcc/configure +++ b/libgcc/configure @@ -4458,7 +4458,7 @@ as_fn_arith $ac_cv_sizeof_long_double \* 8 && long_double_type_size=$as_val for ac_header in inttypes.h stdint.h stdlib.h ftw.h \ unistd.h sys/stat.h sys/types.h \ - string.h strings.h memory.h sys/auxv.h + string.h strings.h memory.h sys/auxv.h sys/mman.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_preproc "$LINENO" "$ac_header" "$as_ac_Header" @@ -4913,7 +4913,7 @@ case "$host" in case "$enable_cet" in auto) # Check if target supports multi-byte NOPs - # and if assembler supports CET insn. + # and if compiler and assembler support CET insn. cet_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fcf-protection" cat confdefs.h - <<_ACEOF >conftest.$ac_ext diff --git a/libgcc/configure.ac b/libgcc/configure.ac index ed50c0e..10ffb04 100644 --- a/libgcc/configure.ac +++ b/libgcc/configure.ac @@ -224,7 +224,7 @@ AC_SUBST(long_double_type_size) AC_CHECK_HEADERS(inttypes.h stdint.h stdlib.h ftw.h \ unistd.h sys/stat.h sys/types.h \ - string.h strings.h memory.h sys/auxv.h) + string.h strings.h memory.h sys/auxv.h sys/mman.h) AC_HEADER_STDC # Check for decimal float support. diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c index e474e03..9146235 100644 --- a/libgcc/libgcov-driver.c +++ b/libgcc/libgcov-driver.c @@ -588,11 +588,14 @@ struct gcov_root __gcov_root; struct gcov_master __gcov_master = {GCOV_VERSION, 0}; -/* Pool of pre-allocated gcov_kvp strutures. */ -struct gcov_kvp __gcov_kvp_pool[GCOV_PREALLOCATED_KVP]; +/* Dynamic pool for gcov_kvp structures. */ +struct gcov_kvp *__gcov_kvp_dynamic_pool; -/* Index to first free gcov_kvp in the pool. */ -unsigned __gcov_kvp_pool_index; +/* Index into __gcov_kvp_dynamic_pool array. */ +unsigned __gcov_kvp_dynamic_pool_index; + +/* Size of _gcov_kvp_dynamic_pool array. */ +unsigned __gcov_kvp_dynamic_pool_size; void __gcov_exit (void) diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h index ddc6885..9c5fcfb 100644 --- a/libgcc/libgcov.h +++ b/libgcc/libgcov.h @@ -45,6 +45,10 @@ #include "libgcc_tm.h" #include "gcov.h" +#if HAVE_SYS_MMAN_H +#include +#endif + #if __CHAR_BIT__ == 8 typedef unsigned gcov_unsigned_t __attribute__ ((mode (SI))); typedef unsigned gcov_position_t __attribute__ ((mode (SI))); @@ -250,8 +254,9 @@ struct indirect_call_tuple /* Exactly one of these will be active in the process. */ extern struct gcov_master __gcov_master; -extern struct gcov_kvp __gcov_kvp_pool[GCOV_PREALLOCATED_KVP]; -extern unsigned __gcov_kvp_pool_index; +extern struct gcov_kvp *__gcov_kvp_dynamic_pool; +extern unsigned __gcov_kvp_dynamic_pool_index; +extern unsigned __gcov_kvp_dynamic_pool_size; /* Dump a set of gcov objects. */ extern void __gcov_dump_one (struct gcov_root *) ATTRIBUTE_HIDDEN; @@ -410,25 +415,44 @@ gcov_counter_add (gcov_type *counter, gcov_type value, static inline struct gcov_kvp * allocate_gcov_kvp (void) { +#define MMAP_CHUNK_SIZE (128 * 1024) struct gcov_kvp *new_node = NULL; + unsigned kvp_sizeof = sizeof(struct gcov_kvp); + + /* Try mmaped pool if available. */ +#if !defined(IN_GCOV_TOOL) && !defined(L_gcov_merge_topn) && HAVE_SYS_MMAN_H + if (__gcov_kvp_dynamic_pool == NULL + || __gcov_kvp_dynamic_pool_index >= __gcov_kvp_dynamic_pool_size) + { + void *ptr = mmap (NULL, MMAP_CHUNK_SIZE, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + if (ptr != MAP_FAILED) + { + __gcov_kvp_dynamic_pool = ptr; + __gcov_kvp_dynamic_pool_size = MMAP_CHUNK_SIZE / kvp_sizeof; + __gcov_kvp_dynamic_pool_index = 0; + } + } -#if !defined(IN_GCOV_TOOL) && !defined(L_gcov_merge_topn) - if (__gcov_kvp_pool_index < GCOV_PREALLOCATED_KVP) + if (__gcov_kvp_dynamic_pool != NULL) { unsigned index; #if GCOV_SUPPORTS_ATOMIC index - = __atomic_fetch_add (&__gcov_kvp_pool_index, 1, __ATOMIC_RELAXED); + = __atomic_fetch_add (&__gcov_kvp_dynamic_pool_index, 1, + __ATOMIC_RELAXED); #else - index = __gcov_kvp_pool_index++; + index = __gcov_kvp_dynamic_pool_index++; #endif - if (index < GCOV_PREALLOCATED_KVP) - new_node = &__gcov_kvp_pool[index]; + if (index < __gcov_kvp_dynamic_pool_size) + new_node = __gcov_kvp_dynamic_pool + index; } #endif + /* Fallback to malloc. */ if (new_node == NULL) - new_node = (struct gcov_kvp *)xcalloc (1, sizeof (struct gcov_kvp)); + new_node = (struct gcov_kvp *)xcalloc (1, kvp_sizeof); return new_node; } -- cgit v1.1 From f3641ac70eb0ae9f8983b7ddb1660c92439565de Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Thu, 4 Mar 2021 00:16:48 +0000 Subject: Daily bump. --- libgcc/ChangeLog | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 0a75105..25e2f87 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,15 @@ +2021-03-03 Martin Liska + + PR gcov-profile/97461 + * config.in: Regenerate. + * configure: Likewise. + * configure.ac: Check sys/mman.h header file + * libgcov-driver.c (struct gcov_kvp): Remove static + pre-allocated pool and use a dynamic one. + * libgcov.h (MMAP_CHUNK_SIZE): New. + (gcov_counter_add): Use mmap to allocate pool for struct + gcov_kvp. + 2021-03-02 Michael Meissner * config/rs6000/_sprintfkf.h (__sprintfkf): Fix prototype to match -- cgit v1.1 From 4c955b4ad37cf31c1d7cfa146c2b3ead2042869b Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Thu, 4 Mar 2021 11:45:47 +0100 Subject: gcov: call mmap MAP_ANONYMOUS with fd equal to -1 libgcc/ChangeLog: PR gcov-profile/99385 * libgcov.h (allocate_gcov_kvp): Call mmap with fd equal to -1. --- libgcc/libgcov.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libgcc') diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h index 9c5fcfb..acdb7cd 100644 --- a/libgcc/libgcov.h +++ b/libgcc/libgcov.h @@ -426,7 +426,7 @@ allocate_gcov_kvp (void) { void *ptr = mmap (NULL, MMAP_CHUNK_SIZE, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (ptr != MAP_FAILED) { __gcov_kvp_dynamic_pool = ptr; -- cgit v1.1 From 6a8fc0c31a9ae759fe9bf59b5418abf2af938f91 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 16 Feb 2021 16:28:06 +0100 Subject: profiling: fix streaming of TOPN counters libgcc/ChangeLog: PR gcov-profile/99105 * libgcov-driver.c (write_top_counters): Rename to ... (write_topn_counters): ... this. (write_one_data): Pre-allocate buffer for number of items in the corresponding linked lists. * libgcov.h (malloc_mmap): New function. (allocate_gcov_kvp): Use it. gcc/testsuite/ChangeLog: PR gcov-profile/99105 * gcc.dg/tree-prof/indir-call-prof-malloc.c: Use profile correction as the wrapped malloc is called one more time from libgcov. * gcc.dg/tree-prof/pr97461.c: Likewise. --- libgcc/libgcov-driver.c | 55 ++++++++++++++++++++++++++++++++++++++++++------- libgcc/libgcov.h | 17 ++++++++++++--- 2 files changed, 61 insertions(+), 11 deletions(-) (limited to 'libgcc') diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c index 9146235..a1338b6 100644 --- a/libgcc/libgcov-driver.c +++ b/libgcc/libgcov-driver.c @@ -42,6 +42,10 @@ void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {} #include #endif +#if HAVE_SYS_MMAN_H +#include +#endif + #ifdef L_gcov /* A utility function for outputting errors. */ @@ -334,30 +338,65 @@ read_error: return -1; } +#define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) + /* Store all TOP N counters where each has a dynamic length. */ static void -write_top_counters (const struct gcov_ctr_info *ci_ptr, - unsigned t_ix, - gcov_unsigned_t n_counts) +write_topn_counters (const struct gcov_ctr_info *ci_ptr, + unsigned t_ix, + gcov_unsigned_t n_counts) { unsigned counters = n_counts / GCOV_TOPN_MEM_COUNTERS; gcc_assert (n_counts % GCOV_TOPN_MEM_COUNTERS == 0); + + /* It can happen in a multi-threaded environment that number of counters is + different from the size of the corresponding linked lists. */ +#define LIST_SIZE_MIN_LENGTH 4 * 1024 + + static unsigned *list_sizes = NULL; + static unsigned list_size_length = 0; + + if (list_sizes == NULL || counters > list_size_length) + { + list_size_length = MAX (LIST_SIZE_MIN_LENGTH, 2 * counters); +#if HAVE_SYS_MMAN_H + list_sizes + = (unsigned *)malloc_mmap (list_size_length * sizeof (unsigned)); +#endif + + /* Malloc fallback. */ + if (list_sizes == NULL) + list_sizes = (unsigned *)xmalloc (list_size_length * sizeof (unsigned)); + } + + memset (list_sizes, 0, counters * sizeof (unsigned)); unsigned pair_total = 0; + for (unsigned i = 0; i < counters; i++) - pair_total += ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 1]; + { + gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2]; + for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start; + node != NULL; node = node->next) + { + ++pair_total; + ++list_sizes[i]; + } + } + unsigned disk_size = GCOV_TOPN_DISK_COUNTERS * counters + 2 * pair_total; gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix), GCOV_TAG_COUNTER_LENGTH (disk_size)); for (unsigned i = 0; i < counters; i++) { - gcov_type pair_count = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 1]; gcov_write_counter (ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i]); - gcov_write_counter (pair_count); + gcov_write_counter (list_sizes[i]); gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2]; + + unsigned j = 0; for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start; - node != NULL; node = node->next) + j < list_sizes[i]; node = node->next, j++) { gcov_write_counter (node->value); gcov_write_counter (node->count); @@ -425,7 +464,7 @@ write_one_data (const struct gcov_info *gi_ptr, n_counts = ci_ptr->num; if (t_ix == GCOV_COUNTER_V_TOPN || t_ix == GCOV_COUNTER_V_INDIR) - write_top_counters (ci_ptr, t_ix, n_counts); + write_topn_counters (ci_ptr, t_ix, n_counts); else { /* Do not stream when all counters are zero. */ diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h index acdb7cd..2780cc0 100644 --- a/libgcc/libgcov.h +++ b/libgcc/libgcov.h @@ -409,6 +409,19 @@ gcov_counter_add (gcov_type *counter, gcov_type value, *counter += value; } +#if HAVE_SYS_MMAN_H + +/* Allocate LENGTH with mmap function. */ + +static inline void * +malloc_mmap (size_t length) +{ + return mmap (NULL, length, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +} + +#endif + /* Allocate gcov_kvp from statically pre-allocated pool, or use heap otherwise. */ @@ -424,9 +437,7 @@ allocate_gcov_kvp (void) if (__gcov_kvp_dynamic_pool == NULL || __gcov_kvp_dynamic_pool_index >= __gcov_kvp_dynamic_pool_size) { - void *ptr = mmap (NULL, MMAP_CHUNK_SIZE, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + void *ptr = malloc_mmap (MMAP_CHUNK_SIZE); if (ptr != MAP_FAILED) { __gcov_kvp_dynamic_pool = ptr; -- cgit v1.1 From 67f10d28f05fdae7ab25107d5be0b66b065b819b Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 5 Mar 2021 00:16:21 +0000 Subject: Daily bump. --- libgcc/ChangeLog | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 25e2f87..79b6b69 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,18 @@ +2021-03-04 Martin Liska + + PR gcov-profile/99105 + * libgcov-driver.c (write_top_counters): Rename to ... + (write_topn_counters): ... this. + (write_one_data): Pre-allocate buffer for number of items + in the corresponding linked lists. + * libgcov.h (malloc_mmap): New function. + (allocate_gcov_kvp): Use it. + +2021-03-04 Martin Liska + + PR gcov-profile/99385 + * libgcov.h (allocate_gcov_kvp): Call mmap with fd equal to -1. + 2021-03-03 Martin Liska PR gcov-profile/97461 -- cgit v1.1 From 73a9216b8a47889234c94e3aaec193391ee6604d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 6 Mar 2021 16:22:27 +0100 Subject: libgcov: Fix build on Darwin [PR99406] As reported, bootstrap currently fails on older Darwin because MAP_ANONYMOUS is not defined. The following is what gcc/system.h does, so I think it should work for libgcov. 2021-03-06 Jakub Jelinek PR gcov-profile/99406 * libgcov.h (MAP_FAILED, MAP_ANONYMOUS): If HAVE_SYS_MMAN_H is defined, define these macros if not defined already. --- libgcc/libgcov.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'libgcc') diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h index 2780cc0..7b0d367 100644 --- a/libgcc/libgcov.h +++ b/libgcc/libgcov.h @@ -172,6 +172,16 @@ extern struct gcov_info *gcov_list; #define ATTRIBUTE_HIDDEN #endif +#if HAVE_SYS_MMAN_H +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +#if !defined (MAP_ANONYMOUS) && defined (MAP_ANON) +#define MAP_ANONYMOUS MAP_ANON +#endif +#endif + #include "gcov-io.h" /* Structures embedded in coveraged program. The structures generated -- cgit v1.1 From 0ad6a2e2f0c667f9916cfcdb81f41f6055f1d0b3 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 7 Mar 2021 00:16:24 +0000 Subject: Daily bump. --- libgcc/ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'libgcc') diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 79b6b69..a99aaa0 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,9 @@ +2021-03-06 Jakub Jelinek + + PR gcov-profile/99406 + * libgcov.h (MAP_FAILED, MAP_ANONYMOUS): If HAVE_SYS_MMAN_H is + defined, define these macros if not defined already. + 2021-03-04 Martin Liska PR gcov-profile/99105 -- cgit v1.1