diff options
author | Joseph Myers <joseph@codesourcery.com> | 2013-11-06 22:46:39 +0000 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2013-11-06 22:46:39 +0000 |
commit | 9954c743b9e985bd30194525464a0a8a64697b68 (patch) | |
tree | a0be3468d26216a37289e1817e7dbfea037f2f7c | |
parent | 3c40bae1c50f4fd8c23ee04d7fe768d7df68f2e6 (diff) | |
download | gcc-9954c743b9e985bd30194525464a0a8a64697b68.tar.gz |
float128-cmp-invalid.c, [...]: New tests.
gcc/testsuite:
* gcc.dg/torture/float128-cmp-invalid.c,
gcc.dg/torture/float128-div-underflow.c,
gcc.dg/torture/float128-extend-nan.c,
gcc.dg/torture/fp-int-convert-float128-timode-3.c: New tests.
libgcc:
* soft-fp/README: Update.
* soft-fp/adddf3.c: Update from glibc.
* soft-fp/addsf3.c: Likewise.
* soft-fp/addtf3.c: Likewise.
* soft-fp/divdf3.c: Likewise.
* soft-fp/divsf3.c: Likewise.
* soft-fp/divtf3.c: Likewise.
* soft-fp/double.h: Likewise.
* soft-fp/eqdf2.c: Likewise.
* soft-fp/eqsf2.c: Likewise.
* soft-fp/eqtf2.c: Likewise.
* soft-fp/extenddftf2.c: Likewise.
* soft-fp/extended.h: Likewise.
* soft-fp/extendsfdf2.c: Likewise.
* soft-fp/extendsftf2.c: Likewise.
* soft-fp/extendxftf2.c: Likewise.
* soft-fp/fixdfdi.c: Likewise.
* soft-fp/fixdfsi.c: Likewise.
* soft-fp/fixdfti.c: Likewise.
* soft-fp/fixsfdi.c: Likewise.
* soft-fp/fixsfsi.c: Likewise.
* soft-fp/fixsfti.c: Likewise.
* soft-fp/fixtfdi.c: Likewise.
* soft-fp/fixtfsi.c: Likewise.
* soft-fp/fixtfti.c: Likewise.
* soft-fp/fixunsdfdi.c: Likewise.
* soft-fp/fixunsdfsi.c: Likewise.
* soft-fp/fixunsdfti.c: Likewise.
* soft-fp/fixunssfdi.c: Likewise.
* soft-fp/fixunssfsi.c: Likewise.
* soft-fp/fixunssfti.c: Likewise.
* soft-fp/fixunstfdi.c: Likewise.
* soft-fp/fixunstfsi.c: Likewise.
* soft-fp/fixunstfti.c: Likewise.
* soft-fp/floatdidf.c: Likewise.
* soft-fp/floatdisf.c: Likewise.
* soft-fp/floatditf.c: Likewise.
* soft-fp/floatsidf.c: Likewise.
* soft-fp/floatsisf.c: Likewise.
* soft-fp/floatsitf.c: Likewise.
* soft-fp/floattidf.c: Likewise.
* soft-fp/floattisf.c: Likewise.
* soft-fp/floattitf.c: Likewise.
* soft-fp/floatundidf.c: Likewise.
* soft-fp/floatundisf.c: Likewise.
* soft-fp/floatunditf.c: Likewise.
* soft-fp/floatunsidf.c: Likewise.
* soft-fp/floatunsisf.c: Likewise.
* soft-fp/floatunsitf.c: Likewise.
* soft-fp/floatuntidf.c: Likewise.
* soft-fp/floatuntisf.c: Likewise.
* soft-fp/floatuntitf.c: Likewise.
* soft-fp/gedf2.c: Likewise.
* soft-fp/gesf2.c: Likewise.
* soft-fp/getf2.c: Likewise.
* soft-fp/ledf2.c: Likewise.
* soft-fp/lesf2.c: Likewise.
* soft-fp/letf2.c: Likewise.
* soft-fp/muldf3.c: Likewise.
* soft-fp/mulsf3.c: Likewise.
* soft-fp/multf3.c: Likewise.
* soft-fp/negdf2.c: Likewise.
* soft-fp/negsf2.c: Likewise.
* soft-fp/negtf2.c: Likewise.
* soft-fp/op-1.h: Likewise.
* soft-fp/op-2.h: Likewise.
* soft-fp/op-4.h: Likewise.
* soft-fp/op-8.h: Likewise.
* soft-fp/op-common.h: Likewise.
* soft-fp/quad.h: Likewise.
* soft-fp/single.h: Likewise.
* soft-fp/soft-fp.h: Likewise.
* soft-fp/subdf3.c: Likewise.
* soft-fp/subsf3.c: Likewise.
* soft-fp/subtf3.c: Likewise.
* soft-fp/truncdfsf2.c: Likewise.
* soft-fp/trunctfdf2.c: Likewise.
* soft-fp/trunctfsf2.c: Likewise.
* soft-fp/trunctfxf2.c: Likewise.
* soft-fp/unorddf2.c: Likewise.
* soft-fp/unordsf2.c: Likewise.
* soft-fp/unordtf2.c: Likewise.
From-SVN: r204489
88 files changed, 4803 insertions, 3802 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cb7b15bfcbb..27a76280e5d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2013-11-06 Joseph Myers <joseph@codesourcery.com> + + * gcc.dg/torture/float128-cmp-invalid.c, + gcc.dg/torture/float128-div-underflow.c, + gcc.dg/torture/float128-extend-nan.c, + gcc.dg/torture/fp-int-convert-float128-timode-3.c: New tests. + 2013-11-06 Oleg Endo <olegendo@gcc.gnu.org> * gcc.target/sh/pr51244-11.c: Remove target line. diff --git a/gcc/testsuite/gcc.dg/torture/float128-cmp-invalid.c b/gcc/testsuite/gcc.dg/torture/float128-cmp-invalid.c new file mode 100644 index 00000000000..53ef7ed01b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/float128-cmp-invalid.c @@ -0,0 +1,18 @@ +/* Test for "invalid" exceptions from __float128 comparisons. */ +/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */ +/* { dg-options "" } */ + +#include <fenv.h> +#include <stdlib.h> + +int +main (void) +{ + volatile __float128 a = __builtin_nan (""), b = 0; + volatile int r = a < b; + if (!fetestexcept (FE_INVALID)) + abort (); + if (r) + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/torture/float128-div-underflow.c b/gcc/testsuite/gcc.dg/torture/float128-div-underflow.c new file mode 100644 index 00000000000..43d350f4e44 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/float128-div-underflow.c @@ -0,0 +1,18 @@ +/* Test for spurious underflow from __float128 division. */ +/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */ +/* { dg-options "" } */ + +#include <fenv.h> +#include <stdlib.h> + +int +main (void) +{ + volatile __float128 a = 0x0.fffp-16382q, b = 0x0.fffp0q, c; + c = a / b; + if (fetestexcept (FE_UNDERFLOW | FE_INEXACT)) + abort (); + if (c != 0x1p-16382q) + abort (); + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/torture/float128-extend-nan.c b/gcc/testsuite/gcc.dg/torture/float128-extend-nan.c new file mode 100644 index 00000000000..1942d80f190 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/float128-extend-nan.c @@ -0,0 +1,22 @@ +/* Test extensions to __float128 quiet signaling NaNs. */ +/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */ +/* { dg-options "-fsignaling-nans" } */ + +#include <fenv.h> +#include <float.h> +#include <stdlib.h> + +volatile long double a = __builtin_nansl (""); + +int +main (void) +{ +#if LDBL_MANT_DIG < 113 + volatile __float128 r = a; + feclearexcept (FE_INVALID); + r += 1; + if (fetestexcept (FE_INVALID)) + abort (); +#endif + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode-3.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode-3.c new file mode 100644 index 00000000000..944494d9bcc --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-float128-timode-3.c @@ -0,0 +1,23 @@ +/* Test for correct rounding of conversions from __int128 to + __float128. */ +/* { dg-do run { target i?86-*-* x86_64-*-* ia64-*-* } } */ +/* { dg-require-effective-target int128 } */ +/* { dg-options "-frounding-math" } */ + +#include <fenv.h> +#include <stdlib.h> + +int +main (void) +{ + volatile unsigned long long h = -1ULL; + volatile unsigned __int128 u128 = (((unsigned __int128) h) << 64) | h; + volatile __int128 s128 = u128 >> 1; + fesetround (FE_TOWARDZERO); + __float128 ru = u128, rs = s128; + if (ru != 0x1.ffffffffffffffffffffffffffffp127q) + abort (); + if (rs != 0x1.ffffffffffffffffffffffffffffp126q) + abort (); + exit (0); +} diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 41bf1c55ff4..4da11a0406b 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,88 @@ +2013-11-06 Joseph Myers <joseph@codesourcery.com> + + * soft-fp/README: Update. + * soft-fp/adddf3.c: Update from glibc. + * soft-fp/addsf3.c: Likewise. + * soft-fp/addtf3.c: Likewise. + * soft-fp/divdf3.c: Likewise. + * soft-fp/divsf3.c: Likewise. + * soft-fp/divtf3.c: Likewise. + * soft-fp/double.h: Likewise. + * soft-fp/eqdf2.c: Likewise. + * soft-fp/eqsf2.c: Likewise. + * soft-fp/eqtf2.c: Likewise. + * soft-fp/extenddftf2.c: Likewise. + * soft-fp/extended.h: Likewise. + * soft-fp/extendsfdf2.c: Likewise. + * soft-fp/extendsftf2.c: Likewise. + * soft-fp/extendxftf2.c: Likewise. + * soft-fp/fixdfdi.c: Likewise. + * soft-fp/fixdfsi.c: Likewise. + * soft-fp/fixdfti.c: Likewise. + * soft-fp/fixsfdi.c: Likewise. + * soft-fp/fixsfsi.c: Likewise. + * soft-fp/fixsfti.c: Likewise. + * soft-fp/fixtfdi.c: Likewise. + * soft-fp/fixtfsi.c: Likewise. + * soft-fp/fixtfti.c: Likewise. + * soft-fp/fixunsdfdi.c: Likewise. + * soft-fp/fixunsdfsi.c: Likewise. + * soft-fp/fixunsdfti.c: Likewise. + * soft-fp/fixunssfdi.c: Likewise. + * soft-fp/fixunssfsi.c: Likewise. + * soft-fp/fixunssfti.c: Likewise. + * soft-fp/fixunstfdi.c: Likewise. + * soft-fp/fixunstfsi.c: Likewise. + * soft-fp/fixunstfti.c: Likewise. + * soft-fp/floatdidf.c: Likewise. + * soft-fp/floatdisf.c: Likewise. + * soft-fp/floatditf.c: Likewise. + * soft-fp/floatsidf.c: Likewise. + * soft-fp/floatsisf.c: Likewise. + * soft-fp/floatsitf.c: Likewise. + * soft-fp/floattidf.c: Likewise. + * soft-fp/floattisf.c: Likewise. + * soft-fp/floattitf.c: Likewise. + * soft-fp/floatundidf.c: Likewise. + * soft-fp/floatundisf.c: Likewise. + * soft-fp/floatunditf.c: Likewise. + * soft-fp/floatunsidf.c: Likewise. + * soft-fp/floatunsisf.c: Likewise. + * soft-fp/floatunsitf.c: Likewise. + * soft-fp/floatuntidf.c: Likewise. + * soft-fp/floatuntisf.c: Likewise. + * soft-fp/floatuntitf.c: Likewise. + * soft-fp/gedf2.c: Likewise. + * soft-fp/gesf2.c: Likewise. + * soft-fp/getf2.c: Likewise. + * soft-fp/ledf2.c: Likewise. + * soft-fp/lesf2.c: Likewise. + * soft-fp/letf2.c: Likewise. + * soft-fp/muldf3.c: Likewise. + * soft-fp/mulsf3.c: Likewise. + * soft-fp/multf3.c: Likewise. + * soft-fp/negdf2.c: Likewise. + * soft-fp/negsf2.c: Likewise. + * soft-fp/negtf2.c: Likewise. + * soft-fp/op-1.h: Likewise. + * soft-fp/op-2.h: Likewise. + * soft-fp/op-4.h: Likewise. + * soft-fp/op-8.h: Likewise. + * soft-fp/op-common.h: Likewise. + * soft-fp/quad.h: Likewise. + * soft-fp/single.h: Likewise. + * soft-fp/soft-fp.h: Likewise. + * soft-fp/subdf3.c: Likewise. + * soft-fp/subsf3.c: Likewise. + * soft-fp/subtf3.c: Likewise. + * soft-fp/truncdfsf2.c: Likewise. + * soft-fp/trunctfdf2.c: Likewise. + * soft-fp/trunctfsf2.c: Likewise. + * soft-fp/trunctfxf2.c: Likewise. + * soft-fp/unorddf2.c: Likewise. + * soft-fp/unordsf2.c: Likewise. + * soft-fp/unordtf2.c: Likewise. + 2013-11-05 Uros Bizjak <ubizjak@gmail.com> * config/i386/32/sfp-machine.h (_FP_MUL_MEAT_S): Define. diff --git a/libgcc/soft-fp/README b/libgcc/soft-fp/README index 361386de771..d60e88b7fec 100644 --- a/libgcc/soft-fp/README +++ b/libgcc/soft-fp/README @@ -1,5 +1,4 @@ -Except for conversions involving TImode and conversions involving -XFmode, the files in this directory are part of the GNU C Library, not part -of GCC. As described at <http://gcc.gnu.org/codingconventions.html>, changes -should be made to the GNU C Library and the changed files then imported -into GCC. +The files in this directory are part of the GNU C Library, not part of +GCC. As described at <http://gcc.gnu.org/codingconventions.html>, +changes should be made to the GNU C Library and the changed files then +imported into GCC. diff --git a/libgcc/soft-fp/adddf3.c b/libgcc/soft-fp/adddf3.c index 55df554b050..5aadfa3318b 100644 --- a/libgcc/soft-fp/adddf3.c +++ b/libgcc/soft-fp/adddf3.c @@ -31,17 +31,20 @@ #include "soft-fp.h" #include "double.h" -DFtype __adddf3(DFtype a, DFtype b) +DFtype +__adddf3 (DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); + FP_DECL_D (A); + FP_DECL_D (B); + FP_DECL_D (R); DFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_SEMIRAW_D(A, a); - FP_UNPACK_SEMIRAW_D(B, b); - FP_ADD_D(R, A, B); - FP_PACK_SEMIRAW_D(r, R); + FP_UNPACK_SEMIRAW_D (A, a); + FP_UNPACK_SEMIRAW_D (B, b); + FP_ADD_D (R, A, B); + FP_PACK_SEMIRAW_D (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/addsf3.c b/libgcc/soft-fp/addsf3.c index 8a31449e379..ac571bad06b 100644 --- a/libgcc/soft-fp/addsf3.c +++ b/libgcc/soft-fp/addsf3.c @@ -31,17 +31,20 @@ #include "soft-fp.h" #include "single.h" -SFtype __addsf3(SFtype a, SFtype b) +SFtype +__addsf3 (SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R); + FP_DECL_S (A); + FP_DECL_S (B); + FP_DECL_S (R); SFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_SEMIRAW_S(A, a); - FP_UNPACK_SEMIRAW_S(B, b); - FP_ADD_S(R, A, B); - FP_PACK_SEMIRAW_S(r, R); + FP_UNPACK_SEMIRAW_S (A, a); + FP_UNPACK_SEMIRAW_S (B, b); + FP_ADD_S (R, A, B); + FP_PACK_SEMIRAW_S (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/addtf3.c b/libgcc/soft-fp/addtf3.c index 7a2732513a9..1c0d266c66c 100644 --- a/libgcc/soft-fp/addtf3.c +++ b/libgcc/soft-fp/addtf3.c @@ -31,17 +31,20 @@ #include "soft-fp.h" #include "quad.h" -TFtype __addtf3(TFtype a, TFtype b) +TFtype +__addtf3 (TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R); + FP_DECL_Q (A); + FP_DECL_Q (B); + FP_DECL_Q (R); TFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_SEMIRAW_Q(A, a); - FP_UNPACK_SEMIRAW_Q(B, b); - FP_ADD_Q(R, A, B); - FP_PACK_SEMIRAW_Q(r, R); + FP_UNPACK_SEMIRAW_Q (A, a); + FP_UNPACK_SEMIRAW_Q (B, b); + FP_ADD_Q (R, A, B); + FP_PACK_SEMIRAW_Q (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/divdf3.c b/libgcc/soft-fp/divdf3.c index c3dcf8085e4..d357bf0222c 100644 --- a/libgcc/soft-fp/divdf3.c +++ b/libgcc/soft-fp/divdf3.c @@ -31,17 +31,20 @@ #include "soft-fp.h" #include "double.h" -DFtype __divdf3(DFtype a, DFtype b) +DFtype +__divdf3 (DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); + FP_DECL_D (A); + FP_DECL_D (B); + FP_DECL_D (R); DFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_D(A, a); - FP_UNPACK_D(B, b); - FP_DIV_D(R, A, B); - FP_PACK_D(r, R); + FP_UNPACK_D (A, a); + FP_UNPACK_D (B, b); + FP_DIV_D (R, A, B); + FP_PACK_D (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/divsf3.c b/libgcc/soft-fp/divsf3.c index 063462f8a16..b53b4031d7a 100644 --- a/libgcc/soft-fp/divsf3.c +++ b/libgcc/soft-fp/divsf3.c @@ -31,17 +31,20 @@ #include "soft-fp.h" #include "single.h" -SFtype __divsf3(SFtype a, SFtype b) +SFtype +__divsf3 (SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R); + FP_DECL_S (A); + FP_DECL_S (B); + FP_DECL_S (R); SFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_S(A, a); - FP_UNPACK_S(B, b); - FP_DIV_S(R, A, B); - FP_PACK_S(r, R); + FP_UNPACK_S (A, a); + FP_UNPACK_S (B, b); + FP_DIV_S (R, A, B); + FP_PACK_S (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/divtf3.c b/libgcc/soft-fp/divtf3.c index 03d017ddb6e..5b7175da54c 100644 --- a/libgcc/soft-fp/divtf3.c +++ b/libgcc/soft-fp/divtf3.c @@ -31,17 +31,20 @@ #include "soft-fp.h" #include "quad.h" -TFtype __divtf3(TFtype a, TFtype b) +TFtype +__divtf3 (TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R); + FP_DECL_Q (A); + FP_DECL_Q (B); + FP_DECL_Q (R); TFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_Q(A, a); - FP_UNPACK_Q(B, b); - FP_DIV_Q(R, A, B); - FP_PACK_Q(r, R); + FP_UNPACK_Q (A, a); + FP_UNPACK_Q (B, b); + FP_DIV_Q (R, A, B); + FP_PACK_Q (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/double.h b/libgcc/soft-fp/double.h index 759c2eb661a..ef4576707a7 100644 --- a/libgcc/soft-fp/double.h +++ b/libgcc/soft-fp/double.h @@ -31,13 +31,15 @@ <http://www.gnu.org/licenses/>. */ #if _FP_W_TYPE_SIZE < 32 -#error "Here's a nickel kid. Go buy yourself a real computer." +# error "Here's a nickel kid. Go buy yourself a real computer." #endif #if _FP_W_TYPE_SIZE < 64 -#define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE) +# define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE) +# define _FP_FRACTBITS_DW_D (4 * _FP_W_TYPE_SIZE) #else -#define _FP_FRACTBITS_D _FP_W_TYPE_SIZE +# define _FP_FRACTBITS_D _FP_W_TYPE_SIZE +# define _FP_FRACTBITS_DW_D (2 * _FP_W_TYPE_SIZE) #endif #define _FP_FRACBITS_D 53 @@ -49,215 +51,264 @@ #define _FP_EXPMAX_D 2047 #define _FP_QNANBIT_D \ - ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE) + ((_FP_W_TYPE) 1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE) #define _FP_QNANBIT_SH_D \ - ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) + ((_FP_W_TYPE) 1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) #define _FP_IMPLBIT_D \ - ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE) + ((_FP_W_TYPE) 1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE) #define _FP_IMPLBIT_SH_D \ - ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) + ((_FP_W_TYPE) 1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) #define _FP_OVERFLOW_D \ - ((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE) + ((_FP_W_TYPE) 1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE) -typedef float DFtype __attribute__((mode(DF))); +#define _FP_WFRACBITS_DW_D (2 * _FP_WFRACBITS_D) +#define _FP_WFRACXBITS_DW_D (_FP_FRACTBITS_DW_D - _FP_WFRACBITS_DW_D) +#define _FP_HIGHBIT_DW_D \ + ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_DW_D - 1) % _FP_W_TYPE_SIZE) + +typedef float DFtype __attribute__ ((mode (DF))); #if _FP_W_TYPE_SIZE < 64 union _FP_UNION_D { DFtype flt; - struct _FP_STRUCT_LAYOUT { -#if __BYTE_ORDER == __BIG_ENDIAN + struct _FP_STRUCT_LAYOUT + { +# if __BYTE_ORDER == __BIG_ENDIAN unsigned sign : 1; unsigned exp : _FP_EXPBITS_D; unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; unsigned frac0 : _FP_W_TYPE_SIZE; -#else +# else unsigned frac0 : _FP_W_TYPE_SIZE; unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE; unsigned exp : _FP_EXPBITS_D; unsigned sign : 1; -#endif - } bits __attribute__((packed)); +# endif + } bits __attribute__ ((packed)); }; -#define FP_DECL_D(X) _FP_DECL(2,X) -#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val) -#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_2_P(D,X,val) -#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X) -#define FP_PACK_RAW_DP(val,X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_2_P(D,val,X); \ - } while (0) - -#define FP_UNPACK_D(X,val) \ - do { \ - _FP_UNPACK_RAW_2(D,X,val); \ - _FP_UNPACK_CANONICAL(D,2,X); \ - } while (0) - -#define FP_UNPACK_DP(X,val) \ - do { \ - _FP_UNPACK_RAW_2_P(D,X,val); \ - _FP_UNPACK_CANONICAL(D,2,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_D(X,val) \ - do { \ - _FP_UNPACK_RAW_2(D,X,val); \ - _FP_UNPACK_SEMIRAW(D,2,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_DP(X,val) \ - do { \ - _FP_UNPACK_RAW_2_P(D,X,val); \ - _FP_UNPACK_SEMIRAW(D,2,X); \ - } while (0) - -#define FP_PACK_D(val,X) \ - do { \ - _FP_PACK_CANONICAL(D,2,X); \ - _FP_PACK_RAW_2(D,val,X); \ - } while (0) - -#define FP_PACK_DP(val,X) \ - do { \ - _FP_PACK_CANONICAL(D,2,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_2_P(D,val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_D(val,X) \ - do { \ - _FP_PACK_SEMIRAW(D,2,X); \ - _FP_PACK_RAW_2(D,val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_DP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(D,2,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_2_P(D,val,X); \ - } while (0) - -#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,2,X) -#define FP_NEG_D(R,X) _FP_NEG(D,2,R,X) -#define FP_ADD_D(R,X,Y) _FP_ADD(D,2,R,X,Y) -#define FP_SUB_D(R,X,Y) _FP_SUB(D,2,R,X,Y) -#define FP_MUL_D(R,X,Y) _FP_MUL(D,2,R,X,Y) -#define FP_DIV_D(R,X,Y) _FP_DIV(D,2,R,X,Y) -#define FP_SQRT_D(R,X) _FP_SQRT(D,2,R,X) -#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q) - -#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,2,r,X,Y,un) -#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y) -#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,2,r,X,Y) - -#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg) -#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt) - -#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_2(X) -#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_2(X) +# define FP_DECL_D(X) _FP_DECL (2, X) +# define FP_UNPACK_RAW_D(X, val) _FP_UNPACK_RAW_2 (D, X, val) +# define FP_UNPACK_RAW_DP(X, val) _FP_UNPACK_RAW_2_P (D, X, val) +# define FP_PACK_RAW_D(val, X) _FP_PACK_RAW_2 (D, val, X) +# define FP_PACK_RAW_DP(val, X) \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_2_P (D, val, X); \ + } \ + while (0) + +# define FP_UNPACK_D(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_2 (D, X, val); \ + _FP_UNPACK_CANONICAL (D, 2, X); \ + } \ + while (0) + +# define FP_UNPACK_DP(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_2_P (D, X, val); \ + _FP_UNPACK_CANONICAL (D, 2, X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_D(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_2 (D, X, val); \ + _FP_UNPACK_SEMIRAW (D, 2, X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_DP(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_2_P (D, X, val); \ + _FP_UNPACK_SEMIRAW (D, 2, X); \ + } \ + while (0) + +# define FP_PACK_D(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (D, 2, X); \ + _FP_PACK_RAW_2 (D, val, X); \ + } \ + while (0) + +# define FP_PACK_DP(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (D, 2, X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_2_P (D, val, X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_D(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (D, 2, X); \ + _FP_PACK_RAW_2 (D, val, X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_DP(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (D, 2, X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_2_P (D, val, X); \ + } \ + while (0) + +# define FP_ISSIGNAN_D(X) _FP_ISSIGNAN (D, 2, X) +# define FP_NEG_D(R, X) _FP_NEG (D, 2, R, X) +# define FP_ADD_D(R, X, Y) _FP_ADD (D, 2, R, X, Y) +# define FP_SUB_D(R, X, Y) _FP_SUB (D, 2, R, X, Y) +# define FP_MUL_D(R, X, Y) _FP_MUL (D, 2, R, X, Y) +# define FP_DIV_D(R, X, Y) _FP_DIV (D, 2, R, X, Y) +# define FP_SQRT_D(R, X) _FP_SQRT (D, 2, R, X) +# define _FP_SQRT_MEAT_D(R, S, T, X, Q) _FP_SQRT_MEAT_2 (R, S, T, X, Q) +# define FP_FMA_D(R, X, Y, Z) _FP_FMA (D, 2, 4, R, X, Y, Z) + +# define FP_CMP_D(r, X, Y, un) _FP_CMP (D, 2, r, X, Y, un) +# define FP_CMP_EQ_D(r, X, Y) _FP_CMP_EQ (D, 2, r, X, Y) +# define FP_CMP_UNORD_D(r, X, Y) _FP_CMP_UNORD (D, 2, r, X, Y) + +# define FP_TO_INT_D(r, X, rsz, rsg) _FP_TO_INT (D, 2, r, X, rsz, rsg) +# define FP_FROM_INT_D(X, r, rs, rt) _FP_FROM_INT (D, 2, X, r, rs, rt) + +# define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_2 (X) +# define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_2 (X) + +# define _FP_FRAC_HIGH_DW_D(X) _FP_FRAC_HIGH_4 (X) #else union _FP_UNION_D { DFtype flt; - struct _FP_STRUCT_LAYOUT { -#if __BYTE_ORDER == __BIG_ENDIAN + struct _FP_STRUCT_LAYOUT + { +# if __BYTE_ORDER == __BIG_ENDIAN unsigned sign : 1; unsigned exp : _FP_EXPBITS_D; _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); -#else +# else _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0); unsigned exp : _FP_EXPBITS_D; unsigned sign : 1; -#endif - } bits __attribute__((packed)); +# endif + } bits __attribute__ ((packed)); }; -#define FP_DECL_D(X) _FP_DECL(1,X) -#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val) -#define FP_UNPACK_RAW_DP(X,val) _FP_UNPACK_RAW_1_P(D,X,val) -#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X) -#define FP_PACK_RAW_DP(val,X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_1_P(D,val,X); \ - } while (0) - -#define FP_UNPACK_D(X,val) \ - do { \ - _FP_UNPACK_RAW_1(D,X,val); \ - _FP_UNPACK_CANONICAL(D,1,X); \ - } while (0) - -#define FP_UNPACK_DP(X,val) \ - do { \ - _FP_UNPACK_RAW_1_P(D,X,val); \ - _FP_UNPACK_CANONICAL(D,1,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_D(X,val) \ - do { \ - _FP_UNPACK_RAW_1(D,X,val); \ - _FP_UNPACK_SEMIRAW(D,1,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_DP(X,val) \ - do { \ - _FP_UNPACK_RAW_1_P(D,X,val); \ - _FP_UNPACK_SEMIRAW(D,1,X); \ - } while (0) - -#define FP_PACK_D(val,X) \ - do { \ - _FP_PACK_CANONICAL(D,1,X); \ - _FP_PACK_RAW_1(D,val,X); \ - } while (0) - -#define FP_PACK_DP(val,X) \ - do { \ - _FP_PACK_CANONICAL(D,1,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_1_P(D,val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_D(val,X) \ - do { \ - _FP_PACK_SEMIRAW(D,1,X); \ - _FP_PACK_RAW_1(D,val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_DP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(D,1,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_1_P(D,val,X); \ - } while (0) - -#define FP_ISSIGNAN_D(X) _FP_ISSIGNAN(D,1,X) -#define FP_NEG_D(R,X) _FP_NEG(D,1,R,X) -#define FP_ADD_D(R,X,Y) _FP_ADD(D,1,R,X,Y) -#define FP_SUB_D(R,X,Y) _FP_SUB(D,1,R,X,Y) -#define FP_MUL_D(R,X,Y) _FP_MUL(D,1,R,X,Y) -#define FP_DIV_D(R,X,Y) _FP_DIV(D,1,R,X,Y) -#define FP_SQRT_D(R,X) _FP_SQRT(D,1,R,X) -#define _FP_SQRT_MEAT_D(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q) +# define FP_DECL_D(X) _FP_DECL (1, X) +# define FP_UNPACK_RAW_D(X, val) _FP_UNPACK_RAW_1 (D, X, val) +# define FP_UNPACK_RAW_DP(X, val) _FP_UNPACK_RAW_1_P (D, X, val) +# define FP_PACK_RAW_D(val, X) _FP_PACK_RAW_1 (D, val, X) +# define FP_PACK_RAW_DP(val, X) \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_1_P (D, val, X); \ + } \ + while (0) + +# define FP_UNPACK_D(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_1 (D, X, val); \ + _FP_UNPACK_CANONICAL (D, 1, X); \ + } \ + while (0) + +# define FP_UNPACK_DP(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_1_P (D, X, val); \ + _FP_UNPACK_CANONICAL (D, 1, X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_D(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_1 (D, X, val); \ + _FP_UNPACK_SEMIRAW (D, 1, X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_DP(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_1_P (D, X, val); \ + _FP_UNPACK_SEMIRAW (D, 1, X); \ + } \ + while (0) + +# define FP_PACK_D(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (D, 1, X); \ + _FP_PACK_RAW_1 (D, val, X); \ + } \ + while (0) + +# define FP_PACK_DP(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (D, 1, X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_1_P (D, val, X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_D(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (D, 1, X); \ + _FP_PACK_RAW_1 (D, val, X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_DP(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (D, 1, X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_1_P (D, val, X); \ + } \ + while (0) + +# define FP_ISSIGNAN_D(X) _FP_ISSIGNAN (D, 1, X) +# define FP_NEG_D(R, X) _FP_NEG (D, 1, R, X) +# define FP_ADD_D(R, X, Y) _FP_ADD (D, 1, R, X, Y) +# define FP_SUB_D(R, X, Y) _FP_SUB (D, 1, R, X, Y) +# define FP_MUL_D(R, X, Y) _FP_MUL (D, 1, R, X, Y) +# define FP_DIV_D(R, X, Y) _FP_DIV (D, 1, R, X, Y) +# define FP_SQRT_D(R, X) _FP_SQRT (D, 1, R, X) +# define _FP_SQRT_MEAT_D(R, S, T, X, Q) _FP_SQRT_MEAT_1 (R, S, T, X, Q) +# define FP_FMA_D(R, X, Y, Z) _FP_FMA (D, 1, 2, R, X, Y, Z) /* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by the target machine. */ -#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un) -#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y) -#define FP_CMP_UNORD_D(r,X,Y) _FP_CMP_UNORD(D,1,r,X,Y) +# define FP_CMP_D(r, X, Y, un) _FP_CMP (D, 1, r, X, Y, un) +# define FP_CMP_EQ_D(r, X, Y) _FP_CMP_EQ (D, 1, r, X, Y) +# define FP_CMP_UNORD_D(r, X, Y) _FP_CMP_UNORD (D, 1, r, X, Y) + +# define FP_TO_INT_D(r, X, rsz, rsg) _FP_TO_INT (D, 1, r, X, rsz, rsg) +# define FP_FROM_INT_D(X, r, rs, rt) _FP_FROM_INT (D, 1, X, r, rs, rt) -#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg) -#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt) +# define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_1 (X) +# define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_1 (X) -#define _FP_FRAC_HIGH_D(X) _FP_FRAC_HIGH_1(X) -#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_1(X) +# define _FP_FRAC_HIGH_DW_D(X) _FP_FRAC_HIGH_2 (X) #endif /* W_TYPE_SIZE < 64 */ diff --git a/libgcc/soft-fp/eqdf2.c b/libgcc/soft-fp/eqdf2.c index c93c118f4e5..e8cfd7666a9 100644 --- a/libgcc/soft-fp/eqdf2.c +++ b/libgcc/soft-fp/eqdf2.c @@ -31,20 +31,23 @@ #include "soft-fp.h" #include "double.h" -CMPtype __eqdf2(DFtype a, DFtype b) +CMPtype +__eqdf2 (DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); + FP_DECL_D (A); + FP_DECL_D (B); CMPtype r; - FP_UNPACK_RAW_D(A, a); - FP_UNPACK_RAW_D(B, b); - FP_CMP_EQ_D(r, A, B); - if (r && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B))) - FP_SET_EXCEPTION(FP_EX_INVALID); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_D (A, a); + FP_UNPACK_RAW_D (B, b); + FP_CMP_EQ_D (r, A, B); + if (r && (FP_ISSIGNAN_D (A) || FP_ISSIGNAN_D (B))) + FP_SET_EXCEPTION (FP_EX_INVALID); FP_HANDLE_EXCEPTIONS; return r; } -strong_alias(__eqdf2, __nedf2); +strong_alias (__eqdf2, __nedf2); diff --git a/libgcc/soft-fp/eqsf2.c b/libgcc/soft-fp/eqsf2.c index e5b2a5f36aa..0bdb7fb2237 100644 --- a/libgcc/soft-fp/eqsf2.c +++ b/libgcc/soft-fp/eqsf2.c @@ -31,20 +31,23 @@ #include "soft-fp.h" #include "single.h" -CMPtype __eqsf2(SFtype a, SFtype b) +CMPtype +__eqsf2 (SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); + FP_DECL_S (A); + FP_DECL_S (B); CMPtype r; - FP_UNPACK_RAW_S(A, a); - FP_UNPACK_RAW_S(B, b); - FP_CMP_EQ_S(r, A, B); - if (r && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B))) - FP_SET_EXCEPTION(FP_EX_INVALID); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_S (A, a); + FP_UNPACK_RAW_S (B, b); + FP_CMP_EQ_S (r, A, B); + if (r && (FP_ISSIGNAN_S (A) || FP_ISSIGNAN_S (B))) + FP_SET_EXCEPTION (FP_EX_INVALID); FP_HANDLE_EXCEPTIONS; return r; } -strong_alias(__eqsf2, __nesf2); +strong_alias (__eqsf2, __nesf2); diff --git a/libgcc/soft-fp/eqtf2.c b/libgcc/soft-fp/eqtf2.c index 47b5d5cb618..edbc6f6832f 100644 --- a/libgcc/soft-fp/eqtf2.c +++ b/libgcc/soft-fp/eqtf2.c @@ -31,20 +31,23 @@ #include "soft-fp.h" #include "quad.h" -CMPtype __eqtf2(TFtype a, TFtype b) +CMPtype +__eqtf2 (TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); + FP_DECL_Q (A); + FP_DECL_Q (B); CMPtype r; - FP_UNPACK_RAW_Q(A, a); - FP_UNPACK_RAW_Q(B, b); - FP_CMP_EQ_Q(r, A, B); - if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) - FP_SET_EXCEPTION(FP_EX_INVALID); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_Q (A, a); + FP_UNPACK_RAW_Q (B, b); + FP_CMP_EQ_Q (r, A, B); + if (r && (FP_ISSIGNAN_Q (A) || FP_ISSIGNAN_Q (B))) + FP_SET_EXCEPTION (FP_EX_INVALID); FP_HANDLE_EXCEPTIONS; return r; } -strong_alias(__eqtf2, __netf2); +strong_alias (__eqtf2, __netf2); diff --git a/libgcc/soft-fp/extenddftf2.c b/libgcc/soft-fp/extenddftf2.c index ff76a8cc2ff..2471fda9546 100644 --- a/libgcc/soft-fp/extenddftf2.c +++ b/libgcc/soft-fp/extenddftf2.c @@ -32,21 +32,22 @@ #include "double.h" #include "quad.h" -TFtype __extenddftf2(DFtype a) +TFtype +__extenddftf2 (DFtype a) { FP_DECL_EX; - FP_DECL_D(A); - FP_DECL_Q(R); + FP_DECL_D (A); + FP_DECL_Q (R); TFtype r; - FP_INIT_ROUNDMODE; - FP_UNPACK_RAW_D(A, a); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_D (A, a); #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q - FP_EXTEND(Q,D,4,2,R,A); + FP_EXTEND (Q, D, 4, 2, R, A); #else - FP_EXTEND(Q,D,2,1,R,A); + FP_EXTEND (Q, D, 2, 1, R, A); #endif - FP_PACK_RAW_Q(r, R); + FP_PACK_RAW_Q (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/extended.h b/libgcc/soft-fp/extended.h index 74927550eb2..1189f7c7d2d 100644 --- a/libgcc/soft-fp/extended.h +++ b/libgcc/soft-fp/extended.h @@ -28,13 +28,15 @@ <http://www.gnu.org/licenses/>. */ #if _FP_W_TYPE_SIZE < 32 -#error "Here's a nickel, kid. Go buy yourself a real computer." +# error "Here's a nickel, kid. Go buy yourself a real computer." #endif #if _FP_W_TYPE_SIZE < 64 -#define _FP_FRACTBITS_E (4*_FP_W_TYPE_SIZE) +# define _FP_FRACTBITS_E (4*_FP_W_TYPE_SIZE) +# define _FP_FRACTBITS_DW_E (8*_FP_W_TYPE_SIZE) #else -#define _FP_FRACTBITS_E (2*_FP_W_TYPE_SIZE) +# define _FP_FRACTBITS_E (2*_FP_W_TYPE_SIZE) +# define _FP_FRACTBITS_DW_E (4*_FP_W_TYPE_SIZE) #endif #define _FP_FRACBITS_E 64 @@ -46,152 +48,187 @@ #define _FP_EXPMAX_E 32767 #define _FP_QNANBIT_E \ - ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE) + ((_FP_W_TYPE) 1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE) #define _FP_QNANBIT_SH_E \ - ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) + ((_FP_W_TYPE) 1 << (_FP_FRACBITS_E-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) #define _FP_IMPLBIT_E \ - ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE) + ((_FP_W_TYPE) 1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE) #define _FP_IMPLBIT_SH_E \ - ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) + ((_FP_W_TYPE) 1 << (_FP_FRACBITS_E-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) #define _FP_OVERFLOW_E \ - ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE)) + ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE)) -typedef float XFtype __attribute__((mode(XF))); +#define _FP_WFRACBITS_DW_E (2 * _FP_WFRACBITS_E) +#define _FP_WFRACXBITS_DW_E (_FP_FRACTBITS_DW_E - _FP_WFRACBITS_DW_E) +#define _FP_HIGHBIT_DW_E \ + ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_DW_E - 1) % _FP_W_TYPE_SIZE) + +typedef float XFtype __attribute__ ((mode (XF))); #if _FP_W_TYPE_SIZE < 64 union _FP_UNION_E { - XFtype flt; - struct _FP_STRUCT_LAYOUT - { -#if __BYTE_ORDER == __BIG_ENDIAN - unsigned long pad1 : _FP_W_TYPE_SIZE; - unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); - unsigned long sign : 1; - unsigned long exp : _FP_EXPBITS_E; - unsigned long frac1 : _FP_W_TYPE_SIZE; - unsigned long frac0 : _FP_W_TYPE_SIZE; -#else - unsigned long frac0 : _FP_W_TYPE_SIZE; - unsigned long frac1 : _FP_W_TYPE_SIZE; - unsigned exp : _FP_EXPBITS_E; - unsigned sign : 1; -#endif /* not bigendian */ - } bits __attribute__((packed)); + XFtype flt; + struct _FP_STRUCT_LAYOUT + { +# if __BYTE_ORDER == __BIG_ENDIAN + unsigned long pad1 : _FP_W_TYPE_SIZE; + unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); + unsigned long sign : 1; + unsigned long exp : _FP_EXPBITS_E; + unsigned long frac1 : _FP_W_TYPE_SIZE; + unsigned long frac0 : _FP_W_TYPE_SIZE; +# else + unsigned long frac0 : _FP_W_TYPE_SIZE; + unsigned long frac1 : _FP_W_TYPE_SIZE; + unsigned exp : _FP_EXPBITS_E; + unsigned sign : 1; +# endif /* not bigendian */ + } bits __attribute__ ((packed)); }; -#define FP_DECL_E(X) _FP_DECL(4,X) - -#define FP_UNPACK_RAW_E(X, val) \ - do { \ - union _FP_UNION_E _flo; _flo.flt = (val); \ - \ - X##_f[2] = 0; X##_f[3] = 0; \ - X##_f[0] = _flo.bits.frac0; \ - X##_f[1] = _flo.bits.frac1; \ - X##_e = _flo.bits.exp; \ - X##_s = _flo.bits.sign; \ - } while (0) - -#define FP_UNPACK_RAW_EP(X, val) \ - do { \ - union _FP_UNION_E *_flo = \ - (union _FP_UNION_E *)(val); \ - \ - X##_f[2] = 0; X##_f[3] = 0; \ - X##_f[0] = _flo->bits.frac0; \ - X##_f[1] = _flo->bits.frac1; \ - X##_e = _flo->bits.exp; \ - X##_s = _flo->bits.sign; \ - } while (0) - -#define FP_PACK_RAW_E(val, X) \ - do { \ - union _FP_UNION_E _flo; \ - \ - if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ - else X##_f[1] &= ~(_FP_IMPLBIT_E); \ - _flo.bits.frac0 = X##_f[0]; \ - _flo.bits.frac1 = X##_f[1]; \ - _flo.bits.exp = X##_e; \ - _flo.bits.sign = X##_s; \ - \ - (val) = _flo.flt; \ - } while (0) - -#define FP_PACK_RAW_EP(val, X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - { \ - union _FP_UNION_E *_flo = \ - (union _FP_UNION_E *)(val); \ - \ - if (X##_e) X##_f[1] |= _FP_IMPLBIT_E; \ - else X##_f[1] &= ~(_FP_IMPLBIT_E); \ - _flo->bits.frac0 = X##_f[0]; \ - _flo->bits.frac1 = X##_f[1]; \ - _flo->bits.exp = X##_e; \ - _flo->bits.sign = X##_s; \ - } \ - } while (0) - -#define FP_UNPACK_E(X,val) \ - do { \ - FP_UNPACK_RAW_E(X,val); \ - _FP_UNPACK_CANONICAL(E,4,X); \ - } while (0) - -#define FP_UNPACK_EP(X,val) \ - do { \ - FP_UNPACK_RAW_EP(X,val); \ - _FP_UNPACK_CANONICAL(E,4,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_E(X,val) \ - do { \ - FP_UNPACK_RAW_E(X,val); \ - _FP_UNPACK_SEMIRAW(E,4,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_EP(X,val) \ - do { \ - FP_UNPACK_RAW_EP(X,val); \ - _FP_UNPACK_SEMIRAW(E,4,X); \ - } while (0) - -#define FP_PACK_E(val,X) \ - do { \ - _FP_PACK_CANONICAL(E,4,X); \ - FP_PACK_RAW_E(val,X); \ - } while (0) - -#define FP_PACK_EP(val,X) \ - do { \ - _FP_PACK_CANONICAL(E,4,X); \ - FP_PACK_RAW_EP(val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_E(val,X) \ - do { \ - _FP_PACK_SEMIRAW(E,4,X); \ - FP_PACK_RAW_E(val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_EP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(E,4,X); \ - FP_PACK_RAW_EP(val,X); \ - } while (0) - -#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,4,X) -#define FP_NEG_E(R,X) _FP_NEG(E,4,R,X) -#define FP_ADD_E(R,X,Y) _FP_ADD(E,4,R,X,Y) -#define FP_SUB_E(R,X,Y) _FP_SUB(E,4,R,X,Y) -#define FP_MUL_E(R,X,Y) _FP_MUL(E,4,R,X,Y) -#define FP_DIV_E(R,X,Y) _FP_DIV(E,4,R,X,Y) -#define FP_SQRT_E(R,X) _FP_SQRT(E,4,R,X) +# define FP_DECL_E(X) _FP_DECL (4, X) + +# define FP_UNPACK_RAW_E(X, val) \ + do \ + { \ + union _FP_UNION_E _flo; \ + _flo.flt = (val); \ + \ + X##_f[2] = 0; \ + X##_f[3] = 0; \ + X##_f[0] = _flo.bits.frac0; \ + X##_f[1] = _flo.bits.frac1; \ + X##_e = _flo.bits.exp; \ + X##_s = _flo.bits.sign; \ + } \ + while (0) + +# define FP_UNPACK_RAW_EP(X, val) \ + do \ + { \ + union _FP_UNION_E *_flo = (union _FP_UNION_E *) (val); \ + \ + X##_f[2] = 0; \ + X##_f[3] = 0; \ + X##_f[0] = _flo->bits.frac0; \ + X##_f[1] = _flo->bits.frac1; \ + X##_e = _flo->bits.exp; \ + X##_s = _flo->bits.sign; \ + } \ + while (0) + +# define FP_PACK_RAW_E(val, X) \ + do \ + { \ + union _FP_UNION_E _flo; \ + \ + if (X##_e) \ + X##_f[1] |= _FP_IMPLBIT_E; \ + else \ + X##_f[1] &= ~(_FP_IMPLBIT_E); \ + _flo.bits.frac0 = X##_f[0]; \ + _flo.bits.frac1 = X##_f[1]; \ + _flo.bits.exp = X##_e; \ + _flo.bits.sign = X##_s; \ + \ + (val) = _flo.flt; \ + } \ + while (0) + +# define FP_PACK_RAW_EP(val, X) \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + { \ + union _FP_UNION_E *_flo = (union _FP_UNION_E *) (val); \ + \ + if (X##_e) \ + X##_f[1] |= _FP_IMPLBIT_E; \ + else \ + X##_f[1] &= ~(_FP_IMPLBIT_E); \ + _flo->bits.frac0 = X##_f[0]; \ + _flo->bits.frac1 = X##_f[1]; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ + } \ + } \ + while (0) + +# define FP_UNPACK_E(X, val) \ + do \ + { \ + FP_UNPACK_RAW_E (X, val); \ + _FP_UNPACK_CANONICAL (E, 4, X); \ + } \ + while (0) + +# define FP_UNPACK_EP(X, val) \ + do \ + { \ + FP_UNPACK_RAW_EP (X, val); \ + _FP_UNPACK_CANONICAL (E, 4, X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_E(X, val) \ + do \ + { \ + FP_UNPACK_RAW_E (X, val); \ + _FP_UNPACK_SEMIRAW (E, 4, X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_EP(X, val) \ + do \ + { \ + FP_UNPACK_RAW_EP (X, val); \ + _FP_UNPACK_SEMIRAW (E, 4, X); \ + } \ + while (0) + +# define FP_PACK_E(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (E, 4, X); \ + FP_PACK_RAW_E (val, X); \ + } \ + while (0) + +# define FP_PACK_EP(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (E, 4, X); \ + FP_PACK_RAW_EP (val, X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_E(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (E, 4, X); \ + FP_PACK_RAW_E (val, X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_EP(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (E, 4, X); \ + FP_PACK_RAW_EP (val, X); \ + } \ + while (0) + +# define FP_ISSIGNAN_E(X) _FP_ISSIGNAN (E, 4, X) +# define FP_NEG_E(R, X) _FP_NEG (E, 4, R, X) +# define FP_ADD_E(R, X, Y) _FP_ADD (E, 4, R, X, Y) +# define FP_SUB_E(R, X, Y) _FP_SUB (E, 4, R, X, Y) +# define FP_MUL_E(R, X, Y) _FP_MUL (E, 4, R, X, Y) +# define FP_DIV_E(R, X, Y) _FP_DIV (E, 4, R, X, Y) +# define FP_SQRT_E(R, X) _FP_SQRT (E, 4, R, X) +# define FP_FMA_E(R, X, Y, Z) _FP_FMA (E, 4, 8, R, X, Y, Z) /* * Square root algorithms: @@ -204,185 +241,218 @@ union _FP_UNION_E * in two UWtype registers instead of four. */ -#define _FP_SQRT_MEAT_E(R, S, T, X, q) \ - do { \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - _FP_FRAC_SRL_4(X, (_FP_WORKBITS)); \ - while (q) \ - { \ - T##_f[1] = S##_f[1] + q; \ - if (T##_f[1] <= X##_f[1]) \ - { \ - S##_f[1] = T##_f[1] + q; \ - X##_f[1] -= T##_f[1]; \ - R##_f[1] += q; \ - } \ - _FP_FRAC_SLL_2(X, 1); \ - q >>= 1; \ - } \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - while (q) \ - { \ - T##_f[0] = S##_f[0] + q; \ - T##_f[1] = S##_f[1]; \ - if (T##_f[1] < X##_f[1] || \ - (T##_f[1] == X##_f[1] && \ - T##_f[0] <= X##_f[0])) \ - { \ - S##_f[0] = T##_f[0] + q; \ - S##_f[1] += (T##_f[0] > S##_f[0]); \ - _FP_FRAC_DEC_2(X, T); \ - R##_f[0] += q; \ - } \ - _FP_FRAC_SLL_2(X, 1); \ - q >>= 1; \ - } \ - _FP_FRAC_SLL_4(R, (_FP_WORKBITS)); \ - if (X##_f[0] | X##_f[1]) \ - { \ - if (S##_f[1] < X##_f[1] || \ - (S##_f[1] == X##_f[1] && \ - S##_f[0] < X##_f[0])) \ - R##_f[0] |= _FP_WORK_ROUND; \ - R##_f[0] |= _FP_WORK_STICKY; \ - } \ - } while (0) - -#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,4,r,X,Y,un) -#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,4,r,X,Y) -#define FP_CMP_UNORD_E(r,X,Y) _FP_CMP_UNORD(E,4,r,X,Y) - -#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,4,r,X,rsz,rsg) -#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,4,X,r,rs,rt) - -#define _FP_FRAC_HIGH_E(X) (X##_f[2]) -#define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1]) +# define _FP_SQRT_MEAT_E(R, S, T, X, q) \ + do \ + { \ + q = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \ + _FP_FRAC_SRL_4 (X, (_FP_WORKBITS)); \ + while (q) \ + { \ + T##_f[1] = S##_f[1] + q; \ + if (T##_f[1] <= X##_f[1]) \ + { \ + S##_f[1] = T##_f[1] + q; \ + X##_f[1] -= T##_f[1]; \ + R##_f[1] += q; \ + } \ + _FP_FRAC_SLL_2 (X, 1); \ + q >>= 1; \ + } \ + q = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \ + while (q) \ + { \ + T##_f[0] = S##_f[0] + q; \ + T##_f[1] = S##_f[1]; \ + if (T##_f[1] < X##_f[1] \ + || (T##_f[1] == X##_f[1] \ + && T##_f[0] <= X##_f[0])) \ + { \ + S##_f[0] = T##_f[0] + q; \ + S##_f[1] += (T##_f[0] > S##_f[0]); \ + _FP_FRAC_DEC_2 (X, T); \ + R##_f[0] += q; \ + } \ + _FP_FRAC_SLL_2 (X, 1); \ + q >>= 1; \ + } \ + _FP_FRAC_SLL_4 (R, (_FP_WORKBITS)); \ + if (X##_f[0] | X##_f[1]) \ + { \ + if (S##_f[1] < X##_f[1] \ + || (S##_f[1] == X##_f[1] \ + && S##_f[0] < X##_f[0])) \ + R##_f[0] |= _FP_WORK_ROUND; \ + R##_f[0] |= _FP_WORK_STICKY; \ + } \ + } \ + while (0) + +# define FP_CMP_E(r, X, Y, un) _FP_CMP (E, 4, r, X, Y, un) +# define FP_CMP_EQ_E(r, X, Y) _FP_CMP_EQ (E, 4, r, X, Y) +# define FP_CMP_UNORD_E(r, X, Y) _FP_CMP_UNORD (E, 4, r, X, Y) + +# define FP_TO_INT_E(r, X, rsz, rsg) _FP_TO_INT (E, 4, r, X, rsz, rsg) +# define FP_FROM_INT_E(X, r, rs, rt) _FP_FROM_INT (E, 4, X, r, rs, rt) + +# define _FP_FRAC_HIGH_E(X) (X##_f[2]) +# define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1]) + +# define _FP_FRAC_HIGH_DW_E(X) (X##_f[4]) #else /* not _FP_W_TYPE_SIZE < 64 */ union _FP_UNION_E { XFtype flt; - struct _FP_STRUCT_LAYOUT { -#if __BYTE_ORDER == __BIG_ENDIAN + struct _FP_STRUCT_LAYOUT + { +# if __BYTE_ORDER == __BIG_ENDIAN _FP_W_TYPE pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E); unsigned sign : 1; unsigned exp : _FP_EXPBITS_E; _FP_W_TYPE frac : _FP_W_TYPE_SIZE; -#else +# else _FP_W_TYPE frac : _FP_W_TYPE_SIZE; unsigned exp : _FP_EXPBITS_E; unsigned sign : 1; -#endif +# endif } bits; }; -#define FP_DECL_E(X) _FP_DECL(2,X) - -#define FP_UNPACK_RAW_E(X, val) \ - do { \ - union _FP_UNION_E _flo; _flo.flt = (val); \ - \ - X##_f0 = _flo.bits.frac; \ - X##_f1 = 0; \ - X##_e = _flo.bits.exp; \ - X##_s = _flo.bits.sign; \ - } while (0) - -#define FP_UNPACK_RAW_EP(X, val) \ - do { \ - union _FP_UNION_E *_flo = \ - (union _FP_UNION_E *)(val); \ - \ - X##_f0 = _flo->bits.frac; \ - X##_f1 = 0; \ - X##_e = _flo->bits.exp; \ - X##_s = _flo->bits.sign; \ - } while (0) - -#define FP_PACK_RAW_E(val, X) \ - do { \ - union _FP_UNION_E _flo; \ - \ - if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ - else X##_f0 &= ~(_FP_IMPLBIT_E); \ - _flo.bits.frac = X##_f0; \ - _flo.bits.exp = X##_e; \ - _flo.bits.sign = X##_s; \ - \ - (val) = _flo.flt; \ - } while (0) - -#define FP_PACK_RAW_EP(fs, val, X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - { \ - union _FP_UNION_E *_flo = \ - (union _FP_UNION_E *)(val); \ +# define FP_DECL_E(X) _FP_DECL (2, X) + +# define FP_UNPACK_RAW_E(X, val) \ + do \ + { \ + union _FP_UNION_E _flo; \ + _flo.flt = (val); \ + \ + X##_f0 = _flo.bits.frac; \ + X##_f1 = 0; \ + X##_e = _flo.bits.exp; \ + X##_s = _flo.bits.sign; \ + } \ + while (0) + +# define FP_UNPACK_RAW_EP(X, val) \ + do \ + { \ + union _FP_UNION_E *_flo = (union _FP_UNION_E *) (val); \ \ - if (X##_e) X##_f0 |= _FP_IMPLBIT_E; \ - else X##_f0 &= ~(_FP_IMPLBIT_E); \ - _flo->bits.frac = X##_f0; \ - _flo->bits.exp = X##_e; \ - _flo->bits.sign = X##_s; \ - } \ - } while (0) - - -#define FP_UNPACK_E(X,val) \ - do { \ - FP_UNPACK_RAW_E(X,val); \ - _FP_UNPACK_CANONICAL(E,2,X); \ - } while (0) - -#define FP_UNPACK_EP(X,val) \ - do { \ - FP_UNPACK_RAW_EP(X,val); \ - _FP_UNPACK_CANONICAL(E,2,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_E(X,val) \ - do { \ - FP_UNPACK_RAW_E(X,val); \ - _FP_UNPACK_SEMIRAW(E,2,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_EP(X,val) \ - do { \ - FP_UNPACK_RAW_EP(X,val); \ - _FP_UNPACK_SEMIRAW(E,2,X); \ - } while (0) - -#define FP_PACK_E(val,X) \ - do { \ - _FP_PACK_CANONICAL(E,2,X); \ - FP_PACK_RAW_E(val,X); \ - } while (0) - -#define FP_PACK_EP(val,X) \ - do { \ - _FP_PACK_CANONICAL(E,2,X); \ - FP_PACK_RAW_EP(val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_E(val,X) \ - do { \ - _FP_PACK_SEMIRAW(E,2,X); \ - FP_PACK_RAW_E(val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_EP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(E,2,X); \ - FP_PACK_RAW_EP(val,X); \ - } while (0) - -#define FP_ISSIGNAN_E(X) _FP_ISSIGNAN(E,2,X) -#define FP_NEG_E(R,X) _FP_NEG(E,2,R,X) -#define FP_ADD_E(R,X,Y) _FP_ADD(E,2,R,X,Y) -#define FP_SUB_E(R,X,Y) _FP_SUB(E,2,R,X,Y) -#define FP_MUL_E(R,X,Y) _FP_MUL(E,2,R,X,Y) -#define FP_DIV_E(R,X,Y) _FP_DIV(E,2,R,X,Y) -#define FP_SQRT_E(R,X) _FP_SQRT(E,2,R,X) + X##_f0 = _flo->bits.frac; \ + X##_f1 = 0; \ + X##_e = _flo->bits.exp; \ + X##_s = _flo->bits.sign; \ + } \ + while (0) + +# define FP_PACK_RAW_E(val, X) \ + do \ + { \ + union _FP_UNION_E _flo; \ + \ + if (X##_e) \ + X##_f0 |= _FP_IMPLBIT_E; \ + else \ + X##_f0 &= ~(_FP_IMPLBIT_E); \ + _flo.bits.frac = X##_f0; \ + _flo.bits.exp = X##_e; \ + _flo.bits.sign = X##_s; \ + \ + (val) = _flo.flt; \ + } \ + while (0) + +# define FP_PACK_RAW_EP(fs, val, X) \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + { \ + union _FP_UNION_E *_flo = (union _FP_UNION_E *) (val); \ + \ + if (X##_e) \ + X##_f0 |= _FP_IMPLBIT_E; \ + else \ + X##_f0 &= ~(_FP_IMPLBIT_E); \ + _flo->bits.frac = X##_f0; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ + } \ + } \ + while (0) + + +# define FP_UNPACK_E(X, val) \ + do \ + { \ + FP_UNPACK_RAW_E (X, val); \ + _FP_UNPACK_CANONICAL (E, 2, X); \ + } \ + while (0) + +# define FP_UNPACK_EP(X, val) \ + do \ + { \ + FP_UNPACK_RAW_EP (X, val); \ + _FP_UNPACK_CANONICAL (E, 2, X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_E(X, val) \ + do \ + { \ + FP_UNPACK_RAW_E (X, val); \ + _FP_UNPACK_SEMIRAW (E, 2, X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_EP(X, val) \ + do \ + { \ + FP_UNPACK_RAW_EP (X, val); \ + _FP_UNPACK_SEMIRAW (E, 2, X); \ + } \ + while (0) + +# define FP_PACK_E(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (E, 2, X); \ + FP_PACK_RAW_E (val, X); \ + } \ + while (0) + +# define FP_PACK_EP(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (E, 2, X); \ + FP_PACK_RAW_EP (val, X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_E(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (E, 2, X); \ + FP_PACK_RAW_E (val, X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_EP(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (E, 2, X); \ + FP_PACK_RAW_EP (val, X); \ + } \ + while (0) + +# define FP_ISSIGNAN_E(X) _FP_ISSIGNAN (E, 2, X) +# define FP_NEG_E(R, X) _FP_NEG (E, 2, R, X) +# define FP_ADD_E(R, X, Y) _FP_ADD (E, 2, R, X, Y) +# define FP_SUB_E(R, X, Y) _FP_SUB (E, 2, R, X, Y) +# define FP_MUL_E(R, X, Y) _FP_MUL (E, 2, R, X, Y) +# define FP_DIV_E(R, X, Y) _FP_DIV (E, 2, R, X, Y) +# define FP_SQRT_E(R, X) _FP_SQRT (E, 2, R, X) +# define FP_FMA_E(R, X, Y, Z) _FP_FMA (E, 2, 4, R, X, Y, Z) /* * Square root algorithms: @@ -392,39 +462,43 @@ union _FP_UNION_E * in one UWtype registers instead of two, although we don't * have to. */ -#define _FP_SQRT_MEAT_E(R, S, T, X, q) \ - do { \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - _FP_FRAC_SRL_2(X, (_FP_WORKBITS)); \ - while (q) \ - { \ - T##_f0 = S##_f0 + q; \ - if (T##_f0 <= X##_f0) \ - { \ - S##_f0 = T##_f0 + q; \ - X##_f0 -= T##_f0; \ - R##_f0 += q; \ - } \ - _FP_FRAC_SLL_1(X, 1); \ - q >>= 1; \ - } \ - _FP_FRAC_SLL_2(R, (_FP_WORKBITS)); \ - if (X##_f0) \ - { \ - if (S##_f0 < X##_f0) \ - R##_f0 |= _FP_WORK_ROUND; \ - R##_f0 |= _FP_WORK_STICKY; \ - } \ - } while (0) - -#define FP_CMP_E(r,X,Y,un) _FP_CMP(E,2,r,X,Y,un) -#define FP_CMP_EQ_E(r,X,Y) _FP_CMP_EQ(E,2,r,X,Y) -#define FP_CMP_UNORD_E(r,X,Y) _FP_CMP_UNORD(E,2,r,X,Y) - -#define FP_TO_INT_E(r,X,rsz,rsg) _FP_TO_INT(E,2,r,X,rsz,rsg) -#define FP_FROM_INT_E(X,r,rs,rt) _FP_FROM_INT(E,2,X,r,rs,rt) - -#define _FP_FRAC_HIGH_E(X) (X##_f1) -#define _FP_FRAC_HIGH_RAW_E(X) (X##_f0) +# define _FP_SQRT_MEAT_E(R, S, T, X, q) \ + do \ + { \ + q = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \ + _FP_FRAC_SRL_2 (X, (_FP_WORKBITS)); \ + while (q) \ + { \ + T##_f0 = S##_f0 + q; \ + if (T##_f0 <= X##_f0) \ + { \ + S##_f0 = T##_f0 + q; \ + X##_f0 -= T##_f0; \ + R##_f0 += q; \ + } \ + _FP_FRAC_SLL_1 (X, 1); \ + q >>= 1; \ + } \ + _FP_FRAC_SLL_2 (R, (_FP_WORKBITS)); \ + if (X##_f0) \ + { \ + if (S##_f0 < X##_f0) \ + R##_f0 |= _FP_WORK_ROUND; \ + R##_f0 |= _FP_WORK_STICKY; \ + } \ + } \ + while (0) + +# define FP_CMP_E(r, X, Y, un) _FP_CMP (E, 2, r, X, Y, un) +# define FP_CMP_EQ_E(r, X, Y) _FP_CMP_EQ (E, 2, r, X, Y) +# define FP_CMP_UNORD_E(r, X, Y) _FP_CMP_UNORD (E, 2, r, X, Y) + +# define FP_TO_INT_E(r, X, rsz, rsg) _FP_TO_INT (E, 2, r, X, rsz, rsg) +# define FP_FROM_INT_E(X, r, rs, rt) _FP_FROM_INT (E, 2, X, r, rs, rt) + +# define _FP_FRAC_HIGH_E(X) (X##_f1) +# define _FP_FRAC_HIGH_RAW_E(X) (X##_f0) + +# define _FP_FRAC_HIGH_DW_E(X) (X##_f[2]) #endif /* not _FP_W_TYPE_SIZE < 64 */ diff --git a/libgcc/soft-fp/extendsfdf2.c b/libgcc/soft-fp/extendsfdf2.c index 7fc4046f8ae..2276de527f0 100644 --- a/libgcc/soft-fp/extendsfdf2.c +++ b/libgcc/soft-fp/extendsfdf2.c @@ -32,21 +32,22 @@ #include "single.h" #include "double.h" -DFtype __extendsfdf2(SFtype a) +DFtype +__extendsfdf2 (SFtype a) { FP_DECL_EX; - FP_DECL_S(A); - FP_DECL_D(R); + FP_DECL_S (A); + FP_DECL_D (R); DFtype r; - FP_INIT_ROUNDMODE; - FP_UNPACK_RAW_S(A, a); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_S (A, a); #if _FP_W_TYPE_SIZE < _FP_FRACBITS_D - FP_EXTEND(D,S,2,1,R,A); + FP_EXTEND (D, S, 2, 1, R, A); #else - FP_EXTEND(D,S,1,1,R,A); + FP_EXTEND (D, S, 1, 1, R, A); #endif - FP_PACK_RAW_D(r, R); + FP_PACK_RAW_D (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/extendsftf2.c b/libgcc/soft-fp/extendsftf2.c index 8271a88466b..51f60c45698 100644 --- a/libgcc/soft-fp/extendsftf2.c +++ b/libgcc/soft-fp/extendsftf2.c @@ -32,21 +32,22 @@ #include "single.h" #include "quad.h" -TFtype __extendsftf2(SFtype a) +TFtype +__extendsftf2 (SFtype a) { FP_DECL_EX; - FP_DECL_S(A); - FP_DECL_Q(R); + FP_DECL_S (A); + FP_DECL_Q (R); TFtype r; - FP_INIT_ROUNDMODE; - FP_UNPACK_RAW_S(A, a); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_S (A, a); #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q - FP_EXTEND(Q,S,4,1,R,A); + FP_EXTEND (Q, S, 4, 1, R, A); #else - FP_EXTEND(Q,S,2,1,R,A); + FP_EXTEND (Q, S, 2, 1, R, A); #endif - FP_PACK_RAW_Q(r, R); + FP_PACK_RAW_Q (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/extendxftf2.c b/libgcc/soft-fp/extendxftf2.c index af29a2ae9cc..684052d8744 100644 --- a/libgcc/soft-fp/extendxftf2.c +++ b/libgcc/soft-fp/extendxftf2.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Return a converted to IEEE quad - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,29 +24,29 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "extended.h" #include "quad.h" -TFtype __extendxftf2(XFtype a) +TFtype +__extendxftf2 (XFtype a) { FP_DECL_EX; - FP_DECL_E(A); - FP_DECL_Q(R); + FP_DECL_E (A); + FP_DECL_Q (R); TFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_RAW_E(A, a); + FP_UNPACK_RAW_E (A, a); #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q - FP_EXTEND(Q,E,4,4,R,A); + FP_EXTEND (Q, E, 4, 4, R, A); #else - FP_EXTEND(Q,E,2,2,R,A); + FP_EXTEND (Q, E, 2, 2, R, A); #endif - FP_PACK_RAW_Q(r, R); + FP_PACK_RAW_Q (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixdfdi.c b/libgcc/soft-fp/fixdfdi.c index 71ce1d4d71c..7b926b3d692 100644 --- a/libgcc/soft-fp/fixdfdi.c +++ b/libgcc/soft-fp/fixdfdi.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "double.h" -DItype __fixdfdi(DFtype a) +DItype +__fixdfdi (DFtype a) { FP_DECL_EX; - FP_DECL_D(A); + FP_DECL_D (A); UDItype r; - FP_UNPACK_RAW_D(A, a); - FP_TO_INT_D(r, A, DI_BITS, 1); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_D (A, a); + FP_TO_INT_D (r, A, DI_BITS, 1); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixdfsi.c b/libgcc/soft-fp/fixdfsi.c index f0c9960644b..79b2d215059 100644 --- a/libgcc/soft-fp/fixdfsi.c +++ b/libgcc/soft-fp/fixdfsi.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "double.h" -SItype __fixdfsi(DFtype a) +SItype +__fixdfsi (DFtype a) { FP_DECL_EX; - FP_DECL_D(A); + FP_DECL_D (A); USItype r; - FP_UNPACK_RAW_D(A, a); - FP_TO_INT_D(r, A, SI_BITS, 1); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_D (A, a); + FP_TO_INT_D (r, A, SI_BITS, 1); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixdfti.c b/libgcc/soft-fp/fixdfti.c index 473165725e1..b5fe4f99fc1 100644 --- a/libgcc/soft-fp/fixdfti.c +++ b/libgcc/soft-fp/fixdfti.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert IEEE double to 128bit signed integer - Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,21 +24,22 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "double.h" -TItype __fixdfti(DFtype a) +TItype +__fixdfti (DFtype a) { FP_DECL_EX; - FP_DECL_D(A); + FP_DECL_D (A); UTItype r; - FP_UNPACK_RAW_D(A, a); - FP_TO_INT_D(r, A, TI_BITS, 1); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_D (A, a); + FP_TO_INT_D (r, A, TI_BITS, 1); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixsfdi.c b/libgcc/soft-fp/fixsfdi.c index 5f69d6a2885..df6b9c728a2 100644 --- a/libgcc/soft-fp/fixsfdi.c +++ b/libgcc/soft-fp/fixsfdi.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "single.h" -DItype __fixsfdi(SFtype a) +DItype +__fixsfdi (SFtype a) { FP_DECL_EX; - FP_DECL_S(A); + FP_DECL_S (A); UDItype r; - FP_UNPACK_RAW_S(A, a); - FP_TO_INT_S(r, A, DI_BITS, 1); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_S (A, a); + FP_TO_INT_S (r, A, DI_BITS, 1); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixsfsi.c b/libgcc/soft-fp/fixsfsi.c index 6fffdd73782..4c0bfd39db1 100644 --- a/libgcc/soft-fp/fixsfsi.c +++ b/libgcc/soft-fp/fixsfsi.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "single.h" -SItype __fixsfsi(SFtype a) +SItype +__fixsfsi (SFtype a) { FP_DECL_EX; - FP_DECL_S(A); + FP_DECL_S (A); USItype r; - FP_UNPACK_RAW_S(A, a); - FP_TO_INT_S(r, A, SI_BITS, 1); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_S (A, a); + FP_TO_INT_S (r, A, SI_BITS, 1); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixsfti.c b/libgcc/soft-fp/fixsfti.c index 779628eb403..6b5229fe91a 100644 --- a/libgcc/soft-fp/fixsfti.c +++ b/libgcc/soft-fp/fixsfti.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert IEEE single to 128bit signed integer - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,21 +24,22 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "single.h" -TItype __fixsfti(SFtype a) +TItype +__fixsfti (SFtype a) { FP_DECL_EX; - FP_DECL_S(A); + FP_DECL_S (A); UTItype r; - FP_UNPACK_RAW_S(A, a); - FP_TO_INT_S(r, A, TI_BITS, 1); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_S (A, a); + FP_TO_INT_S (r, A, TI_BITS, 1); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixtfdi.c b/libgcc/soft-fp/fixtfdi.c index ac67bfbd3c0..a65173aa781 100644 --- a/libgcc/soft-fp/fixtfdi.c +++ b/libgcc/soft-fp/fixtfdi.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "quad.h" -DItype __fixtfdi(TFtype a) +DItype +__fixtfdi (TFtype a) { FP_DECL_EX; - FP_DECL_Q(A); + FP_DECL_Q (A); UDItype r; - FP_UNPACK_RAW_Q(A, a); - FP_TO_INT_Q(r, A, DI_BITS, 1); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_Q (A, a); + FP_TO_INT_Q (r, A, DI_BITS, 1); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixtfsi.c b/libgcc/soft-fp/fixtfsi.c index 8f27ff66f0e..bc0ea0b87d2 100644 --- a/libgcc/soft-fp/fixtfsi.c +++ b/libgcc/soft-fp/fixtfsi.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "quad.h" -SItype __fixtfsi(TFtype a) +SItype +__fixtfsi (TFtype a) { FP_DECL_EX; - FP_DECL_Q(A); + FP_DECL_Q (A); USItype r; - FP_UNPACK_RAW_Q(A, a); - FP_TO_INT_Q(r, A, SI_BITS, 1); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_Q (A, a); + FP_TO_INT_Q (r, A, SI_BITS, 1); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixtfti.c b/libgcc/soft-fp/fixtfti.c index 8311ea5a72c..573ca0ed11b 100644 --- a/libgcc/soft-fp/fixtfti.c +++ b/libgcc/soft-fp/fixtfti.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert IEEE quad to 128bit signed integer - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,21 +24,22 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "quad.h" -TItype __fixtfti(TFtype a) +TItype +__fixtfti (TFtype a) { FP_DECL_EX; - FP_DECL_Q(A); + FP_DECL_Q (A); UTItype r; - FP_UNPACK_RAW_Q(A, a); - FP_TO_INT_Q(r, A, TI_BITS, 1); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_Q (A, a); + FP_TO_INT_Q (r, A, TI_BITS, 1); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixunsdfdi.c b/libgcc/soft-fp/fixunsdfdi.c index 82fe1c75380..8831cc3d19f 100644 --- a/libgcc/soft-fp/fixunsdfdi.c +++ b/libgcc/soft-fp/fixunsdfdi.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "double.h" -UDItype __fixunsdfdi(DFtype a) +UDItype +__fixunsdfdi (DFtype a) { FP_DECL_EX; - FP_DECL_D(A); + FP_DECL_D (A); UDItype r; - FP_UNPACK_RAW_D(A, a); - FP_TO_INT_D(r, A, DI_BITS, 0); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_D (A, a); + FP_TO_INT_D (r, A, DI_BITS, 0); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixunsdfsi.c b/libgcc/soft-fp/fixunsdfsi.c index 43287b00732..ff3744467a2 100644 --- a/libgcc/soft-fp/fixunsdfsi.c +++ b/libgcc/soft-fp/fixunsdfsi.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "double.h" -USItype __fixunsdfsi(DFtype a) +USItype +__fixunsdfsi (DFtype a) { FP_DECL_EX; - FP_DECL_D(A); + FP_DECL_D (A); USItype r; - FP_UNPACK_RAW_D(A, a); - FP_TO_INT_D(r, A, SI_BITS, 0); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_D (A, a); + FP_TO_INT_D (r, A, SI_BITS, 0); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixunsdfti.c b/libgcc/soft-fp/fixunsdfti.c index 48c41d4ac99..f124a7c6a8d 100644 --- a/libgcc/soft-fp/fixunsdfti.c +++ b/libgcc/soft-fp/fixunsdfti.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert IEEE double to 128bit unsigned integer - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,21 +24,22 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "double.h" -UTItype __fixunsdfti(DFtype a) +UTItype +__fixunsdfti (DFtype a) { FP_DECL_EX; - FP_DECL_D(A); + FP_DECL_D (A); UTItype r; - FP_UNPACK_RAW_D(A, a); - FP_TO_INT_D(r, A, TI_BITS, 0); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_D (A, a); + FP_TO_INT_D (r, A, TI_BITS, 0); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixunssfdi.c b/libgcc/soft-fp/fixunssfdi.c index c0691c663cf..4261c5e6a7a 100644 --- a/libgcc/soft-fp/fixunssfdi.c +++ b/libgcc/soft-fp/fixunssfdi.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "single.h" -UDItype __fixunssfdi(SFtype a) +UDItype +__fixunssfdi (SFtype a) { FP_DECL_EX; - FP_DECL_S(A); + FP_DECL_S (A); UDItype r; - FP_UNPACK_RAW_S(A, a); - FP_TO_INT_S(r, A, DI_BITS, 0); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_S (A, a); + FP_TO_INT_S (r, A, DI_BITS, 0); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixunssfsi.c b/libgcc/soft-fp/fixunssfsi.c index 3d00ce8d56c..b4bb890299c 100644 --- a/libgcc/soft-fp/fixunssfsi.c +++ b/libgcc/soft-fp/fixunssfsi.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "single.h" -USItype __fixunssfsi(SFtype a) +USItype +__fixunssfsi (SFtype a) { FP_DECL_EX; - FP_DECL_S(A); + FP_DECL_S (A); USItype r; - FP_UNPACK_RAW_S(A, a); - FP_TO_INT_S(r, A, SI_BITS, 0); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_S (A, a); + FP_TO_INT_S (r, A, SI_BITS, 0); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixunssfti.c b/libgcc/soft-fp/fixunssfti.c index 89bcedbadc3..36d01b0cfe8 100644 --- a/libgcc/soft-fp/fixunssfti.c +++ b/libgcc/soft-fp/fixunssfti.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert IEEE single to 128bit unsigned integer - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,21 +24,22 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "single.h" -UTItype __fixunssfti(SFtype a) +UTItype +__fixunssfti (SFtype a) { FP_DECL_EX; - FP_DECL_S(A); + FP_DECL_S (A); UTItype r; - FP_UNPACK_RAW_S(A, a); - FP_TO_INT_S(r, A, TI_BITS, 0); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_S (A, a); + FP_TO_INT_S (r, A, TI_BITS, 0); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixunstfdi.c b/libgcc/soft-fp/fixunstfdi.c index d6038fa8914..b2355a2ae9d 100644 --- a/libgcc/soft-fp/fixunstfdi.c +++ b/libgcc/soft-fp/fixunstfdi.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "quad.h" -UDItype __fixunstfdi(TFtype a) +UDItype +__fixunstfdi (TFtype a) { FP_DECL_EX; - FP_DECL_Q(A); + FP_DECL_Q (A); UDItype r; - FP_UNPACK_RAW_Q(A, a); - FP_TO_INT_Q(r, A, DI_BITS, 0); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_Q (A, a); + FP_TO_INT_Q (r, A, DI_BITS, 0); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixunstfsi.c b/libgcc/soft-fp/fixunstfsi.c index c8481f1caf0..efa1418da1d 100644 --- a/libgcc/soft-fp/fixunstfsi.c +++ b/libgcc/soft-fp/fixunstfsi.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "quad.h" -USItype __fixunstfsi(TFtype a) +USItype +__fixunstfsi (TFtype a) { FP_DECL_EX; - FP_DECL_Q(A); + FP_DECL_Q (A); USItype r; - FP_UNPACK_RAW_Q(A, a); - FP_TO_INT_Q(r, A, SI_BITS, 0); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_Q (A, a); + FP_TO_INT_Q (r, A, SI_BITS, 0); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/fixunstfti.c b/libgcc/soft-fp/fixunstfti.c index f62bd505c64..efe0cf5c5d5 100644 --- a/libgcc/soft-fp/fixunstfti.c +++ b/libgcc/soft-fp/fixunstfti.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert IEEE quad to 128bit unsigned integer - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,21 +24,22 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "quad.h" -UTItype __fixunstfti(TFtype a) +UTItype +__fixunstfti (TFtype a) { FP_DECL_EX; - FP_DECL_Q(A); + FP_DECL_Q (A); UTItype r; - FP_UNPACK_RAW_Q(A, a); - FP_TO_INT_Q(r, A, TI_BITS, 0); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_Q (A, a); + FP_TO_INT_Q (r, A, TI_BITS, 0); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/floatdidf.c b/libgcc/soft-fp/floatdidf.c index f6f594a84f6..fc8719abd73 100644 --- a/libgcc/soft-fp/floatdidf.c +++ b/libgcc/soft-fp/floatdidf.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "double.h" -DFtype __floatdidf(DItype i) +DFtype +__floatdidf (DItype i) { FP_DECL_EX; - FP_DECL_D(A); + FP_DECL_D (A); DFtype a; - FP_FROM_INT_D(A, i, DI_BITS, UDItype); - FP_PACK_RAW_D(a, A); + FP_INIT_ROUNDMODE; + FP_FROM_INT_D (A, i, DI_BITS, UDItype); + FP_PACK_RAW_D (a, A); FP_HANDLE_EXCEPTIONS; return a; diff --git a/libgcc/soft-fp/floatdisf.c b/libgcc/soft-fp/floatdisf.c index 72252e4a999..b6b6b425250 100644 --- a/libgcc/soft-fp/floatdisf.c +++ b/libgcc/soft-fp/floatdisf.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "single.h" -SFtype __floatdisf(DItype i) +SFtype +__floatdisf (DItype i) { FP_DECL_EX; - FP_DECL_S(A); + FP_DECL_S (A); SFtype a; - FP_FROM_INT_S(A, i, DI_BITS, UDItype); - FP_PACK_RAW_S(a, A); + FP_INIT_ROUNDMODE; + FP_FROM_INT_S (A, i, DI_BITS, UDItype); + FP_PACK_RAW_S (a, A); FP_HANDLE_EXCEPTIONS; return a; diff --git a/libgcc/soft-fp/floatditf.c b/libgcc/soft-fp/floatditf.c index 68da6c60b0d..fc3fba361f7 100644 --- a/libgcc/soft-fp/floatditf.c +++ b/libgcc/soft-fp/floatditf.c @@ -28,18 +28,18 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#define FP_NO_EXCEPTIONS #include "soft-fp.h" #include "quad.h" -TFtype __floatditf(DItype i) +TFtype +__floatditf (DItype i) { - FP_DECL_EX; - FP_DECL_Q(A); + FP_DECL_Q (A); TFtype a; - FP_FROM_INT_Q(A, i, DI_BITS, UDItype); - FP_PACK_RAW_Q(a, A); - FP_HANDLE_EXCEPTIONS; + FP_FROM_INT_Q (A, i, DI_BITS, UDItype); + FP_PACK_RAW_Q (a, A); return a; } diff --git a/libgcc/soft-fp/floatsidf.c b/libgcc/soft-fp/floatsidf.c index ec578fba791..7df5265ffc8 100644 --- a/libgcc/soft-fp/floatsidf.c +++ b/libgcc/soft-fp/floatsidf.c @@ -28,18 +28,18 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#define FP_NO_EXCEPTIONS #include "soft-fp.h" #include "double.h" -DFtype __floatsidf(SItype i) +DFtype +__floatsidf (SItype i) { - FP_DECL_EX; - FP_DECL_D(A); + FP_DECL_D (A); DFtype a; - FP_FROM_INT_D(A, i, SI_BITS, USItype); - FP_PACK_RAW_D(a, A); - FP_HANDLE_EXCEPTIONS; + FP_FROM_INT_D (A, i, SI_BITS, USItype); + FP_PACK_RAW_D (a, A); return a; } diff --git a/libgcc/soft-fp/floatsisf.c b/libgcc/soft-fp/floatsisf.c index c9ff205d7fd..b55fd3329eb 100644 --- a/libgcc/soft-fp/floatsisf.c +++ b/libgcc/soft-fp/floatsisf.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "single.h" -SFtype __floatsisf(SItype i) +SFtype +__floatsisf (SItype i) { FP_DECL_EX; - FP_DECL_S(A); + FP_DECL_S (A); SFtype a; - FP_FROM_INT_S(A, i, SI_BITS, USItype); - FP_PACK_RAW_S(a, A); + FP_INIT_ROUNDMODE; + FP_FROM_INT_S (A, i, SI_BITS, USItype); + FP_PACK_RAW_S (a, A); FP_HANDLE_EXCEPTIONS; return a; diff --git a/libgcc/soft-fp/floatsitf.c b/libgcc/soft-fp/floatsitf.c index 6e24b9ea634..d7c3078e4ba 100644 --- a/libgcc/soft-fp/floatsitf.c +++ b/libgcc/soft-fp/floatsitf.c @@ -28,18 +28,18 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#define FP_NO_EXCEPTIONS #include "soft-fp.h" #include "quad.h" -TFtype __floatsitf(SItype i) +TFtype +__floatsitf (SItype i) { - FP_DECL_EX; - FP_DECL_Q(A); + FP_DECL_Q (A); TFtype a; - FP_FROM_INT_Q(A, i, SI_BITS, USItype); - FP_PACK_RAW_Q(a, A); - FP_HANDLE_EXCEPTIONS; + FP_FROM_INT_Q (A, i, SI_BITS, USItype); + FP_PACK_RAW_Q (a, A); return a; } diff --git a/libgcc/soft-fp/floattidf.c b/libgcc/soft-fp/floattidf.c index 14b6ea36a7a..a28181b23a7 100644 --- a/libgcc/soft-fp/floattidf.c +++ b/libgcc/soft-fp/floattidf.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert a 128bit signed integer to IEEE double - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,21 +24,22 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "double.h" -DFtype __floattidf(TItype i) +DFtype +__floattidf (TItype i) { FP_DECL_EX; - FP_DECL_D(A); + FP_DECL_D (A); DFtype a; - FP_FROM_INT_D(A, i, TI_BITS, UTItype); - FP_PACK_RAW_D(a, A); + FP_INIT_ROUNDMODE; + FP_FROM_INT_D (A, i, TI_BITS, UTItype); + FP_PACK_RAW_D (a, A); FP_HANDLE_EXCEPTIONS; return a; diff --git a/libgcc/soft-fp/floattisf.c b/libgcc/soft-fp/floattisf.c index 475cafa2770..da810479450 100644 --- a/libgcc/soft-fp/floattisf.c +++ b/libgcc/soft-fp/floattisf.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert a 128bit signed integer to IEEE single - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,21 +24,22 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "single.h" -SFtype __floattisf(TItype i) +SFtype +__floattisf (TItype i) { FP_DECL_EX; - FP_DECL_S(A); + FP_DECL_S (A); SFtype a; - FP_FROM_INT_S(A, i, TI_BITS, UTItype); - FP_PACK_RAW_S(a, A); + FP_INIT_ROUNDMODE; + FP_FROM_INT_S (A, i, TI_BITS, UTItype); + FP_PACK_RAW_S (a, A); FP_HANDLE_EXCEPTIONS; return a; diff --git a/libgcc/soft-fp/floattitf.c b/libgcc/soft-fp/floattitf.c index 12bbb2772c2..ffe217a6226 100644 --- a/libgcc/soft-fp/floattitf.c +++ b/libgcc/soft-fp/floattitf.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert a 128bit signed integer to IEEE quad - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,21 +24,22 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "quad.h" -TFtype __floattitf(TItype i) +TFtype +__floattitf (TItype i) { FP_DECL_EX; - FP_DECL_Q(A); + FP_DECL_Q (A); TFtype a; - FP_FROM_INT_Q(A, i, TI_BITS, UTItype); - FP_PACK_RAW_Q(a, A); + FP_INIT_ROUNDMODE; + FP_FROM_INT_Q (A, i, TI_BITS, UTItype); + FP_PACK_RAW_Q (a, A); FP_HANDLE_EXCEPTIONS; return a; diff --git a/libgcc/soft-fp/floatundidf.c b/libgcc/soft-fp/floatundidf.c index 1babcec8e0b..8a041f827a4 100644 --- a/libgcc/soft-fp/floatundidf.c +++ b/libgcc/soft-fp/floatundidf.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "double.h" -DFtype __floatundidf(UDItype i) +DFtype +__floatundidf (UDItype i) { FP_DECL_EX; - FP_DECL_D(A); + FP_DECL_D (A); DFtype a; - FP_FROM_INT_D(A, i, DI_BITS, UDItype); - FP_PACK_RAW_D(a, A); + FP_INIT_ROUNDMODE; + FP_FROM_INT_D (A, i, DI_BITS, UDItype); + FP_PACK_RAW_D (a, A); FP_HANDLE_EXCEPTIONS; return a; diff --git a/libgcc/soft-fp/floatundisf.c b/libgcc/soft-fp/floatundisf.c index 1c645c023d3..8dc750851af 100644 --- a/libgcc/soft-fp/floatundisf.c +++ b/libgcc/soft-fp/floatundisf.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "single.h" -SFtype __floatundisf(UDItype i) +SFtype +__floatundisf (UDItype i) { FP_DECL_EX; - FP_DECL_S(A); + FP_DECL_S (A); SFtype a; - FP_FROM_INT_S(A, i, DI_BITS, UDItype); - FP_PACK_RAW_S(a, A); + FP_INIT_ROUNDMODE; + FP_FROM_INT_S (A, i, DI_BITS, UDItype); + FP_PACK_RAW_S (a, A); FP_HANDLE_EXCEPTIONS; return a; diff --git a/libgcc/soft-fp/floatunditf.c b/libgcc/soft-fp/floatunditf.c index fff73fdb67c..cc8a3fe06c9 100644 --- a/libgcc/soft-fp/floatunditf.c +++ b/libgcc/soft-fp/floatunditf.c @@ -28,19 +28,18 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#define FP_NO_EXCEPTIONS #include "soft-fp.h" #include "quad.h" TFtype -__floatunditf(UDItype i) +__floatunditf (UDItype i) { - FP_DECL_EX; - FP_DECL_Q(A); + FP_DECL_Q (A); TFtype a; - FP_FROM_INT_Q(A, i, DI_BITS, UDItype); - FP_PACK_RAW_Q(a, A); - FP_HANDLE_EXCEPTIONS; + FP_FROM_INT_Q (A, i, DI_BITS, UDItype); + FP_PACK_RAW_Q (a, A); return a; } diff --git a/libgcc/soft-fp/floatunsidf.c b/libgcc/soft-fp/floatunsidf.c index 548dc7c0c46..059029640c9 100644 --- a/libgcc/soft-fp/floatunsidf.c +++ b/libgcc/soft-fp/floatunsidf.c @@ -28,18 +28,18 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#define FP_NO_EXCEPTIONS #include "soft-fp.h" #include "double.h" -DFtype __floatunsidf(USItype i) +DFtype +__floatunsidf (USItype i) { - FP_DECL_EX; - FP_DECL_D(A); + FP_DECL_D (A); DFtype a; - FP_FROM_INT_D(A, i, SI_BITS, USItype); - FP_PACK_RAW_D(a, A); - FP_HANDLE_EXCEPTIONS; + FP_FROM_INT_D (A, i, SI_BITS, USItype); + FP_PACK_RAW_D (a, A); return a; } diff --git a/libgcc/soft-fp/floatunsisf.c b/libgcc/soft-fp/floatunsisf.c index 2c0cc897636..91c1e4d1a96 100644 --- a/libgcc/soft-fp/floatunsisf.c +++ b/libgcc/soft-fp/floatunsisf.c @@ -31,14 +31,16 @@ #include "soft-fp.h" #include "single.h" -SFtype __floatunsisf(USItype i) +SFtype +__floatunsisf (USItype i) { FP_DECL_EX; - FP_DECL_S(A); + FP_DECL_S (A); SFtype a; - FP_FROM_INT_S(A, i, SI_BITS, USItype); - FP_PACK_RAW_S(a, A); + FP_INIT_ROUNDMODE; + FP_FROM_INT_S (A, i, SI_BITS, USItype); + FP_PACK_RAW_S (a, A); FP_HANDLE_EXCEPTIONS; return a; diff --git a/libgcc/soft-fp/floatunsitf.c b/libgcc/soft-fp/floatunsitf.c index 1099c2ee849..b1eecfd7c95 100644 --- a/libgcc/soft-fp/floatunsitf.c +++ b/libgcc/soft-fp/floatunsitf.c @@ -28,19 +28,18 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#define FP_NO_EXCEPTIONS #include "soft-fp.h" #include "quad.h" TFtype -__floatunsitf(USItype i) +__floatunsitf (USItype i) { - FP_DECL_EX; - FP_DECL_Q(A); + FP_DECL_Q (A); TFtype a; - FP_FROM_INT_Q(A, i, SI_BITS, USItype); - FP_PACK_RAW_Q(a, A); - FP_HANDLE_EXCEPTIONS; + FP_FROM_INT_Q (A, i, SI_BITS, USItype); + FP_PACK_RAW_Q (a, A); return a; } diff --git a/libgcc/soft-fp/floatuntidf.c b/libgcc/soft-fp/floatuntidf.c index db1fe1aacb6..6a8981daec0 100644 --- a/libgcc/soft-fp/floatuntidf.c +++ b/libgcc/soft-fp/floatuntidf.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert a 128bit unsigned integer to IEEE double - Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc. + Copyright (C) 1997-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,21 +24,22 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "double.h" -DFtype __floatuntidf(UTItype i) +DFtype +__floatuntidf (UTItype i) { FP_DECL_EX; - FP_DECL_D(A); + FP_DECL_D (A); DFtype a; - FP_FROM_INT_D(A, i, TI_BITS, UTItype); - FP_PACK_RAW_D(a, A); + FP_INIT_ROUNDMODE; + FP_FROM_INT_D (A, i, TI_BITS, UTItype); + FP_PACK_RAW_D (a, A); FP_HANDLE_EXCEPTIONS; return a; diff --git a/libgcc/soft-fp/floatuntisf.c b/libgcc/soft-fp/floatuntisf.c index 73914878b2e..94d0593f26f 100644 --- a/libgcc/soft-fp/floatuntisf.c +++ b/libgcc/soft-fp/floatuntisf.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert a 128bit unsigned integer to IEEE single - Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,21 +24,22 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "single.h" -SFtype __floatuntisf(UTItype i) +SFtype +__floatuntisf (UTItype i) { FP_DECL_EX; - FP_DECL_S(A); + FP_DECL_S (A); SFtype a; - FP_FROM_INT_S(A, i, TI_BITS, UTItype); - FP_PACK_RAW_S(a, A); + FP_INIT_ROUNDMODE; + FP_FROM_INT_S (A, i, TI_BITS, UTItype); + FP_PACK_RAW_S (a, A); FP_HANDLE_EXCEPTIONS; return a; diff --git a/libgcc/soft-fp/floatuntitf.c b/libgcc/soft-fp/floatuntitf.c index 8d669012644..424bfef8fa8 100644 --- a/libgcc/soft-fp/floatuntitf.c +++ b/libgcc/soft-fp/floatuntitf.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Convert a 128bit unsigned integer to IEEE quad - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,21 +24,22 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "quad.h" -TFtype __floatuntitf(UTItype i) +TFtype +__floatuntitf (UTItype i) { FP_DECL_EX; - FP_DECL_Q(A); + FP_DECL_Q (A); TFtype a; - FP_FROM_INT_Q(A, i, TI_BITS, UTItype); - FP_PACK_RAW_Q(a, A); + FP_INIT_ROUNDMODE; + FP_FROM_INT_Q (A, i, TI_BITS, UTItype); + FP_PACK_RAW_Q (a, A); FP_HANDLE_EXCEPTIONS; return a; diff --git a/libgcc/soft-fp/gedf2.c b/libgcc/soft-fp/gedf2.c index 0ef9f5de2c8..5b6fad28492 100644 --- a/libgcc/soft-fp/gedf2.c +++ b/libgcc/soft-fp/gedf2.c @@ -31,20 +31,23 @@ #include "soft-fp.h" #include "double.h" -CMPtype __gedf2(DFtype a, DFtype b) +CMPtype +__gedf2 (DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); + FP_DECL_D (A); + FP_DECL_D (B); CMPtype r; - FP_UNPACK_RAW_D(A, a); - FP_UNPACK_RAW_D(B, b); - FP_CMP_D(r, A, B, -2); - if (r == -2 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B))) - FP_SET_EXCEPTION(FP_EX_INVALID); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_D (A, a); + FP_UNPACK_RAW_D (B, b); + FP_CMP_D (r, A, B, -2); + if (r == -2) + FP_SET_EXCEPTION (FP_EX_INVALID); FP_HANDLE_EXCEPTIONS; return r; } -strong_alias(__gedf2, __gtdf2); +strong_alias (__gedf2, __gtdf2); diff --git a/libgcc/soft-fp/gesf2.c b/libgcc/soft-fp/gesf2.c index f0a83773104..4e5d9393f1e 100644 --- a/libgcc/soft-fp/gesf2.c +++ b/libgcc/soft-fp/gesf2.c @@ -31,20 +31,23 @@ #include "soft-fp.h" #include "single.h" -CMPtype __gesf2(SFtype a, SFtype b) +CMPtype +__gesf2 (SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); + FP_DECL_S (A); + FP_DECL_S (B); CMPtype r; - FP_UNPACK_RAW_S(A, a); - FP_UNPACK_RAW_S(B, b); - FP_CMP_S(r, A, B, -2); - if (r == -2 && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B))) - FP_SET_EXCEPTION(FP_EX_INVALID); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_S (A, a); + FP_UNPACK_RAW_S (B, b); + FP_CMP_S (r, A, B, -2); + if (r == -2) + FP_SET_EXCEPTION (FP_EX_INVALID); FP_HANDLE_EXCEPTIONS; return r; } -strong_alias(__gesf2, __gtsf2); +strong_alias (__gesf2, __gtsf2); diff --git a/libgcc/soft-fp/getf2.c b/libgcc/soft-fp/getf2.c index 705d48b9053..ed02f459ea2 100644 --- a/libgcc/soft-fp/getf2.c +++ b/libgcc/soft-fp/getf2.c @@ -31,20 +31,23 @@ #include "soft-fp.h" #include "quad.h" -CMPtype __getf2(TFtype a, TFtype b) +CMPtype +__getf2 (TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); + FP_DECL_Q (A); + FP_DECL_Q (B); CMPtype r; - FP_UNPACK_RAW_Q(A, a); - FP_UNPACK_RAW_Q(B, b); - FP_CMP_Q(r, A, B, -2); - if (r == -2 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) - FP_SET_EXCEPTION(FP_EX_INVALID); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_Q (A, a); + FP_UNPACK_RAW_Q (B, b); + FP_CMP_Q (r, A, B, -2); + if (r == -2) + FP_SET_EXCEPTION (FP_EX_INVALID); FP_HANDLE_EXCEPTIONS; return r; } -strong_alias(__getf2, __gttf2); +strong_alias (__getf2, __gttf2); diff --git a/libgcc/soft-fp/ledf2.c b/libgcc/soft-fp/ledf2.c index 7b8f403bb80..476f1c47015 100644 --- a/libgcc/soft-fp/ledf2.c +++ b/libgcc/soft-fp/ledf2.c @@ -31,20 +31,23 @@ #include "soft-fp.h" #include "double.h" -CMPtype __ledf2(DFtype a, DFtype b) +CMPtype +__ledf2 (DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); + FP_DECL_D (A); + FP_DECL_D (B); CMPtype r; - FP_UNPACK_RAW_D(A, a); - FP_UNPACK_RAW_D(B, b); - FP_CMP_D(r, A, B, 2); - if (r == 2 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B))) - FP_SET_EXCEPTION(FP_EX_INVALID); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_D (A, a); + FP_UNPACK_RAW_D (B, b); + FP_CMP_D (r, A, B, 2); + if (r == 2) + FP_SET_EXCEPTION (FP_EX_INVALID); FP_HANDLE_EXCEPTIONS; return r; } -strong_alias(__ledf2, __ltdf2); +strong_alias (__ledf2, __ltdf2); diff --git a/libgcc/soft-fp/lesf2.c b/libgcc/soft-fp/lesf2.c index 41f823b5fc2..ac2f748a36c 100644 --- a/libgcc/soft-fp/lesf2.c +++ b/libgcc/soft-fp/lesf2.c @@ -31,20 +31,23 @@ #include "soft-fp.h" #include "single.h" -CMPtype __lesf2(SFtype a, SFtype b) +CMPtype +__lesf2 (SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); + FP_DECL_S (A); + FP_DECL_S (B); CMPtype r; - FP_UNPACK_RAW_S(A, a); - FP_UNPACK_RAW_S(B, b); - FP_CMP_S(r, A, B, 2); - if (r == 2 && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B))) - FP_SET_EXCEPTION(FP_EX_INVALID); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_S (A, a); + FP_UNPACK_RAW_S (B, b); + FP_CMP_S (r, A, B, 2); + if (r == 2) + FP_SET_EXCEPTION (FP_EX_INVALID); FP_HANDLE_EXCEPTIONS; return r; } -strong_alias(__lesf2, __ltsf2); +strong_alias (__lesf2, __ltsf2); diff --git a/libgcc/soft-fp/letf2.c b/libgcc/soft-fp/letf2.c index 59342ca4cb9..a41055b9494 100644 --- a/libgcc/soft-fp/letf2.c +++ b/libgcc/soft-fp/letf2.c @@ -31,20 +31,23 @@ #include "soft-fp.h" #include "quad.h" -CMPtype __letf2(TFtype a, TFtype b) +CMPtype +__letf2 (TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); + FP_DECL_Q (A); + FP_DECL_Q (B); CMPtype r; - FP_UNPACK_RAW_Q(A, a); - FP_UNPACK_RAW_Q(B, b); - FP_CMP_Q(r, A, B, 2); - if (r == 2 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))) - FP_SET_EXCEPTION(FP_EX_INVALID); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_Q (A, a); + FP_UNPACK_RAW_Q (B, b); + FP_CMP_Q (r, A, B, 2); + if (r == 2) + FP_SET_EXCEPTION (FP_EX_INVALID); FP_HANDLE_EXCEPTIONS; return r; } -strong_alias(__letf2, __lttf2); +strong_alias (__letf2, __lttf2); diff --git a/libgcc/soft-fp/muldf3.c b/libgcc/soft-fp/muldf3.c index 8c08281b46f..dee3f76e5b9 100644 --- a/libgcc/soft-fp/muldf3.c +++ b/libgcc/soft-fp/muldf3.c @@ -31,17 +31,20 @@ #include "soft-fp.h" #include "double.h" -DFtype __muldf3(DFtype a, DFtype b) +DFtype +__muldf3 (DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); + FP_DECL_D (A); + FP_DECL_D (B); + FP_DECL_D (R); DFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_D(A, a); - FP_UNPACK_D(B, b); - FP_MUL_D(R, A, B); - FP_PACK_D(r, R); + FP_UNPACK_D (A, a); + FP_UNPACK_D (B, b); + FP_MUL_D (R, A, B); + FP_PACK_D (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/mulsf3.c b/libgcc/soft-fp/mulsf3.c index f0341a56c5f..f983b303479 100644 --- a/libgcc/soft-fp/mulsf3.c +++ b/libgcc/soft-fp/mulsf3.c @@ -31,17 +31,20 @@ #include "soft-fp.h" #include "single.h" -SFtype __mulsf3(SFtype a, SFtype b) +SFtype +__mulsf3 (SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R); + FP_DECL_S (A); + FP_DECL_S (B); + FP_DECL_S (R); SFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_S(A, a); - FP_UNPACK_S(B, b); - FP_MUL_S(R, A, B); - FP_PACK_S(r, R); + FP_UNPACK_S (A, a); + FP_UNPACK_S (B, b); + FP_MUL_S (R, A, B); + FP_PACK_S (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/multf3.c b/libgcc/soft-fp/multf3.c index 35badf2fc8d..1306c63f8ad 100644 --- a/libgcc/soft-fp/multf3.c +++ b/libgcc/soft-fp/multf3.c @@ -31,17 +31,20 @@ #include "soft-fp.h" #include "quad.h" -TFtype __multf3(TFtype a, TFtype b) +TFtype +__multf3 (TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R); + FP_DECL_Q (A); + FP_DECL_Q (B); + FP_DECL_Q (R); TFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_Q(A, a); - FP_UNPACK_Q(B, b); - FP_MUL_Q(R, A, B); - FP_PACK_Q(r, R); + FP_UNPACK_Q (A, a); + FP_UNPACK_Q (B, b); + FP_MUL_Q (R, A, B); + FP_PACK_Q (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/negdf2.c b/libgcc/soft-fp/negdf2.c index 3cc6f5f400b..d74c16c1ede 100644 --- a/libgcc/soft-fp/negdf2.c +++ b/libgcc/soft-fp/negdf2.c @@ -31,17 +31,16 @@ #include "soft-fp.h" #include "double.h" -DFtype __negdf2(DFtype a) +DFtype +__negdf2 (DFtype a) { - FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(R); + FP_DECL_D (A); + FP_DECL_D (R); DFtype r; - FP_UNPACK_D(A, a); - FP_NEG_D(R, A); - FP_PACK_D(r, R); - FP_CLEAR_EXCEPTIONS; - FP_HANDLE_EXCEPTIONS; + FP_UNPACK_RAW_D (A, a); + FP_NEG_D (R, A); + FP_PACK_RAW_D (r, R); return r; } diff --git a/libgcc/soft-fp/negsf2.c b/libgcc/soft-fp/negsf2.c index d8d59106036..0316105a5dc 100644 --- a/libgcc/soft-fp/negsf2.c +++ b/libgcc/soft-fp/negsf2.c @@ -31,17 +31,16 @@ #include "soft-fp.h" #include "single.h" -SFtype __negsf2(SFtype a) +SFtype +__negsf2 (SFtype a) { - FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(R); + FP_DECL_S (A); + FP_DECL_S (R); SFtype r; - FP_UNPACK_S(A, a); - FP_NEG_S(R, A); - FP_PACK_S(r, R); - FP_CLEAR_EXCEPTIONS; - FP_HANDLE_EXCEPTIONS; + FP_UNPACK_RAW_S (A, a); + FP_NEG_S (R, A); + FP_PACK_RAW_S (r, R); return r; } diff --git a/libgcc/soft-fp/negtf2.c b/libgcc/soft-fp/negtf2.c index 1c08441487b..8540af24d27 100644 --- a/libgcc/soft-fp/negtf2.c +++ b/libgcc/soft-fp/negtf2.c @@ -31,17 +31,16 @@ #include "soft-fp.h" #include "quad.h" -TFtype __negtf2(TFtype a) +TFtype +__negtf2 (TFtype a) { - FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(R); + FP_DECL_Q (A); + FP_DECL_Q (R); TFtype r; - FP_UNPACK_Q(A, a); - FP_NEG_Q(R, A); - FP_PACK_Q(r, R); - FP_CLEAR_EXCEPTIONS; - FP_HANDLE_EXCEPTIONS; + FP_UNPACK_RAW_Q (A, a); + FP_NEG_Q (R, A); + FP_PACK_RAW_Q (r, R); return r; } diff --git a/libgcc/soft-fp/op-1.h b/libgcc/soft-fp/op-1.h index 8e05e2fab7e..8ccb46a7962 100644 --- a/libgcc/soft-fp/op-1.h +++ b/libgcc/soft-fp/op-1.h @@ -31,103 +31,117 @@ <http://www.gnu.org/licenses/>. */ #define _FP_FRAC_DECL_1(X) _FP_W_TYPE X##_f -#define _FP_FRAC_COPY_1(D,S) (D##_f = S##_f) -#define _FP_FRAC_SET_1(X,I) (X##_f = I) +#define _FP_FRAC_COPY_1(D, S) (D##_f = S##_f) +#define _FP_FRAC_SET_1(X, I) (X##_f = I) #define _FP_FRAC_HIGH_1(X) (X##_f) #define _FP_FRAC_LOW_1(X) (X##_f) -#define _FP_FRAC_WORD_1(X,w) (X##_f) - -#define _FP_FRAC_ADDI_1(X,I) (X##_f += I) -#define _FP_FRAC_SLL_1(X,N) \ - do { \ - if (__builtin_constant_p(N) && (N) == 1) \ - X##_f += X##_f; \ - else \ - X##_f <<= (N); \ - } while (0) -#define _FP_FRAC_SRL_1(X,N) (X##_f >>= N) +#define _FP_FRAC_WORD_1(X, w) (X##_f) + +#define _FP_FRAC_ADDI_1(X, I) (X##_f += I) +#define _FP_FRAC_SLL_1(X, N) \ + do \ + { \ + if (__builtin_constant_p (N) && (N) == 1) \ + X##_f += X##_f; \ + else \ + X##_f <<= (N); \ + } \ + while (0) +#define _FP_FRAC_SRL_1(X, N) (X##_f >>= N) /* Right shift with sticky-lsb. */ -#define _FP_FRAC_SRST_1(X,S,N,sz) __FP_FRAC_SRST_1(X##_f, S, N, sz) -#define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz) - -#define __FP_FRAC_SRST_1(X,S,N,sz) \ -do { \ - S = (__builtin_constant_p(N) && (N) == 1 \ - ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0); \ - X = X >> (N); \ -} while (0) - -#define __FP_FRAC_SRS_1(X,N,sz) \ - (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1 \ - ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0))) - -#define _FP_FRAC_ADD_1(R,X,Y) (R##_f = X##_f + Y##_f) -#define _FP_FRAC_SUB_1(R,X,Y) (R##_f = X##_f - Y##_f) -#define _FP_FRAC_DEC_1(X,Y) (X##_f -= Y##_f) -#define _FP_FRAC_CLZ_1(z, X) __FP_CLZ(z, X##_f) +#define _FP_FRAC_SRST_1(X, S, N, sz) __FP_FRAC_SRST_1 (X##_f, S, N, sz) +#define _FP_FRAC_SRS_1(X, N, sz) __FP_FRAC_SRS_1 (X##_f, N, sz) + +#define __FP_FRAC_SRST_1(X, S, N, sz) \ + do \ + { \ + S = (__builtin_constant_p (N) && (N) == 1 \ + ? X & 1 \ + : (X << (_FP_W_TYPE_SIZE - (N))) != 0); \ + X = X >> (N); \ + } \ + while (0) + +#define __FP_FRAC_SRS_1(X, N, sz) \ + (X = (X >> (N) | (__builtin_constant_p (N) && (N) == 1 \ + ? X & 1 \ + : (X << (_FP_W_TYPE_SIZE - (N))) != 0))) + +#define _FP_FRAC_ADD_1(R, X, Y) (R##_f = X##_f + Y##_f) +#define _FP_FRAC_SUB_1(R, X, Y) (R##_f = X##_f - Y##_f) +#define _FP_FRAC_DEC_1(X, Y) (X##_f -= Y##_f) +#define _FP_FRAC_CLZ_1(z, X) __FP_CLZ (z, X##_f) /* Predicates */ -#define _FP_FRAC_NEGP_1(X) ((_FP_WS_TYPE)X##_f < 0) +#define _FP_FRAC_NEGP_1(X) ((_FP_WS_TYPE) X##_f < 0) #define _FP_FRAC_ZEROP_1(X) (X##_f == 0) -#define _FP_FRAC_OVERP_1(fs,X) (X##_f & _FP_OVERFLOW_##fs) -#define _FP_FRAC_CLEAR_OVERP_1(fs,X) (X##_f &= ~_FP_OVERFLOW_##fs) +#define _FP_FRAC_OVERP_1(fs, X) (X##_f & _FP_OVERFLOW_##fs) +#define _FP_FRAC_CLEAR_OVERP_1(fs, X) (X##_f &= ~_FP_OVERFLOW_##fs) +#define _FP_FRAC_HIGHBIT_DW_1(fs, X) (X##_f & _FP_HIGHBIT_DW_##fs) #define _FP_FRAC_EQ_1(X, Y) (X##_f == Y##_f) #define _FP_FRAC_GE_1(X, Y) (X##_f >= Y##_f) #define _FP_FRAC_GT_1(X, Y) (X##_f > Y##_f) #define _FP_ZEROFRAC_1 0 #define _FP_MINFRAC_1 1 -#define _FP_MAXFRAC_1 (~(_FP_WS_TYPE)0) +#define _FP_MAXFRAC_1 (~(_FP_WS_TYPE) 0) /* * Unpack the raw bits of a native fp value. Do not classify or * normalize the data. */ -#define _FP_UNPACK_RAW_1(fs, X, val) \ - do { \ - union _FP_UNION_##fs _flo; _flo.flt = (val); \ - \ - X##_f = _flo.bits.frac; \ - X##_e = _flo.bits.exp; \ - X##_s = _flo.bits.sign; \ - } while (0) - -#define _FP_UNPACK_RAW_1_P(fs, X, val) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)(val); \ - \ - X##_f = _flo->bits.frac; \ - X##_e = _flo->bits.exp; \ - X##_s = _flo->bits.sign; \ - } while (0) +#define _FP_UNPACK_RAW_1(fs, X, val) \ + do \ + { \ + union _FP_UNION_##fs _flo; \ + _flo.flt = (val); \ + \ + X##_f = _flo.bits.frac; \ + X##_e = _flo.bits.exp; \ + X##_s = _flo.bits.sign; \ + } \ + while (0) + +#define _FP_UNPACK_RAW_1_P(fs, X, val) \ + do \ + { \ + union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *) (val); \ + \ + X##_f = _flo->bits.frac; \ + X##_e = _flo->bits.exp; \ + X##_s = _flo->bits.sign; \ + } \ + while (0) /* * Repack the raw bits of a native fp value. */ -#define _FP_PACK_RAW_1(fs, val, X) \ - do { \ - union _FP_UNION_##fs _flo; \ - \ - _flo.bits.frac = X##_f; \ - _flo.bits.exp = X##_e; \ - _flo.bits.sign = X##_s; \ - \ - (val) = _flo.flt; \ - } while (0) - -#define _FP_PACK_RAW_1_P(fs, val, X) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)(val); \ - \ - _flo->bits.frac = X##_f; \ - _flo->bits.exp = X##_e; \ - _flo->bits.sign = X##_s; \ - } while (0) +#define _FP_PACK_RAW_1(fs, val, X) \ + do \ + { \ + union _FP_UNION_##fs _flo; \ + \ + _flo.bits.frac = X##_f; \ + _flo.bits.exp = X##_e; \ + _flo.bits.sign = X##_s; \ + \ + (val) = _flo.flt; \ + } \ + while (0) + +#define _FP_PACK_RAW_1_P(fs, val, X) \ + do \ + { \ + union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *) (val); \ + \ + _flo->bits.frac = X##_f; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ + } \ + while (0) /* @@ -137,57 +151,86 @@ do { \ /* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the multiplication immediately. */ +#define _FP_MUL_MEAT_DW_1_imm(wfracbits, R, X, Y) \ + do \ + { \ + R##_f = X##_f * Y##_f; \ + } \ + while (0) + #define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y) \ - do { \ - R##_f = X##_f * Y##_f; \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_1(R, wfracbits-1, 2*wfracbits); \ - } while (0) + do \ + { \ + _FP_MUL_MEAT_DW_1_imm (wfracbits, R, X, Y); \ + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_1 (R, wfracbits-1, 2*wfracbits); \ + } \ + while (0) /* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ +#define _FP_MUL_MEAT_DW_1_wide(wfracbits, R, X, Y, doit) \ + do \ + { \ + doit (R##_f1, R##_f0, X##_f, Y##_f); \ + } \ + while (0) + #define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit) \ - do { \ - _FP_W_TYPE _Z_f0, _Z_f1; \ - doit(_Z_f1, _Z_f0, X##_f, Y##_f); \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_2(_Z, wfracbits-1, 2*wfracbits); \ - R##_f = _Z_f0; \ - } while (0) + do \ + { \ + _FP_FRAC_DECL_2 (_Z); \ + _FP_MUL_MEAT_DW_1_wide (wfracbits, _Z, X, Y, doit); \ + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_2 (_Z, wfracbits-1, 2*wfracbits); \ + R##_f = _Z_f0; \ + } \ + while (0) /* Finally, a simple widening multiply algorithm. What fun! */ -#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y) \ - do { \ - _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1; \ - \ - /* split the words in half */ \ - _xh = X##_f >> (_FP_W_TYPE_SIZE/2); \ - _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ - _yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \ - _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \ +#define _FP_MUL_MEAT_DW_1_hard(wfracbits, R, X, Y) \ + do \ + { \ + _FP_W_TYPE _xh, _xl, _yh, _yl; \ + _FP_FRAC_DECL_2 (_a); \ \ - /* multiply the pieces */ \ - _z_f0 = _xl * _yl; \ - _a_f0 = _xh * _yl; \ - _a_f1 = _xl * _yh; \ - _z_f1 = _xh * _yh; \ + /* split the words in half */ \ + _xh = X##_f >> (_FP_W_TYPE_SIZE/2); \ + _xl = X##_f & (((_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2)) - 1); \ + _yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \ + _yl = Y##_f & (((_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2)) - 1); \ \ - /* reassemble into two full words */ \ - if ((_a_f0 += _a_f1) < _a_f1) \ - _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2); \ - _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \ - _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \ - _FP_FRAC_ADD_2(_z, _z, _a); \ + /* multiply the pieces */ \ + R##_f0 = _xl * _yl; \ + _a_f0 = _xh * _yl; \ + _a_f1 = _xl * _yh; \ + R##_f1 = _xh * _yh; \ \ - /* normalize */ \ - _FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits); \ - R##_f = _z_f0; \ - } while (0) + /* reassemble into two full words */ \ + if ((_a_f0 += _a_f1) < _a_f1) \ + R##_f1 += (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2); \ + _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \ + _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \ + _FP_FRAC_ADD_2 (R, R, _a); \ + } \ + while (0) + +#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y) \ + do \ + { \ + _FP_FRAC_DECL_2 (_z); \ + _FP_MUL_MEAT_DW_1_hard (wfracbits, _z, X, Y); \ + \ + /* normalize */ \ + _FP_FRAC_SRS_2 (_z, wfracbits - 1, 2*wfracbits); \ + R##_f = _z_f0; \ + } \ + while (0) /* @@ -199,15 +242,17 @@ do { \ C primitives or _FP_DIV_HELP_ldiv for the ISO function. Which you choose will depend on what the compiler does with divrem4. */ -#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \ - do { \ - _FP_W_TYPE _q, _r; \ - X##_f <<= (X##_f < Y##_f \ - ? R##_e--, _FP_WFRACBITS_##fs \ - : _FP_WFRACBITS_##fs - 1); \ - doit(_q, _r, X##_f, Y##_f); \ - R##_f = _q | (_r != 0); \ - } while (0) +#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \ + do \ + { \ + _FP_W_TYPE _q, _r; \ + X##_f <<= (X##_f < Y##_f \ + ? R##_e--, _FP_WFRACBITS_##fs \ + : _FP_WFRACBITS_##fs - 1); \ + doit (_q, _r, X##_f, Y##_f); \ + R##_f = _q | (_r != 0); \ + } \ + while (0) /* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd that may be useful in this situation. This first is for a primitive @@ -215,46 +260,50 @@ do { \ for UDIV_NEEDS_NORMALIZATION to tell which your machine needs. */ #define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \ - do { \ - _FP_W_TYPE _nh, _nl, _q, _r, _y; \ + do \ + { \ + _FP_W_TYPE _nh, _nl, _q, _r, _y; \ \ - /* Normalize Y -- i.e. make the most significant bit set. */ \ - _y = Y##_f << _FP_WFRACXBITS_##fs; \ + /* Normalize Y -- i.e. make the most significant bit set. */ \ + _y = Y##_f << _FP_WFRACXBITS_##fs; \ \ - /* Shift X op correspondingly high, that is, up one full word. */ \ - if (X##_f < Y##_f) \ - { \ - R##_e--; \ - _nl = 0; \ - _nh = X##_f; \ - } \ - else \ - { \ - _nl = X##_f << (_FP_W_TYPE_SIZE - 1); \ - _nh = X##_f >> 1; \ - } \ + /* Shift X op correspondingly high, that is, up one full word. */ \ + if (X##_f < Y##_f) \ + { \ + R##_e--; \ + _nl = 0; \ + _nh = X##_f; \ + } \ + else \ + { \ + _nl = X##_f << (_FP_W_TYPE_SIZE - 1); \ + _nh = X##_f >> 1; \ + } \ \ - udiv_qrnnd(_q, _r, _nh, _nl, _y); \ - R##_f = _q | (_r != 0); \ - } while (0) + udiv_qrnnd (_q, _r, _nh, _nl, _y); \ + R##_f = _q | (_r != 0); \ + } \ + while (0) #define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \ - do { \ - _FP_W_TYPE _nh, _nl, _q, _r; \ - if (X##_f < Y##_f) \ - { \ - R##_e--; \ - _nl = X##_f << _FP_WFRACBITS_##fs; \ - _nh = X##_f >> _FP_WFRACXBITS_##fs; \ - } \ - else \ - { \ - _nl = X##_f << (_FP_WFRACBITS_##fs - 1); \ - _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \ - } \ - udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \ - R##_f = _q | (_r != 0); \ - } while (0) + do \ + { \ + _FP_W_TYPE _nh, _nl, _q, _r; \ + if (X##_f < Y##_f) \ + { \ + R##_e--; \ + _nl = X##_f << _FP_WFRACBITS_##fs; \ + _nh = X##_f >> _FP_WFRACXBITS_##fs; \ + } \ + else \ + { \ + _nl = X##_f << (_FP_WFRACBITS_##fs - 1); \ + _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \ + } \ + udiv_qrnnd (_q, _r, _nh, _nl, Y##_f); \ + R##_f = _q | (_r != 0); \ + } \ + while (0) /* @@ -263,27 +312,29 @@ do { \ * should be added for those machines where division is fast. */ -#define _FP_SQRT_MEAT_1(R, S, T, X, q) \ - do { \ - while (q != _FP_WORK_ROUND) \ - { \ - T##_f = S##_f + q; \ - if (T##_f <= X##_f) \ - { \ - S##_f = T##_f + q; \ - X##_f -= T##_f; \ - R##_f += q; \ - } \ - _FP_FRAC_SLL_1(X, 1); \ - q >>= 1; \ - } \ - if (X##_f) \ - { \ - if (S##_f < X##_f) \ - R##_f |= _FP_WORK_ROUND; \ - R##_f |= _FP_WORK_STICKY; \ - } \ - } while (0) +#define _FP_SQRT_MEAT_1(R, S, T, X, q) \ + do \ + { \ + while (q != _FP_WORK_ROUND) \ + { \ + T##_f = S##_f + q; \ + if (T##_f <= X##_f) \ + { \ + S##_f = T##_f + q; \ + X##_f -= T##_f; \ + R##_f += q; \ + } \ + _FP_FRAC_SLL_1 (X, 1); \ + q >>= 1; \ + } \ + if (X##_f) \ + { \ + if (S##_f < X##_f) \ + R##_f |= _FP_WORK_ROUND; \ + R##_f |= _FP_WORK_STICKY; \ + } \ + } \ + while (0) /* * Assembly/disassembly for converting to/from integral types. diff --git a/libgcc/soft-fp/op-2.h b/libgcc/soft-fp/op-2.h index 48e01d26dc4..5ef4217de12 100644 --- a/libgcc/soft-fp/op-2.h +++ b/libgcc/soft-fp/op-2.h @@ -31,109 +31,113 @@ <http://www.gnu.org/licenses/>. */ #define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0, X##_f1 -#define _FP_FRAC_COPY_2(D,S) (D##_f0 = S##_f0, D##_f1 = S##_f1) -#define _FP_FRAC_SET_2(X,I) __FP_FRAC_SET_2(X, I) +#define _FP_FRAC_COPY_2(D, S) (D##_f0 = S##_f0, D##_f1 = S##_f1) +#define _FP_FRAC_SET_2(X, I) __FP_FRAC_SET_2 (X, I) #define _FP_FRAC_HIGH_2(X) (X##_f1) #define _FP_FRAC_LOW_2(X) (X##_f0) -#define _FP_FRAC_WORD_2(X,w) (X##_f##w) - -#define _FP_FRAC_SLL_2(X,N) \ -(void)(((N) < _FP_W_TYPE_SIZE) \ - ? ({ \ - if (__builtin_constant_p(N) && (N) == 1) \ - { \ - X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \ - X##_f0 += X##_f0; \ - } \ - else \ - { \ - X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \ - X##_f0 <<= (N); \ - } \ - 0; \ - }) \ - : ({ \ - X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \ - X##_f0 = 0; \ - })) - - -#define _FP_FRAC_SRL_2(X,N) \ -(void)(((N) < _FP_W_TYPE_SIZE) \ - ? ({ \ - X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \ - X##_f1 >>= (N); \ - }) \ - : ({ \ - X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \ - X##_f1 = 0; \ - })) +#define _FP_FRAC_WORD_2(X, w) (X##_f##w) + +#define _FP_FRAC_SLL_2(X, N) \ + (void) (((N) < _FP_W_TYPE_SIZE) \ + ? ({ \ + if (__builtin_constant_p (N) && (N) == 1) \ + { \ + X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE) (X##_f0)) < 0); \ + X##_f0 += X##_f0; \ + } \ + else \ + { \ + X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \ + X##_f0 <<= (N); \ + } \ + 0; \ + }) \ + : ({ \ + X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \ + X##_f0 = 0; \ + })) + + +#define _FP_FRAC_SRL_2(X, N) \ + (void) (((N) < _FP_W_TYPE_SIZE) \ + ? ({ \ + X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \ + X##_f1 >>= (N); \ + }) \ + : ({ \ + X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \ + X##_f1 = 0; \ + })) /* Right shift with sticky-lsb. */ -#define _FP_FRAC_SRST_2(X,S, N,sz) \ -(void)(((N) < _FP_W_TYPE_SIZE) \ - ? ({ \ - S = (__builtin_constant_p(N) && (N) == 1 \ - ? X##_f0 & 1 \ - : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0); \ - X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N)); \ - X##_f1 >>= (N); \ - }) \ - : ({ \ - S = ((((N) == _FP_W_TYPE_SIZE \ - ? 0 \ - : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ - | X##_f0) != 0); \ - X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE)); \ - X##_f1 = 0; \ - })) - -#define _FP_FRAC_SRS_2(X,N,sz) \ -(void)(((N) < _FP_W_TYPE_SIZE) \ - ? ({ \ - X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \ - (__builtin_constant_p(N) && (N) == 1 \ - ? X##_f0 & 1 \ - : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \ - X##_f1 >>= (N); \ - }) \ - : ({ \ - X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \ - ((((N) == _FP_W_TYPE_SIZE \ - ? 0 \ - : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ - | X##_f0) != 0)); \ - X##_f1 = 0; \ - })) - -#define _FP_FRAC_ADDI_2(X,I) \ - __FP_FRAC_ADDI_2(X##_f1, X##_f0, I) - -#define _FP_FRAC_ADD_2(R,X,Y) \ - __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) - -#define _FP_FRAC_SUB_2(R,X,Y) \ - __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) - -#define _FP_FRAC_DEC_2(X,Y) \ - __FP_FRAC_DEC_2(X##_f1, X##_f0, Y##_f1, Y##_f0) - -#define _FP_FRAC_CLZ_2(R,X) \ - do { \ - if (X##_f1) \ - __FP_CLZ(R,X##_f1); \ - else \ - { \ - __FP_CLZ(R,X##_f0); \ - R += _FP_W_TYPE_SIZE; \ - } \ - } while(0) +#define _FP_FRAC_SRST_2(X, S, N, sz) \ + (void) (((N) < _FP_W_TYPE_SIZE) \ + ? ({ \ + S = (__builtin_constant_p (N) && (N) == 1 \ + ? X##_f0 & 1 \ + : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0); \ + X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N)); \ + X##_f1 >>= (N); \ + }) \ + : ({ \ + S = ((((N) == _FP_W_TYPE_SIZE \ + ? 0 \ + : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ + | X##_f0) != 0); \ + X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE)); \ + X##_f1 = 0; \ + })) + +#define _FP_FRAC_SRS_2(X, N, sz) \ + (void) (((N) < _FP_W_TYPE_SIZE) \ + ? ({ \ + X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) \ + | (__builtin_constant_p (N) && (N) == 1 \ + ? X##_f0 & 1 \ + : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \ + X##_f1 >>= (N); \ + }) \ + : ({ \ + X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) \ + | ((((N) == _FP_W_TYPE_SIZE \ + ? 0 \ + : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N)))) \ + | X##_f0) != 0)); \ + X##_f1 = 0; \ + })) + +#define _FP_FRAC_ADDI_2(X, I) \ + __FP_FRAC_ADDI_2 (X##_f1, X##_f0, I) + +#define _FP_FRAC_ADD_2(R, X, Y) \ + __FP_FRAC_ADD_2 (R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) + +#define _FP_FRAC_SUB_2(R, X, Y) \ + __FP_FRAC_SUB_2 (R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0) + +#define _FP_FRAC_DEC_2(X, Y) \ + __FP_FRAC_DEC_2 (X##_f1, X##_f0, Y##_f1, Y##_f0) + +#define _FP_FRAC_CLZ_2(R, X) \ + do \ + { \ + if (X##_f1) \ + __FP_CLZ (R, X##_f1); \ + else \ + { \ + __FP_CLZ (R, X##_f0); \ + R += _FP_W_TYPE_SIZE; \ + } \ + } \ + while (0) /* Predicates */ -#define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE)X##_f1 < 0) +#define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE) X##_f1 < 0) #define _FP_FRAC_ZEROP_2(X) ((X##_f1 | X##_f0) == 0) -#define _FP_FRAC_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs) -#define _FP_FRAC_CLEAR_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs) +#define _FP_FRAC_OVERP_2(fs, X) (_FP_FRAC_HIGH_##fs (X) & _FP_OVERFLOW_##fs) +#define _FP_FRAC_CLEAR_OVERP_2(fs, X) (_FP_FRAC_HIGH_##fs (X) &= ~_FP_OVERFLOW_##fs) +#define _FP_FRAC_HIGHBIT_DW_2(fs, X) \ + (_FP_FRAC_HIGH_DW_##fs (X) & _FP_HIGHBIT_DW_##fs) #define _FP_FRAC_EQ_2(X, Y) (X##_f1 == Y##_f1 && X##_f0 == Y##_f0) #define _FP_FRAC_GT_2(X, Y) \ (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0)) @@ -142,57 +146,62 @@ #define _FP_ZEROFRAC_2 0, 0 #define _FP_MINFRAC_2 0, 1 -#define _FP_MAXFRAC_2 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0) +#define _FP_MAXFRAC_2 (~(_FP_WS_TYPE) 0), (~(_FP_WS_TYPE) 0) /* * Internals */ -#define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1) - -#define __FP_CLZ_2(R, xh, xl) \ - do { \ - if (xh) \ - __FP_CLZ(R,xh); \ - else \ - { \ - __FP_CLZ(R,xl); \ - R += _FP_W_TYPE_SIZE; \ - } \ - } while(0) +#define __FP_FRAC_SET_2(X, I1, I0) (X##_f0 = I0, X##_f1 = I1) + +#define __FP_CLZ_2(R, xh, xl) \ + do \ + { \ + if (xh) \ + __FP_CLZ (R, xh); \ + else \ + { \ + __FP_CLZ (R, xl); \ + R += _FP_W_TYPE_SIZE; \ + } \ + } \ + while (0) #if 0 -#ifndef __FP_FRAC_ADDI_2 -#define __FP_FRAC_ADDI_2(xh, xl, i) \ +# ifndef __FP_FRAC_ADDI_2 +# define __FP_FRAC_ADDI_2(xh, xl, i) \ (xh += ((xl += i) < i)) -#endif -#ifndef __FP_FRAC_ADD_2 -#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \ +# endif +# ifndef __FP_FRAC_ADD_2 +# define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \ (rh = xh + yh + ((rl = xl + yl) < xl)) -#endif -#ifndef __FP_FRAC_SUB_2 -#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \ +# endif +# ifndef __FP_FRAC_SUB_2 +# define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \ (rh = xh - yh - ((rl = xl - yl) > xl)) -#endif -#ifndef __FP_FRAC_DEC_2 -#define __FP_FRAC_DEC_2(xh, xl, yh, yl) \ - do { \ - UWtype _t = xl; \ - xh -= yh + ((xl -= yl) > _t); \ - } while (0) -#endif +# endif +# ifndef __FP_FRAC_DEC_2 +# define __FP_FRAC_DEC_2(xh, xl, yh, yl) \ + do \ + { \ + UWtype _t = xl; \ + xh -= yh + ((xl -= yl) > _t); \ + } \ + while (0) +# endif #else -#undef __FP_FRAC_ADDI_2 -#define __FP_FRAC_ADDI_2(xh, xl, i) add_ssaaaa(xh, xl, xh, xl, 0, i) -#undef __FP_FRAC_ADD_2 -#define __FP_FRAC_ADD_2 add_ssaaaa -#undef __FP_FRAC_SUB_2 -#define __FP_FRAC_SUB_2 sub_ddmmss -#undef __FP_FRAC_DEC_2 -#define __FP_FRAC_DEC_2(xh, xl, yh, yl) sub_ddmmss(xh, xl, xh, xl, yh, yl) +# undef __FP_FRAC_ADDI_2 +# define __FP_FRAC_ADDI_2(xh, xl, i) add_ssaaaa (xh, xl, xh, xl, 0, i) +# undef __FP_FRAC_ADD_2 +# define __FP_FRAC_ADD_2 add_ssaaaa +# undef __FP_FRAC_SUB_2 +# define __FP_FRAC_SUB_2 sub_ddmmss +# undef __FP_FRAC_DEC_2 +# define __FP_FRAC_DEC_2(xh, xl, yh, yl) \ + sub_ddmmss (xh, xl, xh, xl, yh, yl) #endif @@ -201,54 +210,61 @@ * normalize the data. */ -#define _FP_UNPACK_RAW_2(fs, X, val) \ - do { \ - union _FP_UNION_##fs _flo; _flo.flt = (val); \ - \ - X##_f0 = _flo.bits.frac0; \ - X##_f1 = _flo.bits.frac1; \ - X##_e = _flo.bits.exp; \ - X##_s = _flo.bits.sign; \ - } while (0) - -#define _FP_UNPACK_RAW_2_P(fs, X, val) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)(val); \ - \ - X##_f0 = _flo->bits.frac0; \ - X##_f1 = _flo->bits.frac1; \ - X##_e = _flo->bits.exp; \ - X##_s = _flo->bits.sign; \ - } while (0) +#define _FP_UNPACK_RAW_2(fs, X, val) \ + do \ + { \ + union _FP_UNION_##fs _flo; \ + _flo.flt = (val); \ + \ + X##_f0 = _flo.bits.frac0; \ + X##_f1 = _flo.bits.frac1; \ + X##_e = _flo.bits.exp; \ + X##_s = _flo.bits.sign; \ + } \ + while (0) + +#define _FP_UNPACK_RAW_2_P(fs, X, val) \ + do \ + { \ + union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *) (val); \ + \ + X##_f0 = _flo->bits.frac0; \ + X##_f1 = _flo->bits.frac1; \ + X##_e = _flo->bits.exp; \ + X##_s = _flo->bits.sign; \ + } \ + while (0) /* * Repack the raw bits of a native fp value. */ -#define _FP_PACK_RAW_2(fs, val, X) \ - do { \ - union _FP_UNION_##fs _flo; \ - \ - _flo.bits.frac0 = X##_f0; \ - _flo.bits.frac1 = X##_f1; \ - _flo.bits.exp = X##_e; \ - _flo.bits.sign = X##_s; \ - \ - (val) = _flo.flt; \ - } while (0) - -#define _FP_PACK_RAW_2_P(fs, val, X) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)(val); \ - \ - _flo->bits.frac0 = X##_f0; \ - _flo->bits.frac1 = X##_f1; \ - _flo->bits.exp = X##_e; \ - _flo->bits.sign = X##_s; \ - } while (0) +#define _FP_PACK_RAW_2(fs, val, X) \ + do \ + { \ + union _FP_UNION_##fs _flo; \ + \ + _flo.bits.frac0 = X##_f0; \ + _flo.bits.frac1 = X##_f1; \ + _flo.bits.exp = X##_e; \ + _flo.bits.sign = X##_s; \ + \ + (val) = _flo.flt; \ + } \ + while (0) + +#define _FP_PACK_RAW_2_P(fs, val, X) \ + do \ + { \ + union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *) (val); \ + \ + _flo->bits.frac0 = X##_f0; \ + _flo->bits.frac1 = X##_f1; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ + } \ + while (0) /* @@ -257,92 +273,128 @@ /* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ -#define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit) \ - do { \ - _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ +#define _FP_MUL_MEAT_DW_2_wide(wfracbits, R, X, Y, doit) \ + do \ + { \ + _FP_FRAC_DECL_2 (_b); \ + _FP_FRAC_DECL_2 (_c); \ + \ + doit (_FP_FRAC_WORD_4 (R, 1), _FP_FRAC_WORD_4 (R, 0), X##_f0, Y##_f0); \ + doit (_b_f1, _b_f0, X##_f0, Y##_f1); \ + doit (_c_f1, _c_f0, X##_f1, Y##_f0); \ + doit (_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), X##_f1, Y##_f1); \ \ - doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \ - doit(_b_f1, _b_f0, X##_f0, Y##_f1); \ - doit(_c_f1, _c_f0, X##_f1, Y##_f0); \ - doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), \ + _FP_FRAC_WORD_4 (R, 1), 0, _b_f1, _b_f0, \ + _FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), \ + _FP_FRAC_WORD_4 (R, 1)); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), \ + _FP_FRAC_WORD_4 (R, 1), 0, _c_f1, _c_f0, \ + _FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), \ + _FP_FRAC_WORD_4 (R, 1)); \ + } \ + while (0) + +#define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit) \ + do \ + { \ + _FP_FRAC_DECL_4 (_z); \ \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ - _FP_FRAC_WORD_4(_z,1), 0, _b_f1, _b_f0, \ - _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ - _FP_FRAC_WORD_4(_z,1)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ - _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0, \ - _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ - _FP_FRAC_WORD_4(_z,1)); \ + _FP_MUL_MEAT_DW_2_wide (wfracbits, _z, X, Y, doit); \ \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ - R##_f0 = _FP_FRAC_WORD_4(_z,0); \ - R##_f1 = _FP_FRAC_WORD_4(_z,1); \ - } while (0) + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_4 (_z, wfracbits-1, 2*wfracbits); \ + R##_f0 = _FP_FRAC_WORD_4 (_z, 0); \ + R##_f1 = _FP_FRAC_WORD_4 (_z, 1); \ + } \ + while (0) /* Given a 1W * 1W => 2W primitive, do the extended multiplication. Do only 3 multiplications instead of four. This one is for machines where multiplication is much more expensive than subtraction. */ -#define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit) \ - do { \ - _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ - _FP_W_TYPE _d; \ - int _c1, _c2; \ +#define _FP_MUL_MEAT_DW_2_wide_3mul(wfracbits, R, X, Y, doit) \ + do \ + { \ + _FP_FRAC_DECL_2 (_b); \ + _FP_FRAC_DECL_2 (_c); \ + _FP_W_TYPE _d; \ + int _c1, _c2; \ \ - _b_f0 = X##_f0 + X##_f1; \ - _c1 = _b_f0 < X##_f0; \ - _b_f1 = Y##_f0 + Y##_f1; \ - _c2 = _b_f1 < Y##_f0; \ - doit(_d, _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \ - doit(_FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1), _b_f0, _b_f1); \ - doit(_c_f1, _c_f0, X##_f1, Y##_f1); \ + _b_f0 = X##_f0 + X##_f1; \ + _c1 = _b_f0 < X##_f0; \ + _b_f1 = Y##_f0 + Y##_f1; \ + _c2 = _b_f1 < Y##_f0; \ + doit (_d, _FP_FRAC_WORD_4 (R, 0), X##_f0, Y##_f0); \ + doit (_FP_FRAC_WORD_4 (R, 2), _FP_FRAC_WORD_4 (R, 1), _b_f0, _b_f1); \ + doit (_c_f1, _c_f0, X##_f1, Y##_f1); \ \ - _b_f0 &= -_c2; \ - _b_f1 &= -_c1; \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ - _FP_FRAC_WORD_4(_z,1), (_c1 & _c2), 0, _d, \ - 0, _FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1)); \ - __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ - _b_f0); \ - __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ - _b_f1); \ - __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ - _FP_FRAC_WORD_4(_z,1), \ - 0, _d, _FP_FRAC_WORD_4(_z,0)); \ - __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \ - _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0); \ - __FP_FRAC_ADD_2(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), \ - _c_f1, _c_f0, \ - _FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2)); \ + _b_f0 &= -_c2; \ + _b_f1 &= -_c1; \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), \ + _FP_FRAC_WORD_4 (R, 1), (_c1 & _c2), 0, _d, \ + 0, _FP_FRAC_WORD_4 (R, 2), _FP_FRAC_WORD_4 (R, 1)); \ + __FP_FRAC_ADDI_2 (_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), \ + _b_f0); \ + __FP_FRAC_ADDI_2 (_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), \ + _b_f1); \ + __FP_FRAC_DEC_3 (_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), \ + _FP_FRAC_WORD_4 (R, 1), \ + 0, _d, _FP_FRAC_WORD_4 (R, 0)); \ + __FP_FRAC_DEC_3 (_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), \ + _FP_FRAC_WORD_4 (R, 1), 0, _c_f1, _c_f0); \ + __FP_FRAC_ADD_2 (_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), \ + _c_f1, _c_f0, \ + _FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2)); \ + } \ + while (0) + +#define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit) \ + do \ + { \ + _FP_FRAC_DECL_4 (_z); \ \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ - R##_f0 = _FP_FRAC_WORD_4(_z,0); \ - R##_f1 = _FP_FRAC_WORD_4(_z,1); \ - } while (0) + _FP_MUL_MEAT_DW_2_wide_3mul (wfracbits, _z, X, Y, doit); \ + \ + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_4 (_z, wfracbits-1, 2*wfracbits); \ + R##_f0 = _FP_FRAC_WORD_4 (_z, 0); \ + R##_f1 = _FP_FRAC_WORD_4 (_z, 1); \ + } \ + while (0) + +#define _FP_MUL_MEAT_DW_2_gmp(wfracbits, R, X, Y) \ + do \ + { \ + _FP_W_TYPE _x[2], _y[2]; \ + _x[0] = X##_f0; \ + _x[1] = X##_f1; \ + _y[0] = Y##_f0; \ + _y[1] = Y##_f1; \ + \ + mpn_mul_n (R##_f, _x, _y, 2); \ + } \ + while (0) #define _FP_MUL_MEAT_2_gmp(wfracbits, R, X, Y) \ - do { \ - _FP_FRAC_DECL_4(_z); \ - _FP_W_TYPE _x[2], _y[2]; \ - _x[0] = X##_f0; _x[1] = X##_f1; \ - _y[0] = Y##_f0; _y[1] = Y##_f1; \ + do \ + { \ + _FP_FRAC_DECL_4 (_z); \ \ - mpn_mul_n(_z_f, _x, _y, 2); \ + _FP_MUL_MEAT_DW_2_gmp (wfracbits, _z, X, Y); \ \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits); \ - R##_f0 = _z_f[0]; \ - R##_f1 = _z_f[1]; \ - } while (0) + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_4 (_z, wfracbits-1, 2*wfracbits); \ + R##_f0 = _z_f[0]; \ + R##_f1 = _z_f[1]; \ + } \ + while (0) /* Do at most 120x120=240 bits multiplication using double floating point multiplication. This is useful if floating point @@ -353,190 +405,173 @@ SETFETZ is a macro which will disable all FPU exceptions and set rounding towards zero, RESETFE should optionally reset it back. */ -#define _FP_MUL_MEAT_2_120_240_double(wfracbits, R, X, Y, setfetz, resetfe) \ - do { \ - static const double _const[] = { \ - /* 2^-24 */ 5.9604644775390625e-08, \ - /* 2^-48 */ 3.5527136788005009e-15, \ - /* 2^-72 */ 2.1175823681357508e-22, \ - /* 2^-96 */ 1.2621774483536189e-29, \ - /* 2^28 */ 2.68435456e+08, \ - /* 2^4 */ 1.600000e+01, \ - /* 2^-20 */ 9.5367431640625e-07, \ - /* 2^-44 */ 5.6843418860808015e-14, \ - /* 2^-68 */ 3.3881317890172014e-21, \ - /* 2^-92 */ 2.0194839173657902e-28, \ - /* 2^-116 */ 1.2037062152420224e-35}; \ - double _a240, _b240, _c240, _d240, _e240, _f240, \ - _g240, _h240, _i240, _j240, _k240; \ - union { double d; UDItype i; } _l240, _m240, _n240, _o240, \ - _p240, _q240, _r240, _s240; \ - UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \ - \ - if (wfracbits < 106 || wfracbits > 120) \ - abort(); \ - \ - setfetz; \ - \ - _e240 = (double)(long)(X##_f0 & 0xffffff); \ - _j240 = (double)(long)(Y##_f0 & 0xffffff); \ - _d240 = (double)(long)((X##_f0 >> 24) & 0xffffff); \ - _i240 = (double)(long)((Y##_f0 >> 24) & 0xffffff); \ - _c240 = (double)(long)(((X##_f1 << 16) & 0xffffff) | (X##_f0 >> 48)); \ - _h240 = (double)(long)(((Y##_f1 << 16) & 0xffffff) | (Y##_f0 >> 48)); \ - _b240 = (double)(long)((X##_f1 >> 8) & 0xffffff); \ - _g240 = (double)(long)((Y##_f1 >> 8) & 0xffffff); \ - _a240 = (double)(long)(X##_f1 >> 32); \ - _f240 = (double)(long)(Y##_f1 >> 32); \ - _e240 *= _const[3]; \ - _j240 *= _const[3]; \ - _d240 *= _const[2]; \ - _i240 *= _const[2]; \ - _c240 *= _const[1]; \ - _h240 *= _const[1]; \ - _b240 *= _const[0]; \ - _g240 *= _const[0]; \ - _s240.d = _e240*_j240;\ - _r240.d = _d240*_j240 + _e240*_i240;\ - _q240.d = _c240*_j240 + _d240*_i240 + _e240*_h240;\ - _p240.d = _b240*_j240 + _c240*_i240 + _d240*_h240 + _e240*_g240;\ - _o240.d = _a240*_j240 + _b240*_i240 + _c240*_h240 + _d240*_g240 + _e240*_f240;\ - _n240.d = _a240*_i240 + _b240*_h240 + _c240*_g240 + _d240*_f240; \ - _m240.d = _a240*_h240 + _b240*_g240 + _c240*_f240; \ - _l240.d = _a240*_g240 + _b240*_f240; \ - _k240 = _a240*_f240; \ - _r240.d += _s240.d; \ - _q240.d += _r240.d; \ - _p240.d += _q240.d; \ - _o240.d += _p240.d; \ - _n240.d += _o240.d; \ - _m240.d += _n240.d; \ - _l240.d += _m240.d; \ - _k240 += _l240.d; \ - _s240.d -= ((_const[10]+_s240.d)-_const[10]); \ - _r240.d -= ((_const[9]+_r240.d)-_const[9]); \ - _q240.d -= ((_const[8]+_q240.d)-_const[8]); \ - _p240.d -= ((_const[7]+_p240.d)-_const[7]); \ - _o240.d += _const[7]; \ - _n240.d += _const[6]; \ - _m240.d += _const[5]; \ - _l240.d += _const[4]; \ - if (_s240.d != 0.0) _y240 = 1; \ - if (_r240.d != 0.0) _y240 = 1; \ - if (_q240.d != 0.0) _y240 = 1; \ - if (_p240.d != 0.0) _y240 = 1; \ - _t240 = (DItype)_k240; \ - _u240 = _l240.i; \ - _v240 = _m240.i; \ - _w240 = _n240.i; \ - _x240 = _o240.i; \ - R##_f1 = (_t240 << (128 - (wfracbits - 1))) \ - | ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104)); \ - R##_f0 = ((_u240 & 0xffffff) << (168 - (wfracbits - 1))) \ - | ((_v240 & 0xffffff) << (144 - (wfracbits - 1))) \ - | ((_w240 & 0xffffff) << (120 - (wfracbits - 1))) \ - | ((_x240 & 0xffffff) >> ((wfracbits - 1) - 96)) \ - | _y240; \ - resetfe; \ - } while (0) +#define _FP_MUL_MEAT_2_120_240_double(wfracbits, R, X, Y, setfetz, resetfe) \ + do \ + { \ + static const double _const[] = \ + { \ + /* 2^-24 */ 5.9604644775390625e-08, \ + /* 2^-48 */ 3.5527136788005009e-15, \ + /* 2^-72 */ 2.1175823681357508e-22, \ + /* 2^-96 */ 1.2621774483536189e-29, \ + /* 2^28 */ 2.68435456e+08, \ + /* 2^4 */ 1.600000e+01, \ + /* 2^-20 */ 9.5367431640625e-07, \ + /* 2^-44 */ 5.6843418860808015e-14, \ + /* 2^-68 */ 3.3881317890172014e-21, \ + /* 2^-92 */ 2.0194839173657902e-28, \ + /* 2^-116 */ 1.2037062152420224e-35 \ + }; \ + double _a240, _b240, _c240, _d240, _e240, _f240, \ + _g240, _h240, _i240, _j240, _k240; \ + union { double d; UDItype i; } _l240, _m240, _n240, _o240, \ + _p240, _q240, _r240, _s240; \ + UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \ + \ + if (wfracbits < 106 || wfracbits > 120) \ + abort (); \ + \ + setfetz; \ + \ + _e240 = (double) (long) (X##_f0 & 0xffffff); \ + _j240 = (double) (long) (Y##_f0 & 0xffffff); \ + _d240 = (double) (long) ((X##_f0 >> 24) & 0xffffff); \ + _i240 = (double) (long) ((Y##_f0 >> 24) & 0xffffff); \ + _c240 = (double) (long) (((X##_f1 << 16) & 0xffffff) | (X##_f0 >> 48)); \ + _h240 = (double) (long) (((Y##_f1 << 16) & 0xffffff) | (Y##_f0 >> 48)); \ + _b240 = (double) (long) ((X##_f1 >> 8) & 0xffffff); \ + _g240 = (double) (long) ((Y##_f1 >> 8) & 0xffffff); \ + _a240 = (double) (long) (X##_f1 >> 32); \ + _f240 = (double) (long) (Y##_f1 >> 32); \ + _e240 *= _const[3]; \ + _j240 *= _const[3]; \ + _d240 *= _const[2]; \ + _i240 *= _const[2]; \ + _c240 *= _const[1]; \ + _h240 *= _const[1]; \ + _b240 *= _const[0]; \ + _g240 *= _const[0]; \ + _s240.d = _e240*_j240; \ + _r240.d = _d240*_j240 + _e240*_i240; \ + _q240.d = _c240*_j240 + _d240*_i240 + _e240*_h240; \ + _p240.d = _b240*_j240 + _c240*_i240 + _d240*_h240 + _e240*_g240; \ + _o240.d = _a240*_j240 + _b240*_i240 + _c240*_h240 + _d240*_g240 + _e240*_f240; \ + _n240.d = _a240*_i240 + _b240*_h240 + _c240*_g240 + _d240*_f240; \ + _m240.d = _a240*_h240 + _b240*_g240 + _c240*_f240; \ + _l240.d = _a240*_g240 + _b240*_f240; \ + _k240 = _a240*_f240; \ + _r240.d += _s240.d; \ + _q240.d += _r240.d; \ + _p240.d += _q240.d; \ + _o240.d += _p240.d; \ + _n240.d += _o240.d; \ + _m240.d += _n240.d; \ + _l240.d += _m240.d; \ + _k240 += _l240.d; \ + _s240.d -= ((_const[10]+_s240.d)-_const[10]); \ + _r240.d -= ((_const[9]+_r240.d)-_const[9]); \ + _q240.d -= ((_const[8]+_q240.d)-_const[8]); \ + _p240.d -= ((_const[7]+_p240.d)-_const[7]); \ + _o240.d += _const[7]; \ + _n240.d += _const[6]; \ + _m240.d += _const[5]; \ + _l240.d += _const[4]; \ + if (_s240.d != 0.0) \ + _y240 = 1; \ + if (_r240.d != 0.0) \ + _y240 = 1; \ + if (_q240.d != 0.0) \ + _y240 = 1; \ + if (_p240.d != 0.0) \ + _y240 = 1; \ + _t240 = (DItype) _k240; \ + _u240 = _l240.i; \ + _v240 = _m240.i; \ + _w240 = _n240.i; \ + _x240 = _o240.i; \ + R##_f1 = ((_t240 << (128 - (wfracbits - 1))) \ + | ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104))); \ + R##_f0 = (((_u240 & 0xffffff) << (168 - (wfracbits - 1))) \ + | ((_v240 & 0xffffff) << (144 - (wfracbits - 1))) \ + | ((_w240 & 0xffffff) << (120 - (wfracbits - 1))) \ + | ((_x240 & 0xffffff) >> ((wfracbits - 1) - 96)) \ + | _y240); \ + resetfe; \ + } \ + while (0) /* * Division algorithms: */ #define _FP_DIV_MEAT_2_udiv(fs, R, X, Y) \ - do { \ - _FP_W_TYPE _n_f2, _n_f1, _n_f0, _r_f1, _r_f0, _m_f1, _m_f0; \ - if (_FP_FRAC_GT_2(X, Y)) \ - { \ - _n_f2 = X##_f1 >> 1; \ - _n_f1 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \ - _n_f0 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \ - } \ - else \ - { \ - R##_e--; \ - _n_f2 = X##_f1; \ - _n_f1 = X##_f0; \ - _n_f0 = 0; \ - } \ - \ - /* Normalize, i.e. make the most significant bit of the \ - denominator set. */ \ - _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs); \ + do \ + { \ + _FP_W_TYPE _n_f2, _n_f1, _n_f0, _r_f1, _r_f0, _m_f1, _m_f0; \ + if (_FP_FRAC_GE_2 (X, Y)) \ + { \ + _n_f2 = X##_f1 >> 1; \ + _n_f1 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \ + _n_f0 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \ + } \ + else \ + { \ + R##_e--; \ + _n_f2 = X##_f1; \ + _n_f1 = X##_f0; \ + _n_f0 = 0; \ + } \ \ - udiv_qrnnd(R##_f1, _r_f1, _n_f2, _n_f1, Y##_f1); \ - umul_ppmm(_m_f1, _m_f0, R##_f1, Y##_f0); \ - _r_f0 = _n_f0; \ - if (_FP_FRAC_GT_2(_m, _r)) \ - { \ - R##_f1--; \ - _FP_FRAC_ADD_2(_r, Y, _r); \ - if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ - { \ - R##_f1--; \ - _FP_FRAC_ADD_2(_r, Y, _r); \ - } \ - } \ - _FP_FRAC_DEC_2(_r, _m); \ + /* Normalize, i.e. make the most significant bit of the \ + denominator set. */ \ + _FP_FRAC_SLL_2 (Y, _FP_WFRACXBITS_##fs); \ \ - if (_r_f1 == Y##_f1) \ - { \ - /* This is a special case, not an optimization \ - (_r/Y##_f1 would not fit into UWtype). \ - As _r is guaranteed to be < Y, R##_f0 can be either \ - (UWtype)-1 or (UWtype)-2. But as we know what kind \ - of bits it is (sticky, guard, round), we don't care. \ - We also don't care what the reminder is, because the \ - guard bit will be set anyway. -jj */ \ - R##_f0 = -1; \ - } \ - else \ - { \ - udiv_qrnnd(R##_f0, _r_f1, _r_f1, _r_f0, Y##_f1); \ - umul_ppmm(_m_f1, _m_f0, R##_f0, Y##_f0); \ - _r_f0 = 0; \ - if (_FP_FRAC_GT_2(_m, _r)) \ - { \ - R##_f0--; \ - _FP_FRAC_ADD_2(_r, Y, _r); \ - if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \ - { \ - R##_f0--; \ - _FP_FRAC_ADD_2(_r, Y, _r); \ - } \ - } \ - if (!_FP_FRAC_EQ_2(_r, _m)) \ - R##_f0 |= _FP_WORK_STICKY; \ - } \ - } while (0) - - -#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y) \ - do { \ - _FP_W_TYPE _x[4], _y[2], _z[4]; \ - _y[0] = Y##_f0; _y[1] = Y##_f1; \ - _x[0] = _x[3] = 0; \ - if (_FP_FRAC_GT_2(X, Y)) \ - { \ - R##_e++; \ - _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE) | \ - X##_f1 >> (_FP_W_TYPE_SIZE - \ - (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE))); \ - _x[2] = X##_f1 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE); \ - } \ - else \ - { \ - _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE) | \ - X##_f1 >> (_FP_W_TYPE_SIZE - \ - (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE))); \ - _x[2] = X##_f1 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE); \ - } \ + udiv_qrnnd (R##_f1, _r_f1, _n_f2, _n_f1, Y##_f1); \ + umul_ppmm (_m_f1, _m_f0, R##_f1, Y##_f0); \ + _r_f0 = _n_f0; \ + if (_FP_FRAC_GT_2 (_m, _r)) \ + { \ + R##_f1--; \ + _FP_FRAC_ADD_2 (_r, Y, _r); \ + if (_FP_FRAC_GE_2 (_r, Y) && _FP_FRAC_GT_2 (_m, _r)) \ + { \ + R##_f1--; \ + _FP_FRAC_ADD_2 (_r, Y, _r); \ + } \ + } \ + _FP_FRAC_DEC_2 (_r, _m); \ \ - (void) mpn_divrem (_z, 0, _x, 4, _y, 2); \ - R##_f1 = _z[1]; \ - R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0); \ - } while (0) + if (_r_f1 == Y##_f1) \ + { \ + /* This is a special case, not an optimization \ + (_r/Y##_f1 would not fit into UWtype). \ + As _r is guaranteed to be < Y, R##_f0 can be either \ + (UWtype)-1 or (UWtype)-2. But as we know what kind \ + of bits it is (sticky, guard, round), we don't care. \ + We also don't care what the reminder is, because the \ + guard bit will be set anyway. -jj */ \ + R##_f0 = -1; \ + } \ + else \ + { \ + udiv_qrnnd (R##_f0, _r_f1, _r_f1, _r_f0, Y##_f1); \ + umul_ppmm (_m_f1, _m_f0, R##_f0, Y##_f0); \ + _r_f0 = 0; \ + if (_FP_FRAC_GT_2 (_m, _r)) \ + { \ + R##_f0--; \ + _FP_FRAC_ADD_2 (_r, Y, _r); \ + if (_FP_FRAC_GE_2 (_r, Y) && _FP_FRAC_GT_2 (_m, _r)) \ + { \ + R##_f0--; \ + _FP_FRAC_ADD_2 (_r, Y, _r); \ + } \ + } \ + if (!_FP_FRAC_EQ_2 (_r, _m)) \ + R##_f0 |= _FP_WORK_STICKY; \ + } \ + } \ + while (0) /* @@ -545,44 +580,46 @@ * should be added for those machines where division is fast. */ -#define _FP_SQRT_MEAT_2(R, S, T, X, q) \ - do { \ - while (q) \ - { \ - T##_f1 = S##_f1 + q; \ - if (T##_f1 <= X##_f1) \ - { \ - S##_f1 = T##_f1 + q; \ - X##_f1 -= T##_f1; \ - R##_f1 += q; \ - } \ - _FP_FRAC_SLL_2(X, 1); \ - q >>= 1; \ - } \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - while (q != _FP_WORK_ROUND) \ - { \ - T##_f0 = S##_f0 + q; \ - T##_f1 = S##_f1; \ - if (T##_f1 < X##_f1 || \ - (T##_f1 == X##_f1 && T##_f0 <= X##_f0)) \ - { \ - S##_f0 = T##_f0 + q; \ - S##_f1 += (T##_f0 > S##_f0); \ - _FP_FRAC_DEC_2(X, T); \ - R##_f0 += q; \ - } \ - _FP_FRAC_SLL_2(X, 1); \ - q >>= 1; \ - } \ - if (X##_f0 | X##_f1) \ - { \ - if (S##_f1 < X##_f1 || \ - (S##_f1 == X##_f1 && S##_f0 < X##_f0)) \ - R##_f0 |= _FP_WORK_ROUND; \ - R##_f0 |= _FP_WORK_STICKY; \ - } \ - } while (0) +#define _FP_SQRT_MEAT_2(R, S, T, X, q) \ + do \ + { \ + while (q) \ + { \ + T##_f1 = S##_f1 + q; \ + if (T##_f1 <= X##_f1) \ + { \ + S##_f1 = T##_f1 + q; \ + X##_f1 -= T##_f1; \ + R##_f1 += q; \ + } \ + _FP_FRAC_SLL_2 (X, 1); \ + q >>= 1; \ + } \ + q = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \ + while (q != _FP_WORK_ROUND) \ + { \ + T##_f0 = S##_f0 + q; \ + T##_f1 = S##_f1; \ + if (T##_f1 < X##_f1 \ + || (T##_f1 == X##_f1 && T##_f0 <= X##_f0)) \ + { \ + S##_f0 = T##_f0 + q; \ + S##_f1 += (T##_f0 > S##_f0); \ + _FP_FRAC_DEC_2 (X, T); \ + R##_f0 += q; \ + } \ + _FP_FRAC_SLL_2 (X, 1); \ + q >>= 1; \ + } \ + if (X##_f0 | X##_f1) \ + { \ + if (S##_f1 < X##_f1 \ + || (S##_f1 == X##_f1 && S##_f0 < X##_f0)) \ + R##_f0 |= _FP_WORK_ROUND; \ + R##_f0 |= _FP_WORK_STICKY; \ + } \ + } \ + while (0) /* @@ -591,19 +628,21 @@ */ #define _FP_FRAC_ASSEMBLE_2(r, X, rsize) \ -(void)((rsize <= _FP_W_TYPE_SIZE) \ - ? ({ r = X##_f0; }) \ - : ({ \ - r = X##_f1; \ - r <<= _FP_W_TYPE_SIZE; \ - r += X##_f0; \ - })) + (void) ((rsize <= _FP_W_TYPE_SIZE) \ + ? ({ r = X##_f0; }) \ + : ({ \ + r = X##_f1; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f0; \ + })) #define _FP_FRAC_DISASSEMBLE_2(X, r, rsize) \ - do { \ - X##_f0 = r; \ - X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ - } while (0) + do \ + { \ + X##_f0 = r; \ + X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ + } \ + while (0) /* * Convert FP values between word sizes @@ -613,4 +652,4 @@ #define _FP_FRAC_COPY_2_1(D, S) ((D##_f0 = S##_f), (D##_f1 = 0)) -#define _FP_FRAC_COPY_2_2(D,S) _FP_FRAC_COPY_2(D,S) +#define _FP_FRAC_COPY_2_2(D, S) _FP_FRAC_COPY_2 (D, S) diff --git a/libgcc/soft-fp/op-4.h b/libgcc/soft-fp/op-4.h index 007b01f36c8..3515bdc497b 100644 --- a/libgcc/soft-fp/op-4.h +++ b/libgcc/soft-fp/op-4.h @@ -31,54 +31,58 @@ <http://www.gnu.org/licenses/>. */ #define _FP_FRAC_DECL_4(X) _FP_W_TYPE X##_f[4] -#define _FP_FRAC_COPY_4(D,S) \ +#define _FP_FRAC_COPY_4(D, S) \ (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1], \ D##_f[2] = S##_f[2], D##_f[3] = S##_f[3]) -#define _FP_FRAC_SET_4(X,I) __FP_FRAC_SET_4(X, I) +#define _FP_FRAC_SET_4(X, I) __FP_FRAC_SET_4 (X, I) #define _FP_FRAC_HIGH_4(X) (X##_f[3]) #define _FP_FRAC_LOW_4(X) (X##_f[0]) -#define _FP_FRAC_WORD_4(X,w) (X##_f[w]) - -#define _FP_FRAC_SLL_4(X,N) \ - do { \ - _FP_I_TYPE _up, _down, _skip, _i; \ - _skip = (N) / _FP_W_TYPE_SIZE; \ - _up = (N) % _FP_W_TYPE_SIZE; \ - _down = _FP_W_TYPE_SIZE - _up; \ - if (!_up) \ - for (_i = 3; _i >= _skip; --_i) \ - X##_f[_i] = X##_f[_i-_skip]; \ - else \ - { \ - for (_i = 3; _i > _skip; --_i) \ - X##_f[_i] = X##_f[_i-_skip] << _up \ - | X##_f[_i-_skip-1] >> _down; \ - X##_f[_i--] = X##_f[0] << _up; \ - } \ - for (; _i >= 0; --_i) \ - X##_f[_i] = 0; \ - } while (0) +#define _FP_FRAC_WORD_4(X, w) (X##_f[w]) + +#define _FP_FRAC_SLL_4(X, N) \ + do \ + { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _up = (N) % _FP_W_TYPE_SIZE; \ + _down = _FP_W_TYPE_SIZE - _up; \ + if (!_up) \ + for (_i = 3; _i >= _skip; --_i) \ + X##_f[_i] = X##_f[_i-_skip]; \ + else \ + { \ + for (_i = 3; _i > _skip; --_i) \ + X##_f[_i] = (X##_f[_i-_skip] << _up \ + | X##_f[_i-_skip-1] >> _down); \ + X##_f[_i--] = X##_f[0] << _up; \ + } \ + for (; _i >= 0; --_i) \ + X##_f[_i] = 0; \ + } \ + while (0) /* This one was broken too */ -#define _FP_FRAC_SRL_4(X,N) \ - do { \ - _FP_I_TYPE _up, _down, _skip, _i; \ - _skip = (N) / _FP_W_TYPE_SIZE; \ - _down = (N) % _FP_W_TYPE_SIZE; \ - _up = _FP_W_TYPE_SIZE - _down; \ - if (!_down) \ - for (_i = 0; _i <= 3-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip]; \ - else \ - { \ - for (_i = 0; _i < 3-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip] >> _down \ - | X##_f[_i+_skip+1] << _up; \ - X##_f[_i++] = X##_f[3] >> _down; \ - } \ - for (; _i < 4; ++_i) \ - X##_f[_i] = 0; \ - } while (0) +#define _FP_FRAC_SRL_4(X, N) \ + do \ + { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _down = (N) % _FP_W_TYPE_SIZE; \ + _up = _FP_W_TYPE_SIZE - _down; \ + if (!_down) \ + for (_i = 0; _i <= 3-_skip; ++_i) \ + X##_f[_i] = X##_f[_i+_skip]; \ + else \ + { \ + for (_i = 0; _i < 3-_skip; ++_i) \ + X##_f[_i] = (X##_f[_i+_skip] >> _down \ + | X##_f[_i+_skip+1] << _up); \ + X##_f[_i++] = X##_f[3] >> _down; \ + } \ + for (; _i < 4; ++_i) \ + X##_f[_i] = 0; \ + } \ + while (0) /* Right shift with sticky-lsb. @@ -86,159 +90,172 @@ * but that if any of the bits that fall off the right hand side * were one then we always set the LSbit. */ -#define _FP_FRAC_SRST_4(X,S,N,size) \ - do { \ - _FP_I_TYPE _up, _down, _skip, _i; \ - _FP_W_TYPE _s; \ - _skip = (N) / _FP_W_TYPE_SIZE; \ - _down = (N) % _FP_W_TYPE_SIZE; \ - _up = _FP_W_TYPE_SIZE - _down; \ - for (_s = _i = 0; _i < _skip; ++_i) \ - _s |= X##_f[_i]; \ - if (!_down) \ - for (_i = 0; _i <= 3-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip]; \ - else \ - { \ - _s |= X##_f[_i] << _up; \ - for (_i = 0; _i < 3-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip] >> _down \ - | X##_f[_i+_skip+1] << _up; \ - X##_f[_i++] = X##_f[3] >> _down; \ - } \ - for (; _i < 4; ++_i) \ - X##_f[_i] = 0; \ - S = (_s != 0); \ - } while (0) - -#define _FP_FRAC_SRS_4(X,N,size) \ - do { \ - int _sticky; \ - _FP_FRAC_SRST_4(X, _sticky, N, size); \ - X##_f[0] |= _sticky; \ - } while (0) - -#define _FP_FRAC_ADD_4(R,X,Y) \ - __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ - X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ - Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) - -#define _FP_FRAC_SUB_4(R,X,Y) \ - __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ - X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ - Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) - -#define _FP_FRAC_DEC_4(X,Y) \ - __FP_FRAC_DEC_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ - Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) - -#define _FP_FRAC_ADDI_4(X,I) \ - __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I) - -#define _FP_ZEROFRAC_4 0,0,0,0 -#define _FP_MINFRAC_4 0,0,0,1 -#define _FP_MAXFRAC_4 (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0) +#define _FP_FRAC_SRST_4(X, S, N, size) \ + do \ + { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _FP_W_TYPE _s; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _down = (N) % _FP_W_TYPE_SIZE; \ + _up = _FP_W_TYPE_SIZE - _down; \ + for (_s = _i = 0; _i < _skip; ++_i) \ + _s |= X##_f[_i]; \ + if (!_down) \ + for (_i = 0; _i <= 3-_skip; ++_i) \ + X##_f[_i] = X##_f[_i+_skip]; \ + else \ + { \ + _s |= X##_f[_i] << _up; \ + for (_i = 0; _i < 3-_skip; ++_i) \ + X##_f[_i] = (X##_f[_i+_skip] >> _down \ + | X##_f[_i+_skip+1] << _up); \ + X##_f[_i++] = X##_f[3] >> _down; \ + } \ + for (; _i < 4; ++_i) \ + X##_f[_i] = 0; \ + S = (_s != 0); \ + } \ + while (0) + +#define _FP_FRAC_SRS_4(X, N, size) \ + do \ + { \ + int _sticky; \ + _FP_FRAC_SRST_4 (X, _sticky, N, size); \ + X##_f[0] |= _sticky; \ + } \ + while (0) + +#define _FP_FRAC_ADD_4(R, X, Y) \ + __FP_FRAC_ADD_4 (R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ + X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ + Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) + +#define _FP_FRAC_SUB_4(R, X, Y) \ + __FP_FRAC_SUB_4 (R##_f[3], R##_f[2], R##_f[1], R##_f[0], \ + X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ + Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) + +#define _FP_FRAC_DEC_4(X, Y) \ + __FP_FRAC_DEC_4 (X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ + Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0]) + +#define _FP_FRAC_ADDI_4(X, I) \ + __FP_FRAC_ADDI_4 (X##_f[3], X##_f[2], X##_f[1], X##_f[0], I) + +#define _FP_ZEROFRAC_4 0, 0, 0, 0 +#define _FP_MINFRAC_4 0, 0, 0, 1 +#define _FP_MAXFRAC_4 (~(_FP_WS_TYPE) 0), (~(_FP_WS_TYPE) 0), (~(_FP_WS_TYPE) 0), (~(_FP_WS_TYPE) 0) #define _FP_FRAC_ZEROP_4(X) ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0) -#define _FP_FRAC_NEGP_4(X) ((_FP_WS_TYPE)X##_f[3] < 0) -#define _FP_FRAC_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs) -#define _FP_FRAC_CLEAR_OVERP_4(fs,X) (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs) - -#define _FP_FRAC_EQ_4(X,Y) \ - (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \ - && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3]) - -#define _FP_FRAC_GT_4(X,Y) \ - (X##_f[3] > Y##_f[3] || \ - (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ - (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ - (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0]) \ - )) \ - )) \ - ) - -#define _FP_FRAC_GE_4(X,Y) \ - (X##_f[3] > Y##_f[3] || \ - (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \ - (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \ - (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0]) \ - )) \ - )) \ - ) - - -#define _FP_FRAC_CLZ_4(R,X) \ - do { \ - if (X##_f[3]) \ - { \ - __FP_CLZ(R,X##_f[3]); \ - } \ - else if (X##_f[2]) \ - { \ - __FP_CLZ(R,X##_f[2]); \ - R += _FP_W_TYPE_SIZE; \ - } \ - else if (X##_f[1]) \ - { \ - __FP_CLZ(R,X##_f[1]); \ - R += _FP_W_TYPE_SIZE*2; \ - } \ - else \ - { \ - __FP_CLZ(R,X##_f[0]); \ - R += _FP_W_TYPE_SIZE*3; \ - } \ - } while(0) - - -#define _FP_UNPACK_RAW_4(fs, X, val) \ - do { \ - union _FP_UNION_##fs _flo; _flo.flt = (val); \ - X##_f[0] = _flo.bits.frac0; \ - X##_f[1] = _flo.bits.frac1; \ - X##_f[2] = _flo.bits.frac2; \ - X##_f[3] = _flo.bits.frac3; \ - X##_e = _flo.bits.exp; \ - X##_s = _flo.bits.sign; \ - } while (0) - -#define _FP_UNPACK_RAW_4_P(fs, X, val) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)(val); \ - \ - X##_f[0] = _flo->bits.frac0; \ - X##_f[1] = _flo->bits.frac1; \ - X##_f[2] = _flo->bits.frac2; \ - X##_f[3] = _flo->bits.frac3; \ - X##_e = _flo->bits.exp; \ - X##_s = _flo->bits.sign; \ - } while (0) - -#define _FP_PACK_RAW_4(fs, val, X) \ - do { \ - union _FP_UNION_##fs _flo; \ - _flo.bits.frac0 = X##_f[0]; \ - _flo.bits.frac1 = X##_f[1]; \ - _flo.bits.frac2 = X##_f[2]; \ - _flo.bits.frac3 = X##_f[3]; \ - _flo.bits.exp = X##_e; \ - _flo.bits.sign = X##_s; \ - (val) = _flo.flt; \ - } while (0) - -#define _FP_PACK_RAW_4_P(fs, val, X) \ - do { \ - union _FP_UNION_##fs *_flo = \ - (union _FP_UNION_##fs *)(val); \ - \ - _flo->bits.frac0 = X##_f[0]; \ - _flo->bits.frac1 = X##_f[1]; \ - _flo->bits.frac2 = X##_f[2]; \ - _flo->bits.frac3 = X##_f[3]; \ - _flo->bits.exp = X##_e; \ - _flo->bits.sign = X##_s; \ - } while (0) +#define _FP_FRAC_NEGP_4(X) ((_FP_WS_TYPE) X##_f[3] < 0) +#define _FP_FRAC_OVERP_4(fs, X) (_FP_FRAC_HIGH_##fs (X) & _FP_OVERFLOW_##fs) +#define _FP_FRAC_HIGHBIT_DW_4(fs, X) \ + (_FP_FRAC_HIGH_DW_##fs (X) & _FP_HIGHBIT_DW_##fs) +#define _FP_FRAC_CLEAR_OVERP_4(fs, X) (_FP_FRAC_HIGH_##fs (X) &= ~_FP_OVERFLOW_##fs) + +#define _FP_FRAC_EQ_4(X, Y) \ + (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \ + && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3]) + +#define _FP_FRAC_GT_4(X, Y) \ + (X##_f[3] > Y##_f[3] \ + || (X##_f[3] == Y##_f[3] \ + && (X##_f[2] > Y##_f[2] \ + || (X##_f[2] == Y##_f[2] \ + && (X##_f[1] > Y##_f[1] \ + || (X##_f[1] == Y##_f[1] \ + && X##_f[0] > Y##_f[0])))))) + +#define _FP_FRAC_GE_4(X, Y) \ + (X##_f[3] > Y##_f[3] \ + || (X##_f[3] == Y##_f[3] \ + && (X##_f[2] > Y##_f[2] \ + || (X##_f[2] == Y##_f[2] \ + && (X##_f[1] > Y##_f[1] \ + || (X##_f[1] == Y##_f[1] \ + && X##_f[0] >= Y##_f[0])))))) + + +#define _FP_FRAC_CLZ_4(R, X) \ + do \ + { \ + if (X##_f[3]) \ + __FP_CLZ (R, X##_f[3]); \ + else if (X##_f[2]) \ + { \ + __FP_CLZ (R, X##_f[2]); \ + R += _FP_W_TYPE_SIZE; \ + } \ + else if (X##_f[1]) \ + { \ + __FP_CLZ (R, X##_f[1]); \ + R += _FP_W_TYPE_SIZE*2; \ + } \ + else \ + { \ + __FP_CLZ (R, X##_f[0]); \ + R += _FP_W_TYPE_SIZE*3; \ + } \ + } \ + while (0) + + +#define _FP_UNPACK_RAW_4(fs, X, val) \ + do \ + { \ + union _FP_UNION_##fs _flo; \ + _flo.flt = (val); \ + X##_f[0] = _flo.bits.frac0; \ + X##_f[1] = _flo.bits.frac1; \ + X##_f[2] = _flo.bits.frac2; \ + X##_f[3] = _flo.bits.frac3; \ + X##_e = _flo.bits.exp; \ + X##_s = _flo.bits.sign; \ + } \ + while (0) + +#define _FP_UNPACK_RAW_4_P(fs, X, val) \ + do \ + { \ + union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *) (val); \ + \ + X##_f[0] = _flo->bits.frac0; \ + X##_f[1] = _flo->bits.frac1; \ + X##_f[2] = _flo->bits.frac2; \ + X##_f[3] = _flo->bits.frac3; \ + X##_e = _flo->bits.exp; \ + X##_s = _flo->bits.sign; \ + } \ + while (0) + +#define _FP_PACK_RAW_4(fs, val, X) \ + do \ + { \ + union _FP_UNION_##fs _flo; \ + _flo.bits.frac0 = X##_f[0]; \ + _flo.bits.frac1 = X##_f[1]; \ + _flo.bits.frac2 = X##_f[2]; \ + _flo.bits.frac3 = X##_f[3]; \ + _flo.bits.exp = X##_e; \ + _flo.bits.sign = X##_s; \ + (val) = _flo.flt; \ + } \ + while (0) + +#define _FP_PACK_RAW_4_P(fs, val, X) \ + do \ + { \ + union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *) (val); \ + \ + _flo->bits.frac0 = X##_f[0]; \ + _flo->bits.frac1 = X##_f[1]; \ + _flo->bits.frac2 = X##_f[2]; \ + _flo->bits.frac3 = X##_f[3]; \ + _flo->bits.exp = X##_e; \ + _flo->bits.sign = X##_s; \ + } \ + while (0) /* * Multiplication algorithms: @@ -246,188 +263,216 @@ /* Given a 1W * 1W => 2W primitive, do the extended multiplication. */ -#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit) \ - do { \ - _FP_FRAC_DECL_8(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \ - _FP_FRAC_DECL_2(_d); _FP_FRAC_DECL_2(_e); _FP_FRAC_DECL_2(_f); \ - \ - doit(_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0), X##_f[0], Y##_f[0]); \ - doit(_b_f1, _b_f0, X##_f[0], Y##_f[1]); \ - doit(_c_f1, _c_f0, X##_f[1], Y##_f[0]); \ - doit(_d_f1, _d_f0, X##_f[1], Y##_f[1]); \ - doit(_e_f1, _e_f0, X##_f[0], Y##_f[2]); \ - doit(_f_f1, _f_f0, X##_f[2], Y##_f[0]); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ - _FP_FRAC_WORD_8(_z,1), 0,_b_f1,_b_f0, \ - 0,0,_FP_FRAC_WORD_8(_z,1)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ - _FP_FRAC_WORD_8(_z,1), 0,_c_f1,_c_f0, \ - _FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2), \ - _FP_FRAC_WORD_8(_z,1)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ - _FP_FRAC_WORD_8(_z,2), 0,_d_f1,_d_f0, \ - 0,_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ - _FP_FRAC_WORD_8(_z,2), 0,_e_f1,_e_f0, \ - _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ - _FP_FRAC_WORD_8(_z,2)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ - _FP_FRAC_WORD_8(_z,2), 0,_f_f1,_f_f0, \ - _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3), \ - _FP_FRAC_WORD_8(_z,2)); \ - doit(_b_f1, _b_f0, X##_f[0], Y##_f[3]); \ - doit(_c_f1, _c_f0, X##_f[3], Y##_f[0]); \ - doit(_d_f1, _d_f0, X##_f[1], Y##_f[2]); \ - doit(_e_f1, _e_f0, X##_f[2], Y##_f[1]); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ - _FP_FRAC_WORD_8(_z,3), 0,_b_f1,_b_f0, \ - 0,_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ - _FP_FRAC_WORD_8(_z,3), 0,_c_f1,_c_f0, \ - _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ - _FP_FRAC_WORD_8(_z,3)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ - _FP_FRAC_WORD_8(_z,3), 0,_d_f1,_d_f0, \ - _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ - _FP_FRAC_WORD_8(_z,3)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ - _FP_FRAC_WORD_8(_z,3), 0,_e_f1,_e_f0, \ - _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4), \ - _FP_FRAC_WORD_8(_z,3)); \ - doit(_b_f1, _b_f0, X##_f[2], Y##_f[2]); \ - doit(_c_f1, _c_f0, X##_f[1], Y##_f[3]); \ - doit(_d_f1, _d_f0, X##_f[3], Y##_f[1]); \ - doit(_e_f1, _e_f0, X##_f[2], Y##_f[3]); \ - doit(_f_f1, _f_f0, X##_f[3], Y##_f[2]); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ - _FP_FRAC_WORD_8(_z,4), 0,_b_f1,_b_f0, \ - 0,_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ - _FP_FRAC_WORD_8(_z,4), 0,_c_f1,_c_f0, \ - _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ - _FP_FRAC_WORD_8(_z,4)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ - _FP_FRAC_WORD_8(_z,4), 0,_d_f1,_d_f0, \ - _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5), \ - _FP_FRAC_WORD_8(_z,4)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ - _FP_FRAC_WORD_8(_z,5), 0,_e_f1,_e_f0, \ - 0,_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5)); \ - __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ - _FP_FRAC_WORD_8(_z,5), 0,_f_f1,_f_f0, \ - _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ - _FP_FRAC_WORD_8(_z,5)); \ - doit(_b_f1, _b_f0, X##_f[3], Y##_f[3]); \ - __FP_FRAC_ADD_2(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6), \ - _b_f1,_b_f0, \ - _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6)); \ - \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ - __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ - _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ - } while (0) - -#define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y) \ - do { \ - _FP_FRAC_DECL_8(_z); \ - \ - mpn_mul_n(_z_f, _x_f, _y_f, 4); \ - \ - /* Normalize since we know where the msb of the multiplicands \ - were (bit B), we know that the msb of the of the product is \ - at either 2B or 2B-1. */ \ - _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits); \ - __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2), \ - _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0)); \ - } while (0) +#define _FP_MUL_MEAT_DW_4_wide(wfracbits, R, X, Y, doit) \ + do \ + { \ + _FP_FRAC_DECL_2 (_b); \ + _FP_FRAC_DECL_2 (_c); \ + _FP_FRAC_DECL_2 (_d); \ + _FP_FRAC_DECL_2 (_e); \ + _FP_FRAC_DECL_2 (_f); \ + \ + doit (_FP_FRAC_WORD_8 (R, 1), _FP_FRAC_WORD_8 (R, 0), X##_f[0], Y##_f[0]); \ + doit (_b_f1, _b_f0, X##_f[0], Y##_f[1]); \ + doit (_c_f1, _c_f0, X##_f[1], Y##_f[0]); \ + doit (_d_f1, _d_f0, X##_f[1], Y##_f[1]); \ + doit (_e_f1, _e_f0, X##_f[0], Y##_f[2]); \ + doit (_f_f1, _f_f0, X##_f[2], Y##_f[0]); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 3), _FP_FRAC_WORD_8 (R, 2), \ + _FP_FRAC_WORD_8 (R, 1), 0, _b_f1, _b_f0, \ + 0, 0, _FP_FRAC_WORD_8 (R, 1)); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 3), _FP_FRAC_WORD_8 (R, 2), \ + _FP_FRAC_WORD_8 (R, 1), 0, _c_f1, _c_f0, \ + _FP_FRAC_WORD_8 (R, 3), _FP_FRAC_WORD_8 (R, 2), \ + _FP_FRAC_WORD_8 (R, 1)); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 4), _FP_FRAC_WORD_8 (R, 3), \ + _FP_FRAC_WORD_8 (R, 2), 0, _d_f1, _d_f0, \ + 0, _FP_FRAC_WORD_8 (R, 3), _FP_FRAC_WORD_8 (R, 2)); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 4), _FP_FRAC_WORD_8 (R, 3), \ + _FP_FRAC_WORD_8 (R, 2), 0, _e_f1, _e_f0, \ + _FP_FRAC_WORD_8 (R, 4), _FP_FRAC_WORD_8 (R, 3), \ + _FP_FRAC_WORD_8 (R, 2)); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 4), _FP_FRAC_WORD_8 (R, 3), \ + _FP_FRAC_WORD_8 (R, 2), 0, _f_f1, _f_f0, \ + _FP_FRAC_WORD_8 (R, 4), _FP_FRAC_WORD_8 (R, 3), \ + _FP_FRAC_WORD_8 (R, 2)); \ + doit (_b_f1, _b_f0, X##_f[0], Y##_f[3]); \ + doit (_c_f1, _c_f0, X##_f[3], Y##_f[0]); \ + doit (_d_f1, _d_f0, X##_f[1], Y##_f[2]); \ + doit (_e_f1, _e_f0, X##_f[2], Y##_f[1]); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \ + _FP_FRAC_WORD_8 (R, 3), 0, _b_f1, _b_f0, \ + 0, _FP_FRAC_WORD_8 (R, 4), _FP_FRAC_WORD_8 (R, 3)); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \ + _FP_FRAC_WORD_8 (R, 3), 0, _c_f1, _c_f0, \ + _FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \ + _FP_FRAC_WORD_8 (R, 3)); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \ + _FP_FRAC_WORD_8 (R, 3), 0, _d_f1, _d_f0, \ + _FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \ + _FP_FRAC_WORD_8 (R, 3)); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \ + _FP_FRAC_WORD_8 (R, 3), 0, _e_f1, _e_f0, \ + _FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \ + _FP_FRAC_WORD_8 (R, 3)); \ + doit (_b_f1, _b_f0, X##_f[2], Y##_f[2]); \ + doit (_c_f1, _c_f0, X##_f[1], Y##_f[3]); \ + doit (_d_f1, _d_f0, X##_f[3], Y##_f[1]); \ + doit (_e_f1, _e_f0, X##_f[2], Y##_f[3]); \ + doit (_f_f1, _f_f0, X##_f[3], Y##_f[2]); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 6), _FP_FRAC_WORD_8 (R, 5), \ + _FP_FRAC_WORD_8 (R, 4), 0, _b_f1, _b_f0, \ + 0, _FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4)); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 6), _FP_FRAC_WORD_8 (R, 5), \ + _FP_FRAC_WORD_8 (R, 4), 0, _c_f1, _c_f0, \ + _FP_FRAC_WORD_8 (R, 6), _FP_FRAC_WORD_8 (R, 5), \ + _FP_FRAC_WORD_8 (R, 4)); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 6), _FP_FRAC_WORD_8 (R, 5), \ + _FP_FRAC_WORD_8 (R, 4), 0, _d_f1, _d_f0, \ + _FP_FRAC_WORD_8 (R, 6), _FP_FRAC_WORD_8 (R, 5), \ + _FP_FRAC_WORD_8 (R, 4)); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 7), _FP_FRAC_WORD_8 (R, 6), \ + _FP_FRAC_WORD_8 (R, 5), 0, _e_f1, _e_f0, \ + 0, _FP_FRAC_WORD_8 (R, 6), _FP_FRAC_WORD_8 (R, 5)); \ + __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 7), _FP_FRAC_WORD_8 (R, 6), \ + _FP_FRAC_WORD_8 (R, 5), 0, _f_f1, _f_f0, \ + _FP_FRAC_WORD_8 (R, 7), _FP_FRAC_WORD_8 (R, 6), \ + _FP_FRAC_WORD_8 (R, 5)); \ + doit (_b_f1, _b_f0, X##_f[3], Y##_f[3]); \ + __FP_FRAC_ADD_2 (_FP_FRAC_WORD_8 (R, 7), _FP_FRAC_WORD_8 (R, 6), \ + _b_f1, _b_f0, \ + _FP_FRAC_WORD_8 (R, 7), _FP_FRAC_WORD_8 (R, 6)); \ + } \ + while (0) + +#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit) \ + do \ + { \ + _FP_FRAC_DECL_8 (_z); \ + \ + _FP_MUL_MEAT_DW_4_wide (wfracbits, _z, X, Y, doit); \ + \ + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_8 (_z, wfracbits-1, 2*wfracbits); \ + __FP_FRAC_SET_4 (R, _FP_FRAC_WORD_8 (_z, 3), _FP_FRAC_WORD_8 (_z, 2), \ + _FP_FRAC_WORD_8 (_z, 1), _FP_FRAC_WORD_8 (_z, 0)); \ + } \ + while (0) + +#define _FP_MUL_MEAT_DW_4_gmp(wfracbits, R, X, Y) \ + do \ + { \ + mpn_mul_n (R##_f, _x_f, _y_f, 4); \ + } \ + while (0) + +#define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y) \ + do \ + { \ + _FP_FRAC_DECL_8 (_z); \ + \ + _FP_MUL_MEAT_DW_4_gmp (wfracbits, _z, X, Y); \ + \ + /* Normalize since we know where the msb of the multiplicands \ + were (bit B), we know that the msb of the of the product is \ + at either 2B or 2B-1. */ \ + _FP_FRAC_SRS_8 (_z, wfracbits-1, 2*wfracbits); \ + __FP_FRAC_SET_4 (R, _FP_FRAC_WORD_8 (_z, 3), _FP_FRAC_WORD_8 (_z, 2), \ + _FP_FRAC_WORD_8 (_z, 1), _FP_FRAC_WORD_8 (_z, 0)); \ + } \ + while (0) /* * Helper utility for _FP_DIV_MEAT_4_udiv: * pppp = m * nnn */ -#define umul_ppppmnnn(p3,p2,p1,p0,m,n2,n1,n0) \ - do { \ - UWtype _t; \ - umul_ppmm(p1,p0,m,n0); \ - umul_ppmm(p2,_t,m,n1); \ - __FP_FRAC_ADDI_2(p2,p1,_t); \ - umul_ppmm(p3,_t,m,n2); \ - __FP_FRAC_ADDI_2(p3,p2,_t); \ - } while (0) +#define umul_ppppmnnn(p3, p2, p1, p0, m, n2, n1, n0) \ + do \ + { \ + UWtype _t; \ + umul_ppmm (p1, p0, m, n0); \ + umul_ppmm (p2, _t, m, n1); \ + __FP_FRAC_ADDI_2 (p2, p1, _t); \ + umul_ppmm (p3, _t, m, n2); \ + __FP_FRAC_ADDI_2 (p3, p2, _t); \ + } \ + while (0) /* * Division algorithms: */ -#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y) \ - do { \ - int _i; \ - _FP_FRAC_DECL_4(_n); _FP_FRAC_DECL_4(_m); \ - _FP_FRAC_SET_4(_n, _FP_ZEROFRAC_4); \ - if (_FP_FRAC_GT_4(X, Y)) \ - { \ - _n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1); \ - _FP_FRAC_SRL_4(X, 1); \ - } \ - else \ - R##_e--; \ - \ - /* Normalize, i.e. make the most significant bit of the \ - denominator set. */ \ - _FP_FRAC_SLL_4(Y, _FP_WFRACXBITS_##fs); \ - \ - for (_i = 3; ; _i--) \ - { \ - if (X##_f[3] == Y##_f[3]) \ - { \ - /* This is a special case, not an optimization \ - (X##_f[3]/Y##_f[3] would not fit into UWtype). \ - As X## is guaranteed to be < Y, R##_f[_i] can be either \ - (UWtype)-1 or (UWtype)-2. */ \ - R##_f[_i] = -1; \ - if (!_i) \ - break; \ - __FP_FRAC_SUB_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ - Y##_f[2], Y##_f[1], Y##_f[0], 0, \ - X##_f[2], X##_f[1], X##_f[0], _n_f[_i]); \ - _FP_FRAC_SUB_4(X, Y, X); \ - if (X##_f[3] > Y##_f[3]) \ - { \ - R##_f[_i] = -2; \ - _FP_FRAC_ADD_4(X, Y, X); \ - } \ - } \ - else \ - { \ - udiv_qrnnd(R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]); \ - umul_ppppmnnn(_m_f[3], _m_f[2], _m_f[1], _m_f[0], \ - R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]); \ - X##_f[2] = X##_f[1]; \ - X##_f[1] = X##_f[0]; \ - X##_f[0] = _n_f[_i]; \ - if (_FP_FRAC_GT_4(_m, X)) \ - { \ - R##_f[_i]--; \ - _FP_FRAC_ADD_4(X, Y, X); \ - if (_FP_FRAC_GE_4(X, Y) && _FP_FRAC_GT_4(_m, X)) \ - { \ - R##_f[_i]--; \ - _FP_FRAC_ADD_4(X, Y, X); \ - } \ - } \ - _FP_FRAC_DEC_4(X, _m); \ - if (!_i) \ - { \ - if (!_FP_FRAC_EQ_4(X, _m)) \ - R##_f[0] |= _FP_WORK_STICKY; \ - break; \ - } \ - } \ - } \ - } while (0) +#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y) \ + do \ + { \ + int _i; \ + _FP_FRAC_DECL_4 (_n); \ + _FP_FRAC_DECL_4 (_m); \ + _FP_FRAC_SET_4 (_n, _FP_ZEROFRAC_4); \ + if (_FP_FRAC_GE_4 (X, Y)) \ + { \ + _n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1); \ + _FP_FRAC_SRL_4 (X, 1); \ + } \ + else \ + R##_e--; \ + \ + /* Normalize, i.e. make the most significant bit of the \ + denominator set. */ \ + _FP_FRAC_SLL_4 (Y, _FP_WFRACXBITS_##fs); \ + \ + for (_i = 3; ; _i--) \ + { \ + if (X##_f[3] == Y##_f[3]) \ + { \ + /* This is a special case, not an optimization \ + (X##_f[3]/Y##_f[3] would not fit into UWtype). \ + As X## is guaranteed to be < Y, R##_f[_i] can be either \ + (UWtype)-1 or (UWtype)-2. */ \ + R##_f[_i] = -1; \ + if (!_i) \ + break; \ + __FP_FRAC_SUB_4 (X##_f[3], X##_f[2], X##_f[1], X##_f[0], \ + Y##_f[2], Y##_f[1], Y##_f[0], 0, \ + X##_f[2], X##_f[1], X##_f[0], _n_f[_i]); \ + _FP_FRAC_SUB_4 (X, Y, X); \ + if (X##_f[3] > Y##_f[3]) \ + { \ + R##_f[_i] = -2; \ + _FP_FRAC_ADD_4 (X, Y, X); \ + } \ + } \ + else \ + { \ + udiv_qrnnd (R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]); \ + umul_ppppmnnn (_m_f[3], _m_f[2], _m_f[1], _m_f[0], \ + R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]); \ + X##_f[2] = X##_f[1]; \ + X##_f[1] = X##_f[0]; \ + X##_f[0] = _n_f[_i]; \ + if (_FP_FRAC_GT_4 (_m, X)) \ + { \ + R##_f[_i]--; \ + _FP_FRAC_ADD_4 (X, Y, X); \ + if (_FP_FRAC_GE_4 (X, Y) && _FP_FRAC_GT_4 (_m, X)) \ + { \ + R##_f[_i]--; \ + _FP_FRAC_ADD_4 (X, Y, X); \ + } \ + } \ + _FP_FRAC_DEC_4 (X, _m); \ + if (!_i) \ + { \ + if (!_FP_FRAC_EQ_4 (X, _m)) \ + R##_f[0] |= _FP_WORK_STICKY; \ + break; \ + } \ + } \ + } \ + } \ + while (0) /* @@ -436,183 +481,203 @@ * should be added for those machines where division is fast. */ -#define _FP_SQRT_MEAT_4(R, S, T, X, q) \ - do { \ - while (q) \ - { \ - T##_f[3] = S##_f[3] + q; \ - if (T##_f[3] <= X##_f[3]) \ - { \ - S##_f[3] = T##_f[3] + q; \ - X##_f[3] -= T##_f[3]; \ - R##_f[3] += q; \ - } \ - _FP_FRAC_SLL_4(X, 1); \ - q >>= 1; \ - } \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - while (q) \ - { \ - T##_f[2] = S##_f[2] + q; \ - T##_f[3] = S##_f[3]; \ - if (T##_f[3] < X##_f[3] || \ - (T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2])) \ - { \ - S##_f[2] = T##_f[2] + q; \ - S##_f[3] += (T##_f[2] > S##_f[2]); \ - __FP_FRAC_DEC_2(X##_f[3], X##_f[2], \ - T##_f[3], T##_f[2]); \ - R##_f[2] += q; \ - } \ - _FP_FRAC_SLL_4(X, 1); \ - q >>= 1; \ - } \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - while (q) \ - { \ - T##_f[1] = S##_f[1] + q; \ - T##_f[2] = S##_f[2]; \ - T##_f[3] = S##_f[3]; \ - if (T##_f[3] < X##_f[3] || \ - (T##_f[3] == X##_f[3] && (T##_f[2] < X##_f[2] || \ - (T##_f[2] == X##_f[2] && T##_f[1] <= X##_f[1])))) \ - { \ - S##_f[1] = T##_f[1] + q; \ - S##_f[2] += (T##_f[1] > S##_f[1]); \ - S##_f[3] += (T##_f[2] > S##_f[2]); \ - __FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1], \ - T##_f[3], T##_f[2], T##_f[1]); \ - R##_f[1] += q; \ - } \ - _FP_FRAC_SLL_4(X, 1); \ - q >>= 1; \ - } \ - q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \ - while (q != _FP_WORK_ROUND) \ - { \ - T##_f[0] = S##_f[0] + q; \ - T##_f[1] = S##_f[1]; \ - T##_f[2] = S##_f[2]; \ - T##_f[3] = S##_f[3]; \ - if (_FP_FRAC_GE_4(X,T)) \ - { \ - S##_f[0] = T##_f[0] + q; \ - S##_f[1] += (T##_f[0] > S##_f[0]); \ - S##_f[2] += (T##_f[1] > S##_f[1]); \ - S##_f[3] += (T##_f[2] > S##_f[2]); \ - _FP_FRAC_DEC_4(X, T); \ - R##_f[0] += q; \ - } \ - _FP_FRAC_SLL_4(X, 1); \ - q >>= 1; \ - } \ - if (!_FP_FRAC_ZEROP_4(X)) \ - { \ - if (_FP_FRAC_GT_4(X,S)) \ - R##_f[0] |= _FP_WORK_ROUND; \ - R##_f[0] |= _FP_WORK_STICKY; \ - } \ - } while (0) +#define _FP_SQRT_MEAT_4(R, S, T, X, q) \ + do \ + { \ + while (q) \ + { \ + T##_f[3] = S##_f[3] + q; \ + if (T##_f[3] <= X##_f[3]) \ + { \ + S##_f[3] = T##_f[3] + q; \ + X##_f[3] -= T##_f[3]; \ + R##_f[3] += q; \ + } \ + _FP_FRAC_SLL_4 (X, 1); \ + q >>= 1; \ + } \ + q = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \ + while (q) \ + { \ + T##_f[2] = S##_f[2] + q; \ + T##_f[3] = S##_f[3]; \ + if (T##_f[3] < X##_f[3] \ + || (T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2])) \ + { \ + S##_f[2] = T##_f[2] + q; \ + S##_f[3] += (T##_f[2] > S##_f[2]); \ + __FP_FRAC_DEC_2 (X##_f[3], X##_f[2], \ + T##_f[3], T##_f[2]); \ + R##_f[2] += q; \ + } \ + _FP_FRAC_SLL_4 (X, 1); \ + q >>= 1; \ + } \ + q = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \ + while (q) \ + { \ + T##_f[1] = S##_f[1] + q; \ + T##_f[2] = S##_f[2]; \ + T##_f[3] = S##_f[3]; \ + if (T##_f[3] < X##_f[3] \ + || (T##_f[3] == X##_f[3] \ + && (T##_f[2] < X##_f[2] \ + || (T##_f[2] == X##_f[2] \ + && T##_f[1] <= X##_f[1])))) \ + { \ + S##_f[1] = T##_f[1] + q; \ + S##_f[2] += (T##_f[1] > S##_f[1]); \ + S##_f[3] += (T##_f[2] > S##_f[2]); \ + __FP_FRAC_DEC_3 (X##_f[3], X##_f[2], X##_f[1], \ + T##_f[3], T##_f[2], T##_f[1]); \ + R##_f[1] += q; \ + } \ + _FP_FRAC_SLL_4 (X, 1); \ + q >>= 1; \ + } \ + q = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \ + while (q != _FP_WORK_ROUND) \ + { \ + T##_f[0] = S##_f[0] + q; \ + T##_f[1] = S##_f[1]; \ + T##_f[2] = S##_f[2]; \ + T##_f[3] = S##_f[3]; \ + if (_FP_FRAC_GE_4 (X, T)) \ + { \ + S##_f[0] = T##_f[0] + q; \ + S##_f[1] += (T##_f[0] > S##_f[0]); \ + S##_f[2] += (T##_f[1] > S##_f[1]); \ + S##_f[3] += (T##_f[2] > S##_f[2]); \ + _FP_FRAC_DEC_4 (X, T); \ + R##_f[0] += q; \ + } \ + _FP_FRAC_SLL_4 (X, 1); \ + q >>= 1; \ + } \ + if (!_FP_FRAC_ZEROP_4 (X)) \ + { \ + if (_FP_FRAC_GT_4 (X, S)) \ + R##_f[0] |= _FP_WORK_ROUND; \ + R##_f[0] |= _FP_WORK_STICKY; \ + } \ + } \ + while (0) /* * Internals */ -#define __FP_FRAC_SET_4(X,I3,I2,I1,I0) \ +#define __FP_FRAC_SET_4(X, I3, I2, I1, I0) \ (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0) #ifndef __FP_FRAC_ADD_3 -#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ - do { \ - _FP_W_TYPE _c1, _c2; \ - r0 = x0 + y0; \ - _c1 = r0 < x0; \ - r1 = x1 + y1; \ - _c2 = r1 < x1; \ - r1 += _c1; \ - _c2 |= r1 < _c1; \ - r2 = x2 + y2 + _c2; \ - } while (0) +# define __FP_FRAC_ADD_3(r2, r1, r0, x2, x1, x0, y2, y1, y0) \ + do \ + { \ + _FP_W_TYPE __FP_FRAC_ADD_3_c1, __FP_FRAC_ADD_3_c2; \ + r0 = x0 + y0; \ + __FP_FRAC_ADD_3_c1 = r0 < x0; \ + r1 = x1 + y1; \ + __FP_FRAC_ADD_3_c2 = r1 < x1; \ + r1 += __FP_FRAC_ADD_3_c1; \ + __FP_FRAC_ADD_3_c2 |= r1 < __FP_FRAC_ADD_3_c1; \ + r2 = x2 + y2 + __FP_FRAC_ADD_3_c2; \ + } \ + while (0) #endif #ifndef __FP_FRAC_ADD_4 -#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ - do { \ - _FP_W_TYPE _c1, _c2, _c3; \ - r0 = x0 + y0; \ - _c1 = r0 < x0; \ - r1 = x1 + y1; \ - _c2 = r1 < x1; \ - r1 += _c1; \ - _c2 |= r1 < _c1; \ - r2 = x2 + y2; \ - _c3 = r2 < x2; \ - r2 += _c2; \ - _c3 |= r2 < _c2; \ - r3 = x3 + y3 + _c3; \ - } while (0) +# define __FP_FRAC_ADD_4(r3, r2, r1, r0, x3, x2, x1, x0, y3, y2, y1, y0) \ + do \ + { \ + _FP_W_TYPE _c1, _c2, _c3; \ + r0 = x0 + y0; \ + _c1 = r0 < x0; \ + r1 = x1 + y1; \ + _c2 = r1 < x1; \ + r1 += _c1; \ + _c2 |= r1 < _c1; \ + r2 = x2 + y2; \ + _c3 = r2 < x2; \ + r2 += _c2; \ + _c3 |= r2 < _c2; \ + r3 = x3 + y3 + _c3; \ + } \ + while (0) #endif #ifndef __FP_FRAC_SUB_3 -#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \ - do { \ - _FP_W_TYPE _c1, _c2; \ - r0 = x0 - y0; \ - _c1 = r0 > x0; \ - r1 = x1 - y1; \ - _c2 = r1 > x1; \ - r1 -= _c1; \ - _c2 |= _c1 && (y1 == x1); \ - r2 = x2 - y2 - _c2; \ - } while (0) +# define __FP_FRAC_SUB_3(r2, r1, r0, x2, x1, x0, y2, y1, y0) \ + do \ + { \ + _FP_W_TYPE _c1, _c2; \ + r0 = x0 - y0; \ + _c1 = r0 > x0; \ + r1 = x1 - y1; \ + _c2 = r1 > x1; \ + r1 -= _c1; \ + _c2 |= _c1 && (y1 == x1); \ + r2 = x2 - y2 - _c2; \ + } \ + while (0) #endif #ifndef __FP_FRAC_SUB_4 -#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ - do { \ - _FP_W_TYPE _c1, _c2, _c3; \ - r0 = x0 - y0; \ - _c1 = r0 > x0; \ - r1 = x1 - y1; \ - _c2 = r1 > x1; \ - r1 -= _c1; \ - _c2 |= _c1 && (y1 == x1); \ - r2 = x2 - y2; \ - _c3 = r2 > x2; \ - r2 -= _c2; \ - _c3 |= _c2 && (y2 == x2); \ - r3 = x3 - y3 - _c3; \ - } while (0) +# define __FP_FRAC_SUB_4(r3, r2, r1, r0, x3, x2, x1, x0, y3, y2, y1, y0) \ + do \ + { \ + _FP_W_TYPE _c1, _c2, _c3; \ + r0 = x0 - y0; \ + _c1 = r0 > x0; \ + r1 = x1 - y1; \ + _c2 = r1 > x1; \ + r1 -= _c1; \ + _c2 |= _c1 && (y1 == x1); \ + r2 = x2 - y2; \ + _c3 = r2 > x2; \ + r2 -= _c2; \ + _c3 |= _c2 && (y2 == x2); \ + r3 = x3 - y3 - _c3; \ + } \ + while (0) #endif #ifndef __FP_FRAC_DEC_3 -#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) \ - do { \ - UWtype _t0, _t1, _t2; \ - _t0 = x0, _t1 = x1, _t2 = x2; \ - __FP_FRAC_SUB_3 (x2, x1, x0, _t2, _t1, _t0, y2, y1, y0); \ - } while (0) +# define __FP_FRAC_DEC_3(x2, x1, x0, y2, y1, y0) \ + do \ + { \ + UWtype _t0, _t1, _t2; \ + _t0 = x0, _t1 = x1, _t2 = x2; \ + __FP_FRAC_SUB_3 (x2, x1, x0, _t2, _t1, _t0, y2, y1, y0); \ + } \ + while (0) #endif #ifndef __FP_FRAC_DEC_4 -#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) \ - do { \ - UWtype _t0, _t1, _t2, _t3; \ - _t0 = x0, _t1 = x1, _t2 = x2, _t3 = x3; \ - __FP_FRAC_SUB_4 (x3,x2,x1,x0,_t3,_t2,_t1,_t0, y3,y2,y1,y0); \ - } while (0) +# define __FP_FRAC_DEC_4(x3, x2, x1, x0, y3, y2, y1, y0) \ + do \ + { \ + UWtype _t0, _t1, _t2, _t3; \ + _t0 = x0, _t1 = x1, _t2 = x2, _t3 = x3; \ + __FP_FRAC_SUB_4 (x3, x2, x1, x0, _t3, _t2, _t1, _t0, y3, y2, y1, y0); \ + } \ + while (0) #endif #ifndef __FP_FRAC_ADDI_4 -#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \ - do { \ - UWtype _t; \ - _t = ((x0 += i) < i); \ - x1 += _t; _t = (x1 < _t); \ - x2 += _t; _t = (x2 < _t); \ - x3 += _t; \ - } while (0) +# define __FP_FRAC_ADDI_4(x3, x2, x1, x0, i) \ + do \ + { \ + UWtype _t; \ + _t = ((x0 += i) < i); \ + x1 += _t; \ + _t = (x1 < _t); \ + x2 += _t; \ + _t = (x2 < _t); \ + x3 += _t; \ + } \ + while (0) #endif /* Convert FP values between word sizes. This appears to be more @@ -625,38 +690,42 @@ #define _FP_FRAC_COPY_1_4(D, S) (D##_f = S##_f[0]) #define _FP_FRAC_COPY_2_4(D, S) \ -do { \ - D##_f0 = S##_f[0]; \ - D##_f1 = S##_f[1]; \ -} while (0) + do \ + { \ + D##_f0 = S##_f[0]; \ + D##_f1 = S##_f[1]; \ + } \ + while (0) /* Assembly/disassembly for converting to/from integral types. * No shifting or overflow handled here. */ /* Put the FP value X into r, which is an integer of size rsize. */ #define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \ - do { \ - if (rsize <= _FP_W_TYPE_SIZE) \ - r = X##_f[0]; \ - else if (rsize <= 2*_FP_W_TYPE_SIZE) \ - { \ - r = X##_f[1]; \ - r <<= _FP_W_TYPE_SIZE; \ - r += X##_f[0]; \ - } \ - else \ + do \ { \ - /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \ - /* and int == 4words as a single case. */ \ - r = X##_f[3]; \ - r <<= _FP_W_TYPE_SIZE; \ - r += X##_f[2]; \ - r <<= _FP_W_TYPE_SIZE; \ - r += X##_f[1]; \ - r <<= _FP_W_TYPE_SIZE; \ - r += X##_f[0]; \ + if (rsize <= _FP_W_TYPE_SIZE) \ + r = X##_f[0]; \ + else if (rsize <= 2*_FP_W_TYPE_SIZE) \ + { \ + r = X##_f[1]; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f[0]; \ + } \ + else \ + { \ + /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \ + /* and int == 4words as a single case. */ \ + r = X##_f[3]; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f[2]; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f[1]; \ + r <<= _FP_W_TYPE_SIZE; \ + r += X##_f[0]; \ + } \ } \ - } while (0) + while (0) /* "No disassemble Number Five!" */ /* move an integer of size rsize into X's fractional part. We rely on @@ -664,24 +733,30 @@ do { \ * having to mask the values we store into it. */ #define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \ - do { \ - X##_f[0] = r; \ - X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ - X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \ - X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \ - } while (0); + do \ + { \ + X##_f[0] = r; \ + X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \ + X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \ + X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \ + } \ + while (0) #define _FP_FRAC_COPY_4_1(D, S) \ -do { \ - D##_f[0] = S##_f; \ - D##_f[1] = D##_f[2] = D##_f[3] = 0; \ -} while (0) + do \ + { \ + D##_f[0] = S##_f; \ + D##_f[1] = D##_f[2] = D##_f[3] = 0; \ + } \ + while (0) #define _FP_FRAC_COPY_4_2(D, S) \ -do { \ - D##_f[0] = S##_f0; \ - D##_f[1] = S##_f1; \ - D##_f[2] = D##_f[3] = 0; \ -} while (0) - -#define _FP_FRAC_COPY_4_4(D,S) _FP_FRAC_COPY_4(D,S) + do \ + { \ + D##_f[0] = S##_f0; \ + D##_f[1] = S##_f1; \ + D##_f[2] = D##_f[3] = 0; \ + } \ + while (0) + +#define _FP_FRAC_COPY_4_4(D, S) _FP_FRAC_COPY_4 (D, S) diff --git a/libgcc/soft-fp/op-8.h b/libgcc/soft-fp/op-8.h index 8890d02201c..f1b23db80db 100644 --- a/libgcc/soft-fp/op-8.h +++ b/libgcc/soft-fp/op-8.h @@ -34,47 +34,51 @@ #define _FP_FRAC_DECL_8(X) _FP_W_TYPE X##_f[8] #define _FP_FRAC_HIGH_8(X) (X##_f[7]) #define _FP_FRAC_LOW_8(X) (X##_f[0]) -#define _FP_FRAC_WORD_8(X,w) (X##_f[w]) +#define _FP_FRAC_WORD_8(X, w) (X##_f[w]) -#define _FP_FRAC_SLL_8(X,N) \ - do { \ - _FP_I_TYPE _up, _down, _skip, _i; \ - _skip = (N) / _FP_W_TYPE_SIZE; \ - _up = (N) % _FP_W_TYPE_SIZE; \ - _down = _FP_W_TYPE_SIZE - _up; \ - if (!_up) \ - for (_i = 7; _i >= _skip; --_i) \ - X##_f[_i] = X##_f[_i-_skip]; \ - else \ - { \ - for (_i = 7; _i > _skip; --_i) \ - X##_f[_i] = X##_f[_i-_skip] << _up \ - | X##_f[_i-_skip-1] >> _down; \ - X##_f[_i--] = X##_f[0] << _up; \ - } \ - for (; _i >= 0; --_i) \ - X##_f[_i] = 0; \ - } while (0) +#define _FP_FRAC_SLL_8(X, N) \ + do \ + { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _up = (N) % _FP_W_TYPE_SIZE; \ + _down = _FP_W_TYPE_SIZE - _up; \ + if (!_up) \ + for (_i = 7; _i >= _skip; --_i) \ + X##_f[_i] = X##_f[_i-_skip]; \ + else \ + { \ + for (_i = 7; _i > _skip; --_i) \ + X##_f[_i] = (X##_f[_i-_skip] << _up \ + | X##_f[_i-_skip-1] >> _down); \ + X##_f[_i--] = X##_f[0] << _up; \ + } \ + for (; _i >= 0; --_i) \ + X##_f[_i] = 0; \ + } \ + while (0) -#define _FP_FRAC_SRL_8(X,N) \ - do { \ - _FP_I_TYPE _up, _down, _skip, _i; \ - _skip = (N) / _FP_W_TYPE_SIZE; \ - _down = (N) % _FP_W_TYPE_SIZE; \ - _up = _FP_W_TYPE_SIZE - _down; \ - if (!_down) \ - for (_i = 0; _i <= 7-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip]; \ - else \ - { \ - for (_i = 0; _i < 7-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip] >> _down \ - | X##_f[_i+_skip+1] << _up; \ - X##_f[_i++] = X##_f[7] >> _down; \ - } \ - for (; _i < 8; ++_i) \ - X##_f[_i] = 0; \ - } while (0) +#define _FP_FRAC_SRL_8(X, N) \ + do \ + { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _down = (N) % _FP_W_TYPE_SIZE; \ + _up = _FP_W_TYPE_SIZE - _down; \ + if (!_down) \ + for (_i = 0; _i <= 7-_skip; ++_i) \ + X##_f[_i] = X##_f[_i+_skip]; \ + else \ + { \ + for (_i = 0; _i < 7-_skip; ++_i) \ + X##_f[_i] = (X##_f[_i+_skip] >> _down \ + | X##_f[_i+_skip+1] << _up); \ + X##_f[_i++] = X##_f[7] >> _down; \ + } \ + for (; _i < 8; ++_i) \ + X##_f[_i] = 0; \ + } \ + while (0) /* Right shift with sticky-lsb. @@ -82,28 +86,31 @@ * but that if any of the bits that fall off the right hand side * were one then we always set the LSbit. */ -#define _FP_FRAC_SRS_8(X,N,size) \ - do { \ - _FP_I_TYPE _up, _down, _skip, _i; \ - _FP_W_TYPE _s; \ - _skip = (N) / _FP_W_TYPE_SIZE; \ - _down = (N) % _FP_W_TYPE_SIZE; \ - _up = _FP_W_TYPE_SIZE - _down; \ - for (_s = _i = 0; _i < _skip; ++_i) \ - _s |= X##_f[_i]; \ - if (!_down) \ - for (_i = 0; _i <= 7-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip]; \ - else \ - { \ - _s |= X##_f[_i] << _up; \ - for (_i = 0; _i < 7-_skip; ++_i) \ - X##_f[_i] = X##_f[_i+_skip] >> _down \ - | X##_f[_i+_skip+1] << _up; \ - X##_f[_i++] = X##_f[7] >> _down; \ - } \ - for (; _i < 8; ++_i) \ - X##_f[_i] = 0; \ - /* don't fix the LSB until the very end when we're sure f[0] is stable */ \ - X##_f[0] |= (_s != 0); \ - } while (0) +#define _FP_FRAC_SRS_8(X, N, size) \ + do \ + { \ + _FP_I_TYPE _up, _down, _skip, _i; \ + _FP_W_TYPE _s; \ + _skip = (N) / _FP_W_TYPE_SIZE; \ + _down = (N) % _FP_W_TYPE_SIZE; \ + _up = _FP_W_TYPE_SIZE - _down; \ + for (_s = _i = 0; _i < _skip; ++_i) \ + _s |= X##_f[_i]; \ + if (!_down) \ + for (_i = 0; _i <= 7-_skip; ++_i) \ + X##_f[_i] = X##_f[_i+_skip]; \ + else \ + { \ + _s |= X##_f[_i] << _up; \ + for (_i = 0; _i < 7-_skip; ++_i) \ + X##_f[_i] = (X##_f[_i+_skip] >> _down \ + | X##_f[_i+_skip+1] << _up); \ + X##_f[_i++] = X##_f[7] >> _down; \ + } \ + for (; _i < 8; ++_i) \ + X##_f[_i] = 0; \ + /* don't fix the LSB until the very end when we're sure f[0] is \ + stable */ \ + X##_f[0] |= (_s != 0); \ + } \ + while (0) diff --git a/libgcc/soft-fp/op-common.h b/libgcc/soft-fp/op-common.h index c4acb991613..67cdc33b4cf 100644 --- a/libgcc/soft-fp/op-common.h +++ b/libgcc/soft-fp/op-common.h @@ -30,145 +30,157 @@ <http://www.gnu.org/licenses/>. */ #define _FP_DECL(wc, X) \ - _FP_I_TYPE X##_c __attribute__((unused)); \ - _FP_I_TYPE X##_s __attribute__((unused)); \ + _FP_I_TYPE X##_c __attribute__ ((unused)); \ + _FP_I_TYPE X##_s __attribute__ ((unused)); \ _FP_I_TYPE X##_e; \ - _FP_FRAC_DECL_##wc(X) + _FP_FRAC_DECL_##wc (X) /* Test whether the qNaN bit denotes a signaling NaN. */ -#define _FP_FRAC_SNANP(fs, X) \ - ((_FP_QNANNEGATEDP) \ - ? (_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \ - : !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) -#define _FP_FRAC_SNANP_SEMIRAW(fs, X) \ - ((_FP_QNANNEGATEDP) \ - ? (_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs) \ - : !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) +#define _FP_FRAC_SNANP(fs, X) \ + ((_FP_QNANNEGATEDP) \ + ? (_FP_FRAC_HIGH_RAW_##fs (X) & _FP_QNANBIT_##fs) \ + : !(_FP_FRAC_HIGH_RAW_##fs (X) & _FP_QNANBIT_##fs)) +#define _FP_FRAC_SNANP_SEMIRAW(fs, X) \ + ((_FP_QNANNEGATEDP) \ + ? (_FP_FRAC_HIGH_##fs (X) & _FP_QNANBIT_SH_##fs) \ + : !(_FP_FRAC_HIGH_##fs (X) & _FP_QNANBIT_SH_##fs)) /* - * Finish truely unpacking a native fp value by classifying the kind + * Finish truly unpacking a native fp value by classifying the kind * of fp value and normalizing both the exponent and the fraction. */ -#define _FP_UNPACK_CANONICAL(fs, wc, X) \ -do { \ - switch (X##_e) \ - { \ - default: \ - _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ - _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ - X##_e -= _FP_EXPBIAS_##fs; \ - X##_c = FP_CLS_NORMAL; \ - break; \ - \ - case 0: \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - X##_c = FP_CLS_ZERO; \ - else \ - { \ - /* a denormalized number */ \ - _FP_I_TYPE _shift; \ - _FP_FRAC_CLZ_##wc(_shift, X); \ - _shift -= _FP_FRACXBITS_##fs; \ - _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \ - X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \ - X##_c = FP_CLS_NORMAL; \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - } \ - break; \ - \ - case _FP_EXPMAX_##fs: \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - X##_c = FP_CLS_INF; \ - else \ - { \ - X##_c = FP_CLS_NAN; \ - /* Check for signaling NaN */ \ - if (_FP_FRAC_SNANP(fs, X)) \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - } \ - break; \ - } \ -} while (0) +#define _FP_UNPACK_CANONICAL(fs, wc, X) \ + do \ + { \ + switch (X##_e) \ + { \ + default: \ + _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs; \ + _FP_FRAC_SLL_##wc (X, _FP_WORKBITS); \ + X##_e -= _FP_EXPBIAS_##fs; \ + X##_c = FP_CLS_NORMAL; \ + break; \ + \ + case 0: \ + if (_FP_FRAC_ZEROP_##wc (X)) \ + X##_c = FP_CLS_ZERO; \ + else \ + { \ + /* a denormalized number */ \ + _FP_I_TYPE _shift; \ + _FP_FRAC_CLZ_##wc (_shift, X); \ + _shift -= _FP_FRACXBITS_##fs; \ + _FP_FRAC_SLL_##wc (X, (_shift+_FP_WORKBITS)); \ + X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \ + X##_c = FP_CLS_NORMAL; \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + } \ + break; \ + \ + case _FP_EXPMAX_##fs: \ + if (_FP_FRAC_ZEROP_##wc (X)) \ + X##_c = FP_CLS_INF; \ + else \ + { \ + X##_c = FP_CLS_NAN; \ + /* Check for signaling NaN */ \ + if (_FP_FRAC_SNANP (fs, X)) \ + FP_SET_EXCEPTION (FP_EX_INVALID); \ + } \ + break; \ + } \ + } \ + while (0) /* Finish unpacking an fp value in semi-raw mode: the mantissa is shifted by _FP_WORKBITS but the implicit MSB is not inserted and other classification is not done. */ -#define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc(X, _FP_WORKBITS) +#define _FP_UNPACK_SEMIRAW(fs, wc, X) _FP_FRAC_SLL_##wc (X, _FP_WORKBITS) /* A semi-raw value has overflowed to infinity. Adjust the mantissa and exponent appropriately. */ #define _FP_OVERFLOW_SEMIRAW(fs, wc, X) \ -do { \ - if (FP_ROUNDMODE == FP_RND_NEAREST \ - || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \ - || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \ + do \ { \ - X##_e = _FP_EXPMAX_##fs; \ - _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ + if (FP_ROUNDMODE == FP_RND_NEAREST \ + || (FP_ROUNDMODE == FP_RND_PINF && !X##_s) \ + || (FP_ROUNDMODE == FP_RND_MINF && X##_s)) \ + { \ + X##_e = _FP_EXPMAX_##fs; \ + _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ + } \ + else \ + { \ + X##_e = _FP_EXPMAX_##fs - 1; \ + _FP_FRAC_SET_##wc (X, _FP_MAXFRAC_##wc); \ + } \ + FP_SET_EXCEPTION (FP_EX_INEXACT); \ + FP_SET_EXCEPTION (FP_EX_OVERFLOW); \ } \ - else \ - { \ - X##_e = _FP_EXPMAX_##fs - 1; \ - _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ - } \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ -} while (0) + while (0) /* Check for a semi-raw value being a signaling NaN and raise the invalid exception if so. */ -#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \ -do { \ - if (X##_e == _FP_EXPMAX_##fs \ - && !_FP_FRAC_ZEROP_##wc(X) \ - && _FP_FRAC_SNANP_SEMIRAW(fs, X)) \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ -} while (0) +#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X) \ + do \ + { \ + if (X##_e == _FP_EXPMAX_##fs \ + && !_FP_FRAC_ZEROP_##wc (X) \ + && _FP_FRAC_SNANP_SEMIRAW (fs, X)) \ + FP_SET_EXCEPTION (FP_EX_INVALID); \ + } \ + while (0) /* Choose a NaN result from an operation on two semi-raw NaN values. */ #define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP) \ -do { \ - /* _FP_CHOOSENAN expects raw values, so shift as required. */ \ - _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ - _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS); \ - _FP_CHOOSENAN(fs, wc, R, X, Y, OP); \ - _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ -} while (0) + do \ + { \ + /* _FP_CHOOSENAN expects raw values, so shift as required. */ \ + _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \ + _FP_FRAC_SRL_##wc (Y, _FP_WORKBITS); \ + _FP_CHOOSENAN (fs, wc, R, X, Y, OP); \ + _FP_FRAC_SLL_##wc (R, _FP_WORKBITS); \ + } \ + while (0) /* Make the fractional part a quiet NaN, preserving the payload if possible, otherwise make it the canonical quiet NaN and set the sign bit accordingly. */ -#define _FP_SETQNAN(fs, wc, X) \ -do { \ - if (_FP_QNANNEGATEDP) \ - { \ - _FP_FRAC_HIGH_RAW_##fs(X) &= _FP_QNANBIT_##fs - 1; \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - X##_s = _FP_NANSIGN_##fs; \ - _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ - } \ - } \ - else \ - _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \ -} while (0) -#define _FP_SETQNAN_SEMIRAW(fs, wc, X) \ -do { \ - if (_FP_QNANNEGATEDP) \ - { \ - _FP_FRAC_HIGH_##fs(X) &= _FP_QNANBIT_SH_##fs - 1; \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - X##_s = _FP_NANSIGN_##fs; \ - _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ - _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \ - } \ - } \ - else \ - _FP_FRAC_HIGH_##fs(X) |= _FP_QNANBIT_SH_##fs; \ -} while (0) +#define _FP_SETQNAN(fs, wc, X) \ + do \ + { \ + if (_FP_QNANNEGATEDP) \ + { \ + _FP_FRAC_HIGH_RAW_##fs (X) &= _FP_QNANBIT_##fs - 1; \ + if (_FP_FRAC_ZEROP_##wc (X)) \ + { \ + X##_s = _FP_NANSIGN_##fs; \ + _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \ + } \ + } \ + else \ + _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_QNANBIT_##fs; \ + } \ + while (0) +#define _FP_SETQNAN_SEMIRAW(fs, wc, X) \ + do \ + { \ + if (_FP_QNANNEGATEDP) \ + { \ + _FP_FRAC_HIGH_##fs (X) &= _FP_QNANBIT_SH_##fs - 1; \ + if (_FP_FRAC_ZEROP_##wc (X)) \ + { \ + X##_s = _FP_NANSIGN_##fs; \ + _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \ + _FP_FRAC_SLL_##wc (X, _FP_WORKBITS); \ + } \ + } \ + else \ + _FP_FRAC_HIGH_##fs (X) |= _FP_QNANBIT_SH_##fs; \ + } \ + while (0) /* Test whether a biased exponent is normal (not zero or maximum). */ #define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1) @@ -177,34 +189,36 @@ do { \ rounded and shifted right, with the rounding possibly increasing the exponent (including changing a finite value to infinity). */ #define _FP_PACK_SEMIRAW(fs, wc, X) \ -do { \ - _FP_ROUND(wc, X); \ - if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc(X)) \ - { \ + do \ + { \ + _FP_ROUND (wc, X); \ + if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X)) \ + { \ if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \ || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \ - FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ - } \ - if (_FP_FRAC_HIGH_##fs(X) \ - & (_FP_OVERFLOW_##fs >> 1)) \ - { \ - _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1); \ - X##_e++; \ - if (X##_e == _FP_EXPMAX_##fs) \ - _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ - } \ - _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ - if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ - { \ - if (!_FP_KEEPNANFRACP) \ + FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \ + } \ + if (_FP_FRAC_HIGH_##fs (X) \ + & (_FP_OVERFLOW_##fs >> 1)) \ { \ - _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ - X##_s = _FP_NANSIGN_##fs; \ + _FP_FRAC_HIGH_##fs (X) &= ~(_FP_OVERFLOW_##fs >> 1); \ + X##_e++; \ + if (X##_e == _FP_EXPMAX_##fs) \ + _FP_OVERFLOW_SEMIRAW (fs, wc, X); \ + } \ + _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \ + if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \ + { \ + if (!_FP_KEEPNANFRACP) \ + { \ + _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \ + X##_s = _FP_NANSIGN_##fs; \ + } \ + else \ + _FP_SETQNAN (fs, wc, X); \ } \ - else \ - _FP_SETQNAN(fs, wc, X); \ } \ -} while (0) + while (0) /* * Before packing the bits back into the native fp result, take care @@ -213,701 +227,927 @@ do { \ * extracted -- but that is ok, we can regenerate them now. */ -#define _FP_PACK_CANONICAL(fs, wc, X) \ -do { \ - switch (X##_c) \ - { \ - case FP_CLS_NORMAL: \ - X##_e += _FP_EXPBIAS_##fs; \ - if (X##_e > 0) \ - { \ - _FP_ROUND(wc, X); \ - if (_FP_FRAC_OVERP_##wc(fs, X)) \ - { \ - _FP_FRAC_CLEAR_OVERP_##wc(fs, X); \ - X##_e++; \ - } \ - _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ - if (X##_e >= _FP_EXPMAX_##fs) \ - { \ - /* overflow */ \ - switch (FP_ROUNDMODE) \ - { \ - case FP_RND_NEAREST: \ - X##_c = FP_CLS_INF; \ - break; \ - case FP_RND_PINF: \ - if (!X##_s) X##_c = FP_CLS_INF; \ - break; \ - case FP_RND_MINF: \ - if (X##_s) X##_c = FP_CLS_INF; \ - break; \ - } \ - if (X##_c == FP_CLS_INF) \ - { \ - /* Overflow to infinity */ \ - X##_e = _FP_EXPMAX_##fs; \ - _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ - } \ - else \ - { \ - /* Overflow to maximum normal */ \ - X##_e = _FP_EXPMAX_##fs - 1; \ - _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc); \ - } \ - FP_SET_EXCEPTION(FP_EX_OVERFLOW); \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - } \ - } \ - else \ - { \ - /* we've got a denormalized number */ \ - X##_e = -X##_e + 1; \ - if (X##_e <= _FP_WFRACBITS_##fs) \ - { \ - _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \ - _FP_ROUND(wc, X); \ - if (_FP_FRAC_HIGH_##fs(X) \ - & (_FP_OVERFLOW_##fs >> 1)) \ - { \ - X##_e = 1; \ - _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - } \ - else \ - { \ - X##_e = 0; \ - _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ - } \ - if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \ - || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \ - FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ - } \ - else \ - { \ - /* underflow to zero */ \ - X##_e = 0; \ - if (!_FP_FRAC_ZEROP_##wc(X)) \ - { \ - _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ - _FP_ROUND(wc, X); \ - _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS); \ - } \ - FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ - } \ - } \ - break; \ - \ - case FP_CLS_ZERO: \ - X##_e = 0; \ - _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ - break; \ - \ - case FP_CLS_INF: \ - X##_e = _FP_EXPMAX_##fs; \ - _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ - break; \ - \ - case FP_CLS_NAN: \ - X##_e = _FP_EXPMAX_##fs; \ - if (!_FP_KEEPNANFRACP) \ - { \ - _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \ - X##_s = _FP_NANSIGN_##fs; \ - } \ - else \ - _FP_SETQNAN(fs, wc, X); \ - break; \ - } \ -} while (0) +#define _FP_PACK_CANONICAL(fs, wc, X) \ + do \ + { \ + switch (X##_c) \ + { \ + case FP_CLS_NORMAL: \ + X##_e += _FP_EXPBIAS_##fs; \ + if (X##_e > 0) \ + { \ + _FP_ROUND (wc, X); \ + if (_FP_FRAC_OVERP_##wc (fs, X)) \ + { \ + _FP_FRAC_CLEAR_OVERP_##wc (fs, X); \ + X##_e++; \ + } \ + _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \ + if (X##_e >= _FP_EXPMAX_##fs) \ + { \ + /* overflow */ \ + switch (FP_ROUNDMODE) \ + { \ + case FP_RND_NEAREST: \ + X##_c = FP_CLS_INF; \ + break; \ + case FP_RND_PINF: \ + if (!X##_s) \ + X##_c = FP_CLS_INF; \ + break; \ + case FP_RND_MINF: \ + if (X##_s) \ + X##_c = FP_CLS_INF; \ + break; \ + } \ + if (X##_c == FP_CLS_INF) \ + { \ + /* Overflow to infinity */ \ + X##_e = _FP_EXPMAX_##fs; \ + _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ + } \ + else \ + { \ + /* Overflow to maximum normal */ \ + X##_e = _FP_EXPMAX_##fs - 1; \ + _FP_FRAC_SET_##wc (X, _FP_MAXFRAC_##wc); \ + } \ + FP_SET_EXCEPTION (FP_EX_OVERFLOW); \ + FP_SET_EXCEPTION (FP_EX_INEXACT); \ + } \ + } \ + else \ + { \ + /* we've got a denormalized number */ \ + X##_e = -X##_e + 1; \ + if (X##_e <= _FP_WFRACBITS_##fs) \ + { \ + _FP_FRAC_SRS_##wc (X, X##_e, _FP_WFRACBITS_##fs); \ + _FP_ROUND (wc, X); \ + if (_FP_FRAC_HIGH_##fs (X) \ + & (_FP_OVERFLOW_##fs >> 1)) \ + { \ + X##_e = 1; \ + _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ + FP_SET_EXCEPTION (FP_EX_INEXACT); \ + } \ + else \ + { \ + X##_e = 0; \ + _FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \ + } \ + if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \ + || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \ + FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \ + } \ + else \ + { \ + /* underflow to zero */ \ + X##_e = 0; \ + if (!_FP_FRAC_ZEROP_##wc (X)) \ + { \ + _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc); \ + _FP_ROUND (wc, X); \ + _FP_FRAC_LOW_##wc (X) >>= (_FP_WORKBITS); \ + } \ + FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \ + } \ + } \ + break; \ + \ + case FP_CLS_ZERO: \ + X##_e = 0; \ + _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ + break; \ + \ + case FP_CLS_INF: \ + X##_e = _FP_EXPMAX_##fs; \ + _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ + break; \ + \ + case FP_CLS_NAN: \ + X##_e = _FP_EXPMAX_##fs; \ + if (!_FP_KEEPNANFRACP) \ + { \ + _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs); \ + X##_s = _FP_NANSIGN_##fs; \ + } \ + else \ + _FP_SETQNAN (fs, wc, X); \ + break; \ + } \ + } \ + while (0) /* This one accepts raw argument and not cooked, returns * 1 if X is a signaling NaN. */ -#define _FP_ISSIGNAN(fs, wc, X) \ -({ \ - int __ret = 0; \ - if (X##_e == _FP_EXPMAX_##fs) \ - { \ - if (!_FP_FRAC_ZEROP_##wc(X) \ - && _FP_FRAC_SNANP(fs, X)) \ - __ret = 1; \ - } \ - __ret; \ -}) +#define _FP_ISSIGNAN(fs, wc, X) \ + ({ \ + int __ret = 0; \ + if (X##_e == _FP_EXPMAX_##fs) \ + { \ + if (!_FP_FRAC_ZEROP_##wc (X) \ + && _FP_FRAC_SNANP (fs, X)) \ + __ret = 1; \ + } \ + __ret; \ + }) /* Addition on semi-raw values. */ -#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \ -do { \ - if (X##_s == Y##_s) \ - { \ - /* Addition. */ \ - R##_s = X##_s; \ - int ediff = X##_e - Y##_e; \ - if (ediff > 0) \ - { \ - R##_e = X##_e; \ - if (Y##_e == 0) \ - { \ - /* Y is zero or denormalized. */ \ - if (_FP_FRAC_ZEROP_##wc(Y)) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto add_done; \ - } \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - ediff--; \ - if (ediff == 0) \ - { \ - _FP_FRAC_ADD_##wc(R, X, Y); \ - goto add3; \ - } \ - if (X##_e == _FP_EXPMAX_##fs) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto add_done; \ - } \ - goto add1; \ - } \ - } \ - else if (X##_e == _FP_EXPMAX_##fs) \ - { \ - /* X is NaN or Inf, Y is normal. */ \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto add_done; \ - } \ - \ - /* Insert implicit MSB of Y. */ \ - _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ - \ - add1: \ - /* Shift the mantissa of Y to the right EDIFF steps; \ - remember to account later for the implicit MSB of X. */ \ - if (ediff <= _FP_WFRACBITS_##fs) \ - _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ - else if (!_FP_FRAC_ZEROP_##wc(Y)) \ - _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ - _FP_FRAC_ADD_##wc(R, X, Y); \ - } \ - else if (ediff < 0) \ - { \ - ediff = -ediff; \ - R##_e = Y##_e; \ - if (X##_e == 0) \ - { \ - /* X is zero or denormalized. */ \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto add_done; \ - } \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - ediff--; \ - if (ediff == 0) \ - { \ - _FP_FRAC_ADD_##wc(R, Y, X); \ - goto add3; \ - } \ - if (Y##_e == _FP_EXPMAX_##fs) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto add_done; \ - } \ - goto add2; \ - } \ - } \ - else if (Y##_e == _FP_EXPMAX_##fs) \ - { \ - /* Y is NaN or Inf, X is normal. */ \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto add_done; \ - } \ - \ - /* Insert implicit MSB of X. */ \ - _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ - \ - add2: \ - /* Shift the mantissa of X to the right EDIFF steps; \ - remember to account later for the implicit MSB of Y. */ \ - if (ediff <= _FP_WFRACBITS_##fs) \ - _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ - else if (!_FP_FRAC_ZEROP_##wc(X)) \ - _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ - _FP_FRAC_ADD_##wc(R, Y, X); \ - } \ - else \ - { \ - /* ediff == 0. */ \ - if (!_FP_EXP_NORMAL(fs, wc, X)) \ - { \ - if (X##_e == 0) \ - { \ - /* X and Y are zero or denormalized. */ \ - R##_e = 0; \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - if (!_FP_FRAC_ZEROP_##wc(Y)) \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto add_done; \ - } \ - else if (_FP_FRAC_ZEROP_##wc(Y)) \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto add_done; \ - } \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_ADD_##wc(R, X, Y); \ - if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ - { \ - /* Normalized result. */ \ - _FP_FRAC_HIGH_##fs(R) \ - &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ - R##_e = 1; \ - } \ - goto add_done; \ - } \ - } \ - else \ - { \ - /* X and Y are NaN or Inf. */ \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - R##_e = _FP_EXPMAX_##fs; \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - _FP_FRAC_COPY_##wc(R, Y); \ - else if (_FP_FRAC_ZEROP_##wc(Y)) \ - _FP_FRAC_COPY_##wc(R, X); \ - else \ - _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ - goto add_done; \ - } \ - } \ - /* The exponents of X and Y, both normal, are equal. The \ - implicit MSBs will always add to increase the \ - exponent. */ \ - _FP_FRAC_ADD_##wc(R, X, Y); \ - R##_e = X##_e + 1; \ - _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ - if (R##_e == _FP_EXPMAX_##fs) \ - /* Overflow to infinity (depending on rounding mode). */ \ - _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ - goto add_done; \ - } \ - add3: \ - if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ - { \ - /* Overflow. */ \ - _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ - R##_e++; \ - _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ - if (R##_e == _FP_EXPMAX_##fs) \ - /* Overflow to infinity (depending on rounding mode). */ \ - _FP_OVERFLOW_SEMIRAW(fs, wc, R); \ - } \ - add_done: ; \ - } \ - else \ - { \ - /* Subtraction. */ \ - int ediff = X##_e - Y##_e; \ - if (ediff > 0) \ - { \ - R##_e = X##_e; \ - R##_s = X##_s; \ - if (Y##_e == 0) \ - { \ - /* Y is zero or denormalized. */ \ - if (_FP_FRAC_ZEROP_##wc(Y)) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto sub_done; \ - } \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - ediff--; \ - if (ediff == 0) \ - { \ - _FP_FRAC_SUB_##wc(R, X, Y); \ - goto sub3; \ - } \ - if (X##_e == _FP_EXPMAX_##fs) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto sub_done; \ - } \ - goto sub1; \ - } \ - } \ - else if (X##_e == _FP_EXPMAX_##fs) \ - { \ - /* X is NaN or Inf, Y is normal. */ \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_FRAC_COPY_##wc(R, X); \ - goto sub_done; \ - } \ - \ - /* Insert implicit MSB of Y. */ \ - _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs; \ - \ - sub1: \ - /* Shift the mantissa of Y to the right EDIFF steps; \ - remember to account later for the implicit MSB of X. */ \ - if (ediff <= _FP_WFRACBITS_##fs) \ - _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs); \ - else if (!_FP_FRAC_ZEROP_##wc(Y)) \ - _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \ - _FP_FRAC_SUB_##wc(R, X, Y); \ - } \ - else if (ediff < 0) \ - { \ - ediff = -ediff; \ - R##_e = Y##_e; \ - R##_s = Y##_s; \ - if (X##_e == 0) \ - { \ - /* X is zero or denormalized. */ \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto sub_done; \ - } \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - ediff--; \ - if (ediff == 0) \ - { \ - _FP_FRAC_SUB_##wc(R, Y, X); \ - goto sub3; \ - } \ - if (Y##_e == _FP_EXPMAX_##fs) \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto sub_done; \ - } \ - goto sub2; \ - } \ - } \ - else if (Y##_e == _FP_EXPMAX_##fs) \ - { \ - /* Y is NaN or Inf, X is normal. */ \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - _FP_FRAC_COPY_##wc(R, Y); \ - goto sub_done; \ - } \ - \ - /* Insert implicit MSB of X. */ \ - _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs; \ - \ - sub2: \ - /* Shift the mantissa of X to the right EDIFF steps; \ - remember to account later for the implicit MSB of Y. */ \ - if (ediff <= _FP_WFRACBITS_##fs) \ - _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs); \ - else if (!_FP_FRAC_ZEROP_##wc(X)) \ - _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \ - _FP_FRAC_SUB_##wc(R, Y, X); \ - } \ - else \ - { \ - /* ediff == 0. */ \ - if (!_FP_EXP_NORMAL(fs, wc, X)) \ - { \ - if (X##_e == 0) \ - { \ - /* X and Y are zero or denormalized. */ \ - R##_e = 0; \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - _FP_FRAC_COPY_##wc(R, Y); \ - if (_FP_FRAC_ZEROP_##wc(Y)) \ - R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - R##_s = Y##_s; \ - } \ - goto sub_done; \ - } \ - else if (_FP_FRAC_ZEROP_##wc(Y)) \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_COPY_##wc(R, X); \ - R##_s = X##_s; \ - goto sub_done; \ - } \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_SUB_##wc(R, X, Y); \ - R##_s = X##_s; \ - if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ - { \ - /* |X| < |Y|, negate result. */ \ - _FP_FRAC_SUB_##wc(R, Y, X); \ - R##_s = Y##_s; \ - } \ - else if (_FP_FRAC_ZEROP_##wc(R)) \ - R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ - goto sub_done; \ - } \ - } \ - else \ - { \ - /* X and Y are NaN or Inf, of opposite signs. */ \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X); \ - _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y); \ - R##_e = _FP_EXPMAX_##fs; \ - if (_FP_FRAC_ZEROP_##wc(X)) \ - { \ - if (_FP_FRAC_ZEROP_##wc(Y)) \ - { \ - /* Inf - Inf. */ \ - R##_s = _FP_NANSIGN_##fs; \ - _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ - _FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - } \ - else \ - { \ - /* Inf - NaN. */ \ - R##_s = Y##_s; \ - _FP_FRAC_COPY_##wc(R, Y); \ - } \ - } \ - else \ - { \ - if (_FP_FRAC_ZEROP_##wc(Y)) \ - { \ - /* NaN - Inf. */ \ - R##_s = X##_s; \ - _FP_FRAC_COPY_##wc(R, X); \ - } \ - else \ - { \ - /* NaN - NaN. */ \ - _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP); \ - } \ - } \ - goto sub_done; \ - } \ - } \ - /* The exponents of X and Y, both normal, are equal. The \ - implicit MSBs cancel. */ \ - R##_e = X##_e; \ - _FP_FRAC_SUB_##wc(R, X, Y); \ - R##_s = X##_s; \ - if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ - { \ - /* |X| < |Y|, negate result. */ \ - _FP_FRAC_SUB_##wc(R, Y, X); \ - R##_s = Y##_s; \ - } \ - else if (_FP_FRAC_ZEROP_##wc(R)) \ - { \ - R##_e = 0; \ - R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ - goto sub_done; \ - } \ - goto norm; \ - } \ - sub3: \ - if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs) \ - { \ - int diff; \ - /* Carry into most significant bit of larger one of X and Y, \ - canceling it; renormalize. */ \ - _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1; \ - norm: \ - _FP_FRAC_CLZ_##wc(diff, R); \ - diff -= _FP_WFRACXBITS_##fs; \ - _FP_FRAC_SLL_##wc(R, diff); \ - if (R##_e <= diff) \ - { \ - /* R is denormalized. */ \ - diff = diff - R##_e + 1; \ - _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs); \ - R##_e = 0; \ - } \ - else \ - { \ - R##_e -= diff; \ - _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ - } \ - } \ - sub_done: ; \ - } \ -} while (0) +#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP) \ + do \ + { \ + if (X##_s == Y##_s) \ + { \ + /* Addition. */ \ + R##_s = X##_s; \ + int ediff = X##_e - Y##_e; \ + if (ediff > 0) \ + { \ + R##_e = X##_e; \ + if (Y##_e == 0) \ + { \ + /* Y is zero or denormalized. */ \ + if (_FP_FRAC_ZEROP_##wc (Y)) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ + _FP_FRAC_COPY_##wc (R, X); \ + goto add_done; \ + } \ + else \ + { \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + ediff--; \ + if (ediff == 0) \ + { \ + _FP_FRAC_ADD_##wc (R, X, Y); \ + goto add3; \ + } \ + if (X##_e == _FP_EXPMAX_##fs) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ + _FP_FRAC_COPY_##wc (R, X); \ + goto add_done; \ + } \ + goto add1; \ + } \ + } \ + else if (X##_e == _FP_EXPMAX_##fs) \ + { \ + /* X is NaN or Inf, Y is normal. */ \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ + _FP_FRAC_COPY_##wc (R, X); \ + goto add_done; \ + } \ + \ + /* Insert implicit MSB of Y. */ \ + _FP_FRAC_HIGH_##fs (Y) |= _FP_IMPLBIT_SH_##fs; \ + \ + add1: \ + /* Shift the mantissa of Y to the right EDIFF steps; \ + remember to account later for the implicit MSB of X. */ \ + if (ediff <= _FP_WFRACBITS_##fs) \ + _FP_FRAC_SRS_##wc (Y, ediff, _FP_WFRACBITS_##fs); \ + else if (!_FP_FRAC_ZEROP_##wc (Y)) \ + _FP_FRAC_SET_##wc (Y, _FP_MINFRAC_##wc); \ + _FP_FRAC_ADD_##wc (R, X, Y); \ + } \ + else if (ediff < 0) \ + { \ + ediff = -ediff; \ + R##_e = Y##_e; \ + if (X##_e == 0) \ + { \ + /* X is zero or denormalized. */ \ + if (_FP_FRAC_ZEROP_##wc (X)) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ + _FP_FRAC_COPY_##wc (R, Y); \ + goto add_done; \ + } \ + else \ + { \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + ediff--; \ + if (ediff == 0) \ + { \ + _FP_FRAC_ADD_##wc (R, Y, X); \ + goto add3; \ + } \ + if (Y##_e == _FP_EXPMAX_##fs) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ + _FP_FRAC_COPY_##wc (R, Y); \ + goto add_done; \ + } \ + goto add2; \ + } \ + } \ + else if (Y##_e == _FP_EXPMAX_##fs) \ + { \ + /* Y is NaN or Inf, X is normal. */ \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ + _FP_FRAC_COPY_##wc (R, Y); \ + goto add_done; \ + } \ + \ + /* Insert implicit MSB of X. */ \ + _FP_FRAC_HIGH_##fs (X) |= _FP_IMPLBIT_SH_##fs; \ + \ + add2: \ + /* Shift the mantissa of X to the right EDIFF steps; \ + remember to account later for the implicit MSB of Y. */ \ + if (ediff <= _FP_WFRACBITS_##fs) \ + _FP_FRAC_SRS_##wc (X, ediff, _FP_WFRACBITS_##fs); \ + else if (!_FP_FRAC_ZEROP_##wc (X)) \ + _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc); \ + _FP_FRAC_ADD_##wc (R, Y, X); \ + } \ + else \ + { \ + /* ediff == 0. */ \ + if (!_FP_EXP_NORMAL (fs, wc, X)) \ + { \ + if (X##_e == 0) \ + { \ + /* X and Y are zero or denormalized. */ \ + R##_e = 0; \ + if (_FP_FRAC_ZEROP_##wc (X)) \ + { \ + if (!_FP_FRAC_ZEROP_##wc (Y)) \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + _FP_FRAC_COPY_##wc (R, Y); \ + goto add_done; \ + } \ + else if (_FP_FRAC_ZEROP_##wc (Y)) \ + { \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + _FP_FRAC_COPY_##wc (R, X); \ + goto add_done; \ + } \ + else \ + { \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + _FP_FRAC_ADD_##wc (R, X, Y); \ + if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \ + { \ + /* Normalized result. */ \ + _FP_FRAC_HIGH_##fs (R) \ + &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \ + R##_e = 1; \ + } \ + goto add_done; \ + } \ + } \ + else \ + { \ + /* X and Y are NaN or Inf. */ \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ + R##_e = _FP_EXPMAX_##fs; \ + if (_FP_FRAC_ZEROP_##wc (X)) \ + _FP_FRAC_COPY_##wc (R, Y); \ + else if (_FP_FRAC_ZEROP_##wc (Y)) \ + _FP_FRAC_COPY_##wc (R, X); \ + else \ + _FP_CHOOSENAN_SEMIRAW (fs, wc, R, X, Y, OP); \ + goto add_done; \ + } \ + } \ + /* The exponents of X and Y, both normal, are equal. The \ + implicit MSBs will always add to increase the \ + exponent. */ \ + _FP_FRAC_ADD_##wc (R, X, Y); \ + R##_e = X##_e + 1; \ + _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \ + if (R##_e == _FP_EXPMAX_##fs) \ + /* Overflow to infinity (depending on rounding mode). */ \ + _FP_OVERFLOW_SEMIRAW (fs, wc, R); \ + goto add_done; \ + } \ + add3: \ + if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \ + { \ + /* Overflow. */ \ + _FP_FRAC_HIGH_##fs (R) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \ + R##_e++; \ + _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \ + if (R##_e == _FP_EXPMAX_##fs) \ + /* Overflow to infinity (depending on rounding mode). */ \ + _FP_OVERFLOW_SEMIRAW (fs, wc, R); \ + } \ + add_done: ; \ + } \ + else \ + { \ + /* Subtraction. */ \ + int ediff = X##_e - Y##_e; \ + if (ediff > 0) \ + { \ + R##_e = X##_e; \ + R##_s = X##_s; \ + if (Y##_e == 0) \ + { \ + /* Y is zero or denormalized. */ \ + if (_FP_FRAC_ZEROP_##wc (Y)) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ + _FP_FRAC_COPY_##wc (R, X); \ + goto sub_done; \ + } \ + else \ + { \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + ediff--; \ + if (ediff == 0) \ + { \ + _FP_FRAC_SUB_##wc (R, X, Y); \ + goto sub3; \ + } \ + if (X##_e == _FP_EXPMAX_##fs) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ + _FP_FRAC_COPY_##wc (R, X); \ + goto sub_done; \ + } \ + goto sub1; \ + } \ + } \ + else if (X##_e == _FP_EXPMAX_##fs) \ + { \ + /* X is NaN or Inf, Y is normal. */ \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ + _FP_FRAC_COPY_##wc (R, X); \ + goto sub_done; \ + } \ + \ + /* Insert implicit MSB of Y. */ \ + _FP_FRAC_HIGH_##fs (Y) |= _FP_IMPLBIT_SH_##fs; \ + \ + sub1: \ + /* Shift the mantissa of Y to the right EDIFF steps; \ + remember to account later for the implicit MSB of X. */ \ + if (ediff <= _FP_WFRACBITS_##fs) \ + _FP_FRAC_SRS_##wc (Y, ediff, _FP_WFRACBITS_##fs); \ + else if (!_FP_FRAC_ZEROP_##wc (Y)) \ + _FP_FRAC_SET_##wc (Y, _FP_MINFRAC_##wc); \ + _FP_FRAC_SUB_##wc (R, X, Y); \ + } \ + else if (ediff < 0) \ + { \ + ediff = -ediff; \ + R##_e = Y##_e; \ + R##_s = Y##_s; \ + if (X##_e == 0) \ + { \ + /* X is zero or denormalized. */ \ + if (_FP_FRAC_ZEROP_##wc (X)) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ + _FP_FRAC_COPY_##wc (R, Y); \ + goto sub_done; \ + } \ + else \ + { \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + ediff--; \ + if (ediff == 0) \ + { \ + _FP_FRAC_SUB_##wc (R, Y, X); \ + goto sub3; \ + } \ + if (Y##_e == _FP_EXPMAX_##fs) \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ + _FP_FRAC_COPY_##wc (R, Y); \ + goto sub_done; \ + } \ + goto sub2; \ + } \ + } \ + else if (Y##_e == _FP_EXPMAX_##fs) \ + { \ + /* Y is NaN or Inf, X is normal. */ \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ + _FP_FRAC_COPY_##wc (R, Y); \ + goto sub_done; \ + } \ + \ + /* Insert implicit MSB of X. */ \ + _FP_FRAC_HIGH_##fs (X) |= _FP_IMPLBIT_SH_##fs; \ + \ + sub2: \ + /* Shift the mantissa of X to the right EDIFF steps; \ + remember to account later for the implicit MSB of Y. */ \ + if (ediff <= _FP_WFRACBITS_##fs) \ + _FP_FRAC_SRS_##wc (X, ediff, _FP_WFRACBITS_##fs); \ + else if (!_FP_FRAC_ZEROP_##wc (X)) \ + _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc); \ + _FP_FRAC_SUB_##wc (R, Y, X); \ + } \ + else \ + { \ + /* ediff == 0. */ \ + if (!_FP_EXP_NORMAL (fs, wc, X)) \ + { \ + if (X##_e == 0) \ + { \ + /* X and Y are zero or denormalized. */ \ + R##_e = 0; \ + if (_FP_FRAC_ZEROP_##wc (X)) \ + { \ + _FP_FRAC_COPY_##wc (R, Y); \ + if (_FP_FRAC_ZEROP_##wc (Y)) \ + R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ + else \ + { \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + R##_s = Y##_s; \ + } \ + goto sub_done; \ + } \ + else if (_FP_FRAC_ZEROP_##wc (Y)) \ + { \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + _FP_FRAC_COPY_##wc (R, X); \ + R##_s = X##_s; \ + goto sub_done; \ + } \ + else \ + { \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + _FP_FRAC_SUB_##wc (R, X, Y); \ + R##_s = X##_s; \ + if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \ + { \ + /* |X| < |Y|, negate result. */ \ + _FP_FRAC_SUB_##wc (R, Y, X); \ + R##_s = Y##_s; \ + } \ + else if (_FP_FRAC_ZEROP_##wc (R)) \ + R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ + goto sub_done; \ + } \ + } \ + else \ + { \ + /* X and Y are NaN or Inf, of opposite signs. */ \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X); \ + _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y); \ + R##_e = _FP_EXPMAX_##fs; \ + if (_FP_FRAC_ZEROP_##wc (X)) \ + { \ + if (_FP_FRAC_ZEROP_##wc (Y)) \ + { \ + /* Inf - Inf. */ \ + R##_s = _FP_NANSIGN_##fs; \ + _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \ + _FP_FRAC_SLL_##wc (R, _FP_WORKBITS); \ + FP_SET_EXCEPTION (FP_EX_INVALID); \ + } \ + else \ + { \ + /* Inf - NaN. */ \ + R##_s = Y##_s; \ + _FP_FRAC_COPY_##wc (R, Y); \ + } \ + } \ + else \ + { \ + if (_FP_FRAC_ZEROP_##wc (Y)) \ + { \ + /* NaN - Inf. */ \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc (R, X); \ + } \ + else \ + { \ + /* NaN - NaN. */ \ + _FP_CHOOSENAN_SEMIRAW (fs, wc, R, X, Y, OP); \ + } \ + } \ + goto sub_done; \ + } \ + } \ + /* The exponents of X and Y, both normal, are equal. The \ + implicit MSBs cancel. */ \ + R##_e = X##_e; \ + _FP_FRAC_SUB_##wc (R, X, Y); \ + R##_s = X##_s; \ + if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \ + { \ + /* |X| < |Y|, negate result. */ \ + _FP_FRAC_SUB_##wc (R, Y, X); \ + R##_s = Y##_s; \ + } \ + else if (_FP_FRAC_ZEROP_##wc (R)) \ + { \ + R##_e = 0; \ + R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ + goto sub_done; \ + } \ + goto norm; \ + } \ + sub3: \ + if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \ + { \ + int diff; \ + /* Carry into most significant bit of larger one of X and Y, \ + canceling it; renormalize. */ \ + _FP_FRAC_HIGH_##fs (R) &= _FP_IMPLBIT_SH_##fs - 1; \ + norm: \ + _FP_FRAC_CLZ_##wc (diff, R); \ + diff -= _FP_WFRACXBITS_##fs; \ + _FP_FRAC_SLL_##wc (R, diff); \ + if (R##_e <= diff) \ + { \ + /* R is denormalized. */ \ + diff = diff - R##_e + 1; \ + _FP_FRAC_SRS_##wc (R, diff, _FP_WFRACBITS_##fs); \ + R##_e = 0; \ + } \ + else \ + { \ + R##_e -= diff; \ + _FP_FRAC_HIGH_##fs (R) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \ + } \ + } \ + sub_done: ; \ + } \ + } \ + while (0) -#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+') -#define _FP_SUB(fs, wc, R, X, Y) \ - do { \ - if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \ - _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-'); \ - } while (0) +#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL (fs, wc, R, X, Y, '+') +#define _FP_SUB(fs, wc, R, X, Y) \ + do \ + { \ + if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))) \ + Y##_s ^= 1; \ + _FP_ADD_INTERNAL (fs, wc, R, X, Y, '-'); \ + } \ + while (0) /* - * Main negation routine. FIXME -- when we care about setting exception - * bits reliably, this will not do. We should examine all of the fp classes. + * Main negation routine. The input value is raw. */ -#define _FP_NEG(fs, wc, R, X) \ - do { \ - _FP_FRAC_COPY_##wc(R, X); \ - R##_c = X##_c; \ - R##_e = X##_e; \ - R##_s = 1 ^ X##_s; \ - } while (0) +#define _FP_NEG(fs, wc, R, X) \ + do \ + { \ + _FP_FRAC_COPY_##wc (R, X); \ + R##_e = X##_e; \ + R##_s = 1 ^ X##_s; \ + } \ + while (0) /* * Main multiplication routine. The input values should be cooked. */ -#define _FP_MUL(fs, wc, R, X, Y) \ -do { \ - R##_s = X##_s ^ Y##_s; \ - R##_e = X##_e + Y##_e + 1; \ - switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ - { \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ - R##_c = FP_CLS_NORMAL; \ - \ - _FP_MUL_MEAT_##fs(R,X,Y); \ - \ - if (_FP_FRAC_OVERP_##wc(fs, R)) \ - _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \ - else \ - R##_e--; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ - _FP_CHOOSENAN(fs, wc, R, X, Y, '*'); \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ - R##_s = X##_s; \ - \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ - _FP_FRAC_COPY_##wc(R, X); \ - R##_c = X##_c; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ - R##_s = Y##_s; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ - _FP_FRAC_COPY_##wc(R, Y); \ - R##_c = Y##_c; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ - R##_s = _FP_NANSIGN_##fs; \ - R##_c = FP_CLS_NAN; \ - _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - break; \ - \ - default: \ - abort(); \ - } \ -} while (0) +#define _FP_MUL(fs, wc, R, X, Y) \ + do \ + { \ + R##_s = X##_s ^ Y##_s; \ + R##_e = X##_e + Y##_e + 1; \ + switch (_FP_CLS_COMBINE (X##_c, Y##_c)) \ + { \ + case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL): \ + R##_c = FP_CLS_NORMAL; \ + \ + _FP_MUL_MEAT_##fs (R, X, Y); \ + \ + if (_FP_FRAC_OVERP_##wc (fs, R)) \ + _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \ + else \ + R##_e--; \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \ + _FP_CHOOSENAN (fs, wc, R, X, Y, '*'); \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \ + R##_s = X##_s; \ + \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \ + _FP_FRAC_COPY_##wc (R, X); \ + R##_c = X##_c; \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN): \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \ + R##_s = Y##_s; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF): \ + case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO): \ + _FP_FRAC_COPY_##wc (R, Y); \ + R##_c = Y##_c; \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \ + R##_s = _FP_NANSIGN_##fs; \ + R##_c = FP_CLS_NAN; \ + _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \ + FP_SET_EXCEPTION (FP_EX_INVALID); \ + break; \ + \ + default: \ + abort (); \ + } \ + } \ + while (0) + + +/* Fused multiply-add. The input values should be cooked. */ + +#define _FP_FMA(fs, wc, dwc, R, X, Y, Z) \ + do \ + { \ + FP_DECL_##fs (T); \ + T##_s = X##_s ^ Y##_s; \ + T##_e = X##_e + Y##_e + 1; \ + switch (_FP_CLS_COMBINE (X##_c, Y##_c)) \ + { \ + case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL): \ + switch (Z##_c) \ + { \ + case FP_CLS_INF: \ + case FP_CLS_NAN: \ + R##_s = Z##_s; \ + _FP_FRAC_COPY_##wc (R, Z); \ + R##_c = Z##_c; \ + break; \ + \ + case FP_CLS_ZERO: \ + R##_c = FP_CLS_NORMAL; \ + R##_s = T##_s; \ + R##_e = T##_e; \ + \ + _FP_MUL_MEAT_##fs (R, X, Y); \ + \ + if (_FP_FRAC_OVERP_##wc (fs, R)) \ + _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs); \ + else \ + R##_e--; \ + break; \ + \ + case FP_CLS_NORMAL:; \ + _FP_FRAC_DECL_##dwc (TD); \ + _FP_FRAC_DECL_##dwc (ZD); \ + _FP_FRAC_DECL_##dwc (RD); \ + _FP_MUL_MEAT_DW_##fs (TD, X, Y); \ + R##_e = T##_e; \ + int tsh = _FP_FRAC_HIGHBIT_DW_##dwc (fs, TD) == 0; \ + T##_e -= tsh; \ + int ediff = T##_e - Z##_e; \ + if (ediff >= 0) \ + { \ + int shift = _FP_WFRACBITS_##fs - tsh - ediff; \ + if (shift <= -_FP_WFRACBITS_##fs) \ + _FP_FRAC_SET_##dwc (ZD, _FP_MINFRAC_##dwc); \ + else \ + { \ + _FP_FRAC_COPY_##dwc##_##wc (ZD, Z); \ + if (shift < 0) \ + _FP_FRAC_SRS_##dwc (ZD, -shift, \ + _FP_WFRACBITS_DW_##fs); \ + else if (shift > 0) \ + _FP_FRAC_SLL_##dwc (ZD, shift); \ + } \ + R##_s = T##_s; \ + if (T##_s == Z##_s) \ + _FP_FRAC_ADD_##dwc (RD, TD, ZD); \ + else \ + { \ + _FP_FRAC_SUB_##dwc (RD, TD, ZD); \ + if (_FP_FRAC_NEGP_##dwc (RD)) \ + { \ + R##_s = Z##_s; \ + _FP_FRAC_SUB_##dwc (RD, ZD, TD); \ + } \ + } \ + } \ + else \ + { \ + R##_e = Z##_e; \ + R##_s = Z##_s; \ + _FP_FRAC_COPY_##dwc##_##wc (ZD, Z); \ + _FP_FRAC_SLL_##dwc (ZD, _FP_WFRACBITS_##fs); \ + int shift = -ediff - tsh; \ + if (shift >= _FP_WFRACBITS_DW_##fs) \ + _FP_FRAC_SET_##dwc (TD, _FP_MINFRAC_##dwc); \ + else if (shift > 0) \ + _FP_FRAC_SRS_##dwc (TD, shift, \ + _FP_WFRACBITS_DW_##fs); \ + if (Z##_s == T##_s) \ + _FP_FRAC_ADD_##dwc (RD, ZD, TD); \ + else \ + _FP_FRAC_SUB_##dwc (RD, ZD, TD); \ + } \ + if (_FP_FRAC_ZEROP_##dwc (RD)) \ + { \ + if (T##_s == Z##_s) \ + R##_s = Z##_s; \ + else \ + R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ + _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ + R##_c = FP_CLS_ZERO; \ + } \ + else \ + { \ + int rlz; \ + _FP_FRAC_CLZ_##dwc (rlz, RD); \ + rlz -= _FP_WFRACXBITS_DW_##fs; \ + R##_e -= rlz; \ + int shift = _FP_WFRACBITS_##fs - rlz; \ + if (shift > 0) \ + _FP_FRAC_SRS_##dwc (RD, shift, \ + _FP_WFRACBITS_DW_##fs); \ + else if (shift < 0) \ + _FP_FRAC_SLL_##dwc (RD, -shift); \ + _FP_FRAC_COPY_##wc##_##dwc (R, RD); \ + R##_c = FP_CLS_NORMAL; \ + } \ + break; \ + } \ + goto done_fma; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \ + _FP_CHOOSENAN (fs, wc, T, X, Y, '*'); \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \ + T##_s = X##_s; \ + \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \ + _FP_FRAC_COPY_##wc (T, X); \ + T##_c = X##_c; \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN): \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \ + T##_s = Y##_s; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF): \ + case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO): \ + _FP_FRAC_COPY_##wc (T, Y); \ + T##_c = Y##_c; \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \ + T##_s = _FP_NANSIGN_##fs; \ + T##_c = FP_CLS_NAN; \ + _FP_FRAC_SET_##wc (T, _FP_NANFRAC_##fs); \ + FP_SET_EXCEPTION (FP_EX_INVALID); \ + break; \ + \ + default: \ + abort (); \ + } \ + \ + /* T = X * Y is zero, infinity or NaN. */ \ + switch (_FP_CLS_COMBINE (T##_c, Z##_c)) \ + { \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \ + _FP_CHOOSENAN (fs, wc, R, T, Z, '+'); \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \ + R##_s = T##_s; \ + _FP_FRAC_COPY_##wc (R, T); \ + R##_c = T##_c; \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \ + R##_s = Z##_s; \ + _FP_FRAC_COPY_##wc (R, Z); \ + R##_c = Z##_c; \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \ + if (T##_s == Z##_s) \ + { \ + R##_s = Z##_s; \ + _FP_FRAC_COPY_##wc (R, Z); \ + R##_c = Z##_c; \ + } \ + else \ + { \ + R##_s = _FP_NANSIGN_##fs; \ + R##_c = FP_CLS_NAN; \ + _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \ + FP_SET_EXCEPTION (FP_EX_INVALID); \ + } \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \ + if (T##_s == Z##_s) \ + R##_s = Z##_s; \ + else \ + R##_s = (FP_ROUNDMODE == FP_RND_MINF); \ + _FP_FRAC_COPY_##wc (R, Z); \ + R##_c = Z##_c; \ + break; \ + \ + default: \ + abort (); \ + } \ + done_fma: ; \ + } \ + while (0) /* * Main division routine. The input values should be cooked. */ -#define _FP_DIV(fs, wc, R, X, Y) \ -do { \ - R##_s = X##_s ^ Y##_s; \ - R##_e = X##_e - Y##_e; \ - switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \ - { \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \ - R##_c = FP_CLS_NORMAL; \ - \ - _FP_DIV_MEAT_##fs(R,X,Y); \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \ - _FP_CHOOSENAN(fs, wc, R, X, Y, '/'); \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \ - R##_s = X##_s; \ - _FP_FRAC_COPY_##wc(R, X); \ - R##_c = X##_c; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \ - R##_s = Y##_s; \ - _FP_FRAC_COPY_##wc(R, Y); \ - R##_c = Y##_c; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \ - R##_c = FP_CLS_ZERO; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \ - FP_SET_EXCEPTION(FP_EX_DIVZERO); \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \ - R##_c = FP_CLS_INF; \ - break; \ - \ - case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \ - case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \ - R##_s = _FP_NANSIGN_##fs; \ - R##_c = FP_CLS_NAN; \ - _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - break; \ - \ - default: \ - abort(); \ - } \ -} while (0) +#define _FP_DIV(fs, wc, R, X, Y) \ + do \ + { \ + R##_s = X##_s ^ Y##_s; \ + R##_e = X##_e - Y##_e; \ + switch (_FP_CLS_COMBINE (X##_c, Y##_c)) \ + { \ + case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL): \ + R##_c = FP_CLS_NORMAL; \ + \ + _FP_DIV_MEAT_##fs (R, X, Y); \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN): \ + _FP_CHOOSENAN (fs, wc, R, X, Y, '/'); \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL): \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF): \ + case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO): \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc (R, X); \ + R##_c = X##_c; \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN): \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN): \ + R##_s = Y##_s; \ + _FP_FRAC_COPY_##wc (R, Y); \ + R##_c = Y##_c; \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL): \ + R##_c = FP_CLS_ZERO; \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO): \ + FP_SET_EXCEPTION (FP_EX_DIVZERO); \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO): \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL): \ + R##_c = FP_CLS_INF; \ + break; \ + \ + case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF): \ + case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO): \ + R##_s = _FP_NANSIGN_##fs; \ + R##_c = FP_CLS_NAN; \ + _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \ + FP_SET_EXCEPTION (FP_EX_INVALID); \ + break; \ + \ + default: \ + abort (); \ + } \ + } \ + while (0) /* @@ -916,122 +1156,131 @@ do { \ */ #define _FP_CMP(fs, wc, ret, X, Y, un) \ - do { \ - /* NANs are unordered */ \ - if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ - || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ - { \ - ret = un; \ - } \ - else \ - { \ - int __is_zero_x; \ - int __is_zero_y; \ + do \ + { \ + /* NANs are unordered */ \ + if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \ + || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))) \ + { \ + ret = un; \ + } \ + else \ + { \ + int __is_zero_x; \ + int __is_zero_y; \ \ - __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \ - __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \ + __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc (X)) ? 1 : 0; \ + __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc (Y)) ? 1 : 0; \ \ - if (__is_zero_x && __is_zero_y) \ - ret = 0; \ - else if (__is_zero_x) \ - ret = Y##_s ? 1 : -1; \ - else if (__is_zero_y) \ - ret = X##_s ? -1 : 1; \ - else if (X##_s != Y##_s) \ - ret = X##_s ? -1 : 1; \ - else if (X##_e > Y##_e) \ - ret = X##_s ? -1 : 1; \ - else if (X##_e < Y##_e) \ - ret = X##_s ? 1 : -1; \ - else if (_FP_FRAC_GT_##wc(X, Y)) \ - ret = X##_s ? -1 : 1; \ - else if (_FP_FRAC_GT_##wc(Y, X)) \ - ret = X##_s ? 1 : -1; \ - else \ - ret = 0; \ - } \ - } while (0) + if (__is_zero_x && __is_zero_y) \ + ret = 0; \ + else if (__is_zero_x) \ + ret = Y##_s ? 1 : -1; \ + else if (__is_zero_y) \ + ret = X##_s ? -1 : 1; \ + else if (X##_s != Y##_s) \ + ret = X##_s ? -1 : 1; \ + else if (X##_e > Y##_e) \ + ret = X##_s ? -1 : 1; \ + else if (X##_e < Y##_e) \ + ret = X##_s ? 1 : -1; \ + else if (_FP_FRAC_GT_##wc (X, Y)) \ + ret = X##_s ? -1 : 1; \ + else if (_FP_FRAC_GT_##wc (Y, X)) \ + ret = X##_s ? 1 : -1; \ + else \ + ret = 0; \ + } \ + } \ + while (0) /* Simplification for strict equality. */ -#define _FP_CMP_EQ(fs, wc, ret, X, Y) \ - do { \ - /* NANs are unordered */ \ - if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ - || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \ - { \ - ret = 1; \ - } \ - else \ - { \ - ret = !(X##_e == Y##_e \ - && _FP_FRAC_EQ_##wc(X, Y) \ - && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \ - } \ - } while (0) +#define _FP_CMP_EQ(fs, wc, ret, X, Y) \ + do \ + { \ + /* NANs are unordered */ \ + if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \ + || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))) \ + { \ + ret = 1; \ + } \ + else \ + { \ + ret = !(X##_e == Y##_e \ + && _FP_FRAC_EQ_##wc (X, Y) \ + && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc (X)))); \ + } \ + } \ + while (0) /* Version to test unordered. */ #define _FP_CMP_UNORD(fs, wc, ret, X, Y) \ - do { \ - ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \ - || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))); \ - } while (0) + do \ + { \ + ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X)) \ + || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))); \ + } \ + while (0) /* * Main square root routine. The input value should be cooked. */ -#define _FP_SQRT(fs, wc, R, X) \ -do { \ - _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \ - _FP_W_TYPE q; \ - switch (X##_c) \ - { \ - case FP_CLS_NAN: \ - _FP_FRAC_COPY_##wc(R, X); \ - R##_s = X##_s; \ - R##_c = FP_CLS_NAN; \ - break; \ - case FP_CLS_INF: \ - if (X##_s) \ - { \ - R##_s = _FP_NANSIGN_##fs; \ - R##_c = FP_CLS_NAN; /* NAN */ \ - _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - } \ - else \ - { \ - R##_s = 0; \ - R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \ - } \ - break; \ - case FP_CLS_ZERO: \ - R##_s = X##_s; \ - R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \ - break; \ - case FP_CLS_NORMAL: \ - R##_s = 0; \ - if (X##_s) \ - { \ - R##_c = FP_CLS_NAN; /* NAN */ \ - R##_s = _FP_NANSIGN_##fs; \ - _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - break; \ - } \ - R##_c = FP_CLS_NORMAL; \ - if (X##_e & 1) \ - _FP_FRAC_SLL_##wc(X, 1); \ - R##_e = X##_e >> 1; \ - _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \ - _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \ - q = _FP_OVERFLOW_##fs >> 1; \ - _FP_SQRT_MEAT_##wc(R, S, T, X, q); \ - } \ - } while (0) +#define _FP_SQRT(fs, wc, R, X) \ + do \ + { \ + _FP_FRAC_DECL_##wc (T); \ + _FP_FRAC_DECL_##wc (S); \ + _FP_W_TYPE q; \ + switch (X##_c) \ + { \ + case FP_CLS_NAN: \ + _FP_FRAC_COPY_##wc (R, X); \ + R##_s = X##_s; \ + R##_c = FP_CLS_NAN; \ + break; \ + case FP_CLS_INF: \ + if (X##_s) \ + { \ + R##_s = _FP_NANSIGN_##fs; \ + R##_c = FP_CLS_NAN; /* NAN */ \ + _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \ + FP_SET_EXCEPTION (FP_EX_INVALID); \ + } \ + else \ + { \ + R##_s = 0; \ + R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \ + } \ + break; \ + case FP_CLS_ZERO: \ + R##_s = X##_s; \ + R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \ + break; \ + case FP_CLS_NORMAL: \ + R##_s = 0; \ + if (X##_s) \ + { \ + R##_c = FP_CLS_NAN; /* NAN */ \ + R##_s = _FP_NANSIGN_##fs; \ + _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \ + FP_SET_EXCEPTION (FP_EX_INVALID); \ + break; \ + } \ + R##_c = FP_CLS_NORMAL; \ + if (X##_e & 1) \ + _FP_FRAC_SLL_##wc (X, 1); \ + R##_e = X##_e >> 1; \ + _FP_FRAC_SET_##wc (S, _FP_ZEROFRAC_##wc); \ + _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ + q = _FP_OVERFLOW_##fs >> 1; \ + _FP_SQRT_MEAT_##wc (R, S, T, X, q); \ + } \ + } \ + while (0) /* * Convert from FP to integer. Input is raw. @@ -1049,292 +1298,306 @@ do { \ * depending on the sign in such case. */ #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \ -do { \ - if (X##_e < _FP_EXPBIAS_##fs) \ + do \ { \ - r = 0; \ - if (X##_e == 0) \ + if (X##_e < _FP_EXPBIAS_##fs) \ { \ - if (!_FP_FRAC_ZEROP_##wc(X)) \ + r = 0; \ + if (X##_e == 0) \ { \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ + if (!_FP_FRAC_ZEROP_##wc (X)) \ + { \ + FP_SET_EXCEPTION (FP_EX_INEXACT); \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + } \ } \ + else \ + FP_SET_EXCEPTION (FP_EX_INEXACT); \ } \ - else \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - } \ - else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \ - || (!rsigned && X##_s)) \ - { \ - /* Overflow or converting to the most negative integer. */ \ - if (rsigned) \ + else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s) \ + || (!rsigned && X##_s)) \ { \ - r = 1; \ - r <<= rsize - 1; \ - r -= 1 - X##_s; \ - } else { \ - r = 0; \ - if (X##_s) \ - r = ~r; \ - } \ + /* Overflow or converting to the most negative integer. */ \ + if (rsigned) \ + { \ + r = 1; \ + r <<= rsize - 1; \ + r -= 1 - X##_s; \ + } else { \ + r = 0; \ + if (!X##_s) \ + r = ~r; \ + } \ \ - if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \ - { \ - /* Possibly converting to most negative integer; check the \ - mantissa. */ \ - int inexact = 0; \ - (void)((_FP_FRACBITS_##fs > rsize) \ - ? ({ _FP_FRAC_SRST_##wc(X, inexact, \ - _FP_FRACBITS_##fs - rsize, \ - _FP_FRACBITS_##fs); 0; }) \ - : 0); \ - if (!_FP_FRAC_ZEROP_##wc(X)) \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - else if (inexact) \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ + if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1) \ + { \ + /* Possibly converting to most negative integer; check the \ + mantissa. */ \ + int inexact = 0; \ + (void) ((_FP_FRACBITS_##fs > rsize) \ + ? ({ \ + _FP_FRAC_SRST_##wc (X, inexact, \ + _FP_FRACBITS_##fs - rsize, \ + _FP_FRACBITS_##fs); \ + 0; \ + }) \ + : 0); \ + if (!_FP_FRAC_ZEROP_##wc (X)) \ + FP_SET_EXCEPTION (FP_EX_INVALID); \ + else if (inexact) \ + FP_SET_EXCEPTION (FP_EX_INEXACT); \ + } \ + else \ + FP_SET_EXCEPTION (FP_EX_INVALID); \ } \ else \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ + { \ + _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs; \ + if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \ + { \ + _FP_FRAC_ASSEMBLE_##wc (r, X, rsize); \ + r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \ + } \ + else \ + { \ + int inexact; \ + _FP_FRAC_SRST_##wc (X, inexact, \ + (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \ + - X##_e), \ + _FP_FRACBITS_##fs); \ + if (inexact) \ + FP_SET_EXCEPTION (FP_EX_INEXACT); \ + _FP_FRAC_ASSEMBLE_##wc (r, X, rsize); \ + } \ + if (rsigned && X##_s) \ + r = -r; \ + } \ } \ - else \ + while (0) + +/* Convert integer to fp. Output is raw. RTYPE is unsigned even if + input is signed. */ +#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \ + do \ { \ - _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs; \ - if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1) \ + if (r) \ { \ - _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ - r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \ + rtype ur_; \ + \ + if ((X##_s = (r < 0))) \ + r = -(rtype) r; \ + \ + ur_ = (rtype) r; \ + (void) ((rsize <= _FP_W_TYPE_SIZE) \ + ? ({ \ + int lz_; \ + __FP_CLZ (lz_, (_FP_W_TYPE) ur_); \ + X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \ + }) \ + : ((rsize <= 2 * _FP_W_TYPE_SIZE) \ + ? ({ \ + int lz_; \ + __FP_CLZ_2 (lz_, \ + (_FP_W_TYPE) (ur_ >> _FP_W_TYPE_SIZE), \ + (_FP_W_TYPE) ur_); \ + X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \ + - lz_); \ + }) \ + : (abort (), 0))); \ + \ + if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \ + && X##_e >= _FP_EXPMAX_##fs) \ + { \ + /* Exponent too big; overflow to infinity. (May also \ + happen after rounding below.) */ \ + _FP_OVERFLOW_SEMIRAW (fs, wc, X); \ + goto pack_semiraw; \ + } \ + \ + if (rsize <= _FP_FRACBITS_##fs \ + || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \ + { \ + /* Exactly representable; shift left. */ \ + _FP_FRAC_DISASSEMBLE_##wc (X, ur_, rsize); \ + if (_FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1 - X##_e > 0) \ + _FP_FRAC_SLL_##wc (X, (_FP_EXPBIAS_##fs \ + + _FP_FRACBITS_##fs - 1 - X##_e)); \ + } \ + else \ + { \ + /* More bits in integer than in floating type; need to \ + round. */ \ + if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \ + ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \ + - _FP_WFRACBITS_##fs + 1)) \ + | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \ + - _FP_WFRACBITS_##fs + 1))) \ + != 0)); \ + _FP_FRAC_DISASSEMBLE_##wc (X, ur_, rsize); \ + if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \ + _FP_FRAC_SLL_##wc (X, (_FP_EXPBIAS_##fs \ + + _FP_WFRACBITS_##fs - 1 - X##_e)); \ + _FP_FRAC_HIGH_##fs (X) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \ + pack_semiraw: \ + _FP_PACK_SEMIRAW (fs, wc, X); \ + } \ } \ else \ { \ - int inexact; \ - _FP_FRAC_SRST_##wc(X, inexact, \ - (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \ - - X##_e), \ - _FP_FRACBITS_##fs); \ - if (inexact) \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \ + X##_s = 0; \ + X##_e = 0; \ + _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc); \ } \ - if (rsigned && X##_s) \ - r = -r; \ } \ -} while (0) - -/* Convert integer to fp. Output is raw. RTYPE is unsigned even if - input is signed. */ -#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \ - do { \ - if (r) \ - { \ - rtype ur_; \ - \ - if ((X##_s = (r < 0))) \ - r = -(rtype)r; \ - \ - ur_ = (rtype) r; \ - (void)((rsize <= _FP_W_TYPE_SIZE) \ - ? ({ \ - int lz_; \ - __FP_CLZ(lz_, (_FP_W_TYPE)ur_); \ - X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_; \ - }) \ - : ((rsize <= 2 * _FP_W_TYPE_SIZE) \ - ? ({ \ - int lz_; \ - __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \ - (_FP_W_TYPE)ur_); \ - X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \ - - lz_); \ - }) \ - : (abort(), 0))); \ - \ - if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \ - && X##_e >= _FP_EXPMAX_##fs) \ - { \ - /* Exponent too big; overflow to infinity. (May also \ - happen after rounding below.) */ \ - _FP_OVERFLOW_SEMIRAW(fs, wc, X); \ - goto pack_semiraw; \ - } \ - \ - if (rsize <= _FP_FRACBITS_##fs \ - || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs) \ - { \ - /* Exactly representable; shift left. */ \ - _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ - if (_FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1 - X##_e > 0) \ - _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ - + _FP_FRACBITS_##fs - 1 - X##_e)); \ - } \ - else \ - { \ - /* More bits in integer than in floating type; need to \ - round. */ \ - if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e) \ - ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs \ - - _FP_WFRACBITS_##fs + 1)) \ - | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs \ - - _FP_WFRACBITS_##fs + 1))) \ - != 0)); \ - _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize); \ - if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \ - _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs \ - + _FP_WFRACBITS_##fs - 1 - X##_e)); \ - _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \ - pack_semiraw: \ - _FP_PACK_SEMIRAW(fs, wc, X); \ - } \ - } \ - else \ - { \ - X##_s = 0; \ - X##_e = 0; \ - _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \ - } \ - } while (0) + while (0) /* Extend from a narrower floating-point format to a wider one. Input and output are raw. */ -#define FP_EXTEND(dfs,sfs,dwc,swc,D,S) \ -do { \ - if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \ - || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \ - < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \ - || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \ - && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \ - abort(); \ - D##_s = S##_s; \ - _FP_FRAC_COPY_##dwc##_##swc(D, S); \ - if (_FP_EXP_NORMAL(sfs, swc, S)) \ - { \ - D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ - _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \ - } \ - else \ - { \ - if (S##_e == 0) \ - { \ - if (_FP_FRAC_ZEROP_##swc(S)) \ - D##_e = 0; \ - else if (_FP_EXPBIAS_##dfs \ - < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ - - _FP_FRACBITS_##sfs)); \ - D##_e = 0; \ - } \ - else \ - { \ - int _lz; \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - _FP_FRAC_CLZ_##swc(_lz, S); \ - _FP_FRAC_SLL_##dwc(D, \ - _lz + _FP_FRACBITS_##dfs \ - - _FP_FRACTBITS_##sfs); \ - D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \ - + _FP_FRACXBITS_##sfs - _lz); \ - } \ - } \ - else \ - { \ - D##_e = _FP_EXPMAX_##dfs; \ - if (!_FP_FRAC_ZEROP_##swc(S)) \ - { \ - if (_FP_FRAC_SNANP(sfs, S)) \ - FP_SET_EXCEPTION(FP_EX_INVALID); \ - _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \ - - _FP_FRACBITS_##sfs)); \ - } \ - } \ - } \ -} while (0) +#define FP_EXTEND(dfs, sfs, dwc, swc, D, S) \ + do \ + { \ + if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \ + || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \ + < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \ + || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \ + && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \ + abort (); \ + D##_s = S##_s; \ + _FP_FRAC_COPY_##dwc##_##swc (D, S); \ + if (_FP_EXP_NORMAL (sfs, swc, S)) \ + { \ + D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ + _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \ + } \ + else \ + { \ + if (S##_e == 0) \ + { \ + if (_FP_FRAC_ZEROP_##swc (S)) \ + D##_e = 0; \ + else if (_FP_EXPBIAS_##dfs \ + < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \ + { \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs \ + - _FP_FRACBITS_##sfs)); \ + D##_e = 0; \ + } \ + else \ + { \ + int _lz; \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + _FP_FRAC_CLZ_##swc (_lz, S); \ + _FP_FRAC_SLL_##dwc (D, \ + _lz + _FP_FRACBITS_##dfs \ + - _FP_FRACTBITS_##sfs); \ + D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1 \ + + _FP_FRACXBITS_##sfs - _lz); \ + } \ + } \ + else \ + { \ + D##_e = _FP_EXPMAX_##dfs; \ + if (!_FP_FRAC_ZEROP_##swc (S)) \ + { \ + if (_FP_FRAC_SNANP (sfs, S)) \ + FP_SET_EXCEPTION (FP_EX_INVALID); \ + _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs \ + - _FP_FRACBITS_##sfs)); \ + _FP_SETQNAN (dfs, dwc, D); \ + } \ + } \ + } \ + } \ + while (0) /* Truncate from a wider floating-point format to a narrower one. Input and output are semi-raw. */ -#define FP_TRUNC(dfs,sfs,dwc,swc,D,S) \ -do { \ - if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \ - || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \ - && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \ - abort(); \ - D##_s = S##_s; \ - if (_FP_EXP_NORMAL(sfs, swc, S)) \ - { \ - D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ - if (D##_e >= _FP_EXPMAX_##dfs) \ - _FP_OVERFLOW_SEMIRAW(dfs, dwc, D); \ - else \ - { \ - if (D##_e <= 0) \ - { \ - if (D##_e < 1 - _FP_FRACBITS_##dfs) \ - { \ - _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc); \ - _FP_FRAC_LOW_##swc(S) |= 1; \ - } \ - else \ - { \ - _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs; \ - _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ - - _FP_WFRACBITS_##dfs + 1 - D##_e), \ - _FP_WFRACBITS_##sfs); \ - } \ - D##_e = 0; \ - } \ - else \ - _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ - - _FP_WFRACBITS_##dfs), \ - _FP_WFRACBITS_##sfs); \ - _FP_FRAC_COPY_##dwc##_##swc(D, S); \ - } \ - } \ - else \ - { \ - if (S##_e == 0) \ - { \ - D##_e = 0; \ - if (_FP_FRAC_ZEROP_##swc(S)) \ - _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ - else \ - { \ - FP_SET_EXCEPTION(FP_EX_DENORM); \ - if (_FP_EXPBIAS_##sfs \ - < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \ - { \ - _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs \ - - _FP_WFRACBITS_##dfs), \ - _FP_WFRACBITS_##sfs); \ - _FP_FRAC_COPY_##dwc##_##swc(D, S); \ - } \ - else \ - { \ - _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ - _FP_FRAC_LOW_##dwc(D) |= 1; \ - } \ - } \ - } \ - else \ - { \ - D##_e = _FP_EXPMAX_##dfs; \ - if (_FP_FRAC_ZEROP_##swc(S)) \ - _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc); \ - else \ - { \ - _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S); \ - _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs \ - - _FP_WFRACBITS_##dfs)); \ - _FP_FRAC_COPY_##dwc##_##swc(D, S); \ - /* Semi-raw NaN must have all workbits cleared. */ \ - _FP_FRAC_LOW_##dwc(D) \ - &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \ - _FP_SETQNAN_SEMIRAW(dfs, dwc, D); \ - } \ - } \ - } \ -} while (0) +#define FP_TRUNC(dfs, sfs, dwc, swc, D, S) \ + do \ + { \ + if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \ + || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \ + && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \ + abort (); \ + D##_s = S##_s; \ + if (_FP_EXP_NORMAL (sfs, swc, S)) \ + { \ + D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs; \ + if (D##_e >= _FP_EXPMAX_##dfs) \ + _FP_OVERFLOW_SEMIRAW (dfs, dwc, D); \ + else \ + { \ + if (D##_e <= 0) \ + { \ + if (D##_e < 1 - _FP_FRACBITS_##dfs) \ + { \ + _FP_FRAC_SET_##swc (S, _FP_ZEROFRAC_##swc); \ + _FP_FRAC_LOW_##swc (S) |= 1; \ + } \ + else \ + { \ + _FP_FRAC_HIGH_##sfs (S) |= _FP_IMPLBIT_SH_##sfs; \ + _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs \ + - _FP_WFRACBITS_##dfs \ + + 1 - D##_e), \ + _FP_WFRACBITS_##sfs); \ + } \ + D##_e = 0; \ + } \ + else \ + _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs \ + - _FP_WFRACBITS_##dfs), \ + _FP_WFRACBITS_##sfs); \ + _FP_FRAC_COPY_##dwc##_##swc (D, S); \ + } \ + } \ + else \ + { \ + if (S##_e == 0) \ + { \ + D##_e = 0; \ + if (_FP_FRAC_ZEROP_##swc (S)) \ + _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc); \ + else \ + { \ + FP_SET_EXCEPTION (FP_EX_DENORM); \ + if (_FP_EXPBIAS_##sfs \ + < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1) \ + { \ + _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs \ + - _FP_WFRACBITS_##dfs), \ + _FP_WFRACBITS_##sfs); \ + _FP_FRAC_COPY_##dwc##_##swc (D, S); \ + } \ + else \ + { \ + _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc); \ + _FP_FRAC_LOW_##dwc (D) |= 1; \ + } \ + } \ + } \ + else \ + { \ + D##_e = _FP_EXPMAX_##dfs; \ + if (_FP_FRAC_ZEROP_##swc (S)) \ + _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc); \ + else \ + { \ + _FP_CHECK_SIGNAN_SEMIRAW (sfs, swc, S); \ + _FP_FRAC_SRL_##swc (S, (_FP_WFRACBITS_##sfs \ + - _FP_WFRACBITS_##dfs)); \ + _FP_FRAC_COPY_##dwc##_##swc (D, S); \ + /* Semi-raw NaN must have all workbits cleared. */ \ + _FP_FRAC_LOW_##dwc (D) \ + &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \ + _FP_SETQNAN_SEMIRAW (dfs, dwc, D); \ + } \ + } \ + } \ + } \ + while (0) /* * Helper primitives. @@ -1344,64 +1607,72 @@ do { \ #ifndef __FP_CLZ /* GCC 3.4 and later provide the builtins for us. */ -#define __FP_CLZ(r, x) \ - do { \ - if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \ - r = __builtin_clz (x); \ - else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \ - r = __builtin_clzl (x); \ - else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \ - r = __builtin_clzll (x); \ - else \ - abort (); \ - } while (0) +# define __FP_CLZ(r, x) \ + do \ + { \ + if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \ + r = __builtin_clz (x); \ + else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \ + r = __builtin_clzl (x); \ + else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \ + r = __builtin_clzll (x); \ + else \ + abort (); \ + } \ + while (0) #endif /* ndef __FP_CLZ */ #define _FP_DIV_HELP_imm(q, r, n, d) \ - do { \ - q = n / d, r = n % d; \ - } while (0) + do \ + { \ + q = n / d, r = n % d; \ + } \ + while (0) /* A restoring bit-by-bit division primitive. */ #define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y) \ - do { \ - int count = _FP_WFRACBITS_##fs; \ - _FP_FRAC_DECL_##wc (u); \ - _FP_FRAC_DECL_##wc (v); \ - _FP_FRAC_COPY_##wc (u, X); \ - _FP_FRAC_COPY_##wc (v, Y); \ - _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ - /* Normalize U and V. */ \ - _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \ - _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \ - /* First round. Since the operands are normalized, either the \ - first or second bit will be set in the fraction. Produce a \ - normalized result by checking which and adjusting the loop \ - count and exponent accordingly. */ \ - if (_FP_FRAC_GE_1 (u, v)) \ - { \ - _FP_FRAC_SUB_##wc (u, u, v); \ - _FP_FRAC_LOW_##wc (R) |= 1; \ - count--; \ - } \ - else \ - R##_e--; \ - /* Subsequent rounds. */ \ - do { \ - int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \ - _FP_FRAC_SLL_##wc (u, 1); \ - _FP_FRAC_SLL_##wc (R, 1); \ - if (msb || _FP_FRAC_GE_1 (u, v)) \ + do \ + { \ + int count = _FP_WFRACBITS_##fs; \ + _FP_FRAC_DECL_##wc (u); \ + _FP_FRAC_DECL_##wc (v); \ + _FP_FRAC_COPY_##wc (u, X); \ + _FP_FRAC_COPY_##wc (v, Y); \ + _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc); \ + /* Normalize U and V. */ \ + _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs); \ + _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs); \ + /* First round. Since the operands are normalized, either the \ + first or second bit will be set in the fraction. Produce a \ + normalized result by checking which and adjusting the loop \ + count and exponent accordingly. */ \ + if (_FP_FRAC_GE_1 (u, v)) \ { \ _FP_FRAC_SUB_##wc (u, u, v); \ _FP_FRAC_LOW_##wc (R) |= 1; \ + count--; \ } \ - } while (--count > 0); \ - /* If there's anything left in U, the result is inexact. */ \ - _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \ - } while (0) + else \ + R##_e--; \ + /* Subsequent rounds. */ \ + do \ + { \ + int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0; \ + _FP_FRAC_SLL_##wc (u, 1); \ + _FP_FRAC_SLL_##wc (R, 1); \ + if (msb || _FP_FRAC_GE_1 (u, v)) \ + { \ + _FP_FRAC_SUB_##wc (u, u, v); \ + _FP_FRAC_LOW_##wc (R) |= 1; \ + } \ + } \ + while (--count > 0); \ + /* If there's anything left in U, the result is inexact. */ \ + _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u); \ + } \ + while (0) #define _FP_DIV_MEAT_1_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y) #define _FP_DIV_MEAT_2_loop(fs, R, X, Y) _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y) diff --git a/libgcc/soft-fp/quad.h b/libgcc/soft-fp/quad.h index f0aa07e74f1..5002da5a533 100644 --- a/libgcc/soft-fp/quad.h +++ b/libgcc/soft-fp/quad.h @@ -31,13 +31,15 @@ <http://www.gnu.org/licenses/>. */ #if _FP_W_TYPE_SIZE < 32 -#error "Here's a nickel, kid. Go buy yourself a real computer." +# error "Here's a nickel, kid. Go buy yourself a real computer." #endif #if _FP_W_TYPE_SIZE < 64 -#define _FP_FRACTBITS_Q (4*_FP_W_TYPE_SIZE) +# define _FP_FRACTBITS_Q (4*_FP_W_TYPE_SIZE) +# define _FP_FRACTBITS_DW_Q (8*_FP_W_TYPE_SIZE) #else -#define _FP_FRACTBITS_Q (2*_FP_W_TYPE_SIZE) +# define _FP_FRACTBITS_Q (2*_FP_W_TYPE_SIZE) +# define _FP_FRACTBITS_DW_Q (4*_FP_W_TYPE_SIZE) #endif #define _FP_FRACBITS_Q 113 @@ -49,222 +51,271 @@ #define _FP_EXPMAX_Q 32767 #define _FP_QNANBIT_Q \ - ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE) + ((_FP_W_TYPE) 1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE) #define _FP_QNANBIT_SH_Q \ - ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) + ((_FP_W_TYPE) 1 << (_FP_FRACBITS_Q-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE) #define _FP_IMPLBIT_Q \ - ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE) + ((_FP_W_TYPE) 1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE) #define _FP_IMPLBIT_SH_Q \ - ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) + ((_FP_W_TYPE) 1 << (_FP_FRACBITS_Q-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE) #define _FP_OVERFLOW_Q \ - ((_FP_W_TYPE)1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE)) + ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE)) -typedef float TFtype __attribute__((mode(TF))); +#define _FP_WFRACBITS_DW_Q (2 * _FP_WFRACBITS_Q) +#define _FP_WFRACXBITS_DW_Q (_FP_FRACTBITS_DW_Q - _FP_WFRACBITS_DW_Q) +#define _FP_HIGHBIT_DW_Q \ + ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_DW_Q - 1) % _FP_W_TYPE_SIZE) + +typedef float TFtype __attribute__ ((mode (TF))); #if _FP_W_TYPE_SIZE < 64 union _FP_UNION_Q { - TFtype flt; - struct _FP_STRUCT_LAYOUT - { -#if __BYTE_ORDER == __BIG_ENDIAN - unsigned sign : 1; - unsigned exp : _FP_EXPBITS_Q; - unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); - unsigned long frac2 : _FP_W_TYPE_SIZE; - unsigned long frac1 : _FP_W_TYPE_SIZE; - unsigned long frac0 : _FP_W_TYPE_SIZE; -#else - unsigned long frac0 : _FP_W_TYPE_SIZE; - unsigned long frac1 : _FP_W_TYPE_SIZE; - unsigned long frac2 : _FP_W_TYPE_SIZE; - unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); - unsigned exp : _FP_EXPBITS_Q; - unsigned sign : 1; -#endif /* not bigendian */ - } bits __attribute__((packed)); + TFtype flt; + struct _FP_STRUCT_LAYOUT + { +# if __BYTE_ORDER == __BIG_ENDIAN + unsigned sign : 1; + unsigned exp : _FP_EXPBITS_Q; + unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); + unsigned long frac2 : _FP_W_TYPE_SIZE; + unsigned long frac1 : _FP_W_TYPE_SIZE; + unsigned long frac0 : _FP_W_TYPE_SIZE; +# else + unsigned long frac0 : _FP_W_TYPE_SIZE; + unsigned long frac1 : _FP_W_TYPE_SIZE; + unsigned long frac2 : _FP_W_TYPE_SIZE; + unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3); + unsigned exp : _FP_EXPBITS_Q; + unsigned sign : 1; +# endif /* not bigendian */ + } bits __attribute__ ((packed)); }; -#define FP_DECL_Q(X) _FP_DECL(4,X) -#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_4(Q,X,val) -#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_4_P(Q,X,val) -#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_4(Q,val,X) -#define FP_PACK_RAW_QP(val,X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_4_P(Q,val,X); \ - } while (0) - -#define FP_UNPACK_Q(X,val) \ - do { \ - _FP_UNPACK_RAW_4(Q,X,val); \ - _FP_UNPACK_CANONICAL(Q,4,X); \ - } while (0) - -#define FP_UNPACK_QP(X,val) \ - do { \ - _FP_UNPACK_RAW_4_P(Q,X,val); \ - _FP_UNPACK_CANONICAL(Q,4,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_Q(X,val) \ - do { \ - _FP_UNPACK_RAW_4(Q,X,val); \ - _FP_UNPACK_SEMIRAW(Q,4,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_QP(X,val) \ - do { \ - _FP_UNPACK_RAW_4_P(Q,X,val); \ - _FP_UNPACK_SEMIRAW(Q,4,X); \ - } while (0) - -#define FP_PACK_Q(val,X) \ - do { \ - _FP_PACK_CANONICAL(Q,4,X); \ - _FP_PACK_RAW_4(Q,val,X); \ - } while (0) - -#define FP_PACK_QP(val,X) \ - do { \ - _FP_PACK_CANONICAL(Q,4,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_4_P(Q,val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_Q(val,X) \ - do { \ - _FP_PACK_SEMIRAW(Q,4,X); \ - _FP_PACK_RAW_4(Q,val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_QP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(Q,4,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_4_P(Q,val,X); \ - } while (0) - -#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,4,X) -#define FP_NEG_Q(R,X) _FP_NEG(Q,4,R,X) -#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,4,R,X,Y) -#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,4,R,X,Y) -#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,4,R,X,Y) -#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,4,R,X,Y) -#define FP_SQRT_Q(R,X) _FP_SQRT(Q,4,R,X) -#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_4(R,S,T,X,Q) - -#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,4,r,X,Y,un) -#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,4,r,X,Y) -#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,4,r,X,Y) - -#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,4,r,X,rsz,rsg) -#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,4,X,r,rs,rt) - -#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_4(X) -#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_4(X) +# define FP_DECL_Q(X) _FP_DECL (4, X) +# define FP_UNPACK_RAW_Q(X, val) _FP_UNPACK_RAW_4 (Q, X, val) +# define FP_UNPACK_RAW_QP(X, val) _FP_UNPACK_RAW_4_P (Q, X, val) +# define FP_PACK_RAW_Q(val, X) _FP_PACK_RAW_4 (Q, val, X) +# define FP_PACK_RAW_QP(val, X) \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_4_P (Q, val, X); \ + } \ + while (0) + +# define FP_UNPACK_Q(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_4 (Q, X, val); \ + _FP_UNPACK_CANONICAL (Q, 4, X); \ + } \ + while (0) + +# define FP_UNPACK_QP(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_4_P (Q, X, val); \ + _FP_UNPACK_CANONICAL (Q, 4, X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_Q(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_4 (Q, X, val); \ + _FP_UNPACK_SEMIRAW (Q, 4, X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_QP(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_4_P (Q, X, val); \ + _FP_UNPACK_SEMIRAW (Q, 4, X); \ + } \ + while (0) + +# define FP_PACK_Q(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (Q, 4, X); \ + _FP_PACK_RAW_4 (Q, val, X); \ + } \ + while (0) + +# define FP_PACK_QP(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (Q, 4, X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_4_P (Q, val, X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_Q(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (Q, 4, X); \ + _FP_PACK_RAW_4 (Q, val, X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_QP(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (Q, 4, X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_4_P (Q, val, X); \ + } \ + while (0) + +# define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN (Q, 4, X) +# define FP_NEG_Q(R, X) _FP_NEG (Q, 4, R, X) +# define FP_ADD_Q(R, X, Y) _FP_ADD (Q, 4, R, X, Y) +# define FP_SUB_Q(R, X, Y) _FP_SUB (Q, 4, R, X, Y) +# define FP_MUL_Q(R, X, Y) _FP_MUL (Q, 4, R, X, Y) +# define FP_DIV_Q(R, X, Y) _FP_DIV (Q, 4, R, X, Y) +# define FP_SQRT_Q(R, X) _FP_SQRT (Q, 4, R, X) +# define _FP_SQRT_MEAT_Q(R, S, T, X, Q) _FP_SQRT_MEAT_4 (R, S, T, X, Q) +# define FP_FMA_Q(R, X, Y, Z) _FP_FMA (Q, 4, 8, R, X, Y, Z) + +# define FP_CMP_Q(r, X, Y, un) _FP_CMP (Q, 4, r, X, Y, un) +# define FP_CMP_EQ_Q(r, X, Y) _FP_CMP_EQ (Q, 4, r, X, Y) +# define FP_CMP_UNORD_Q(r, X, Y) _FP_CMP_UNORD (Q, 4, r, X, Y) + +# define FP_TO_INT_Q(r, X, rsz, rsg) _FP_TO_INT (Q, 4, r, X, rsz, rsg) +# define FP_FROM_INT_Q(X, r, rs, rt) _FP_FROM_INT (Q, 4, X, r, rs, rt) + +# define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_4 (X) +# define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_4 (X) + +# define _FP_FRAC_HIGH_DW_Q(X) _FP_FRAC_HIGH_8 (X) #else /* not _FP_W_TYPE_SIZE < 64 */ union _FP_UNION_Q { - TFtype flt /* __attribute__((mode(TF))) */ ; - struct _FP_STRUCT_LAYOUT { + TFtype flt /* __attribute__ ((mode (TF))) */ ; + struct _FP_STRUCT_LAYOUT + { _FP_W_TYPE a, b; } longs; - struct _FP_STRUCT_LAYOUT { -#if __BYTE_ORDER == __BIG_ENDIAN + struct _FP_STRUCT_LAYOUT + { +# if __BYTE_ORDER == __BIG_ENDIAN unsigned sign : 1; unsigned exp : _FP_EXPBITS_Q; _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; -#else +# else _FP_W_TYPE frac0 : _FP_W_TYPE_SIZE; _FP_W_TYPE frac1 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0) - _FP_W_TYPE_SIZE; unsigned exp : _FP_EXPBITS_Q; unsigned sign : 1; -#endif +# endif } bits; }; -#define FP_DECL_Q(X) _FP_DECL(2,X) -#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_2(Q,X,val) -#define FP_UNPACK_RAW_QP(X,val) _FP_UNPACK_RAW_2_P(Q,X,val) -#define FP_PACK_RAW_Q(val,X) _FP_PACK_RAW_2(Q,val,X) -#define FP_PACK_RAW_QP(val,X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_2_P(Q,val,X); \ - } while (0) - -#define FP_UNPACK_Q(X,val) \ - do { \ - _FP_UNPACK_RAW_2(Q,X,val); \ - _FP_UNPACK_CANONICAL(Q,2,X); \ - } while (0) - -#define FP_UNPACK_QP(X,val) \ - do { \ - _FP_UNPACK_RAW_2_P(Q,X,val); \ - _FP_UNPACK_CANONICAL(Q,2,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_Q(X,val) \ - do { \ - _FP_UNPACK_RAW_2(Q,X,val); \ - _FP_UNPACK_SEMIRAW(Q,2,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_QP(X,val) \ - do { \ - _FP_UNPACK_RAW_2_P(Q,X,val); \ - _FP_UNPACK_SEMIRAW(Q,2,X); \ - } while (0) - -#define FP_PACK_Q(val,X) \ - do { \ - _FP_PACK_CANONICAL(Q,2,X); \ - _FP_PACK_RAW_2(Q,val,X); \ - } while (0) - -#define FP_PACK_QP(val,X) \ - do { \ - _FP_PACK_CANONICAL(Q,2,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_2_P(Q,val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_Q(val,X) \ - do { \ - _FP_PACK_SEMIRAW(Q,2,X); \ - _FP_PACK_RAW_2(Q,val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_QP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(Q,2,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_2_P(Q,val,X); \ - } while (0) - -#define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN(Q,2,X) -#define FP_NEG_Q(R,X) _FP_NEG(Q,2,R,X) -#define FP_ADD_Q(R,X,Y) _FP_ADD(Q,2,R,X,Y) -#define FP_SUB_Q(R,X,Y) _FP_SUB(Q,2,R,X,Y) -#define FP_MUL_Q(R,X,Y) _FP_MUL(Q,2,R,X,Y) -#define FP_DIV_Q(R,X,Y) _FP_DIV(Q,2,R,X,Y) -#define FP_SQRT_Q(R,X) _FP_SQRT(Q,2,R,X) -#define _FP_SQRT_MEAT_Q(R,S,T,X,Q) _FP_SQRT_MEAT_2(R,S,T,X,Q) - -#define FP_CMP_Q(r,X,Y,un) _FP_CMP(Q,2,r,X,Y,un) -#define FP_CMP_EQ_Q(r,X,Y) _FP_CMP_EQ(Q,2,r,X,Y) -#define FP_CMP_UNORD_Q(r,X,Y) _FP_CMP_UNORD(Q,2,r,X,Y) - -#define FP_TO_INT_Q(r,X,rsz,rsg) _FP_TO_INT(Q,2,r,X,rsz,rsg) -#define FP_FROM_INT_Q(X,r,rs,rt) _FP_FROM_INT(Q,2,X,r,rs,rt) - -#define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_2(X) -#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_2(X) +# define FP_DECL_Q(X) _FP_DECL (2, X) +# define FP_UNPACK_RAW_Q(X, val) _FP_UNPACK_RAW_2 (Q, X, val) +# define FP_UNPACK_RAW_QP(X, val) _FP_UNPACK_RAW_2_P (Q, X, val) +# define FP_PACK_RAW_Q(val, X) _FP_PACK_RAW_2 (Q, val, X) +# define FP_PACK_RAW_QP(val, X) \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_2_P (Q, val, X); \ + } \ + while (0) + +# define FP_UNPACK_Q(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_2 (Q, X, val); \ + _FP_UNPACK_CANONICAL (Q, 2, X); \ + } \ + while (0) + +# define FP_UNPACK_QP(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_2_P (Q, X, val); \ + _FP_UNPACK_CANONICAL (Q, 2, X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_Q(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_2 (Q, X, val); \ + _FP_UNPACK_SEMIRAW (Q, 2, X); \ + } \ + while (0) + +# define FP_UNPACK_SEMIRAW_QP(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_2_P (Q, X, val); \ + _FP_UNPACK_SEMIRAW (Q, 2, X); \ + } \ + while (0) + +# define FP_PACK_Q(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (Q, 2, X); \ + _FP_PACK_RAW_2 (Q, val, X); \ + } \ + while (0) + +# define FP_PACK_QP(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (Q, 2, X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_2_P (Q, val, X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_Q(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (Q, 2, X); \ + _FP_PACK_RAW_2 (Q, val, X); \ + } \ + while (0) + +# define FP_PACK_SEMIRAW_QP(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (Q, 2, X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_2_P (Q, val, X); \ + } \ + while (0) + +# define FP_ISSIGNAN_Q(X) _FP_ISSIGNAN (Q, 2, X) +# define FP_NEG_Q(R, X) _FP_NEG (Q, 2, R, X) +# define FP_ADD_Q(R, X, Y) _FP_ADD (Q, 2, R, X, Y) +# define FP_SUB_Q(R, X, Y) _FP_SUB (Q, 2, R, X, Y) +# define FP_MUL_Q(R, X, Y) _FP_MUL (Q, 2, R, X, Y) +# define FP_DIV_Q(R, X, Y) _FP_DIV (Q, 2, R, X, Y) +# define FP_SQRT_Q(R, X) _FP_SQRT (Q, 2, R, X) +# define _FP_SQRT_MEAT_Q(R, S, T, X, Q) _FP_SQRT_MEAT_2 (R, S, T, X, Q) +# define FP_FMA_Q(R, X, Y, Z) _FP_FMA (Q, 2, 4, R, X, Y, Z) + +# define FP_CMP_Q(r, X, Y, un) _FP_CMP (Q, 2, r, X, Y, un) +# define FP_CMP_EQ_Q(r, X, Y) _FP_CMP_EQ (Q, 2, r, X, Y) +# define FP_CMP_UNORD_Q(r, X, Y) _FP_CMP_UNORD (Q, 2, r, X, Y) + +# define FP_TO_INT_Q(r, X, rsz, rsg) _FP_TO_INT (Q, 2, r, X, rsz, rsg) +# define FP_FROM_INT_Q(X, r, rs, rt) _FP_FROM_INT (Q, 2, X, r, rs, rt) + +# define _FP_FRAC_HIGH_Q(X) _FP_FRAC_HIGH_2 (X) +# define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_2 (X) + +# define _FP_FRAC_HIGH_DW_Q(X) _FP_FRAC_HIGH_4 (X) #endif /* not _FP_W_TYPE_SIZE < 64 */ diff --git a/libgcc/soft-fp/single.h b/libgcc/soft-fp/single.h index dec0031e9a9..af60c96e682 100644 --- a/libgcc/soft-fp/single.h +++ b/libgcc/soft-fp/single.h @@ -31,11 +31,17 @@ <http://www.gnu.org/licenses/>. */ #if _FP_W_TYPE_SIZE < 32 -#error "Here's a nickel kid. Go buy yourself a real computer." +# error "Here's a nickel kid. Go buy yourself a real computer." #endif #define _FP_FRACTBITS_S _FP_W_TYPE_SIZE +#if _FP_W_TYPE_SIZE < 64 +# define _FP_FRACTBITS_DW_S (2 * _FP_W_TYPE_SIZE) +#else +# define _FP_FRACTBITS_DW_S _FP_W_TYPE_SIZE +#endif + #define _FP_FRACBITS_S 24 #define _FP_FRACXBITS_S (_FP_FRACTBITS_S - _FP_FRACBITS_S) #define _FP_WFRACBITS_S (_FP_WORKBITS + _FP_FRACBITS_S) @@ -43,21 +49,27 @@ #define _FP_EXPBITS_S 8 #define _FP_EXPBIAS_S 127 #define _FP_EXPMAX_S 255 -#define _FP_QNANBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2)) -#define _FP_QNANBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2+_FP_WORKBITS)) -#define _FP_IMPLBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1)) -#define _FP_IMPLBIT_SH_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1+_FP_WORKBITS)) -#define _FP_OVERFLOW_S ((_FP_W_TYPE)1 << (_FP_WFRACBITS_S)) +#define _FP_QNANBIT_S ((_FP_W_TYPE) 1 << (_FP_FRACBITS_S-2)) +#define _FP_QNANBIT_SH_S ((_FP_W_TYPE) 1 << (_FP_FRACBITS_S-2+_FP_WORKBITS)) +#define _FP_IMPLBIT_S ((_FP_W_TYPE) 1 << (_FP_FRACBITS_S-1)) +#define _FP_IMPLBIT_SH_S ((_FP_W_TYPE) 1 << (_FP_FRACBITS_S-1+_FP_WORKBITS)) +#define _FP_OVERFLOW_S ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_S)) + +#define _FP_WFRACBITS_DW_S (2 * _FP_WFRACBITS_S) +#define _FP_WFRACXBITS_DW_S (_FP_FRACTBITS_DW_S - _FP_WFRACBITS_DW_S) +#define _FP_HIGHBIT_DW_S \ + ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_DW_S - 1) % _FP_W_TYPE_SIZE) /* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be chosen by the target machine. */ -typedef float SFtype __attribute__((mode(SF))); +typedef float SFtype __attribute__ ((mode (SF))); union _FP_UNION_S { SFtype flt; - struct _FP_STRUCT_LAYOUT { + struct _FP_STRUCT_LAYOUT + { #if __BYTE_ORDER == __BIG_ENDIAN unsigned sign : 1; unsigned exp : _FP_EXPBITS_S; @@ -67,84 +79,114 @@ union _FP_UNION_S unsigned exp : _FP_EXPBITS_S; unsigned sign : 1; #endif - } bits __attribute__((packed)); + } bits __attribute__ ((packed)); }; -#define FP_DECL_S(X) _FP_DECL(1,X) -#define FP_UNPACK_RAW_S(X,val) _FP_UNPACK_RAW_1(S,X,val) -#define FP_UNPACK_RAW_SP(X,val) _FP_UNPACK_RAW_1_P(S,X,val) -#define FP_PACK_RAW_S(val,X) _FP_PACK_RAW_1(S,val,X) -#define FP_PACK_RAW_SP(val,X) \ - do { \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_1_P(S,val,X); \ - } while (0) - -#define FP_UNPACK_S(X,val) \ - do { \ - _FP_UNPACK_RAW_1(S,X,val); \ - _FP_UNPACK_CANONICAL(S,1,X); \ - } while (0) - -#define FP_UNPACK_SP(X,val) \ - do { \ - _FP_UNPACK_RAW_1_P(S,X,val); \ - _FP_UNPACK_CANONICAL(S,1,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_S(X,val) \ - do { \ - _FP_UNPACK_RAW_1(S,X,val); \ - _FP_UNPACK_SEMIRAW(S,1,X); \ - } while (0) - -#define FP_UNPACK_SEMIRAW_SP(X,val) \ - do { \ - _FP_UNPACK_RAW_1_P(S,X,val); \ - _FP_UNPACK_SEMIRAW(S,1,X); \ - } while (0) - -#define FP_PACK_S(val,X) \ - do { \ - _FP_PACK_CANONICAL(S,1,X); \ - _FP_PACK_RAW_1(S,val,X); \ - } while (0) - -#define FP_PACK_SP(val,X) \ - do { \ - _FP_PACK_CANONICAL(S,1,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_1_P(S,val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_S(val,X) \ - do { \ - _FP_PACK_SEMIRAW(S,1,X); \ - _FP_PACK_RAW_1(S,val,X); \ - } while (0) - -#define FP_PACK_SEMIRAW_SP(val,X) \ - do { \ - _FP_PACK_SEMIRAW(S,1,X); \ - if (!FP_INHIBIT_RESULTS) \ - _FP_PACK_RAW_1_P(S,val,X); \ - } while (0) - -#define FP_ISSIGNAN_S(X) _FP_ISSIGNAN(S,1,X) -#define FP_NEG_S(R,X) _FP_NEG(S,1,R,X) -#define FP_ADD_S(R,X,Y) _FP_ADD(S,1,R,X,Y) -#define FP_SUB_S(R,X,Y) _FP_SUB(S,1,R,X,Y) -#define FP_MUL_S(R,X,Y) _FP_MUL(S,1,R,X,Y) -#define FP_DIV_S(R,X,Y) _FP_DIV(S,1,R,X,Y) -#define FP_SQRT_S(R,X) _FP_SQRT(S,1,R,X) -#define _FP_SQRT_MEAT_S(R,S,T,X,Q) _FP_SQRT_MEAT_1(R,S,T,X,Q) - -#define FP_CMP_S(r,X,Y,un) _FP_CMP(S,1,r,X,Y,un) -#define FP_CMP_EQ_S(r,X,Y) _FP_CMP_EQ(S,1,r,X,Y) -#define FP_CMP_UNORD_S(r,X,Y) _FP_CMP_UNORD(S,1,r,X,Y) - -#define FP_TO_INT_S(r,X,rsz,rsg) _FP_TO_INT(S,1,r,X,rsz,rsg) -#define FP_FROM_INT_S(X,r,rs,rt) _FP_FROM_INT(S,1,X,r,rs,rt) - -#define _FP_FRAC_HIGH_S(X) _FP_FRAC_HIGH_1(X) -#define _FP_FRAC_HIGH_RAW_S(X) _FP_FRAC_HIGH_1(X) +#define FP_DECL_S(X) _FP_DECL (1, X) +#define FP_UNPACK_RAW_S(X, val) _FP_UNPACK_RAW_1 (S, X, val) +#define FP_UNPACK_RAW_SP(X, val) _FP_UNPACK_RAW_1_P (S, X, val) +#define FP_PACK_RAW_S(val, X) _FP_PACK_RAW_1 (S, val, X) +#define FP_PACK_RAW_SP(val, X) \ + do \ + { \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_1_P (S, val, X); \ + } \ + while (0) + +#define FP_UNPACK_S(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_1 (S, X, val); \ + _FP_UNPACK_CANONICAL (S, 1, X); \ + } \ + while (0) + +#define FP_UNPACK_SP(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_1_P (S, X, val); \ + _FP_UNPACK_CANONICAL (S, 1, X); \ + } \ + while (0) + +#define FP_UNPACK_SEMIRAW_S(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_1 (S, X, val); \ + _FP_UNPACK_SEMIRAW (S, 1, X); \ + } \ + while (0) + +#define FP_UNPACK_SEMIRAW_SP(X, val) \ + do \ + { \ + _FP_UNPACK_RAW_1_P (S, X, val); \ + _FP_UNPACK_SEMIRAW (S, 1, X); \ + } \ + while (0) + +#define FP_PACK_S(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (S, 1, X); \ + _FP_PACK_RAW_1 (S, val, X); \ + } \ + while (0) + +#define FP_PACK_SP(val, X) \ + do \ + { \ + _FP_PACK_CANONICAL (S, 1, X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_1_P (S, val, X); \ + } \ + while (0) + +#define FP_PACK_SEMIRAW_S(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (S, 1, X); \ + _FP_PACK_RAW_1 (S, val, X); \ + } \ + while (0) + +#define FP_PACK_SEMIRAW_SP(val, X) \ + do \ + { \ + _FP_PACK_SEMIRAW (S, 1, X); \ + if (!FP_INHIBIT_RESULTS) \ + _FP_PACK_RAW_1_P (S, val, X); \ + } \ + while (0) + +#define FP_ISSIGNAN_S(X) _FP_ISSIGNAN (S, 1, X) +#define FP_NEG_S(R, X) _FP_NEG (S, 1, R, X) +#define FP_ADD_S(R, X, Y) _FP_ADD (S, 1, R, X, Y) +#define FP_SUB_S(R, X, Y) _FP_SUB (S, 1, R, X, Y) +#define FP_MUL_S(R, X, Y) _FP_MUL (S, 1, R, X, Y) +#define FP_DIV_S(R, X, Y) _FP_DIV (S, 1, R, X, Y) +#define FP_SQRT_S(R, X) _FP_SQRT (S, 1, R, X) +#define _FP_SQRT_MEAT_S(R, S, T, X, Q) _FP_SQRT_MEAT_1 (R, S, T, X, Q) + +#if _FP_W_TYPE_SIZE < 64 +# define FP_FMA_S(R, X, Y, Z) _FP_FMA (S, 1, 2, R, X, Y, Z) +#else +# define FP_FMA_S(R, X, Y, Z) _FP_FMA (S, 1, 1, R, X, Y, Z) +#endif + +#define FP_CMP_S(r, X, Y, un) _FP_CMP (S, 1, r, X, Y, un) +#define FP_CMP_EQ_S(r, X, Y) _FP_CMP_EQ (S, 1, r, X, Y) +#define FP_CMP_UNORD_S(r, X, Y) _FP_CMP_UNORD (S, 1, r, X, Y) + +#define FP_TO_INT_S(r, X, rsz, rsg) _FP_TO_INT (S, 1, r, X, rsz, rsg) +#define FP_FROM_INT_S(X, r, rs, rt) _FP_FROM_INT (S, 1, X, r, rs, rt) + +#define _FP_FRAC_HIGH_S(X) _FP_FRAC_HIGH_1 (X) +#define _FP_FRAC_HIGH_RAW_S(X) _FP_FRAC_HIGH_1 (X) + +#if _FP_W_TYPE_SIZE < 64 +# define _FP_FRAC_HIGH_DW_S(X) _FP_FRAC_HIGH_2 (X) +#else +# define _FP_FRAC_HIGH_DW_S(X) _FP_FRAC_HIGH_1 (X) +#endif diff --git a/libgcc/soft-fp/soft-fp.h b/libgcc/soft-fp/soft-fp.h index b1c6e619b5e..696fc8676c7 100644 --- a/libgcc/soft-fp/soft-fp.h +++ b/libgcc/soft-fp/soft-fp.h @@ -33,25 +33,25 @@ #define SOFT_FP_H #ifdef _LIBC -#include <sfp-machine.h> +# include <sfp-machine.h> #else -#include "sfp-machine.h" +# include "sfp-machine.h" #endif /* Allow sfp-machine to have its own byte order definitions. */ #ifndef __BYTE_ORDER -#ifdef _LIBC -#include <endian.h> -#else -#error "endianness not defined by sfp-machine.h" -#endif +# ifdef _LIBC +# include <endian.h> +# else +# error "endianness not defined by sfp-machine.h" +# endif #endif #define _FP_WORKBITS 3 -#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3) -#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2) -#define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1) -#define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0) +#define _FP_WORK_LSB ((_FP_W_TYPE) 1 << 3) +#define _FP_WORK_ROUND ((_FP_W_TYPE) 1 << 2) +#define _FP_WORK_GUARD ((_FP_W_TYPE) 1 << 1) +#define _FP_WORK_STICKY ((_FP_W_TYPE) 1 << 0) #ifndef FP_RND_NEAREST # define FP_RND_NEAREST 0 @@ -65,22 +65,22 @@ /* By default don't care about exceptions. */ #ifndef FP_EX_INVALID -#define FP_EX_INVALID 0 +# define FP_EX_INVALID 0 #endif #ifndef FP_EX_OVERFLOW -#define FP_EX_OVERFLOW 0 +# define FP_EX_OVERFLOW 0 #endif #ifndef FP_EX_UNDERFLOW -#define FP_EX_UNDERFLOW 0 +# define FP_EX_UNDERFLOW 0 #endif #ifndef FP_EX_DIVZERO -#define FP_EX_DIVZERO 0 +# define FP_EX_DIVZERO 0 #endif #ifndef FP_EX_INEXACT -#define FP_EX_INEXACT 0 +# define FP_EX_INEXACT 0 #endif #ifndef FP_EX_DENORM -#define FP_EX_DENORM 0 +# define FP_EX_DENORM 0 #endif /* _FP_STRUCT_LAYOUT may be defined as an attribute to determine the @@ -90,23 +90,31 @@ differences in how consecutive bit-fields are laid out from the default expected by soft-fp. */ #ifndef _FP_STRUCT_LAYOUT -#define _FP_STRUCT_LAYOUT +# define _FP_STRUCT_LAYOUT #endif #ifdef _FP_DECL_EX -#define FP_DECL_EX \ +# define FP_DECL_EX \ int _fex = 0; \ _FP_DECL_EX #else -#define FP_DECL_EX int _fex = 0 +# define FP_DECL_EX int _fex = 0 #endif +/* Initialize any machine-specific state used in FP_ROUNDMODE, + FP_TRAPPING_EXCEPTIONS or FP_HANDLE_EXCEPTIONS. */ #ifndef FP_INIT_ROUNDMODE -#define FP_INIT_ROUNDMODE do {} while (0) +# define FP_INIT_ROUNDMODE do {} while (0) +#endif + +/* Initialize any machine-specific state used in + FP_HANDLE_EXCEPTIONS. */ +#ifndef FP_INIT_EXCEPTIONS +# define FP_INIT_EXCEPTIONS FP_INIT_ROUNDMODE #endif #ifndef FP_HANDLE_EXCEPTIONS -#define FP_HANDLE_EXCEPTIONS do {} while (0) +# define FP_HANDLE_EXCEPTIONS do {} while (0) #endif #ifndef FP_INHIBIT_RESULTS @@ -115,15 +123,12 @@ * check if some exceptions are unmasked * and inhibit it in such a case. */ -#define FP_INHIBIT_RESULTS 0 +# define FP_INHIBIT_RESULTS 0 #endif #define FP_SET_EXCEPTION(ex) \ _fex |= (ex) -#define FP_UNSET_EXCEPTION(ex) \ - _fex &= ~(ex) - #define FP_CLEAR_EXCEPTIONS \ _fex = 0 @@ -131,58 +136,90 @@ (_fex) #ifndef FP_TRAPPING_EXCEPTIONS -#define FP_TRAPPING_EXCEPTIONS 0 +# define FP_TRAPPING_EXCEPTIONS 0 #endif -#define _FP_ROUND_NEAREST(wc, X) \ -do { \ - if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \ - _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ -} while (0) +/* A file using soft-fp may define FP_NO_EXCEPTIONS before including + soft-fp.h to indicate that, although a macro used there could raise + exceptions, or do rounding and potentially thereby raise + exceptions, for some arguments, for the particular arguments used + in that file no exceptions or rounding can occur. Such a file + should not itself use macros relating to handling exceptions and + rounding modes; this is only for indirect uses (in particular, in + _FP_FROM_INT and the macros it calls). */ +#ifdef FP_NO_EXCEPTIONS -#define _FP_ROUND_ZERO(wc, X) (void)0 +# undef FP_SET_EXCEPTION +# define FP_SET_EXCEPTION(ex) do {} while (0) -#define _FP_ROUND_PINF(wc, X) \ -do { \ - if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ - _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ -} while (0) +# undef FP_CUR_EXCEPTIONS +# define FP_CUR_EXCEPTIONS 0 -#define _FP_ROUND_MINF(wc, X) \ -do { \ - if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ - _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ -} while (0) +# undef FP_TRAPPING_EXCEPTIONS +# define FP_TRAPPING_EXCEPTIONS 0 + +# undef FP_ROUNDMODE +# define FP_ROUNDMODE FP_RND_ZERO + +#endif + +#define _FP_ROUND_NEAREST(wc, X) \ + do \ + { \ + if ((_FP_FRAC_LOW_##wc (X) & 15) != _FP_WORK_ROUND) \ + _FP_FRAC_ADDI_##wc (X, _FP_WORK_ROUND); \ + } \ + while (0) + +#define _FP_ROUND_ZERO(wc, X) (void) 0 + +#define _FP_ROUND_PINF(wc, X) \ + do \ + { \ + if (!X##_s && (_FP_FRAC_LOW_##wc (X) & 7)) \ + _FP_FRAC_ADDI_##wc (X, _FP_WORK_LSB); \ + } \ + while (0) + +#define _FP_ROUND_MINF(wc, X) \ + do \ + { \ + if (X##_s && (_FP_FRAC_LOW_##wc (X) & 7)) \ + _FP_FRAC_ADDI_##wc (X, _FP_WORK_LSB); \ + } \ + while (0) #define _FP_ROUND(wc, X) \ -do { \ - if (_FP_FRAC_LOW_##wc(X) & 7) \ - { \ - FP_SET_EXCEPTION(FP_EX_INEXACT); \ - switch (FP_ROUNDMODE) \ - { \ - case FP_RND_NEAREST: \ - _FP_ROUND_NEAREST(wc,X); \ - break; \ - case FP_RND_ZERO: \ - _FP_ROUND_ZERO(wc,X); \ - break; \ - case FP_RND_PINF: \ - _FP_ROUND_PINF(wc,X); \ - break; \ - case FP_RND_MINF: \ - _FP_ROUND_MINF(wc,X); \ - break; \ - } \ - } \ -} while (0) + do \ + { \ + if (_FP_FRAC_LOW_##wc (X) & 7) \ + { \ + FP_SET_EXCEPTION (FP_EX_INEXACT); \ + switch (FP_ROUNDMODE) \ + { \ + case FP_RND_NEAREST: \ + _FP_ROUND_NEAREST (wc, X); \ + break; \ + case FP_RND_ZERO: \ + _FP_ROUND_ZERO (wc, X); \ + break; \ + case FP_RND_PINF: \ + _FP_ROUND_PINF (wc, X); \ + break; \ + case FP_RND_MINF: \ + _FP_ROUND_MINF (wc, X); \ + break; \ + } \ + } \ + } \ + while (0) #define FP_CLS_NORMAL 0 #define FP_CLS_ZERO 1 #define FP_CLS_INF 2 #define FP_CLS_NAN 3 -#define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y)) +#define _FP_CLS_COMBINE(x, y) (((x) << 2) | (y)) #include "op-1.h" #include "op-2.h" @@ -194,35 +231,35 @@ do { \ #define UWtype _FP_W_TYPE #define W_TYPE_SIZE _FP_W_TYPE_SIZE -typedef int QItype __attribute__((mode(QI))); -typedef int SItype __attribute__((mode(SI))); -typedef int DItype __attribute__((mode(DI))); -typedef unsigned int UQItype __attribute__((mode(QI))); -typedef unsigned int USItype __attribute__((mode(SI))); -typedef unsigned int UDItype __attribute__((mode(DI))); +typedef int QItype __attribute__ ((mode (QI))); +typedef int SItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); #if _FP_W_TYPE_SIZE == 32 -typedef unsigned int UHWtype __attribute__((mode(HI))); +typedef unsigned int UHWtype __attribute__ ((mode (HI))); #elif _FP_W_TYPE_SIZE == 64 typedef USItype UHWtype; #endif #ifndef CMPtype -#define CMPtype int +# define CMPtype int #endif -#define SI_BITS (__CHAR_BIT__ * (int)sizeof(SItype)) -#define DI_BITS (__CHAR_BIT__ * (int)sizeof(DItype)) +#define SI_BITS (__CHAR_BIT__ * (int) sizeof (SItype)) +#define DI_BITS (__CHAR_BIT__ * (int) sizeof (DItype)) #ifndef umul_ppmm -#ifdef _LIBC -#include <stdlib/longlong.h> -#else -#include "longlong.h" -#endif +# ifdef _LIBC +# include <stdlib/longlong.h> +# else +# include "longlong.h" +# endif #endif #ifdef _LIBC -#include <stdlib.h> +# include <stdlib.h> #else extern void abort (void); #endif diff --git a/libgcc/soft-fp/subdf3.c b/libgcc/soft-fp/subdf3.c index 032ac0f291f..6846e98dbd6 100644 --- a/libgcc/soft-fp/subdf3.c +++ b/libgcc/soft-fp/subdf3.c @@ -31,17 +31,20 @@ #include "soft-fp.h" #include "double.h" -DFtype __subdf3(DFtype a, DFtype b) +DFtype +__subdf3 (DFtype a, DFtype b) { FP_DECL_EX; - FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R); + FP_DECL_D (A); + FP_DECL_D (B); + FP_DECL_D (R); DFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_SEMIRAW_D(A, a); - FP_UNPACK_SEMIRAW_D(B, b); - FP_SUB_D(R, A, B); - FP_PACK_SEMIRAW_D(r, R); + FP_UNPACK_SEMIRAW_D (A, a); + FP_UNPACK_SEMIRAW_D (B, b); + FP_SUB_D (R, A, B); + FP_PACK_SEMIRAW_D (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/subsf3.c b/libgcc/soft-fp/subsf3.c index c9f56c7176e..d46ddf58ae6 100644 --- a/libgcc/soft-fp/subsf3.c +++ b/libgcc/soft-fp/subsf3.c @@ -31,17 +31,20 @@ #include "soft-fp.h" #include "single.h" -SFtype __subsf3(SFtype a, SFtype b) +SFtype +__subsf3 (SFtype a, SFtype b) { FP_DECL_EX; - FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R); + FP_DECL_S (A); + FP_DECL_S (B); + FP_DECL_S (R); SFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_SEMIRAW_S(A, a); - FP_UNPACK_SEMIRAW_S(B, b); - FP_SUB_S(R, A, B); - FP_PACK_SEMIRAW_S(r, R); + FP_UNPACK_SEMIRAW_S (A, a); + FP_UNPACK_SEMIRAW_S (B, b); + FP_SUB_S (R, A, B); + FP_PACK_SEMIRAW_S (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/subtf3.c b/libgcc/soft-fp/subtf3.c index a111d571e1b..88c6edeb612 100644 --- a/libgcc/soft-fp/subtf3.c +++ b/libgcc/soft-fp/subtf3.c @@ -31,17 +31,20 @@ #include "soft-fp.h" #include "quad.h" -TFtype __subtf3(TFtype a, TFtype b) +TFtype +__subtf3 (TFtype a, TFtype b) { FP_DECL_EX; - FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R); + FP_DECL_Q (A); + FP_DECL_Q (B); + FP_DECL_Q (R); TFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_SEMIRAW_Q(A, a); - FP_UNPACK_SEMIRAW_Q(B, b); - FP_SUB_Q(R, A, B); - FP_PACK_SEMIRAW_Q(r, R); + FP_UNPACK_SEMIRAW_Q (A, a); + FP_UNPACK_SEMIRAW_Q (B, b); + FP_SUB_Q (R, A, B); + FP_PACK_SEMIRAW_Q (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/truncdfsf2.c b/libgcc/soft-fp/truncdfsf2.c index e9a7223674f..3ec56fdf8ad 100644 --- a/libgcc/soft-fp/truncdfsf2.c +++ b/libgcc/soft-fp/truncdfsf2.c @@ -32,21 +32,22 @@ #include "single.h" #include "double.h" -SFtype __truncdfsf2(DFtype a) +SFtype +__truncdfsf2 (DFtype a) { FP_DECL_EX; - FP_DECL_D(A); - FP_DECL_S(R); + FP_DECL_D (A); + FP_DECL_S (R); SFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_SEMIRAW_D(A, a); + FP_UNPACK_SEMIRAW_D (A, a); #if _FP_W_TYPE_SIZE < _FP_FRACBITS_D - FP_TRUNC(S,D,1,2,R,A); + FP_TRUNC (S, D, 1, 2, R, A); #else - FP_TRUNC(S,D,1,1,R,A); + FP_TRUNC (S, D, 1, 1, R, A); #endif - FP_PACK_SEMIRAW_S(r, R); + FP_PACK_SEMIRAW_S (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/trunctfdf2.c b/libgcc/soft-fp/trunctfdf2.c index 35c6496362f..e9702101291 100644 --- a/libgcc/soft-fp/trunctfdf2.c +++ b/libgcc/soft-fp/trunctfdf2.c @@ -32,21 +32,22 @@ #include "double.h" #include "quad.h" -DFtype __trunctfdf2(TFtype a) +DFtype +__trunctfdf2 (TFtype a) { FP_DECL_EX; - FP_DECL_Q(A); - FP_DECL_D(R); + FP_DECL_Q (A); + FP_DECL_D (R); DFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_SEMIRAW_Q(A, a); + FP_UNPACK_SEMIRAW_Q (A, a); #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q - FP_TRUNC(D,Q,2,4,R,A); + FP_TRUNC (D, Q, 2, 4, R, A); #else - FP_TRUNC(D,Q,1,2,R,A); + FP_TRUNC (D, Q, 1, 2, R, A); #endif - FP_PACK_SEMIRAW_D(r, R); + FP_PACK_SEMIRAW_D (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/trunctfsf2.c b/libgcc/soft-fp/trunctfsf2.c index 751c7c8d76e..d8a3728a0da 100644 --- a/libgcc/soft-fp/trunctfsf2.c +++ b/libgcc/soft-fp/trunctfsf2.c @@ -32,21 +32,22 @@ #include "single.h" #include "quad.h" -SFtype __trunctfsf2(TFtype a) +SFtype +__trunctfsf2 (TFtype a) { FP_DECL_EX; - FP_DECL_Q(A); - FP_DECL_S(R); + FP_DECL_Q (A); + FP_DECL_S (R); SFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_SEMIRAW_Q(A, a); + FP_UNPACK_SEMIRAW_Q (A, a); #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q - FP_TRUNC(S,Q,1,4,R,A); + FP_TRUNC (S, Q, 1, 4, R, A); #else - FP_TRUNC(S,Q,1,2,R,A); + FP_TRUNC (S, Q, 1, 2, R, A); #endif - FP_PACK_SEMIRAW_S(r, R); + FP_PACK_SEMIRAW_S (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/trunctfxf2.c b/libgcc/soft-fp/trunctfxf2.c index 50d60bc5d53..750bec1808e 100644 --- a/libgcc/soft-fp/trunctfxf2.c +++ b/libgcc/soft-fp/trunctfxf2.c @@ -1,6 +1,6 @@ /* Software floating-point emulation. Truncate IEEE quad into IEEE extended - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Uros Bizjak (ubizjak@gmail.com). @@ -24,29 +24,29 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "soft-fp.h" #include "extended.h" #include "quad.h" -XFtype __trunctfxf2(TFtype a) +XFtype +__trunctfxf2 (TFtype a) { FP_DECL_EX; - FP_DECL_Q(A); - FP_DECL_E(R); + FP_DECL_Q (A); + FP_DECL_E (R); XFtype r; FP_INIT_ROUNDMODE; - FP_UNPACK_SEMIRAW_Q(A, a); + FP_UNPACK_SEMIRAW_Q (A, a); #if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q - FP_TRUNC(E,Q,4,4,R,A); + FP_TRUNC (E, Q, 4, 4, R, A); #else - FP_TRUNC(E,Q,2,2,R,A); + FP_TRUNC (E, Q, 2, 2, R, A); #endif - FP_PACK_SEMIRAW_E(r, R); + FP_PACK_SEMIRAW_E (r, R); FP_HANDLE_EXCEPTIONS; return r; diff --git a/libgcc/soft-fp/unorddf2.c b/libgcc/soft-fp/unorddf2.c index 2e77f2d8ff7..641c8697251 100644 --- a/libgcc/soft-fp/unorddf2.c +++ b/libgcc/soft-fp/unorddf2.c @@ -30,14 +30,21 @@ #include "soft-fp.h" #include "double.h" -CMPtype __unorddf2(DFtype a, DFtype b) +CMPtype +__unorddf2 (DFtype a, DFtype b) { - FP_DECL_D(A); FP_DECL_D(B); + FP_DECL_EX; + FP_DECL_D (A); + FP_DECL_D (B); CMPtype r; - FP_UNPACK_RAW_D(A, a); - FP_UNPACK_RAW_D(B, b); - FP_CMP_UNORD_D(r, A, B); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_D (A, a); + FP_UNPACK_RAW_D (B, b); + FP_CMP_UNORD_D (r, A, B); + if (r && (FP_ISSIGNAN_D (A) || FP_ISSIGNAN_D (B))) + FP_SET_EXCEPTION (FP_EX_INVALID); + FP_HANDLE_EXCEPTIONS; return r; } diff --git a/libgcc/soft-fp/unordsf2.c b/libgcc/soft-fp/unordsf2.c index b5b5322c168..f271421283f 100644 --- a/libgcc/soft-fp/unordsf2.c +++ b/libgcc/soft-fp/unordsf2.c @@ -30,15 +30,21 @@ #include "soft-fp.h" #include "single.h" -CMPtype __unordsf2(SFtype a, SFtype b) +CMPtype +__unordsf2 (SFtype a, SFtype b) { - FP_DECL_S(A); - FP_DECL_S(B); + FP_DECL_EX; + FP_DECL_S (A); + FP_DECL_S (B); CMPtype r; - FP_UNPACK_RAW_S(A, a); - FP_UNPACK_RAW_S(B, b); - FP_CMP_UNORD_S(r, A, B); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_S (A, a); + FP_UNPACK_RAW_S (B, b); + FP_CMP_UNORD_S (r, A, B); + if (r && (FP_ISSIGNAN_S (A) || FP_ISSIGNAN_S (B))) + FP_SET_EXCEPTION (FP_EX_INVALID); + FP_HANDLE_EXCEPTIONS; return r; } diff --git a/libgcc/soft-fp/unordtf2.c b/libgcc/soft-fp/unordtf2.c index 1a85c252c1a..38cc1a78b26 100644 --- a/libgcc/soft-fp/unordtf2.c +++ b/libgcc/soft-fp/unordtf2.c @@ -30,15 +30,21 @@ #include "soft-fp.h" #include "quad.h" -CMPtype __unordtf2(TFtype a, TFtype b) +CMPtype +__unordtf2 (TFtype a, TFtype b) { - FP_DECL_Q(A); - FP_DECL_Q(B); + FP_DECL_EX; + FP_DECL_Q (A); + FP_DECL_Q (B); CMPtype r; - FP_UNPACK_RAW_Q(A, a); - FP_UNPACK_RAW_Q(B, b); - FP_CMP_UNORD_Q(r, A, B); + FP_INIT_EXCEPTIONS; + FP_UNPACK_RAW_Q (A, a); + FP_UNPACK_RAW_Q (B, b); + FP_CMP_UNORD_Q (r, A, B); + if (r && (FP_ISSIGNAN_Q (A) || FP_ISSIGNAN_Q (B))) + FP_SET_EXCEPTION (FP_EX_INVALID); + FP_HANDLE_EXCEPTIONS; return r; } |