Update soft-fp from glibc.
This patch updates libgcc's copy of soft-fp from glibc, adding a testcase for a bug fix this brings in. Bootstrapped with no regressions on x86_64-unknown-linux-gnu. libgcc: * soft-fp/double.h: Update from glibc. * 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/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/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/unorddf2.c: Likewise. * soft-fp/unordsf2.c: Likewise. * soft-fp/unordtf2.c: Likewise. * config/c6x/eqd.c (__c6xabi_eqd): Update call to FP_CMP_EQ_D. * config/c6x/eqf.c (__c6xabi_eqf): Update call to FP_CMP_EQ_S. * config/c6x/ged.c (__c6xabi_ged): Update call to FP_CMP_D. * config/c6x/gef.c (__c6xabi_gef): Update call to FP_CMP_S. * config/c6x/gtd.c (__c6xabi_gtd): Update call to FP_CMP_D. * config/c6x/gtf.c (__c6xabi_gtf): Update call to FP_CMP_S. * config/c6x/led.c (__c6xabi_led): Update call to FP_CMP_D. * config/c6x/lef.c (__c6xabi_lef): Update call to FP_CMP_S. * config/c6x/ltd.c (__c6xabi_ltd): Update call to FP_CMP_D. * config/c6x/ltf.c (__c6xabi_ltf): Update call to FP_CMP_S. gcc/testsuite: * gcc.dg/torture/float128-extendxf-underflow.c: New test. From-SVN: r216048
This commit is contained in:
parent
c386686921
commit
5f60643158
@ -1,3 +1,7 @@
|
||||
2014-10-09 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* gcc.dg/torture/float128-extendxf-underflow.c: New test.
|
||||
|
||||
2014-10-09 Markus Trippelsdorf <markus@trippelsdorf.de>
|
||||
|
||||
* g++.dg/ipa/polymorphic-call-1.C: New testcase.
|
||||
|
40
gcc/testsuite/gcc.dg/torture/float128-extendxf-underflow.c
Normal file
40
gcc/testsuite/gcc.dg/torture/float128-extendxf-underflow.c
Normal file
@ -0,0 +1,40 @@
|
||||
/* Test that extension from XFmode to __float128 raises underflow for
|
||||
exact tiny values, if trapping on underflow is enabled. */
|
||||
|
||||
/* { dg-do run { target i?86-*-*gnu* x86_64-*-*gnu* ia64-*-*gnu* } } */
|
||||
/* { dg-options "-D_GNU_SOURCE" } */
|
||||
/* { dg-require-effective-target fenv_exceptions } */
|
||||
|
||||
#include <fenv.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
volatile sig_atomic_t caught_sigfpe;
|
||||
sigjmp_buf buf;
|
||||
|
||||
static void
|
||||
handle_sigfpe (int sig)
|
||||
{
|
||||
caught_sigfpe = 1;
|
||||
siglongjmp (buf, 1);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
volatile long double a = 0x1p-16384L;
|
||||
volatile __float128 r;
|
||||
r = a;
|
||||
if (fetestexcept (FE_UNDERFLOW))
|
||||
abort ();
|
||||
if (r != 0x1p-16384q)
|
||||
abort ();
|
||||
feenableexcept (FE_UNDERFLOW);
|
||||
signal (SIGFPE, handle_sigfpe);
|
||||
if (sigsetjmp (buf, 1) == 0)
|
||||
r = a;
|
||||
if (!caught_sigfpe)
|
||||
abort ();
|
||||
exit (0);
|
||||
}
|
@ -1,3 +1,42 @@
|
||||
2014-10-09 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* soft-fp/double.h: Update from glibc.
|
||||
* 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/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/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/unorddf2.c: Likewise.
|
||||
* soft-fp/unordsf2.c: Likewise.
|
||||
* soft-fp/unordtf2.c: Likewise.
|
||||
* config/c6x/eqd.c (__c6xabi_eqd): Update call to FP_CMP_EQ_D.
|
||||
* config/c6x/eqf.c (__c6xabi_eqf): Update call to FP_CMP_EQ_S.
|
||||
* config/c6x/ged.c (__c6xabi_ged): Update call to FP_CMP_D.
|
||||
* config/c6x/gef.c (__c6xabi_gef): Update call to FP_CMP_S.
|
||||
* config/c6x/gtd.c (__c6xabi_gtd): Update call to FP_CMP_D.
|
||||
* config/c6x/gtf.c (__c6xabi_gtf): Update call to FP_CMP_S.
|
||||
* config/c6x/led.c (__c6xabi_led): Update call to FP_CMP_D.
|
||||
* config/c6x/lef.c (__c6xabi_lef): Update call to FP_CMP_S.
|
||||
* config/c6x/ltd.c (__c6xabi_ltd): Update call to FP_CMP_D.
|
||||
* config/c6x/ltf.c (__c6xabi_ltf): Update call to FP_CMP_S.
|
||||
|
||||
2014-10-08 Rong Xu <xur@google.com>
|
||||
|
||||
* libgcov-util.c (read_gcda_file): Fix format.
|
||||
|
@ -38,9 +38,7 @@ CMPtype __c6xabi_eqd(DFtype a, DFtype b)
|
||||
|
||||
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_CMP_EQ_D(r, A, B, 1);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return !r;
|
||||
|
@ -38,9 +38,7 @@ CMPtype __c6xabi_eqf(SFtype a, SFtype b)
|
||||
|
||||
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_CMP_EQ_S(r, A, B, 1);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return !r;
|
||||
|
@ -38,9 +38,7 @@ CMPtype __c6xabi_ged(DFtype a, DFtype b)
|
||||
|
||||
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_CMP_D(r, A, B, -2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r >= 0;
|
||||
|
@ -38,9 +38,7 @@ CMPtype __c6xabi_gef(SFtype a, SFtype b)
|
||||
|
||||
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_CMP_S(r, A, B, -2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r >= 0;
|
||||
|
@ -38,9 +38,7 @@ CMPtype __c6xabi_gtd(DFtype a, DFtype b)
|
||||
|
||||
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_CMP_D(r, A, B, -2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r > 0;
|
||||
|
@ -38,9 +38,7 @@ CMPtype __c6xabi_gtf(SFtype a, SFtype b)
|
||||
|
||||
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_CMP_S(r, A, B, -2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r > 0;
|
||||
|
@ -38,9 +38,7 @@ CMPtype __c6xabi_led(DFtype a, DFtype b)
|
||||
|
||||
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_CMP_D(r, A, B, 2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r <= 0;
|
||||
|
@ -38,9 +38,7 @@ CMPtype __c6xabi_lef(SFtype a, SFtype b)
|
||||
|
||||
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_CMP_S(r, A, B, 2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r <= 0;
|
||||
|
@ -38,9 +38,7 @@ CMPtype __c6xabi_ltd(DFtype a, DFtype b)
|
||||
|
||||
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_CMP_D(r, A, B, 2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r < 0;
|
||||
|
@ -38,9 +38,7 @@ CMPtype __c6xabi_ltf(SFtype a, SFtype b)
|
||||
|
||||
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_CMP_S(r, A, B, 2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r < 0;
|
||||
|
@ -90,21 +90,21 @@ union _FP_UNION_D
|
||||
};
|
||||
|
||||
# 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_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); \
|
||||
_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_RAW_2 (D, X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (D, 2, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -112,7 +112,7 @@ union _FP_UNION_D
|
||||
# define FP_UNPACK_DP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_2_P (D, X, val); \
|
||||
_FP_UNPACK_RAW_2_P (D, X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (D, 2, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -120,7 +120,7 @@ union _FP_UNION_D
|
||||
# define FP_UNPACK_SEMIRAW_D(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_2 (D, X, val); \
|
||||
_FP_UNPACK_RAW_2 (D, X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (D, 2, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -128,7 +128,7 @@ union _FP_UNION_D
|
||||
# define FP_UNPACK_SEMIRAW_DP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_2_P (D, X, val); \
|
||||
_FP_UNPACK_RAW_2_P (D, X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (D, 2, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -137,7 +137,7 @@ union _FP_UNION_D
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (D, 2, X); \
|
||||
_FP_PACK_RAW_2 (D, val, X); \
|
||||
_FP_PACK_RAW_2 (D, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -146,7 +146,7 @@ union _FP_UNION_D
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (D, 2, X); \
|
||||
if (!FP_INHIBIT_RESULTS) \
|
||||
_FP_PACK_RAW_2_P (D, val, X); \
|
||||
_FP_PACK_RAW_2_P (D, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -154,7 +154,7 @@ union _FP_UNION_D
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (D, 2, X); \
|
||||
_FP_PACK_RAW_2 (D, val, X); \
|
||||
_FP_PACK_RAW_2 (D, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -163,7 +163,7 @@ union _FP_UNION_D
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (D, 2, X); \
|
||||
if (!FP_INHIBIT_RESULTS) \
|
||||
_FP_PACK_RAW_2_P (D, val, X); \
|
||||
_FP_PACK_RAW_2_P (D, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -174,15 +174,15 @@ union _FP_UNION_D
|
||||
# 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_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_CMP_D(r, X, Y, un, ex) _FP_CMP (D, 2, (r), X, Y, (un), (ex))
|
||||
# define FP_CMP_EQ_D(r, X, Y, ex) _FP_CMP_EQ (D, 2, (r), X, Y, (ex))
|
||||
# define FP_CMP_UNORD_D(r, X, Y, ex) _FP_CMP_UNORD (D, 2, (r), X, Y, (ex))
|
||||
|
||||
# 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_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)
|
||||
@ -209,21 +209,21 @@ union _FP_UNION_D
|
||||
};
|
||||
|
||||
# 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_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); \
|
||||
_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_RAW_1 (D, X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (D, 1, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -231,7 +231,7 @@ union _FP_UNION_D
|
||||
# define FP_UNPACK_DP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_1_P (D, X, val); \
|
||||
_FP_UNPACK_RAW_1_P (D, X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (D, 1, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -239,7 +239,7 @@ union _FP_UNION_D
|
||||
# define FP_UNPACK_SEMIRAW_D(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_1 (D, X, val); \
|
||||
_FP_UNPACK_RAW_1 (D, X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (D, 1, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -247,7 +247,7 @@ union _FP_UNION_D
|
||||
# define FP_UNPACK_SEMIRAW_DP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_1_P (D, X, val); \
|
||||
_FP_UNPACK_RAW_1_P (D, X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (D, 1, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -256,7 +256,7 @@ union _FP_UNION_D
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (D, 1, X); \
|
||||
_FP_PACK_RAW_1 (D, val, X); \
|
||||
_FP_PACK_RAW_1 (D, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -265,7 +265,7 @@ union _FP_UNION_D
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (D, 1, X); \
|
||||
if (!FP_INHIBIT_RESULTS) \
|
||||
_FP_PACK_RAW_1_P (D, val, X); \
|
||||
_FP_PACK_RAW_1_P (D, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -273,7 +273,7 @@ union _FP_UNION_D
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (D, 1, X); \
|
||||
_FP_PACK_RAW_1 (D, val, X); \
|
||||
_FP_PACK_RAW_1 (D, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -282,7 +282,7 @@ union _FP_UNION_D
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (D, 1, X); \
|
||||
if (!FP_INHIBIT_RESULTS) \
|
||||
_FP_PACK_RAW_1_P (D, val, X); \
|
||||
_FP_PACK_RAW_1_P (D, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -293,18 +293,18 @@ union _FP_UNION_D
|
||||
# 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_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, ex) _FP_CMP (D, 1, (r), X, Y, (un), (ex))
|
||||
# define FP_CMP_EQ_D(r, X, Y, ex) _FP_CMP_EQ (D, 1, (r), X, Y, (ex))
|
||||
# define FP_CMP_UNORD_D(r, X, Y, ex) _FP_CMP_UNORD (D, 1, (r), X, Y, (ex))
|
||||
|
||||
# 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)
|
||||
|
@ -42,9 +42,7 @@ __eqdf2 (DFtype a, DFtype b)
|
||||
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_CMP_EQ_D (r, A, B, 1);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
@ -42,9 +42,7 @@ __eqsf2 (SFtype a, SFtype b)
|
||||
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_CMP_EQ_S (r, A, B, 1);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
@ -42,9 +42,7 @@ __eqtf2 (TFtype a, TFtype b)
|
||||
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_CMP_EQ_Q (r, A, B, 1);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
@ -28,6 +28,7 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define FP_NO_EXACT_UNDERFLOW
|
||||
#include "soft-fp.h"
|
||||
#include "double.h"
|
||||
#include "quad.h"
|
||||
|
@ -91,76 +91,78 @@ union _FP_UNION_E
|
||||
|
||||
# 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; \
|
||||
} \
|
||||
# define FP_UNPACK_RAW_E(X, val) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_E FP_UNPACK_RAW_E_flo; \
|
||||
FP_UNPACK_RAW_E_flo.flt = (val); \
|
||||
\
|
||||
X##_f[2] = 0; \
|
||||
X##_f[3] = 0; \
|
||||
X##_f[0] = FP_UNPACK_RAW_E_flo.bits.frac0; \
|
||||
X##_f[1] = FP_UNPACK_RAW_E_flo.bits.frac1; \
|
||||
X##_e = FP_UNPACK_RAW_E_flo.bits.exp; \
|
||||
X##_s = FP_UNPACK_RAW_E_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; \
|
||||
} \
|
||||
# define FP_UNPACK_RAW_EP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_E *FP_UNPACK_RAW_EP_flo \
|
||||
= (union _FP_UNION_E *) (val); \
|
||||
\
|
||||
X##_f[2] = 0; \
|
||||
X##_f[3] = 0; \
|
||||
X##_f[0] = FP_UNPACK_RAW_EP_flo->bits.frac0; \
|
||||
X##_f[1] = FP_UNPACK_RAW_EP_flo->bits.frac1; \
|
||||
X##_e = FP_UNPACK_RAW_EP_flo->bits.exp; \
|
||||
X##_s = FP_UNPACK_RAW_EP_flo->bits.sign; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
# define FP_PACK_RAW_E(val, X) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_E _flo; \
|
||||
union _FP_UNION_E FP_PACK_RAW_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; \
|
||||
FP_PACK_RAW_E_flo.bits.frac0 = X##_f[0]; \
|
||||
FP_PACK_RAW_E_flo.bits.frac1 = X##_f[1]; \
|
||||
FP_PACK_RAW_E_flo.bits.exp = X##_e; \
|
||||
FP_PACK_RAW_E_flo.bits.sign = X##_s; \
|
||||
\
|
||||
(val) = _flo.flt; \
|
||||
(val) = FP_PACK_RAW_E_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; \
|
||||
} \
|
||||
} \
|
||||
# define FP_PACK_RAW_EP(val, X) \
|
||||
do \
|
||||
{ \
|
||||
if (!FP_INHIBIT_RESULTS) \
|
||||
{ \
|
||||
union _FP_UNION_E *FP_PACK_RAW_EP_flo \
|
||||
= (union _FP_UNION_E *) (val); \
|
||||
\
|
||||
if (X##_e) \
|
||||
X##_f[1] |= _FP_IMPLBIT_E; \
|
||||
else \
|
||||
X##_f[1] &= ~(_FP_IMPLBIT_E); \
|
||||
FP_PACK_RAW_EP_flo->bits.frac0 = X##_f[0]; \
|
||||
FP_PACK_RAW_EP_flo->bits.frac1 = X##_f[1]; \
|
||||
FP_PACK_RAW_EP_flo->bits.exp = X##_e; \
|
||||
FP_PACK_RAW_EP_flo->bits.sign = X##_s; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
# define FP_UNPACK_E(X, val) \
|
||||
do \
|
||||
{ \
|
||||
FP_UNPACK_RAW_E (X, val); \
|
||||
FP_UNPACK_RAW_E (X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (E, 4, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -168,7 +170,7 @@ union _FP_UNION_E
|
||||
# define FP_UNPACK_EP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
FP_UNPACK_RAW_EP (X, val); \
|
||||
FP_UNPACK_RAW_EP (X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (E, 4, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -176,7 +178,7 @@ union _FP_UNION_E
|
||||
# define FP_UNPACK_SEMIRAW_E(X, val) \
|
||||
do \
|
||||
{ \
|
||||
FP_UNPACK_RAW_E (X, val); \
|
||||
FP_UNPACK_RAW_E (X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (E, 4, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -184,7 +186,7 @@ union _FP_UNION_E
|
||||
# define FP_UNPACK_SEMIRAW_EP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
FP_UNPACK_RAW_EP (X, val); \
|
||||
FP_UNPACK_RAW_EP (X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (E, 4, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -193,7 +195,7 @@ union _FP_UNION_E
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (E, 4, X); \
|
||||
FP_PACK_RAW_E (val, X); \
|
||||
FP_PACK_RAW_E ((val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -201,7 +203,7 @@ union _FP_UNION_E
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (E, 4, X); \
|
||||
FP_PACK_RAW_EP (val, X); \
|
||||
FP_PACK_RAW_EP ((val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -209,7 +211,7 @@ union _FP_UNION_E
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (E, 4, X); \
|
||||
FP_PACK_RAW_E (val, X); \
|
||||
FP_PACK_RAW_E ((val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -217,7 +219,7 @@ union _FP_UNION_E
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (E, 4, X); \
|
||||
FP_PACK_RAW_EP (val, X); \
|
||||
FP_PACK_RAW_EP ((val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -230,50 +232,48 @@ union _FP_UNION_E
|
||||
# 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:
|
||||
* We have just one right now, maybe Newton approximation
|
||||
* should be added for those machines where division is fast.
|
||||
* This has special _E version because standard _4 square
|
||||
* root would not work (it has to start normally with the
|
||||
* second word and not the first), but as we have to do it
|
||||
* anyway, we optimize it by doing most of the calculations
|
||||
* in two UWtype registers instead of four.
|
||||
*/
|
||||
/* Square root algorithms:
|
||||
We have just one right now, maybe Newton approximation
|
||||
should be added for those machines where division is fast.
|
||||
This has special _E version because standard _4 square
|
||||
root would not work (it has to start normally with the
|
||||
second word and not the first), but as we have to do it
|
||||
anyway, we optimize it by doing most of the calculations
|
||||
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); \
|
||||
(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; \
|
||||
T##_f[1] = S##_f[1] + (q); \
|
||||
if (T##_f[1] <= X##_f[1]) \
|
||||
{ \
|
||||
S##_f[1] = T##_f[1] + q; \
|
||||
S##_f[1] = T##_f[1] + (q); \
|
||||
X##_f[1] -= T##_f[1]; \
|
||||
R##_f[1] += q; \
|
||||
R##_f[1] += (q); \
|
||||
} \
|
||||
_FP_FRAC_SLL_2 (X, 1); \
|
||||
q >>= 1; \
|
||||
(q) >>= 1; \
|
||||
} \
|
||||
q = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \
|
||||
(q) = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \
|
||||
while (q) \
|
||||
{ \
|
||||
T##_f[0] = S##_f[0] + 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[0] = T##_f[0] + (q); \
|
||||
S##_f[1] += (T##_f[0] > S##_f[0]); \
|
||||
_FP_FRAC_DEC_2 (X, T); \
|
||||
R##_f[0] += q; \
|
||||
R##_f[0] += (q); \
|
||||
} \
|
||||
_FP_FRAC_SLL_2 (X, 1); \
|
||||
q >>= 1; \
|
||||
(q) >>= 1; \
|
||||
} \
|
||||
_FP_FRAC_SLL_4 (R, (_FP_WORKBITS)); \
|
||||
if (X##_f[0] | X##_f[1]) \
|
||||
@ -287,12 +287,12 @@ union _FP_UNION_E
|
||||
} \
|
||||
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_CMP_E(r, X, Y, un, ex) _FP_CMP (E, 4, (r), X, Y, (un), (ex))
|
||||
# define FP_CMP_EQ_E(r, X, Y, ex) _FP_CMP_EQ (E, 4, (r), X, Y, (ex))
|
||||
# define FP_CMP_UNORD_E(r, X, Y, ex) _FP_CMP_UNORD (E, 4, (r), X, Y, (ex))
|
||||
|
||||
# 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_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])
|
||||
@ -323,68 +323,70 @@ union _FP_UNION_E
|
||||
# define FP_UNPACK_RAW_E(X, val) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_E _flo; \
|
||||
_flo.flt = (val); \
|
||||
union _FP_UNION_E FP_UNPACK_RAW_E_flo; \
|
||||
FP_UNPACK_RAW_E_flo.flt = (val); \
|
||||
\
|
||||
X##_f0 = _flo.bits.frac; \
|
||||
X##_f0 = FP_UNPACK_RAW_E_flo.bits.frac; \
|
||||
X##_f1 = 0; \
|
||||
X##_e = _flo.bits.exp; \
|
||||
X##_s = _flo.bits.sign; \
|
||||
X##_e = FP_UNPACK_RAW_E_flo.bits.exp; \
|
||||
X##_s = FP_UNPACK_RAW_E_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; \
|
||||
} \
|
||||
# define FP_UNPACK_RAW_EP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_E *FP_UNPACK_RAW_EP_flo \
|
||||
= (union _FP_UNION_E *) (val); \
|
||||
\
|
||||
X##_f0 = FP_UNPACK_RAW_EP_flo->bits.frac; \
|
||||
X##_f1 = 0; \
|
||||
X##_e = FP_UNPACK_RAW_EP_flo->bits.exp; \
|
||||
X##_s = FP_UNPACK_RAW_EP_flo->bits.sign; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
# define FP_PACK_RAW_E(val, X) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_E _flo; \
|
||||
union _FP_UNION_E FP_PACK_RAW_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; \
|
||||
FP_PACK_RAW_E_flo.bits.frac = X##_f0; \
|
||||
FP_PACK_RAW_E_flo.bits.exp = X##_e; \
|
||||
FP_PACK_RAW_E_flo.bits.sign = X##_s; \
|
||||
\
|
||||
(val) = _flo.flt; \
|
||||
(val) = FP_PACK_RAW_E_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; \
|
||||
} \
|
||||
} \
|
||||
# define FP_PACK_RAW_EP(fs, val, X) \
|
||||
do \
|
||||
{ \
|
||||
if (!FP_INHIBIT_RESULTS) \
|
||||
{ \
|
||||
union _FP_UNION_E *FP_PACK_RAW_EP_flo \
|
||||
= (union _FP_UNION_E *) (val); \
|
||||
\
|
||||
if (X##_e) \
|
||||
X##_f0 |= _FP_IMPLBIT_E; \
|
||||
else \
|
||||
X##_f0 &= ~(_FP_IMPLBIT_E); \
|
||||
FP_PACK_RAW_EP_flo->bits.frac = X##_f0; \
|
||||
FP_PACK_RAW_EP_flo->bits.exp = X##_e; \
|
||||
FP_PACK_RAW_EP_flo->bits.sign = X##_s; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
# define FP_UNPACK_E(X, val) \
|
||||
do \
|
||||
{ \
|
||||
FP_UNPACK_RAW_E (X, val); \
|
||||
FP_UNPACK_RAW_E (X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (E, 2, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -392,7 +394,7 @@ union _FP_UNION_E
|
||||
# define FP_UNPACK_EP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
FP_UNPACK_RAW_EP (X, val); \
|
||||
FP_UNPACK_RAW_EP (X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (E, 2, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -400,7 +402,7 @@ union _FP_UNION_E
|
||||
# define FP_UNPACK_SEMIRAW_E(X, val) \
|
||||
do \
|
||||
{ \
|
||||
FP_UNPACK_RAW_E (X, val); \
|
||||
FP_UNPACK_RAW_E (X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (E, 2, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -408,7 +410,7 @@ union _FP_UNION_E
|
||||
# define FP_UNPACK_SEMIRAW_EP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
FP_UNPACK_RAW_EP (X, val); \
|
||||
FP_UNPACK_RAW_EP (X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (E, 2, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -417,7 +419,7 @@ union _FP_UNION_E
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (E, 2, X); \
|
||||
FP_PACK_RAW_E (val, X); \
|
||||
FP_PACK_RAW_E ((val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -425,7 +427,7 @@ union _FP_UNION_E
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (E, 2, X); \
|
||||
FP_PACK_RAW_EP (val, X); \
|
||||
FP_PACK_RAW_EP ((val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -433,7 +435,7 @@ union _FP_UNION_E
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (E, 2, X); \
|
||||
FP_PACK_RAW_E (val, X); \
|
||||
FP_PACK_RAW_E ((val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -441,7 +443,7 @@ union _FP_UNION_E
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (E, 2, X); \
|
||||
FP_PACK_RAW_EP (val, X); \
|
||||
FP_PACK_RAW_EP ((val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -454,30 +456,28 @@ union _FP_UNION_E
|
||||
# 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:
|
||||
* We have just one right now, maybe Newton approximation
|
||||
* should be added for those machines where division is fast.
|
||||
* We optimize it by doing most of the calculations
|
||||
* in one UWtype registers instead of two, although we don't
|
||||
* have to.
|
||||
*/
|
||||
/* Square root algorithms:
|
||||
We have just one right now, maybe Newton approximation
|
||||
should be added for those machines where division is fast.
|
||||
We optimize it by doing most of the calculations
|
||||
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); \
|
||||
(q) = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \
|
||||
_FP_FRAC_SRL_2 (X, (_FP_WORKBITS)); \
|
||||
while (q) \
|
||||
{ \
|
||||
T##_f0 = S##_f0 + q; \
|
||||
T##_f0 = S##_f0 + (q); \
|
||||
if (T##_f0 <= X##_f0) \
|
||||
{ \
|
||||
S##_f0 = T##_f0 + q; \
|
||||
S##_f0 = T##_f0 + (q); \
|
||||
X##_f0 -= T##_f0; \
|
||||
R##_f0 += q; \
|
||||
R##_f0 += (q); \
|
||||
} \
|
||||
_FP_FRAC_SLL_1 (X, 1); \
|
||||
q >>= 1; \
|
||||
(q) >>= 1; \
|
||||
} \
|
||||
_FP_FRAC_SLL_2 (R, (_FP_WORKBITS)); \
|
||||
if (X##_f0) \
|
||||
@ -489,12 +489,12 @@ union _FP_UNION_E
|
||||
} \
|
||||
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_CMP_E(r, X, Y, un, ex) _FP_CMP (E, 2, (r), X, Y, (un), (ex))
|
||||
# define FP_CMP_EQ_E(r, X, Y, ex) _FP_CMP_EQ (E, 2, (r), X, Y, (ex))
|
||||
# define FP_CMP_UNORD_E(r, X, Y, ex) _FP_CMP_UNORD (E, 2, (r), X, Y, (ex))
|
||||
|
||||
# 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_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)
|
||||
|
@ -28,6 +28,7 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define FP_NO_EXACT_UNDERFLOW
|
||||
#include "soft-fp.h"
|
||||
#include "single.h"
|
||||
#include "double.h"
|
||||
|
@ -28,6 +28,7 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define FP_NO_EXACT_UNDERFLOW
|
||||
#include "soft-fp.h"
|
||||
#include "single.h"
|
||||
#include "quad.h"
|
||||
|
@ -39,7 +39,7 @@ __extendxftf2 (XFtype a)
|
||||
FP_DECL_Q (R);
|
||||
TFtype r;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_INIT_TRAPPING_EXCEPTIONS;
|
||||
FP_UNPACK_RAW_E (A, a);
|
||||
#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
|
||||
FP_EXTEND (Q, E, 4, 4, R, A);
|
||||
|
@ -42,9 +42,7 @@ __gedf2 (DFtype a, DFtype b)
|
||||
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_CMP_D (r, A, B, -2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
@ -42,9 +42,7 @@ __gesf2 (SFtype a, SFtype b)
|
||||
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_CMP_S (r, A, B, -2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
@ -42,9 +42,7 @@ __getf2 (TFtype a, TFtype b)
|
||||
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_CMP_Q (r, A, B, -2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
@ -42,9 +42,7 @@ __ledf2 (DFtype a, DFtype b)
|
||||
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_CMP_D (r, A, B, 2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
@ -42,9 +42,7 @@ __lesf2 (SFtype a, SFtype b)
|
||||
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_CMP_S (r, A, B, 2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
@ -42,9 +42,7 @@ __letf2 (TFtype a, TFtype b)
|
||||
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_CMP_Q (r, A, B, 2, 2);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
@ -50,8 +50,8 @@
|
||||
#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) __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 \
|
||||
@ -71,9 +71,9 @@
|
||||
#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_CLZ_1(z, X) __FP_CLZ ((z), X##_f)
|
||||
|
||||
/* Predicates */
|
||||
/* Predicates. */
|
||||
#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)
|
||||
@ -87,66 +87,62 @@
|
||||
#define _FP_MINFRAC_1 1
|
||||
#define _FP_MAXFRAC_1 (~(_FP_WS_TYPE) 0)
|
||||
|
||||
/*
|
||||
* Unpack the raw bits of a native fp value. Do not classify or
|
||||
* normalize the data.
|
||||
*/
|
||||
/* 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; \
|
||||
} \
|
||||
#define _FP_UNPACK_RAW_1(fs, X, val) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_##fs _FP_UNPACK_RAW_1_flo; \
|
||||
_FP_UNPACK_RAW_1_flo.flt = (val); \
|
||||
\
|
||||
X##_f = _FP_UNPACK_RAW_1_flo.bits.frac; \
|
||||
X##_e = _FP_UNPACK_RAW_1_flo.bits.exp; \
|
||||
X##_s = _FP_UNPACK_RAW_1_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; \
|
||||
} \
|
||||
#define _FP_UNPACK_RAW_1_P(fs, X, val) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_##fs *_FP_UNPACK_RAW_1_P_flo \
|
||||
= (union _FP_UNION_##fs *) (val); \
|
||||
\
|
||||
X##_f = _FP_UNPACK_RAW_1_P_flo->bits.frac; \
|
||||
X##_e = _FP_UNPACK_RAW_1_P_flo->bits.exp; \
|
||||
X##_s = _FP_UNPACK_RAW_1_P_flo->bits.sign; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/*
|
||||
* Repack the raw bits of a native fp value.
|
||||
*/
|
||||
/* Repack the raw bits of a native fp value. */
|
||||
|
||||
#define _FP_PACK_RAW_1(fs, val, X) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_##fs _flo; \
|
||||
union _FP_UNION_##fs _FP_PACK_RAW_1_flo; \
|
||||
\
|
||||
_flo.bits.frac = X##_f; \
|
||||
_flo.bits.exp = X##_e; \
|
||||
_flo.bits.sign = X##_s; \
|
||||
_FP_PACK_RAW_1_flo.bits.frac = X##_f; \
|
||||
_FP_PACK_RAW_1_flo.bits.exp = X##_e; \
|
||||
_FP_PACK_RAW_1_flo.bits.sign = X##_s; \
|
||||
\
|
||||
(val) = _flo.flt; \
|
||||
(val) = _FP_PACK_RAW_1_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; \
|
||||
} \
|
||||
#define _FP_PACK_RAW_1_P(fs, val, X) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_##fs *_FP_PACK_RAW_1_P_flo \
|
||||
= (union _FP_UNION_##fs *) (val); \
|
||||
\
|
||||
_FP_PACK_RAW_1_P_flo->bits.frac = X##_f; \
|
||||
_FP_PACK_RAW_1_P_flo->bits.exp = X##_e; \
|
||||
_FP_PACK_RAW_1_P_flo->bits.sign = X##_s; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Multiplication algorithms:
|
||||
*/
|
||||
/* Multiplication algorithms: */
|
||||
|
||||
/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the
|
||||
multiplication immediately. */
|
||||
@ -161,11 +157,11 @@
|
||||
#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y) \
|
||||
do \
|
||||
{ \
|
||||
_FP_MUL_MEAT_DW_1_imm (wfracbits, R, X, Y); \
|
||||
_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); \
|
||||
_FP_FRAC_SRS_1 (R, (wfracbits)-1, 2*(wfracbits)); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -181,13 +177,15 @@
|
||||
#define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit) \
|
||||
do \
|
||||
{ \
|
||||
_FP_FRAC_DECL_2 (_Z); \
|
||||
_FP_MUL_MEAT_DW_1_wide (wfracbits, _Z, X, Y, doit); \
|
||||
_FP_FRAC_DECL_2 (_FP_MUL_MEAT_1_wide_Z); \
|
||||
_FP_MUL_MEAT_DW_1_wide ((wfracbits), _FP_MUL_MEAT_1_wide_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; \
|
||||
_FP_FRAC_SRS_2 (_FP_MUL_MEAT_1_wide_Z, (wfracbits)-1, \
|
||||
2*(wfracbits)); \
|
||||
R##_f = _FP_MUL_MEAT_1_wide_Z_f0; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -196,62 +194,70 @@
|
||||
#define _FP_MUL_MEAT_DW_1_hard(wfracbits, R, X, Y) \
|
||||
do \
|
||||
{ \
|
||||
_FP_W_TYPE _xh, _xl, _yh, _yl; \
|
||||
_FP_FRAC_DECL_2 (_a); \
|
||||
_FP_W_TYPE _FP_MUL_MEAT_DW_1_hard_xh, _FP_MUL_MEAT_DW_1_hard_xl; \
|
||||
_FP_W_TYPE _FP_MUL_MEAT_DW_1_hard_yh, _FP_MUL_MEAT_DW_1_hard_yl; \
|
||||
_FP_FRAC_DECL_2 (_FP_MUL_MEAT_DW_1_hard_a); \
|
||||
\
|
||||
/* 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); \
|
||||
/* Split the words in half. */ \
|
||||
_FP_MUL_MEAT_DW_1_hard_xh = X##_f >> (_FP_W_TYPE_SIZE/2); \
|
||||
_FP_MUL_MEAT_DW_1_hard_xl \
|
||||
= X##_f & (((_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2)) - 1); \
|
||||
_FP_MUL_MEAT_DW_1_hard_yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \
|
||||
_FP_MUL_MEAT_DW_1_hard_yl \
|
||||
= Y##_f & (((_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2)) - 1); \
|
||||
\
|
||||
/* multiply the pieces */ \
|
||||
R##_f0 = _xl * _yl; \
|
||||
_a_f0 = _xh * _yl; \
|
||||
_a_f1 = _xl * _yh; \
|
||||
R##_f1 = _xh * _yh; \
|
||||
/* Multiply the pieces. */ \
|
||||
R##_f0 = _FP_MUL_MEAT_DW_1_hard_xl * _FP_MUL_MEAT_DW_1_hard_yl; \
|
||||
_FP_MUL_MEAT_DW_1_hard_a_f0 \
|
||||
= _FP_MUL_MEAT_DW_1_hard_xh * _FP_MUL_MEAT_DW_1_hard_yl; \
|
||||
_FP_MUL_MEAT_DW_1_hard_a_f1 \
|
||||
= _FP_MUL_MEAT_DW_1_hard_xl * _FP_MUL_MEAT_DW_1_hard_yh; \
|
||||
R##_f1 = _FP_MUL_MEAT_DW_1_hard_xh * _FP_MUL_MEAT_DW_1_hard_yh; \
|
||||
\
|
||||
/* reassemble into two full words */ \
|
||||
if ((_a_f0 += _a_f1) < _a_f1) \
|
||||
/* Reassemble into two full words. */ \
|
||||
if ((_FP_MUL_MEAT_DW_1_hard_a_f0 += _FP_MUL_MEAT_DW_1_hard_a_f1) \
|
||||
< _FP_MUL_MEAT_DW_1_hard_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); \
|
||||
_FP_MUL_MEAT_DW_1_hard_a_f1 \
|
||||
= _FP_MUL_MEAT_DW_1_hard_a_f0 >> (_FP_W_TYPE_SIZE/2); \
|
||||
_FP_MUL_MEAT_DW_1_hard_a_f0 \
|
||||
= _FP_MUL_MEAT_DW_1_hard_a_f0 << (_FP_W_TYPE_SIZE/2); \
|
||||
_FP_FRAC_ADD_2 (R, R, _FP_MUL_MEAT_DW_1_hard_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; \
|
||||
} \
|
||||
#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y) \
|
||||
do \
|
||||
{ \
|
||||
_FP_FRAC_DECL_2 (_FP_MUL_MEAT_1_hard_z); \
|
||||
_FP_MUL_MEAT_DW_1_hard ((wfracbits), \
|
||||
_FP_MUL_MEAT_1_hard_z, X, Y); \
|
||||
\
|
||||
/* Normalize. */ \
|
||||
_FP_FRAC_SRS_2 (_FP_MUL_MEAT_1_hard_z, \
|
||||
(wfracbits) - 1, 2*(wfracbits)); \
|
||||
R##_f = _FP_MUL_MEAT_1_hard_z_f0; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Division algorithms:
|
||||
*/
|
||||
/* Division algorithms: */
|
||||
|
||||
/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the
|
||||
division immediately. Give this macro either _FP_DIV_HELP_imm for
|
||||
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); \
|
||||
} \
|
||||
#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \
|
||||
do \
|
||||
{ \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_1_imm_q, _FP_DIV_MEAT_1_imm_r; \
|
||||
X##_f <<= (X##_f < Y##_f \
|
||||
? R##_e--, _FP_WFRACBITS_##fs \
|
||||
: _FP_WFRACBITS_##fs - 1); \
|
||||
doit (_FP_DIV_MEAT_1_imm_q, _FP_DIV_MEAT_1_imm_r, X##_f, Y##_f); \
|
||||
R##_f = _FP_DIV_MEAT_1_imm_q | (_FP_DIV_MEAT_1_imm_r != 0); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
|
||||
@ -262,70 +268,80 @@
|
||||
#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \
|
||||
do \
|
||||
{ \
|
||||
_FP_W_TYPE _nh, _nl, _q, _r, _y; \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_nh; \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_nl; \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_q; \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_r; \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_y; \
|
||||
\
|
||||
/* Normalize Y -- i.e. make the most significant bit set. */ \
|
||||
_y = Y##_f << _FP_WFRACXBITS_##fs; \
|
||||
_FP_DIV_MEAT_1_udiv_norm_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; \
|
||||
_FP_DIV_MEAT_1_udiv_norm_nl = 0; \
|
||||
_FP_DIV_MEAT_1_udiv_norm_nh = X##_f; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_nl = X##_f << (_FP_W_TYPE_SIZE - 1); \
|
||||
_nh = X##_f >> 1; \
|
||||
_FP_DIV_MEAT_1_udiv_norm_nl = X##_f << (_FP_W_TYPE_SIZE - 1); \
|
||||
_FP_DIV_MEAT_1_udiv_norm_nh = X##_f >> 1; \
|
||||
} \
|
||||
\
|
||||
udiv_qrnnd (_q, _r, _nh, _nl, _y); \
|
||||
R##_f = _q | (_r != 0); \
|
||||
udiv_qrnnd (_FP_DIV_MEAT_1_udiv_norm_q, \
|
||||
_FP_DIV_MEAT_1_udiv_norm_r, \
|
||||
_FP_DIV_MEAT_1_udiv_norm_nh, \
|
||||
_FP_DIV_MEAT_1_udiv_norm_nl, \
|
||||
_FP_DIV_MEAT_1_udiv_norm_y); \
|
||||
R##_f = (_FP_DIV_MEAT_1_udiv_norm_q \
|
||||
| (_FP_DIV_MEAT_1_udiv_norm_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); \
|
||||
} \
|
||||
#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \
|
||||
do \
|
||||
{ \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_1_udiv_nh, _FP_DIV_MEAT_1_udiv_nl; \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_1_udiv_q, _FP_DIV_MEAT_1_udiv_r; \
|
||||
if (X##_f < Y##_f) \
|
||||
{ \
|
||||
R##_e--; \
|
||||
_FP_DIV_MEAT_1_udiv_nl = X##_f << _FP_WFRACBITS_##fs; \
|
||||
_FP_DIV_MEAT_1_udiv_nh = X##_f >> _FP_WFRACXBITS_##fs; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_FP_DIV_MEAT_1_udiv_nl = X##_f << (_FP_WFRACBITS_##fs - 1); \
|
||||
_FP_DIV_MEAT_1_udiv_nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \
|
||||
} \
|
||||
udiv_qrnnd (_FP_DIV_MEAT_1_udiv_q, _FP_DIV_MEAT_1_udiv_r, \
|
||||
_FP_DIV_MEAT_1_udiv_nh, _FP_DIV_MEAT_1_udiv_nl, \
|
||||
Y##_f); \
|
||||
R##_f = _FP_DIV_MEAT_1_udiv_q | (_FP_DIV_MEAT_1_udiv_r != 0); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Square root algorithms:
|
||||
* We have just one right now, maybe Newton approximation
|
||||
* should be added for those machines where division is fast.
|
||||
*/
|
||||
/* Square root algorithms:
|
||||
We have just one right now, maybe Newton approximation
|
||||
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) \
|
||||
while ((q) != _FP_WORK_ROUND) \
|
||||
{ \
|
||||
T##_f = S##_f + q; \
|
||||
T##_f = S##_f + (q); \
|
||||
if (T##_f <= X##_f) \
|
||||
{ \
|
||||
S##_f = T##_f + q; \
|
||||
S##_f = T##_f + (q); \
|
||||
X##_f -= T##_f; \
|
||||
R##_f += q; \
|
||||
R##_f += (q); \
|
||||
} \
|
||||
_FP_FRAC_SLL_1 (X, 1); \
|
||||
q >>= 1; \
|
||||
(q) >>= 1; \
|
||||
} \
|
||||
if (X##_f) \
|
||||
{ \
|
||||
@ -336,17 +352,13 @@
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/*
|
||||
* Assembly/disassembly for converting to/from integral types.
|
||||
* No shifting or overflow handled here.
|
||||
*/
|
||||
/* Assembly/disassembly for converting to/from integral types.
|
||||
No shifting or overflow handled here. */
|
||||
|
||||
#define _FP_FRAC_ASSEMBLE_1(r, X, rsize) (r = X##_f)
|
||||
#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize) (X##_f = r)
|
||||
#define _FP_FRAC_ASSEMBLE_1(r, X, rsize) ((r) = X##_f)
|
||||
#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize) (X##_f = (r))
|
||||
|
||||
|
||||
/*
|
||||
* Convert FP values between word sizes
|
||||
*/
|
||||
/* Convert FP values between word sizes. */
|
||||
|
||||
#define _FP_FRAC_COPY_1_1(D, S) (D##_f = S##_f)
|
||||
|
@ -122,16 +122,16 @@
|
||||
do \
|
||||
{ \
|
||||
if (X##_f1) \
|
||||
__FP_CLZ (R, X##_f1); \
|
||||
__FP_CLZ ((R), X##_f1); \
|
||||
else \
|
||||
{ \
|
||||
__FP_CLZ (R, X##_f0); \
|
||||
R += _FP_W_TYPE_SIZE; \
|
||||
__FP_CLZ ((R), X##_f0); \
|
||||
(R) += _FP_W_TYPE_SIZE; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Predicates */
|
||||
/* Predicates. */
|
||||
#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)
|
||||
@ -148,9 +148,7 @@
|
||||
#define _FP_MINFRAC_2 0, 1
|
||||
#define _FP_MAXFRAC_2 (~(_FP_WS_TYPE) 0), (~(_FP_WS_TYPE) 0)
|
||||
|
||||
/*
|
||||
* Internals
|
||||
*/
|
||||
/* Internals. */
|
||||
|
||||
#define __FP_FRAC_SET_2(X, I1, I0) (X##_f0 = I0, X##_f1 = I1)
|
||||
|
||||
@ -158,11 +156,11 @@
|
||||
do \
|
||||
{ \
|
||||
if (xh) \
|
||||
__FP_CLZ (R, xh); \
|
||||
__FP_CLZ ((R), xh); \
|
||||
else \
|
||||
{ \
|
||||
__FP_CLZ (R, xl); \
|
||||
R += _FP_W_TYPE_SIZE; \
|
||||
__FP_CLZ ((R), xl); \
|
||||
(R) += _FP_W_TYPE_SIZE; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
@ -182,12 +180,12 @@
|
||||
(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); \
|
||||
} \
|
||||
# define __FP_FRAC_DEC_2(xh, xl, yh, yl) \
|
||||
do \
|
||||
{ \
|
||||
UWtype __FP_FRAC_DEC_2_t = xl; \
|
||||
xh -= yh + ((xl -= yl) > __FP_FRAC_DEC_2_t); \
|
||||
} \
|
||||
while (0)
|
||||
# endif
|
||||
|
||||
@ -205,91 +203,95 @@
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Unpack the raw bits of a native fp value. Do not classify or
|
||||
* normalize the data.
|
||||
*/
|
||||
/* Unpack the raw bits of a native fp value. Do not classify or
|
||||
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; \
|
||||
} \
|
||||
#define _FP_UNPACK_RAW_2(fs, X, val) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_##fs _FP_UNPACK_RAW_2_flo; \
|
||||
_FP_UNPACK_RAW_2_flo.flt = (val); \
|
||||
\
|
||||
X##_f0 = _FP_UNPACK_RAW_2_flo.bits.frac0; \
|
||||
X##_f1 = _FP_UNPACK_RAW_2_flo.bits.frac1; \
|
||||
X##_e = _FP_UNPACK_RAW_2_flo.bits.exp; \
|
||||
X##_s = _FP_UNPACK_RAW_2_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; \
|
||||
} \
|
||||
#define _FP_UNPACK_RAW_2_P(fs, X, val) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_##fs *_FP_UNPACK_RAW_2_P_flo \
|
||||
= (union _FP_UNION_##fs *) (val); \
|
||||
\
|
||||
X##_f0 = _FP_UNPACK_RAW_2_P_flo->bits.frac0; \
|
||||
X##_f1 = _FP_UNPACK_RAW_2_P_flo->bits.frac1; \
|
||||
X##_e = _FP_UNPACK_RAW_2_P_flo->bits.exp; \
|
||||
X##_s = _FP_UNPACK_RAW_2_P_flo->bits.sign; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Repack the raw bits of a native fp value.
|
||||
*/
|
||||
/* Repack the raw bits of a native fp value. */
|
||||
|
||||
#define _FP_PACK_RAW_2(fs, val, X) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_##fs _flo; \
|
||||
union _FP_UNION_##fs _FP_PACK_RAW_2_flo; \
|
||||
\
|
||||
_flo.bits.frac0 = X##_f0; \
|
||||
_flo.bits.frac1 = X##_f1; \
|
||||
_flo.bits.exp = X##_e; \
|
||||
_flo.bits.sign = X##_s; \
|
||||
_FP_PACK_RAW_2_flo.bits.frac0 = X##_f0; \
|
||||
_FP_PACK_RAW_2_flo.bits.frac1 = X##_f1; \
|
||||
_FP_PACK_RAW_2_flo.bits.exp = X##_e; \
|
||||
_FP_PACK_RAW_2_flo.bits.sign = X##_s; \
|
||||
\
|
||||
(val) = _flo.flt; \
|
||||
(val) = _FP_PACK_RAW_2_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; \
|
||||
} \
|
||||
#define _FP_PACK_RAW_2_P(fs, val, X) \
|
||||
do \
|
||||
{ \
|
||||
union _FP_UNION_##fs *_FP_PACK_RAW_2_P_flo \
|
||||
= (union _FP_UNION_##fs *) (val); \
|
||||
\
|
||||
_FP_PACK_RAW_2_P_flo->bits.frac0 = X##_f0; \
|
||||
_FP_PACK_RAW_2_P_flo->bits.frac1 = X##_f1; \
|
||||
_FP_PACK_RAW_2_P_flo->bits.exp = X##_e; \
|
||||
_FP_PACK_RAW_2_P_flo->bits.sign = X##_s; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Multiplication algorithms:
|
||||
*/
|
||||
/* Multiplication algorithms: */
|
||||
|
||||
/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
|
||||
|
||||
#define _FP_MUL_MEAT_DW_2_wide(wfracbits, R, X, Y, doit) \
|
||||
do \
|
||||
{ \
|
||||
_FP_FRAC_DECL_2 (_b); \
|
||||
_FP_FRAC_DECL_2 (_c); \
|
||||
_FP_FRAC_DECL_2 (_FP_MUL_MEAT_DW_2_wide_b); \
|
||||
_FP_FRAC_DECL_2 (_FP_MUL_MEAT_DW_2_wide_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 (R, 1), _FP_FRAC_WORD_4 (R, 0), \
|
||||
X##_f0, Y##_f0); \
|
||||
doit (_FP_MUL_MEAT_DW_2_wide_b_f1, _FP_MUL_MEAT_DW_2_wide_b_f0, \
|
||||
X##_f0, Y##_f1); \
|
||||
doit (_FP_MUL_MEAT_DW_2_wide_c_f1, _FP_MUL_MEAT_DW_2_wide_c_f0, \
|
||||
X##_f1, Y##_f0); \
|
||||
doit (_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 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, 1), 0, \
|
||||
_FP_MUL_MEAT_DW_2_wide_b_f1, \
|
||||
_FP_MUL_MEAT_DW_2_wide_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, 1), 0, \
|
||||
_FP_MUL_MEAT_DW_2_wide_c_f1, \
|
||||
_FP_MUL_MEAT_DW_2_wide_c_f0, \
|
||||
_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), \
|
||||
_FP_FRAC_WORD_4 (R, 1)); \
|
||||
} \
|
||||
@ -298,16 +300,18 @@
|
||||
#define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit) \
|
||||
do \
|
||||
{ \
|
||||
_FP_FRAC_DECL_4 (_z); \
|
||||
_FP_FRAC_DECL_4 (_FP_MUL_MEAT_2_wide_z); \
|
||||
\
|
||||
_FP_MUL_MEAT_DW_2_wide (wfracbits, _z, X, Y, doit); \
|
||||
_FP_MUL_MEAT_DW_2_wide ((wfracbits), _FP_MUL_MEAT_2_wide_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); \
|
||||
_FP_FRAC_SRS_4 (_FP_MUL_MEAT_2_wide_z, (wfracbits)-1, \
|
||||
2*(wfracbits)); \
|
||||
R##_f0 = _FP_FRAC_WORD_4 (_FP_MUL_MEAT_2_wide_z, 0); \
|
||||
R##_f1 = _FP_FRAC_WORD_4 (_FP_MUL_MEAT_2_wide_z, 1); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -318,35 +322,51 @@
|
||||
#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; \
|
||||
_FP_FRAC_DECL_2 (_FP_MUL_MEAT_DW_2_wide_3mul_b); \
|
||||
_FP_FRAC_DECL_2 (_FP_MUL_MEAT_DW_2_wide_3mul_c); \
|
||||
_FP_W_TYPE _FP_MUL_MEAT_DW_2_wide_3mul_d; \
|
||||
int _FP_MUL_MEAT_DW_2_wide_3mul_c1; \
|
||||
int _FP_MUL_MEAT_DW_2_wide_3mul_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 (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); \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_b_f0 = X##_f0 + X##_f1; \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_c1 \
|
||||
= _FP_MUL_MEAT_DW_2_wide_3mul_b_f0 < X##_f0; \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_b_f1 = Y##_f0 + Y##_f1; \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_c2 \
|
||||
= _FP_MUL_MEAT_DW_2_wide_3mul_b_f1 < Y##_f0; \
|
||||
doit (_FP_MUL_MEAT_DW_2_wide_3mul_d, _FP_FRAC_WORD_4 (R, 0), \
|
||||
X##_f0, Y##_f0); \
|
||||
doit (_FP_FRAC_WORD_4 (R, 2), _FP_FRAC_WORD_4 (R, 1), \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_b_f0, \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_b_f1); \
|
||||
doit (_FP_MUL_MEAT_DW_2_wide_3mul_c_f1, \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_c_f0, X##_f1, Y##_f1); \
|
||||
\
|
||||
_b_f0 &= -_c2; \
|
||||
_b_f1 &= -_c1; \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_b_f0 \
|
||||
&= -_FP_MUL_MEAT_DW_2_wide_3mul_c2; \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_b_f1 \
|
||||
&= -_FP_MUL_MEAT_DW_2_wide_3mul_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, \
|
||||
_FP_FRAC_WORD_4 (R, 1), \
|
||||
(_FP_MUL_MEAT_DW_2_wide_3mul_c1 \
|
||||
& _FP_MUL_MEAT_DW_2_wide_3mul_c2), 0, \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_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_MUL_MEAT_DW_2_wide_3mul_b_f0); \
|
||||
__FP_FRAC_ADDI_2 (_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), \
|
||||
_b_f1); \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_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)); \
|
||||
0, _FP_MUL_MEAT_DW_2_wide_3mul_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_WORD_4 (R, 1), 0, \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_c_f1, \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_c_f0); \
|
||||
__FP_FRAC_ADD_2 (_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2), \
|
||||
_c_f1, _c_f0, \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_c_f1, \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul_c_f0, \
|
||||
_FP_FRAC_WORD_4 (R, 3), _FP_FRAC_WORD_4 (R, 2)); \
|
||||
} \
|
||||
while (0)
|
||||
@ -354,45 +374,51 @@
|
||||
#define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit) \
|
||||
do \
|
||||
{ \
|
||||
_FP_FRAC_DECL_4 (_z); \
|
||||
_FP_FRAC_DECL_4 (_FP_MUL_MEAT_2_wide_3mul_z); \
|
||||
\
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul (wfracbits, _z, X, Y, doit); \
|
||||
_FP_MUL_MEAT_DW_2_wide_3mul ((wfracbits), \
|
||||
_FP_MUL_MEAT_2_wide_3mul_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); \
|
||||
_FP_FRAC_SRS_4 (_FP_MUL_MEAT_2_wide_3mul_z, \
|
||||
(wfracbits)-1, 2*(wfracbits)); \
|
||||
R##_f0 = _FP_FRAC_WORD_4 (_FP_MUL_MEAT_2_wide_3mul_z, 0); \
|
||||
R##_f1 = _FP_FRAC_WORD_4 (_FP_MUL_MEAT_2_wide_3mul_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; \
|
||||
_FP_W_TYPE _FP_MUL_MEAT_DW_2_gmp_x[2]; \
|
||||
_FP_W_TYPE _FP_MUL_MEAT_DW_2_gmp_y[2]; \
|
||||
_FP_MUL_MEAT_DW_2_gmp_x[0] = X##_f0; \
|
||||
_FP_MUL_MEAT_DW_2_gmp_x[1] = X##_f1; \
|
||||
_FP_MUL_MEAT_DW_2_gmp_y[0] = Y##_f0; \
|
||||
_FP_MUL_MEAT_DW_2_gmp_y[1] = Y##_f1; \
|
||||
\
|
||||
mpn_mul_n (R##_f, _x, _y, 2); \
|
||||
mpn_mul_n (R##_f, _FP_MUL_MEAT_DW_2_gmp_x, \
|
||||
_FP_MUL_MEAT_DW_2_gmp_y, 2); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define _FP_MUL_MEAT_2_gmp(wfracbits, R, X, Y) \
|
||||
do \
|
||||
{ \
|
||||
_FP_FRAC_DECL_4 (_z); \
|
||||
_FP_FRAC_DECL_4 (_FP_MUL_MEAT_2_gmp_z); \
|
||||
\
|
||||
_FP_MUL_MEAT_DW_2_gmp (wfracbits, _z, X, Y); \
|
||||
_FP_MUL_MEAT_DW_2_gmp ((wfracbits), _FP_MUL_MEAT_2_gmp_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]; \
|
||||
_FP_FRAC_SRS_4 (_FP_MUL_MEAT_2_gmp_z, (wfracbits)-1, \
|
||||
2*(wfracbits)); \
|
||||
R##_f0 = _FP_MUL_MEAT_2_gmp_z_f[0]; \
|
||||
R##_f1 = _FP_MUL_MEAT_2_gmp_z_f[1]; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -428,7 +454,7 @@
|
||||
_p240, _q240, _r240, _s240; \
|
||||
UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \
|
||||
\
|
||||
if (wfracbits < 106 || wfracbits > 120) \
|
||||
if ((wfracbits) < 106 || (wfracbits) > 120) \
|
||||
abort (); \
|
||||
\
|
||||
setfetz; \
|
||||
@ -500,116 +526,136 @@
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/*
|
||||
* Division algorithms:
|
||||
*/
|
||||
/* 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; \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_2_udiv_n_f2; \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_2_udiv_n_f1; \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_2_udiv_n_f0; \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_2_udiv_r_f1; \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_2_udiv_r_f0; \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_2_udiv_m_f1; \
|
||||
_FP_W_TYPE _FP_DIV_MEAT_2_udiv_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); \
|
||||
_FP_DIV_MEAT_2_udiv_n_f2 = X##_f1 >> 1; \
|
||||
_FP_DIV_MEAT_2_udiv_n_f1 \
|
||||
= X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \
|
||||
_FP_DIV_MEAT_2_udiv_n_f0 \
|
||||
= X##_f0 << (_FP_W_TYPE_SIZE - 1); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
R##_e--; \
|
||||
_n_f2 = X##_f1; \
|
||||
_n_f1 = X##_f0; \
|
||||
_n_f0 = 0; \
|
||||
_FP_DIV_MEAT_2_udiv_n_f2 = X##_f1; \
|
||||
_FP_DIV_MEAT_2_udiv_n_f1 = X##_f0; \
|
||||
_FP_DIV_MEAT_2_udiv_n_f0 = 0; \
|
||||
} \
|
||||
\
|
||||
/* Normalize, i.e. make the most significant bit of the \
|
||||
denominator set. */ \
|
||||
denominator set. */ \
|
||||
_FP_FRAC_SLL_2 (Y, _FP_WFRACXBITS_##fs); \
|
||||
\
|
||||
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)) \
|
||||
udiv_qrnnd (R##_f1, _FP_DIV_MEAT_2_udiv_r_f1, \
|
||||
_FP_DIV_MEAT_2_udiv_n_f2, _FP_DIV_MEAT_2_udiv_n_f1, \
|
||||
Y##_f1); \
|
||||
umul_ppmm (_FP_DIV_MEAT_2_udiv_m_f1, _FP_DIV_MEAT_2_udiv_m_f0, \
|
||||
R##_f1, Y##_f0); \
|
||||
_FP_DIV_MEAT_2_udiv_r_f0 = _FP_DIV_MEAT_2_udiv_n_f0; \
|
||||
if (_FP_FRAC_GT_2 (_FP_DIV_MEAT_2_udiv_m, _FP_DIV_MEAT_2_udiv_r)) \
|
||||
{ \
|
||||
R##_f1--; \
|
||||
_FP_FRAC_ADD_2 (_r, Y, _r); \
|
||||
if (_FP_FRAC_GE_2 (_r, Y) && _FP_FRAC_GT_2 (_m, _r)) \
|
||||
_FP_FRAC_ADD_2 (_FP_DIV_MEAT_2_udiv_r, Y, \
|
||||
_FP_DIV_MEAT_2_udiv_r); \
|
||||
if (_FP_FRAC_GE_2 (_FP_DIV_MEAT_2_udiv_r, Y) \
|
||||
&& _FP_FRAC_GT_2 (_FP_DIV_MEAT_2_udiv_m, \
|
||||
_FP_DIV_MEAT_2_udiv_r)) \
|
||||
{ \
|
||||
R##_f1--; \
|
||||
_FP_FRAC_ADD_2 (_r, Y, _r); \
|
||||
_FP_FRAC_ADD_2 (_FP_DIV_MEAT_2_udiv_r, Y, \
|
||||
_FP_DIV_MEAT_2_udiv_r); \
|
||||
} \
|
||||
} \
|
||||
_FP_FRAC_DEC_2 (_r, _m); \
|
||||
_FP_FRAC_DEC_2 (_FP_DIV_MEAT_2_udiv_r, _FP_DIV_MEAT_2_udiv_m); \
|
||||
\
|
||||
if (_r_f1 == Y##_f1) \
|
||||
if (_FP_DIV_MEAT_2_udiv_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 */ \
|
||||
(_FP_DIV_MEAT_2_udiv_r/Y##_f1 would not fit into UWtype). \
|
||||
As _FP_DIV_MEAT_2_udiv_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)) \
|
||||
udiv_qrnnd (R##_f0, _FP_DIV_MEAT_2_udiv_r_f1, \
|
||||
_FP_DIV_MEAT_2_udiv_r_f1, \
|
||||
_FP_DIV_MEAT_2_udiv_r_f0, Y##_f1); \
|
||||
umul_ppmm (_FP_DIV_MEAT_2_udiv_m_f1, \
|
||||
_FP_DIV_MEAT_2_udiv_m_f0, R##_f0, Y##_f0); \
|
||||
_FP_DIV_MEAT_2_udiv_r_f0 = 0; \
|
||||
if (_FP_FRAC_GT_2 (_FP_DIV_MEAT_2_udiv_m, \
|
||||
_FP_DIV_MEAT_2_udiv_r)) \
|
||||
{ \
|
||||
R##_f0--; \
|
||||
_FP_FRAC_ADD_2 (_r, Y, _r); \
|
||||
if (_FP_FRAC_GE_2 (_r, Y) && _FP_FRAC_GT_2 (_m, _r)) \
|
||||
_FP_FRAC_ADD_2 (_FP_DIV_MEAT_2_udiv_r, Y, \
|
||||
_FP_DIV_MEAT_2_udiv_r); \
|
||||
if (_FP_FRAC_GE_2 (_FP_DIV_MEAT_2_udiv_r, Y) \
|
||||
&& _FP_FRAC_GT_2 (_FP_DIV_MEAT_2_udiv_m, \
|
||||
_FP_DIV_MEAT_2_udiv_r)) \
|
||||
{ \
|
||||
R##_f0--; \
|
||||
_FP_FRAC_ADD_2 (_r, Y, _r); \
|
||||
_FP_FRAC_ADD_2 (_FP_DIV_MEAT_2_udiv_r, Y, \
|
||||
_FP_DIV_MEAT_2_udiv_r); \
|
||||
} \
|
||||
} \
|
||||
if (!_FP_FRAC_EQ_2 (_r, _m)) \
|
||||
if (!_FP_FRAC_EQ_2 (_FP_DIV_MEAT_2_udiv_r, \
|
||||
_FP_DIV_MEAT_2_udiv_m)) \
|
||||
R##_f0 |= _FP_WORK_STICKY; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Square root algorithms:
|
||||
* We have just one right now, maybe Newton approximation
|
||||
* should be added for those machines where division is fast.
|
||||
*/
|
||||
/* Square root algorithms:
|
||||
We have just one right now, maybe Newton approximation
|
||||
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; \
|
||||
T##_f1 = S##_f1 + (q); \
|
||||
if (T##_f1 <= X##_f1) \
|
||||
{ \
|
||||
S##_f1 = T##_f1 + q; \
|
||||
S##_f1 = T##_f1 + (q); \
|
||||
X##_f1 -= T##_f1; \
|
||||
R##_f1 += q; \
|
||||
R##_f1 += (q); \
|
||||
} \
|
||||
_FP_FRAC_SLL_2 (X, 1); \
|
||||
q >>= 1; \
|
||||
(q) >>= 1; \
|
||||
} \
|
||||
q = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \
|
||||
while (q != _FP_WORK_ROUND) \
|
||||
(q) = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \
|
||||
while ((q) != _FP_WORK_ROUND) \
|
||||
{ \
|
||||
T##_f0 = S##_f0 + q; \
|
||||
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##_f0 = T##_f0 + (q); \
|
||||
S##_f1 += (T##_f0 > S##_f0); \
|
||||
_FP_FRAC_DEC_2 (X, T); \
|
||||
R##_f0 += q; \
|
||||
R##_f0 += (q); \
|
||||
} \
|
||||
_FP_FRAC_SLL_2 (X, 1); \
|
||||
q >>= 1; \
|
||||
(q) >>= 1; \
|
||||
} \
|
||||
if (X##_f0 | X##_f1) \
|
||||
{ \
|
||||
@ -622,31 +668,29 @@
|
||||
while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Assembly/disassembly for converting to/from integral types.
|
||||
* No shifting or overflow handled here.
|
||||
*/
|
||||
/* Assembly/disassembly for converting to/from integral types.
|
||||
No shifting or overflow handled here. */
|
||||
|
||||
#define _FP_FRAC_ASSEMBLE_2(r, X, rsize) \
|
||||
(void) ((rsize <= _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; \
|
||||
(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); \
|
||||
} \
|
||||
#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)
|
||||
|
||||
/*
|
||||
* Convert FP values between word sizes
|
||||
*/
|
||||
/* Convert FP values between word sizes. */
|
||||
|
||||
#define _FP_FRAC_COPY_1_2(D, S) (D##_f = S##_f0)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,87 +30,116 @@
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* We need just a few things from here for op-4, if we ever need some
|
||||
other macros, they can be added. */
|
||||
other macros, they can be added. */
|
||||
#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_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; \
|
||||
} \
|
||||
#define _FP_FRAC_SLL_8(X, N) \
|
||||
do \
|
||||
{ \
|
||||
_FP_I_TYPE _FP_FRAC_SLL_8_up, _FP_FRAC_SLL_8_down; \
|
||||
_FP_I_TYPE _FP_FRAC_SLL_8_skip, _FP_FRAC_SLL_8_i; \
|
||||
_FP_FRAC_SLL_8_skip = (N) / _FP_W_TYPE_SIZE; \
|
||||
_FP_FRAC_SLL_8_up = (N) % _FP_W_TYPE_SIZE; \
|
||||
_FP_FRAC_SLL_8_down = _FP_W_TYPE_SIZE - _FP_FRAC_SLL_8_up; \
|
||||
if (!_FP_FRAC_SLL_8_up) \
|
||||
for (_FP_FRAC_SLL_8_i = 7; \
|
||||
_FP_FRAC_SLL_8_i >= _FP_FRAC_SLL_8_skip; \
|
||||
--_FP_FRAC_SLL_8_i) \
|
||||
X##_f[_FP_FRAC_SLL_8_i] \
|
||||
= X##_f[_FP_FRAC_SLL_8_i-_FP_FRAC_SLL_8_skip]; \
|
||||
else \
|
||||
{ \
|
||||
for (_FP_FRAC_SLL_8_i = 7; \
|
||||
_FP_FRAC_SLL_8_i > _FP_FRAC_SLL_8_skip; \
|
||||
--_FP_FRAC_SLL_8_i) \
|
||||
X##_f[_FP_FRAC_SLL_8_i] \
|
||||
= ((X##_f[_FP_FRAC_SLL_8_i-_FP_FRAC_SLL_8_skip] \
|
||||
<< _FP_FRAC_SLL_8_up) \
|
||||
| (X##_f[_FP_FRAC_SLL_8_i-_FP_FRAC_SLL_8_skip-1] \
|
||||
>> _FP_FRAC_SLL_8_down)); \
|
||||
X##_f[_FP_FRAC_SLL_8_i--] = X##_f[0] << _FP_FRAC_SLL_8_up; \
|
||||
} \
|
||||
for (; _FP_FRAC_SLL_8_i >= 0; --_FP_FRAC_SLL_8_i) \
|
||||
X##_f[_FP_FRAC_SLL_8_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; \
|
||||
} \
|
||||
#define _FP_FRAC_SRL_8(X, N) \
|
||||
do \
|
||||
{ \
|
||||
_FP_I_TYPE _FP_FRAC_SRL_8_up, _FP_FRAC_SRL_8_down; \
|
||||
_FP_I_TYPE _FP_FRAC_SRL_8_skip, _FP_FRAC_SRL_8_i; \
|
||||
_FP_FRAC_SRL_8_skip = (N) / _FP_W_TYPE_SIZE; \
|
||||
_FP_FRAC_SRL_8_down = (N) % _FP_W_TYPE_SIZE; \
|
||||
_FP_FRAC_SRL_8_up = _FP_W_TYPE_SIZE - _FP_FRAC_SRL_8_down; \
|
||||
if (!_FP_FRAC_SRL_8_down) \
|
||||
for (_FP_FRAC_SRL_8_i = 0; \
|
||||
_FP_FRAC_SRL_8_i <= 7-_FP_FRAC_SRL_8_skip; \
|
||||
++_FP_FRAC_SRL_8_i) \
|
||||
X##_f[_FP_FRAC_SRL_8_i] \
|
||||
= X##_f[_FP_FRAC_SRL_8_i+_FP_FRAC_SRL_8_skip]; \
|
||||
else \
|
||||
{ \
|
||||
for (_FP_FRAC_SRL_8_i = 0; \
|
||||
_FP_FRAC_SRL_8_i < 7-_FP_FRAC_SRL_8_skip; \
|
||||
++_FP_FRAC_SRL_8_i) \
|
||||
X##_f[_FP_FRAC_SRL_8_i] \
|
||||
= ((X##_f[_FP_FRAC_SRL_8_i+_FP_FRAC_SRL_8_skip] \
|
||||
>> _FP_FRAC_SRL_8_down) \
|
||||
| (X##_f[_FP_FRAC_SRL_8_i+_FP_FRAC_SRL_8_skip+1] \
|
||||
<< _FP_FRAC_SRL_8_up)); \
|
||||
X##_f[_FP_FRAC_SRL_8_i++] = X##_f[7] >> _FP_FRAC_SRL_8_down; \
|
||||
} \
|
||||
for (; _FP_FRAC_SRL_8_i < 8; ++_FP_FRAC_SRL_8_i) \
|
||||
X##_f[_FP_FRAC_SRL_8_i] = 0; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
/* Right shift with sticky-lsb.
|
||||
* What this actually means is that we do a standard right-shift,
|
||||
* but that if any of the bits that fall off the right hand side
|
||||
* were one then we always set the LSbit.
|
||||
*/
|
||||
What this actually means is that we do a standard right-shift,
|
||||
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]; \
|
||||
_FP_I_TYPE _FP_FRAC_SRS_8_up, _FP_FRAC_SRS_8_down; \
|
||||
_FP_I_TYPE _FP_FRAC_SRS_8_skip, _FP_FRAC_SRS_8_i; \
|
||||
_FP_W_TYPE _FP_FRAC_SRS_8_s; \
|
||||
_FP_FRAC_SRS_8_skip = (N) / _FP_W_TYPE_SIZE; \
|
||||
_FP_FRAC_SRS_8_down = (N) % _FP_W_TYPE_SIZE; \
|
||||
_FP_FRAC_SRS_8_up = _FP_W_TYPE_SIZE - _FP_FRAC_SRS_8_down; \
|
||||
for (_FP_FRAC_SRS_8_s = _FP_FRAC_SRS_8_i = 0; \
|
||||
_FP_FRAC_SRS_8_i < _FP_FRAC_SRS_8_skip; \
|
||||
++_FP_FRAC_SRS_8_i) \
|
||||
_FP_FRAC_SRS_8_s |= X##_f[_FP_FRAC_SRS_8_i]; \
|
||||
if (!_FP_FRAC_SRS_8_down) \
|
||||
for (_FP_FRAC_SRS_8_i = 0; \
|
||||
_FP_FRAC_SRS_8_i <= 7-_FP_FRAC_SRS_8_skip; \
|
||||
++_FP_FRAC_SRS_8_i) \
|
||||
X##_f[_FP_FRAC_SRS_8_i] \
|
||||
= X##_f[_FP_FRAC_SRS_8_i+_FP_FRAC_SRS_8_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; \
|
||||
_FP_FRAC_SRS_8_s \
|
||||
|= X##_f[_FP_FRAC_SRS_8_i] << _FP_FRAC_SRS_8_up; \
|
||||
for (_FP_FRAC_SRS_8_i = 0; \
|
||||
_FP_FRAC_SRS_8_i < 7-_FP_FRAC_SRS_8_skip; \
|
||||
++_FP_FRAC_SRS_8_i) \
|
||||
X##_f[_FP_FRAC_SRS_8_i] \
|
||||
= ((X##_f[_FP_FRAC_SRS_8_i+_FP_FRAC_SRS_8_skip] \
|
||||
>> _FP_FRAC_SRS_8_down) \
|
||||
| (X##_f[_FP_FRAC_SRS_8_i+_FP_FRAC_SRS_8_skip+1] \
|
||||
<< _FP_FRAC_SRS_8_up)); \
|
||||
X##_f[_FP_FRAC_SRS_8_i++] = X##_f[7] >> _FP_FRAC_SRS_8_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); \
|
||||
for (; _FP_FRAC_SRS_8_i < 8; ++_FP_FRAC_SRS_8_i) \
|
||||
X##_f[_FP_FRAC_SRS_8_i] = 0; \
|
||||
/* Don't fix the LSB until the very end when we're sure f[0] is \
|
||||
stable. */ \
|
||||
X##_f[0] |= (_FP_FRAC_SRS_8_s != 0); \
|
||||
} \
|
||||
while (0)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -95,21 +95,21 @@ union _FP_UNION_Q
|
||||
|
||||
|
||||
# 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_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); \
|
||||
_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_RAW_4 (Q, X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (Q, 4, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -117,7 +117,7 @@ union _FP_UNION_Q
|
||||
# define FP_UNPACK_QP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_4_P (Q, X, val); \
|
||||
_FP_UNPACK_RAW_4_P (Q, X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (Q, 4, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -125,7 +125,7 @@ union _FP_UNION_Q
|
||||
# define FP_UNPACK_SEMIRAW_Q(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_4 (Q, X, val); \
|
||||
_FP_UNPACK_RAW_4 (Q, X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (Q, 4, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -133,7 +133,7 @@ union _FP_UNION_Q
|
||||
# define FP_UNPACK_SEMIRAW_QP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_4_P (Q, X, val); \
|
||||
_FP_UNPACK_RAW_4_P (Q, X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (Q, 4, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -142,7 +142,7 @@ union _FP_UNION_Q
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (Q, 4, X); \
|
||||
_FP_PACK_RAW_4 (Q, val, X); \
|
||||
_FP_PACK_RAW_4 (Q, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -151,7 +151,7 @@ union _FP_UNION_Q
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (Q, 4, X); \
|
||||
if (!FP_INHIBIT_RESULTS) \
|
||||
_FP_PACK_RAW_4_P (Q, val, X); \
|
||||
_FP_PACK_RAW_4_P (Q, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -159,7 +159,7 @@ union _FP_UNION_Q
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (Q, 4, X); \
|
||||
_FP_PACK_RAW_4 (Q, val, X); \
|
||||
_FP_PACK_RAW_4 (Q, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -168,7 +168,7 @@ union _FP_UNION_Q
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (Q, 4, X); \
|
||||
if (!FP_INHIBIT_RESULTS) \
|
||||
_FP_PACK_RAW_4_P (Q, val, X); \
|
||||
_FP_PACK_RAW_4_P (Q, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -179,15 +179,15 @@ union _FP_UNION_Q
|
||||
# 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_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_CMP_Q(r, X, Y, un, ex) _FP_CMP (Q, 4, (r), X, Y, (un), (ex))
|
||||
# define FP_CMP_EQ_Q(r, X, Y, ex) _FP_CMP_EQ (Q, 4, (r), X, Y, (ex))
|
||||
# define FP_CMP_UNORD_Q(r, X, Y, ex) _FP_CMP_UNORD (Q, 4, (r), X, Y, (ex))
|
||||
|
||||
# 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_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)
|
||||
@ -219,21 +219,21 @@ union _FP_UNION_Q
|
||||
};
|
||||
|
||||
# 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_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); \
|
||||
_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_RAW_2 (Q, X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (Q, 2, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -241,7 +241,7 @@ union _FP_UNION_Q
|
||||
# define FP_UNPACK_QP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_2_P (Q, X, val); \
|
||||
_FP_UNPACK_RAW_2_P (Q, X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (Q, 2, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -249,7 +249,7 @@ union _FP_UNION_Q
|
||||
# define FP_UNPACK_SEMIRAW_Q(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_2 (Q, X, val); \
|
||||
_FP_UNPACK_RAW_2 (Q, X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (Q, 2, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -257,7 +257,7 @@ union _FP_UNION_Q
|
||||
# define FP_UNPACK_SEMIRAW_QP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_2_P (Q, X, val); \
|
||||
_FP_UNPACK_RAW_2_P (Q, X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (Q, 2, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -266,7 +266,7 @@ union _FP_UNION_Q
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (Q, 2, X); \
|
||||
_FP_PACK_RAW_2 (Q, val, X); \
|
||||
_FP_PACK_RAW_2 (Q, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -275,7 +275,7 @@ union _FP_UNION_Q
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (Q, 2, X); \
|
||||
if (!FP_INHIBIT_RESULTS) \
|
||||
_FP_PACK_RAW_2_P (Q, val, X); \
|
||||
_FP_PACK_RAW_2_P (Q, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -283,7 +283,7 @@ union _FP_UNION_Q
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (Q, 2, X); \
|
||||
_FP_PACK_RAW_2 (Q, val, X); \
|
||||
_FP_PACK_RAW_2 (Q, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -292,7 +292,7 @@ union _FP_UNION_Q
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (Q, 2, X); \
|
||||
if (!FP_INHIBIT_RESULTS) \
|
||||
_FP_PACK_RAW_2_P (Q, val, X); \
|
||||
_FP_PACK_RAW_2_P (Q, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -303,15 +303,15 @@ union _FP_UNION_Q
|
||||
# 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_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_CMP_Q(r, X, Y, un, ex) _FP_CMP (Q, 2, (r), X, Y, (un), (ex))
|
||||
# define FP_CMP_EQ_Q(r, X, Y, ex) _FP_CMP_EQ (Q, 2, (r), X, Y, (ex))
|
||||
# define FP_CMP_UNORD_Q(r, X, Y, ex) _FP_CMP_UNORD (Q, 2, (r), X, Y, (ex))
|
||||
|
||||
# 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_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)
|
||||
|
@ -83,21 +83,21 @@ union _FP_UNION_S
|
||||
};
|
||||
|
||||
#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_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); \
|
||||
_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_RAW_1 (S, X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (S, 1, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -105,7 +105,7 @@ union _FP_UNION_S
|
||||
#define FP_UNPACK_SP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_1_P (S, X, val); \
|
||||
_FP_UNPACK_RAW_1_P (S, X, (val)); \
|
||||
_FP_UNPACK_CANONICAL (S, 1, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -113,7 +113,7 @@ union _FP_UNION_S
|
||||
#define FP_UNPACK_SEMIRAW_S(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_1 (S, X, val); \
|
||||
_FP_UNPACK_RAW_1 (S, X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (S, 1, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -121,7 +121,7 @@ union _FP_UNION_S
|
||||
#define FP_UNPACK_SEMIRAW_SP(X, val) \
|
||||
do \
|
||||
{ \
|
||||
_FP_UNPACK_RAW_1_P (S, X, val); \
|
||||
_FP_UNPACK_RAW_1_P (S, X, (val)); \
|
||||
_FP_UNPACK_SEMIRAW (S, 1, X); \
|
||||
} \
|
||||
while (0)
|
||||
@ -130,7 +130,7 @@ union _FP_UNION_S
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (S, 1, X); \
|
||||
_FP_PACK_RAW_1 (S, val, X); \
|
||||
_FP_PACK_RAW_1 (S, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -139,7 +139,7 @@ union _FP_UNION_S
|
||||
{ \
|
||||
_FP_PACK_CANONICAL (S, 1, X); \
|
||||
if (!FP_INHIBIT_RESULTS) \
|
||||
_FP_PACK_RAW_1_P (S, val, X); \
|
||||
_FP_PACK_RAW_1_P (S, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -147,7 +147,7 @@ union _FP_UNION_S
|
||||
do \
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (S, 1, X); \
|
||||
_FP_PACK_RAW_1 (S, val, X); \
|
||||
_FP_PACK_RAW_1 (S, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -156,7 +156,7 @@ union _FP_UNION_S
|
||||
{ \
|
||||
_FP_PACK_SEMIRAW (S, 1, X); \
|
||||
if (!FP_INHIBIT_RESULTS) \
|
||||
_FP_PACK_RAW_1_P (S, val, X); \
|
||||
_FP_PACK_RAW_1_P (S, (val), X); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -167,7 +167,7 @@ union _FP_UNION_S
|
||||
#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_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)
|
||||
@ -175,12 +175,12 @@ union _FP_UNION_S
|
||||
# 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_CMP_S(r, X, Y, un, ex) _FP_CMP (S, 1, (r), X, Y, (un), (ex))
|
||||
#define FP_CMP_EQ_S(r, X, Y, ex) _FP_CMP_EQ (S, 1, (r), X, Y, (ex))
|
||||
#define FP_CMP_UNORD_S(r, X, Y, ex) _FP_CMP_UNORD (S, 1, (r), X, Y, (ex))
|
||||
|
||||
#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_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)
|
||||
|
@ -38,7 +38,7 @@
|
||||
# include "sfp-machine.h"
|
||||
#endif
|
||||
|
||||
/* Allow sfp-machine to have its own byte order definitions. */
|
||||
/* Allow sfp-machine to have its own byte order definitions. */
|
||||
#ifndef __BYTE_ORDER
|
||||
# ifdef _LIBC
|
||||
# include <endian.h>
|
||||
@ -63,7 +63,7 @@
|
||||
# define FP_ROUNDMODE FP_RND_NEAREST
|
||||
#endif
|
||||
|
||||
/* By default don't care about exceptions. */
|
||||
/* By default don't care about exceptions. */
|
||||
#ifndef FP_EX_INVALID
|
||||
# define FP_EX_INVALID 0
|
||||
#endif
|
||||
@ -83,6 +83,44 @@
|
||||
# define FP_EX_DENORM 0
|
||||
#endif
|
||||
|
||||
/* Sub-exceptions of "invalid". */
|
||||
/* Signaling NaN operand. */
|
||||
#ifndef FP_EX_INVALID_SNAN
|
||||
# define FP_EX_INVALID_SNAN 0
|
||||
#endif
|
||||
/* Inf * 0. */
|
||||
#ifndef FP_EX_INVALID_IMZ
|
||||
# define FP_EX_INVALID_IMZ 0
|
||||
#endif
|
||||
/* fma (Inf, 0, c). */
|
||||
#ifndef FP_EX_INVALID_IMZ_FMA
|
||||
# define FP_EX_INVALID_IMZ_FMA 0
|
||||
#endif
|
||||
/* Inf - Inf. */
|
||||
#ifndef FP_EX_INVALID_ISI
|
||||
# define FP_EX_INVALID_ISI 0
|
||||
#endif
|
||||
/* 0 / 0. */
|
||||
#ifndef FP_EX_INVALID_ZDZ
|
||||
# define FP_EX_INVALID_ZDZ 0
|
||||
#endif
|
||||
/* Inf / Inf. */
|
||||
#ifndef FP_EX_INVALID_IDI
|
||||
# define FP_EX_INVALID_IDI 0
|
||||
#endif
|
||||
/* sqrt (negative). */
|
||||
#ifndef FP_EX_INVALID_SQRT
|
||||
# define FP_EX_INVALID_SQRT 0
|
||||
#endif
|
||||
/* Invalid conversion to integer. */
|
||||
#ifndef FP_EX_INVALID_CVI
|
||||
# define FP_EX_INVALID_CVI 0
|
||||
#endif
|
||||
/* Invalid comparison. */
|
||||
#ifndef FP_EX_INVALID_VC
|
||||
# define FP_EX_INVALID_VC 0
|
||||
#endif
|
||||
|
||||
/* _FP_STRUCT_LAYOUT may be defined as an attribute to determine the
|
||||
struct layout variant used for structures where bit-fields are used
|
||||
to access specific parts of binary floating-point numbers. This is
|
||||
@ -107,31 +145,38 @@
|
||||
# define FP_INIT_ROUNDMODE do {} while (0)
|
||||
#endif
|
||||
|
||||
/* Initialize any machine-specific state used in
|
||||
FP_TRAPPING_EXCEPTIONS or FP_HANDLE_EXCEPTIONS. */
|
||||
#ifndef FP_INIT_TRAPPING_EXCEPTIONS
|
||||
# define FP_INIT_TRAPPING_EXCEPTIONS FP_INIT_ROUNDMODE
|
||||
#endif
|
||||
|
||||
/* Initialize any machine-specific state used in
|
||||
FP_HANDLE_EXCEPTIONS. */
|
||||
#ifndef FP_INIT_EXCEPTIONS
|
||||
# define FP_INIT_EXCEPTIONS FP_INIT_ROUNDMODE
|
||||
# define FP_INIT_EXCEPTIONS FP_INIT_TRAPPING_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
#ifndef FP_HANDLE_EXCEPTIONS
|
||||
# define FP_HANDLE_EXCEPTIONS do {} while (0)
|
||||
#endif
|
||||
|
||||
/* Whether to flush subnormal inputs to zero with the same sign. */
|
||||
#ifndef FP_DENORM_ZERO
|
||||
# define FP_DENORM_ZERO 0
|
||||
#endif
|
||||
|
||||
#ifndef FP_INHIBIT_RESULTS
|
||||
/* By default we write the results always.
|
||||
* sfp-machine may override this and e.g.
|
||||
* check if some exceptions are unmasked
|
||||
* and inhibit it in such a case.
|
||||
*/
|
||||
sfp-machine may override this and e.g.
|
||||
check if some exceptions are unmasked
|
||||
and inhibit it in such a case. */
|
||||
# define FP_INHIBIT_RESULTS 0
|
||||
#endif
|
||||
|
||||
#define FP_SET_EXCEPTION(ex) \
|
||||
_fex |= (ex)
|
||||
|
||||
#define FP_CLEAR_EXCEPTIONS \
|
||||
_fex = 0
|
||||
|
||||
#define FP_CUR_EXCEPTIONS \
|
||||
(_fex)
|
||||
|
||||
@ -166,6 +211,16 @@
|
||||
|
||||
#endif
|
||||
|
||||
/* A file using soft-fp may define FP_NO_EXACT_UNDERFLOW before
|
||||
including soft-fp.h to indicate that, although a macro used there
|
||||
could allow for the case of exact underflow requiring the underflow
|
||||
exception to be raised if traps are enabled, for the particular
|
||||
arguments used in that file no exact underflow can occur. */
|
||||
#ifdef FP_NO_EXACT_UNDERFLOW
|
||||
# undef FP_TRAPPING_EXCEPTIONS
|
||||
# define FP_TRAPPING_EXCEPTIONS 0
|
||||
#endif
|
||||
|
||||
#define _FP_ROUND_NEAREST(wc, X) \
|
||||
do \
|
||||
{ \
|
||||
|
@ -41,9 +41,7 @@ __unorddf2 (DFtype a, DFtype 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_CMP_UNORD_D (r, A, B, 1);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
@ -41,9 +41,7 @@ __unordsf2 (SFtype a, SFtype 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_CMP_UNORD_S (r, A, B, 1);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
@ -41,9 +41,7 @@ __unordtf2 (TFtype a, TFtype 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_CMP_UNORD_Q (r, A, B, 1);
|
||||
FP_HANDLE_EXCEPTIONS;
|
||||
|
||||
return r;
|
||||
|
Loading…
Reference in New Issue
Block a user