On Sun, Aug 31, 2025 at 11:15 AM H.J. Lu <[email protected]> wrote: > > Since _Decimal128 arithmetic requires the round-to-nearest rounding > mode, define DFP_INIT_ROUNDMODE and DFP_RESTORE_ROUNDMODE, similar to > FP_INIT_ROUNDMODE in sfp-machine.h, to set the rounding mode to > round-to-nearest at _Decimal128 related arithmetic function entrances > and restores it upon return.
Akkas, Ahmet is on vacation, let's wait until he's back and has comments on the patch. s > > libgcc/ > > PR target/120691 > * Makefile.in (DECNUMINC): Add -I$(srcdir)/config/$(cpu_type). > * config/i386/dfp-machine.h: New file. > * config/i386/32/dfp-machine.h: Likewise. > * config/i386/64/dfp-machine.h: Likewise. > > libgcc/config/libbid/ > > PR target/120691 > * bid128_div.c: Run DFP_INIT_ROUNDMODE at function entrace and > DFP_RESTORE_ROUNDMODE at function exit. > * bid128_rem.c: Likewise. > * bid128_sqrt.c: Likewise. > * bid64_div.c (bid64_div): Likewise. > * bid64_sqrt.c (bid64_sqrt): Likewise. > * bid_conf.h: Include <dfp-machine.h>. > * dfp-machine.h: New file. > > gcc/testsuite/ > > PR target/120691 > * gcc.target/i386/pr120691.c: New test. > > Signed-off-by: H.J. Lu <[email protected]> > --- > gcc/testsuite/gcc.target/i386/pr120691.c | 19 ++++ > libgcc/Makefile.in | 3 +- > libgcc/config/i386/32/dfp-machine.h | 35 ++++++++ > libgcc/config/i386/64/dfp-machine.h | 21 +++++ > libgcc/config/i386/dfp-machine.h | 55 ++++++++++++ > libgcc/config/libbid/bid128_div.c | 107 ++++++++++++++++++++++ > libgcc/config/libbid/bid128_rem.c | 29 ++++++ > libgcc/config/libbid/bid128_sqrt.c | 31 +++++++ > libgcc/config/libbid/bid64_div.c | 110 +++++++++++++++++++++++ > libgcc/config/libbid/bid64_sqrt.c | 29 ++++++ > libgcc/config/libbid/bid_conf.h | 2 + > libgcc/config/libbid/dfp-machine.h | 34 +++++++ > 12 files changed, 474 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gcc.target/i386/pr120691.c > create mode 100644 libgcc/config/i386/32/dfp-machine.h > create mode 100644 libgcc/config/i386/64/dfp-machine.h > create mode 100644 libgcc/config/i386/dfp-machine.h > create mode 100644 libgcc/config/libbid/dfp-machine.h > > diff --git a/gcc/testsuite/gcc.target/i386/pr120691.c > b/gcc/testsuite/gcc.target/i386/pr120691.c > new file mode 100644 > index 00000000000..9bbd61ed53d > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/pr120691.c > @@ -0,0 +1,19 @@ > +/* { dg-do run } */ > +/* { dg-options "-O0 -mfpmath=sse -msse2" } */ > +/* { dg-require-effective-target sse2 } */ > +/* { dg-require-effective-target fenv } */ > +/* { dg-require-effective-target dfp } */ > + > +#include <fenv.h> > + > +int main() { > + fesetround( FE_UPWARD ); > + _Decimal128 x1 = 9825, x2 = 10000 ; > + > + double c = (double) (x1 / x2); > + > + if (c != 0.9825) > + __builtin_abort (); > + > + return 0 ; > +} > diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in > index e258f943ddd..32a5a15813f 100644 > --- a/libgcc/Makefile.in > +++ b/libgcc/Makefile.in > @@ -232,7 +232,8 @@ version := $(shell @get_gcc_base_ver@ > $(srcdir)/../gcc/BASE-VER) > > ifeq ($(decimal_float),yes) > ifeq ($(enable_decimal_float),bid) > -DECNUMINC = -I$(srcdir)/config/libbid -DENABLE_DECIMAL_BID_FORMAT > +DECNUMINC = -I$(srcdir)/config/$(cpu_type) -I$(srcdir)/config/libbid \ > + -DENABLE_DECIMAL_BID_FORMAT > else > DECNUMINC = -I$(srcdir)/../libdecnumber/$(enable_decimal_float) \ > -I$(srcdir)/../libdecnumber > diff --git a/libgcc/config/i386/32/dfp-machine.h > b/libgcc/config/i386/32/dfp-machine.h > new file mode 100644 > index 00000000000..f4baa3b3d7e > --- /dev/null > +++ b/libgcc/config/i386/32/dfp-machine.h > @@ -0,0 +1,35 @@ > +#ifndef _SOFT_FLOAT > +/* Get the rounding mode. */ > +#define DFP_GET_ROUNDMODE \ > + unsigned int _frnd_orig, _xrnd_orig; \ > + do \ > + { \ > + __asm__ __volatile__ ("fnstcw\t%0" : "=m" (_frnd_orig)); \ > + _frnd_orig &= FP_RND_MASK; \ > + if (__builtin_cpu_supports ("sse")) \ > + { \ > + __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (_xrnd_orig)); \ > + _xrnd_orig &= 0x6000; \ > + } \ > + } \ > + while (0) > + > +/* Set the rounding mode. */ > +#define DFP_SET_ROUNDMODE(round) \ > + do \ > + { \ > + unsigned int _cw; > \ > + __asm__ __volatile__ ("fnstcw\t%0" : "=m" (_cw)); > \ > + _cw &= ~FP_RND_MASK; \ > + _cw |= round; \ > + __asm__ __volatile__ ("fldcw\t%0" :: "m" (_cw)); \ > + if (__builtin_cpu_supports ("sse")) \ > + { \ > + __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (_cw)); \ > + _cw &= ~0x6000; \ > + _cw |= round << 3; \ > + __asm__ __volatile__ ("%vldmxcsr\t%0" :: "m" (_cw)); \ > + } \ > + } \ > + while (0) > +#endif > diff --git a/libgcc/config/i386/64/dfp-machine.h > b/libgcc/config/i386/64/dfp-machine.h > new file mode 100644 > index 00000000000..84d0dc93285 > --- /dev/null > +++ b/libgcc/config/i386/64/dfp-machine.h > @@ -0,0 +1,21 @@ > +/* Get the rounding mode. */ > +#define DFP_GET_ROUNDMODE \ > + unsigned int _frnd_orig; \ > + do \ > + { \ > + __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (_frnd_orig)); \ > + _frnd_orig &= FP_RND_MASK; \ > + } \ > + while (0) > + > +/* Set the rounding mode. */ > +#define DFP_SET_ROUNDMODE(round) \ > + do \ > + { \ > + unsigned int _cw; > \ > + __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (_cw)); \ > + _cw &= ~FP_RND_MASK; \ > + _cw |= round; \ > + __asm__ __volatile__ ("%vldmxcsr\t%0" :: "m" (_cw)); \ > + } \ > + while (0); > diff --git a/libgcc/config/i386/dfp-machine.h > b/libgcc/config/i386/dfp-machine.h > new file mode 100644 > index 00000000000..61e4a577684 > --- /dev/null > +++ b/libgcc/config/i386/dfp-machine.h > @@ -0,0 +1,55 @@ > +/* Rounding mode macros for DFP libbid. x86 version. > + Copyright (C) 2025 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 > + <http://www.gnu.org/licenses/>. */ > + > +#ifndef _DFP_MACHINE_H > +#define _DFP_MACHINE_H > + > +#include "config/i386/sfp-machine.h" > + > +#ifdef __x86_64__ > +#include "config/i386/64/dfp-machine.h" > +#else > +#include "config/i386/32/dfp-machine.h" > +#endif > + > +/* Initialize the rounding mode to round-to-nearest if needed. */ > +#define DFP_INIT_ROUNDMODE \ > + DFP_GET_ROUNDMODE; \ > + do \ > + { \ > + if (_frnd_orig != FP_RND_NEAREST) \ > + DFP_SET_ROUNDMODE (FP_RND_NEAREST); \ > + } \ > + while (0) > + > +/* Restore the rounding mode to round-to-nearest if changed. */ > +#define DFP_RESTORE_ROUNDMODE \ > + do \ > + { \ > + if (_frnd_orig != FP_RND_NEAREST) \ > + DFP_SET_ROUNDMODE (_frnd_orig); \ > + } \ > + while (0) > + > +#endif /* _DFP_MACHINE_H */ > diff --git a/libgcc/config/libbid/bid128_div.c > b/libgcc/config/libbid/bid128_div.c > index 925bf14a336..f05f9f46825 100644 > --- a/libgcc/config/libbid/bid128_div.c > +++ b/libgcc/config/libbid/bid128_div.c > @@ -49,6 +49,9 @@ BID128_FUNCTION_ARG2 (bid128_div, x, y) > fexcept_t binaryflags = 0; > #endif > > + // Set the rounding mode to round-to-nearest (if different). > + DFP_INIT_ROUNDMODE; > + > valid_y = unpack_BID128_value (&sign_y, &exponent_y, &CY, y); > > // unpack arguments, check for NaN or Infinity > @@ -62,6 +65,8 @@ if ((x.w[1] & 0x7c00000000000000ull) == > 0x7c00000000000000ull) { > #endif > res.w[1] = (CX.w[1]) & QUIET_MASK64; > res.w[0] = CX.w[0]; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x is Infinity? > @@ -75,6 +80,8 @@ if ((x.w[1] & 0x7800000000000000ull) == > 0x7800000000000000ull) { > #endif > res.w[1] = 0x7c00000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is NaN? > @@ -85,6 +92,8 @@ if ((x.w[1] & 0x7800000000000000ull) == > 0x7800000000000000ull) { > res.w[1] = ((x.w[1] ^ y.w[1]) & 0x8000000000000000ull) | > 0x7800000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -97,6 +106,8 @@ if ((y.w[1] & 0x7800000000000000ull) < > 0x7800000000000000ull) { > // x=y=0, return NaN > res.w[1] = 0x7c00000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // return 0 > @@ -108,6 +119,8 @@ if ((y.w[1] & 0x7800000000000000ull) < > 0x7800000000000000ull) { > exponent_x = 0; > res.w[1] |= (((UINT64) exponent_x) << 49); > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -122,6 +135,8 @@ if (!valid_y) { > #endif > res.w[1] = CY.w[1] & QUIET_MASK64; > res.w[0] = CY.w[0]; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is Infinity? > @@ -129,6 +144,8 @@ if (!valid_y) { > // return +/-0 > res.w[1] = sign_x ^ sign_y; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is 0, return +/-Inf > @@ -138,6 +155,8 @@ if (!valid_y) { > res.w[1] = > ((x.w[1] ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > @@ -186,6 +205,8 @@ if (__unsigned_compare_gt_128 (CY, CX)) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // get number of decimal digits in CQ > @@ -379,6 +400,8 @@ if (!CA4.w[0] && !CA4.w[1]) > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #endif > @@ -469,6 +492,8 @@ if (diff_expon >= 0) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > > } > @@ -477,6 +502,8 @@ get_BID128 (&res, sign_x ^ sign_y, diff_expon, CQ, > &rnd_mode, pfpsf); > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > +// restore the rounding mode back if it has been changed > +DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > > @@ -500,6 +527,9 @@ TYPE0_FUNCTION_ARGTYPE1_ARGTYPE2 (UINT128, bid128dd_div, > UINT64, x, > fexcept_t binaryflags = 0; > #endif > > + // Set the rounding mode to round-to-nearest (if different). > + DFP_INIT_ROUNDMODE; > + > valid_y = unpack_BID64 (&sign_y, &exponent_y, &CY.w[0], y); > > // unpack arguments, check for NaN or Infinity > @@ -519,6 +549,8 @@ if ((x & NAN_MASK64) == NAN_MASK64) { > res.w[0] = (CX.w[0] & 0x0003ffffffffffffull); > __mul_64x64_to_128 (res, res.w[0], power10_table_128[18].w[0]); > res.w[1] |= ((CX.w[0]) & 0xfc00000000000000ull); > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x is Infinity? > @@ -532,6 +564,8 @@ if (((x) & 0x7800000000000000ull) == > 0x7800000000000000ull) { > #endif > res.w[1] = 0x7c00000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > if ((((y) & 0x7c00000000000000ull) != 0x7c00000000000000ull)) { > @@ -539,6 +573,8 @@ if (((x) & 0x7800000000000000ull) == > 0x7800000000000000ull) { > res.w[1] = > (((x) ^ (y)) & 0x8000000000000000ull) | 0x7800000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -551,6 +587,8 @@ if ((((y) & 0x7800000000000000ull) != > 0x7800000000000000ull)) { > // x=y=0, return NaN > res.w[1] = 0x7c00000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // return 0 > @@ -566,6 +604,8 @@ else if (exponent_x < 0) > exponent_x = 0; > res.w[1] |= (((UINT64) exponent_x) << 49); > res.w[0] = 0; > +// restore the rounding mode back if it has been changed > +DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -583,6 +623,8 @@ if (!valid_y) { > res.w[0] = (CY.w[0] & 0x0003ffffffffffffull); > __mul_64x64_to_128 (res, res.w[0], power10_table_128[18].w[0]); > res.w[1] |= ((CY.w[0]) & 0xfc00000000000000ull); > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is Infinity? > @@ -590,6 +632,8 @@ if (!valid_y) { > // return +/-0 > res.w[1] = sign_x ^ sign_y; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is 0, return +/-Inf > @@ -599,6 +643,8 @@ if (!valid_y) { > #ifdef SET_STATUS_FLAGS > __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > @@ -647,6 +693,8 @@ if (__unsigned_compare_gt_128 (CY, CX)) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // get number of decimal digits in CQ > @@ -843,6 +891,8 @@ __div_256_by_128 (&CQ, &CA4, CY); > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #endif > @@ -932,6 +982,8 @@ if (diff_expon >= 0) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > > } > @@ -940,6 +992,8 @@ get_BID128 (&res, sign_x ^ sign_y, diff_expon, CQ, > &rnd_mode, pfpsf); > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > +// restore the rounding mode back if it has been changed > +DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > > @@ -959,6 +1013,9 @@ BID128_FUNCTION_ARGTYPE1_ARG128 (bid128dq_div, UINT64, > x, y) > fexcept_t binaryflags = 0; > #endif > > + // Set the rounding mode to round-to-nearest (if different) > + DFP_INIT_ROUNDMODE; > + > valid_y = unpack_BID128_value (&sign_y, &exponent_y, &CY, y); > > // unpack arguments, check for NaN or Infinity > @@ -978,6 +1035,8 @@ if ((x & NAN_MASK64) == NAN_MASK64) { > res.w[0] = (CX.w[0] & 0x0003ffffffffffffull); > __mul_64x64_to_128 (res, res.w[0], power10_table_128[18].w[0]); > res.w[1] |= ((CX.w[0]) & 0xfc00000000000000ull); > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x is Infinity? > @@ -991,6 +1050,8 @@ if ((x & 0x7800000000000000ull) == > 0x7800000000000000ull) { > #endif > res.w[1] = 0x7c00000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > if (((y.w[1] & 0x7c00000000000000ull) != 0x7c00000000000000ull)) { > @@ -998,6 +1059,8 @@ if ((x & 0x7800000000000000ull) == > 0x7800000000000000ull) { > res.w[1] = > ((x ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -1010,6 +1073,8 @@ if ((y.w[1] & INFINITY_MASK64) != INFINITY_MASK64) { > // x=y=0, return NaN > res.w[1] = 0x7c00000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // return 0 > @@ -1021,6 +1086,8 @@ if ((y.w[1] & INFINITY_MASK64) != INFINITY_MASK64) { > exponent_x = 0; > res.w[1] |= (((UINT64) exponent_x) << 49); > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -1037,6 +1104,8 @@ if (!valid_y) { > #endif > res.w[1] = CY.w[1] & QUIET_MASK64; > res.w[0] = CY.w[0]; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is Infinity? > @@ -1044,6 +1113,8 @@ if (!valid_y) { > // return +/-0 > res.w[1] = sign_x ^ sign_y; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is 0, return +/-Inf > @@ -1053,6 +1124,8 @@ if (!valid_y) { > #ifdef SET_STATUS_FLAGS > __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > @@ -1101,6 +1174,8 @@ if (__unsigned_compare_gt_128 (CY, CX)) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // get number of decimal digits in CQ > @@ -1300,6 +1375,8 @@ __div_256_by_128 (&CQ, &CA4, CY); > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #endif > @@ -1389,6 +1466,8 @@ if (diff_expon >= 0) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > > @@ -1396,6 +1475,8 @@ get_BID128 (&res, sign_x ^ sign_y, diff_expon, CQ, > &rnd_mode, pfpsf); > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > +// restore the rounding mode back if it has been changed > +DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > > } > @@ -1415,6 +1496,8 @@ BID128_FUNCTION_ARG128_ARGTYPE2 (bid128qd_div, x, > UINT64, y) > fexcept_t binaryflags = 0; > #endif > > + // Set the rounding mode to round-to-nearest (if different) > + DFP_INIT_ROUNDMODE; > > valid_y = unpack_BID64 (&sign_y, &exponent_y, &CY.w[0], y); > // unpack arguments, check for NaN or Infinity > @@ -1428,6 +1511,8 @@ if ((x.w[1] & 0x7c00000000000000ull) == > 0x7c00000000000000ull) { > #endif > res.w[1] = (CX.w[1]) & QUIET_MASK64; > res.w[0] = CX.w[0]; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x is Infinity? > @@ -1441,6 +1526,8 @@ if ((x.w[1] & 0x7800000000000000ull) == > 0x7800000000000000ull) { > #endif > res.w[1] = 0x7c00000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is NaN? > @@ -1451,6 +1538,8 @@ if ((x.w[1] & 0x7800000000000000ull) == > 0x7800000000000000ull) { > res.w[1] = ((x.w[1] ^ y) & 0x8000000000000000ull) | > 0x7800000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -1463,6 +1552,8 @@ if ((y & 0x7800000000000000ull) < > 0x7800000000000000ull) { > // x=y=0, return NaN > res.w[1] = 0x7c00000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // return 0 > @@ -1474,6 +1565,8 @@ if ((y & 0x7800000000000000ull) < > 0x7800000000000000ull) { > exponent_x = 0; > res.w[1] |= (((UINT64) exponent_x) << 49); > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -1490,6 +1583,8 @@ if (!valid_y) { > res.w[0] = (CY.w[0] & 0x0003ffffffffffffull); > __mul_64x64_to_128 (res, res.w[0], power10_table_128[18].w[0]); > res.w[1] |= ((CY.w[0]) & 0xfc00000000000000ull); > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is Infinity? > @@ -1497,6 +1592,8 @@ if (!valid_y) { > // return +/-0 > res.w[1] = ((x.w[1] ^ y) & 0x8000000000000000ull); > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is 0 > @@ -1505,6 +1602,8 @@ if (!valid_y) { > #endif > res.w[1] = (sign_x ^ sign_y) | INFINITY_MASK64; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > @@ -1553,6 +1652,8 @@ if (__unsigned_compare_gt_128 (CY, CX)) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // get number of decimal digits in CQ > @@ -1749,6 +1850,8 @@ __div_256_by_128 (&CQ, &CA4, CY); > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #endif > @@ -1838,6 +1941,8 @@ if (diff_expon >= 0) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > > } > @@ -1846,6 +1951,8 @@ get_BID128 (&res, sign_x ^ sign_y, diff_expon, CQ, > &rnd_mode, pfpsf); > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > +// restore the rounding mode back if it has been changed > +DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > > } > diff --git a/libgcc/config/libbid/bid128_rem.c > b/libgcc/config/libbid/bid128_rem.c > index f229b2869af..1c6da70cf59 100644 > --- a/libgcc/config/libbid/bid128_rem.c > +++ b/libgcc/config/libbid/bid128_rem.c > @@ -35,6 +35,9 @@ BID128_FUNCTION_ARG2_NORND_CUSTOMRESTYPE (UINT128, > bid128_rem, x, y) > int exponent_x, exponent_y, diff_expon, bin_expon_cx, scale, > scale0; > > + // Set the rounding mode to round-to-nearest (if different) > + DFP_INIT_ROUNDMODE; > + > // unpack arguments, check for NaN or Infinity > > valid_y = unpack_BID128_value (&sign_y, &exponent_y, &CY, y); > @@ -52,6 +55,8 @@ if ((x.w[1] & 0x7c00000000000000ull) == > 0x7c00000000000000ull) { > #endif > res.w[1] = CX.w[1] & QUIET_MASK64; > res.w[0] = CX.w[0]; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x is Infinity? > @@ -66,6 +71,8 @@ if ((x.w[1] & 0x7800000000000000ull) == > 0x7800000000000000ull) { > #endif > res.w[1] = 0x7c00000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > > @@ -79,6 +86,8 @@ if ((!CY.w[1]) && (!CY.w[0])) { > // x=y=0, return NaN > res.w[1] = 0x7c00000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > if (valid_y || ((y.w[1] & NAN_MASK64) == INFINITY_MASK64)) { > @@ -89,6 +98,8 @@ if (valid_y || ((y.w[1] & NAN_MASK64) == INFINITY_MASK64)) { > > res.w[1] = sign_x | (((UINT64) exponent_x) << 49); > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -103,6 +114,8 @@ if (!valid_y) { > #endif > res.w[1] = CY.w[1] & QUIET_MASK64; > res.w[0] = CY.w[0]; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is Infinity? > @@ -110,6 +123,8 @@ if (!valid_y) { > // return x > res.w[1] = x.w[1]; > res.w[0] = x.w[0]; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is 0 > @@ -119,6 +134,8 @@ if (!valid_y) { > #endif > res.w[1] = 0x7c00000000000000ull; > res.w[0] = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > > @@ -130,6 +147,8 @@ if (diff_expon <= 0) { > if (diff_expon > 34) { > // |x|<|y| in this case > res = x; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // set exponent of y to exponent_x, scale coefficient_y > @@ -139,6 +158,8 @@ if (diff_expon <= 0) { > if (P256.w[2] || P256.w[3]) { > // |x|<|y| in this case > res = x; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > > @@ -147,6 +168,8 @@ if (diff_expon <= 0) { > if (__unsigned_compare_ge_128 (P256, CX2)) { > // |x|<|y| in this case > res = x; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > > @@ -164,6 +187,8 @@ if (diff_expon <= 0) { > } > > get_BID128_very_fast (&res, sign_x, exponent_x, CR); > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // 2^64 > @@ -200,6 +225,8 @@ while (diff_expon > 0) { > // check for remainder == 0 > if (!CX.w[1] && !CX.w[0]) { > get_BID128_very_fast (&res, sign_x, exponent_y, CX); > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -213,5 +240,7 @@ if ((__unsigned_compare_gt_128 (CX2, CY)) > } > > get_BID128_very_fast (&res, sign_x, exponent_y, CX); > +// restore the rounding mode back if it has been changed > +DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > diff --git a/libgcc/config/libbid/bid128_sqrt.c > b/libgcc/config/libbid/bid128_sqrt.c > index b28038389ad..71a033f54fe 100644 > --- a/libgcc/config/libbid/bid128_sqrt.c > +++ b/libgcc/config/libbid/bid128_sqrt.c > @@ -43,6 +43,9 @@ BID128_FUNCTION_ARG1 (bid128_sqrt, x) > fexcept_t binaryflags = 0; > #endif > > + // Set the rounding mode to round-to-nearest (if different) > + DFP_INIT_ROUNDMODE; > + > // unpack arguments, check for NaN or Infinity > if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) { > res.w[1] = CX.w[1]; > @@ -54,6 +57,8 @@ if ((x.w[1] & 0x7c00000000000000ull) == > 0x7c00000000000000ull) { > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > res.w[1] = CX.w[1] & QUIET_MASK64; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x is Infinity? > @@ -66,6 +71,8 @@ if ((x.w[1] & 0x7800000000000000ull) == > 0x7800000000000000ull) { > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > } > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x is 0 otherwise > @@ -74,6 +81,8 @@ res.w[1] = > sign_x | > ((((UINT64) (exponent_x + DECIMAL_EXPONENT_BIAS_128)) >> 1) << 49); > res.w[0] = 0; > +// restore the rounding mode back if it has been changed > +DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > if (sign_x) { > @@ -82,6 +91,8 @@ if (sign_x) { > #ifdef SET_STATUS_FLAGS > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > @@ -117,6 +128,8 @@ if (CS.w[0] * CS.w[0] == A10.w[0]) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -288,6 +301,8 @@ get_BID128_fast (&res, 0, > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > +// restore the rounding mode back if it has been changed > +DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > > @@ -302,10 +317,14 @@ BID128_FUNCTION_ARGTYPE1 (bid128d_sqrt, UINT64, x) > int_float fx, f64; > int exponent_x, bin_expon_cx; > int digits, scale, exponent_q; > + > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > fexcept_t binaryflags = 0; > #endif > > + // Set the rounding mode to round-to-nearest (if different) > + DFP_INIT_ROUNDMODE; > + > // unpack arguments, check for NaN or Infinity > // unpack arguments, check for NaN or Infinity > CX.w[1] = 0; > @@ -321,6 +340,8 @@ if ((x & 0x7c00000000000000ull) == 0x7c00000000000000ull) > { > res.w[0] = (CX.w[0] & 0x0003ffffffffffffull); > __mul_64x64_to_128 (res, res.w[0], power10_table_128[18].w[0]); > res.w[1] |= ((CX.w[0]) & 0xfc00000000000000ull); > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x is Infinity? > @@ -332,6 +353,8 @@ if ((x & 0x7800000000000000ull) == 0x7800000000000000ull) > { > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > } > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x is 0 otherwise > @@ -342,6 +365,8 @@ res.w[1] = > sign_x | ((((UINT64) (exponent_x + DECIMAL_EXPONENT_BIAS_128)) >> 1) > << 49); > res.w[0] = 0; > +// restore the rounding mode back if it has been changed > +DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > if (sign_x) { > @@ -350,6 +375,8 @@ if (sign_x) { > #ifdef SET_STATUS_FLAGS > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > @@ -387,6 +414,8 @@ if (CS.w[0] * CS.w[0] == A10.w[0]) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -558,6 +587,8 @@ get_BID128_fast (&res, 0, (exponent_q + > DECIMAL_EXPONENT_BIAS_128) >> 1, > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > +// restore the rounding mode back if it has been changed > +DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > > > diff --git a/libgcc/config/libbid/bid64_div.c > b/libgcc/config/libbid/bid64_div.c > index 69758482b89..5de1a4596cc 100644 > --- a/libgcc/config/libbid/bid64_div.c > +++ b/libgcc/config/libbid/bid64_div.c > @@ -106,6 +106,9 @@ bid64_div (UINT64 x, > y = *py; > #endif > > + // Set the rounding mode to round-to-nearest (if different) > + DFP_INIT_ROUNDMODE; > + > valid_x = unpack_BID64 (&sign_x, &exponent_x, &coefficient_x, x); > valid_y = unpack_BID64 (&sign_y, &exponent_y, &coefficient_y, y); > > @@ -123,6 +126,8 @@ bid64_div (UINT64 x, > if ((x & SNAN_MASK64) == SNAN_MASK64) // sNaN > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (coefficient_x & QUIET_MASK64); > } > // x is Infinity? > @@ -134,9 +139,13 @@ bid64_div (UINT64 x, > #ifdef SET_STATUS_FLAGS > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (NAN_MASK64); > } > } else { > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > // otherwise return +/-Inf > BID_RETURN (((x ^ y) & 0x8000000000000000ull) | > INFINITY_MASK64); > @@ -149,6 +158,8 @@ bid64_div (UINT64 x, > #ifdef SET_STATUS_FLAGS > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (NAN_MASK64); > } > if (((y & INFINITY_MASK64) != INFINITY_MASK64)) { > @@ -163,6 +174,8 @@ bid64_div (UINT64 x, > exponent_x = DECIMAL_MAX_EXPON_64; > else if (exponent_x < 0) > exponent_x = 0; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN ((sign_x ^ sign_y) | (((UINT64) exponent_x) << 53)); > } > > @@ -176,10 +189,14 @@ bid64_div (UINT64 x, > if ((y & SNAN_MASK64) == SNAN_MASK64) // sNaN > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (coefficient_y & QUIET_MASK64); > } > // y is Infinity? > if ((y & INFINITY_MASK64) == INFINITY_MASK64) { > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > // return +/-0 > BID_RETURN (((x ^ y) & 0x8000000000000000ull)); > } > @@ -187,6 +204,8 @@ bid64_div (UINT64 x, > #ifdef SET_STATUS_FLAGS > __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN ((sign_x ^ sign_y) | INFINITY_MASK64); > } > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > @@ -255,6 +274,8 @@ bid64_div (UINT64 x, > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // get decimal digits of Q > @@ -424,6 +445,8 @@ bid64_div (UINT64 x, > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -494,6 +517,8 @@ bid64_div (UINT64 x, > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } else { > // UF occurs > @@ -510,6 +535,8 @@ bid64_div (UINT64 x, > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > > } > @@ -532,6 +559,9 @@ unsigned rmode; > fexcept_t binaryflags = 0; > #endif > > +// Set the rounding mode to round-to-nearest (if different) > +DFP_INIT_ROUNDMODE; > + > valid_y = unpack_BID128_value (&sign_y, &exponent_y, &CY, y); > > // unpack arguments, check for NaN or Infinity > @@ -545,6 +575,8 @@ if (!unpack_BID64 (&sign_x, &exponent_x, &CX.w[0], (x))) { > // test if x is NaN > if (((x) & 0x7c00000000000000ull) == 0x7c00000000000000ull) { > res = CX.w[0]; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res & QUIET_MASK64); > } > // x is Infinity? > @@ -557,12 +589,16 @@ if (!unpack_BID64 (&sign_x, &exponent_x, &CX.w[0], > (x))) { > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > res = 0x7c00000000000000ull; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > if (((y.w[1] & 0x7c00000000000000ull) != 0x7c00000000000000ull)) { > // otherwise return +/-Inf > res = > (((x) ^ y.w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -574,6 +610,8 @@ if (!unpack_BID64 (&sign_x, &exponent_x, &CX.w[0], (x))) { > #endif > // x=y=0, return NaN > res = 0x7c00000000000000ull; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // return 0 > @@ -584,6 +622,8 @@ if (!unpack_BID64 (&sign_x, &exponent_x, &CX.w[0], (x))) { > else if (exponent_x < 0) > exponent_x = 0; > res |= (((UINT64) exponent_x) << 53); > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -604,12 +644,16 @@ if (!valid_y) { > amount = recip_scale[18]; > __shr_128 (Tmp, Qh, amount); > res = (CY.w[1] & 0xfc00000000000000ull) | Tmp.w[0]; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is Infinity? > if ((y.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) { > // return +/-0 > res = sign_x ^ sign_y; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is 0, return +/-Inf > @@ -618,6 +662,8 @@ if (!valid_y) { > #ifdef SET_STATUS_FLAGS > __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > @@ -680,6 +726,8 @@ if (__unsigned_compare_gt_128 (CY, CX)) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > > @@ -823,6 +871,8 @@ if (!done) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -905,6 +955,8 @@ if (!done) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } else { > // UF occurs > @@ -921,6 +973,8 @@ if (!done) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > > } > @@ -946,6 +1000,9 @@ unsigned rmode; > fexcept_t binaryflags = 0; > #endif > > +// Set the rounding mode to round-to-nearest (if different) > +DFP_INIT_ROUNDMODE; > + > valid_y = unpack_BID64 (&sign_y, &exponent_y, &CY.w[0], (y)); > > // unpack arguments, check for NaN or Infinity > @@ -964,6 +1021,8 @@ if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) > { > amount = recip_scale[18]; > __shr_128 (Tmp, Qh, amount); > res = (CX.w[1] & 0xfc00000000000000ull) | Tmp.w[0]; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x is Infinity? > @@ -976,12 +1035,16 @@ if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, > x)) { > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > res = 0x7c00000000000000ull; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > if (((y & 0x7c00000000000000ull) != 0x7c00000000000000ull)) { > // otherwise return +/-Inf > res = > ((x.w[1] ^ (y)) & 0x8000000000000000ull) | 0x7800000000000000ull; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -993,6 +1056,8 @@ if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) > { > #endif > // x=y=0, return NaN > res = 0x7c00000000000000ull; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // return 0 > @@ -1002,6 +1067,8 @@ if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, > x)) { > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > res = 0x7c00000000000000ull; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > exponent_x = > @@ -1012,6 +1079,8 @@ if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, > x)) { > else if (exponent_x < 0) > exponent_x = 0; > res = (sign_x ^ sign_y) | (((UINT64) exponent_x) << 53); > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -1025,12 +1094,16 @@ if (!valid_y) { > if ((y & SNAN_MASK64) == SNAN_MASK64) // sNaN > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (CY.w[0] & QUIET_MASK64); > } > // y is Infinity? > if (((y) & 0x7800000000000000ull) == 0x7800000000000000ull) { > // return +/-0 > res = sign_x ^ sign_y; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is 0, return +/-Inf > @@ -1039,6 +1112,8 @@ if (!valid_y) { > #ifdef SET_STATUS_FLAGS > __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > @@ -1103,6 +1178,8 @@ if (__unsigned_compare_gt_128 (CY, CX)) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > > @@ -1252,6 +1329,8 @@ if (!done) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -1337,6 +1416,8 @@ if (!done) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } else { > // UF occurs > @@ -1353,6 +1434,8 @@ if (!done) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > > } > @@ -1383,6 +1466,9 @@ unsigned rmode; > fexcept_t binaryflags = 0; > #endif > > +// Set the rounding mode to round-to-nearest (if different) > +DFP_INIT_ROUNDMODE; > + > valid_y = unpack_BID128_value (&sign_y, &exponent_y, &CY, y); > > // unpack arguments, check for NaN or Infinity > @@ -1401,6 +1487,8 @@ if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, > x)) { > amount = recip_scale[18]; > __shr_128 (Tmp, Qh, amount); > res = (CX.w[1] & 0xfc00000000000000ull) | Tmp.w[0]; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x is Infinity? > @@ -1413,6 +1501,8 @@ if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, > x)) { > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > res = 0x7c00000000000000ull; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > if (((y.w[1] & 0x7c00000000000000ull) != 0x7c00000000000000ull)) { > @@ -1420,6 +1510,8 @@ if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, > x)) { > res = > ((x.w[1] ^ y. > w[1]) & 0x8000000000000000ull) | 0x7800000000000000ull; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -1431,6 +1523,8 @@ if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, > x)) { > #endif > // x=y=0, return NaN > res = 0x7c00000000000000ull; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // return 0 > @@ -1441,6 +1535,8 @@ if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, > x)) { > else if (exponent_x < 0) > exponent_x = 0; > res |= (((UINT64) exponent_x) << 53); > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -1460,12 +1556,16 @@ if (!valid_y) { > amount = recip_scale[18]; > __shr_128 (Tmp, Qh, amount); > res = (CY.w[1] & 0xfc00000000000000ull) | Tmp.w[0]; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is Infinity? > if ((y.w[1] & 0x7800000000000000ull) == 0x7800000000000000ull) { > // return +/-0 > res = sign_x ^ sign_y; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // y is 0, return +/-Inf > @@ -1474,6 +1574,8 @@ if (!valid_y) { > #ifdef SET_STATUS_FLAGS > __set_status_flags (pfpsf, ZERO_DIVIDE_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > @@ -1536,6 +1638,8 @@ if (__unsigned_compare_gt_128 (CY, CX)) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > > @@ -1686,6 +1790,8 @@ if (!done) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -1772,6 +1878,8 @@ if (!done) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } else { > // UF occurs > @@ -1788,6 +1896,8 @@ if (!done) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > > } > diff --git a/libgcc/config/libbid/bid64_sqrt.c > b/libgcc/config/libbid/bid64_sqrt.c > index 29f4cf1f819..dbd06eaa153 100644 > --- a/libgcc/config/libbid/bid64_sqrt.c > +++ b/libgcc/config/libbid/bid64_sqrt.c > @@ -73,6 +73,7 @@ bid64_sqrt (UINT64 x _RND_MODE_PARAM _EXC_FLAGS_PARAM > int exponent_x, exponent_q, bin_expon_cx; > int digits_x; > int scale; > + > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > fexcept_t binaryflags = 0; > #endif > @@ -84,6 +85,9 @@ bid64_sqrt (UINT64 x _RND_MODE_PARAM _EXC_FLAGS_PARAM > x = *px; > #endif > > + // Set the rounding mode to round-to-nearest (if different) > + DFP_INIT_ROUNDMODE; > + > // unpack arguments, check for NaN or Infinity > if (!unpack_BID64 (&sign_x, &exponent_x, &coefficient_x, x)) { > // x is Inf. or NaN or 0 > @@ -100,11 +104,15 @@ bid64_sqrt (UINT64 x _RND_MODE_PARAM _EXC_FLAGS_PARAM > if ((x & SNAN_MASK64) == SNAN_MASK64) // sNaN > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res & QUIET_MASK64); > } > // x is 0 > exponent_x = (exponent_x + DECIMAL_EXPONENT_BIAS) >> 1; > res = sign_x | (((UINT64) exponent_x) << 53); > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x<0? > @@ -113,6 +121,8 @@ bid64_sqrt (UINT64 x _RND_MODE_PARAM _EXC_FLAGS_PARAM > #ifdef SET_STATUS_FLAGS > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > @@ -141,6 +151,8 @@ bid64_sqrt (UINT64 x _RND_MODE_PARAM _EXC_FLAGS_PARAM > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // if exponent is odd, scale coefficient by 10 > @@ -206,6 +218,8 @@ bid64_sqrt (UINT64 x _RND_MODE_PARAM _EXC_FLAGS_PARAM > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > > @@ -224,6 +238,9 @@ int digits, scale, exponent_q = 0, exact = 1, amount, > extra_digits; > fexcept_t binaryflags = 0; > #endif > > +// Set the rounding mode to round-to-nearest (if different) > +DFP_INIT_ROUNDMODE; > + > // unpack arguments, check for NaN or Infinity > if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) { > res = CX.w[1]; > @@ -240,6 +257,8 @@ if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) { > amount = recip_scale[18]; > __shr_128 (Tmp, Qh, amount); > res = (CX.w[1] & 0xfc00000000000000ull) | Tmp.w[0]; > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x is Infinity? > @@ -251,6 +270,8 @@ if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) { > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > } > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > // x is 0 otherwise > @@ -264,6 +285,8 @@ if (!unpack_BID128_value (&sign_x, &exponent_x, &CX, x)) { > exponent_x = DECIMAL_MAX_EXPON_64; > //res= sign_x | (((UINT64)exponent_x)<<53); > res = get_BID64 (sign_x, exponent_x, 0, rnd_mode, pfpsf); > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > if (sign_x) { > @@ -271,6 +294,8 @@ if (sign_x) { > #ifdef SET_STATUS_FLAGS > __set_status_flags (pfpsf, INVALID_EXCEPTION); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > @@ -312,6 +337,8 @@ if (CS.w[0] < 10000000000000000ull) { > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > + // restore the rounding mode back if it has been changed > + DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > } > } > @@ -546,6 +573,8 @@ res = get_BID64 (0, exponent_q, CS.w[0], rnd_mode, pfpsf); > #ifdef UNCHANGED_BINARY_STATUS_FLAGS > (void) fesetexceptflag (&binaryflags, FE_ALL_FLAGS); > #endif > +// restore the rounding mode back if it has been changed > +DFP_RESTORE_ROUNDMODE; > BID_RETURN (res); > > > diff --git a/libgcc/config/libbid/bid_conf.h b/libgcc/config/libbid/bid_conf.h > index 0f39d58d306..56f2b348ec0 100644 > --- a/libgcc/config/libbid/bid_conf.h > +++ b/libgcc/config/libbid/bid_conf.h > @@ -559,6 +559,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. > If not, see > #endif > // #define HPUX_OS > > +#include <dfp-machine.h> > + > // If DECIMAL_CALL_BY_REFERENCE is defined then numerical arguments and > results > // are passed by reference otherwise they are passed by value (except that > // a pointer is always passed to the status flags) > diff --git a/libgcc/config/libbid/dfp-machine.h > b/libgcc/config/libbid/dfp-machine.h > new file mode 100644 > index 00000000000..ae961157abb > --- /dev/null > +++ b/libgcc/config/libbid/dfp-machine.h > @@ -0,0 +1,34 @@ > +/* Rounding mode macros for DFP libbid. Dummy version. > + Copyright (C) 2025 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 > + <http://www.gnu.org/licenses/>. */ > + > +#ifndef _DFP_MACHINE_H > +#define _DFP_MACHINE_H > + > +/* Initialize the rounding mode to round-to-nearest if needed. */ > +#define DFP_INIT_ROUNDMODE > + > +/* Restore the rounding mode to round-to-nearest if changed. */ > +#define DFP_RESTORE_ROUNDMODE > + > +#endif /* _DFP_MACHINE_H */ > -- > 2.51.0 > -- BR, Hongtao
