mirror of git://gcc.gnu.org/git/gcc.git
libbid: Set rounding mode to round-to-nearest for _Decimal128 arithmetic
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. This doesn't require linking with libm when libgcc is used. 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 <hjl.tools@gmail.com>
This commit is contained in:
parent
f4b60fe6d6
commit
3dcf3410a7
|
@ -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 ;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef _SOFT_FLOAT
|
||||
/* Get the rounding mode. */
|
||||
#define DFP_GET_ROUNDMODE \
|
||||
unsigned int _frnd_orig; \
|
||||
do \
|
||||
{ \
|
||||
__asm__ __volatile__ ("fnstcw\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__ ("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
|
|
@ -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);
|
|
@ -0,0 +1,59 @@
|
|||
/* 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 _X86_DFP_MACHINE_H
|
||||
#define _X86_DFP_MACHINE_H
|
||||
|
||||
#ifdef _SOFT_FLOAT
|
||||
#include_next <dfp-machine.h>
|
||||
#else
|
||||
#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
|
||||
|
||||
#endif /* _X86_DFP_MACHINE_H */
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
Loading…
Reference in New Issue