diff options
author | Michael Meissner <meissner@linux.ibm.com> | 2021-02-22 15:33:29 -0500 |
---|---|---|
committer | Michael Meissner <meissner@linux.ibm.com> | 2021-02-22 15:33:29 -0500 |
commit | 781183595acba67a37c66f59a0c1d9b5fee7e248 (patch) | |
tree | aebce9b934a865fdd62b1307093b2b7cd0c14fa2 /libgcc/dfp-bit.c | |
parent | 8e99b5ba4c19526335fe9cabdc6df7fb2edcfe6f (diff) | |
download | gcc-781183595acba67a37c66f59a0c1d9b5fee7e248.zip gcc-781183595acba67a37c66f59a0c1d9b5fee7e248.tar.gz gcc-781183595acba67a37c66f59a0c1d9b5fee7e248.tar.bz2 |
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 <meissner@linux.ibm.com>
* 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.
Diffstat (limited to 'libgcc/dfp-bit.c')
-rw-r--r-- | libgcc/dfp-bit.c | 12 |
1 files changed, 10 insertions, 2 deletions
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); |