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:
Joseph Myers 2014-10-09 19:21:30 +01:00 committed by Joseph Myers
parent c386686921
commit 5f60643158
39 changed files with 1782 additions and 1352 deletions

View File

@ -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.

View 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);
}

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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"

View File

@ -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)

View File

@ -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"

View File

@ -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"

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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 \
{ \

View File

@ -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;

View File

@ -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;

View File

@ -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;