mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-24 14:00:30 +00:00
MIPS: soft-fp NaN representation corrections
[BZ #15442] This adds support for the inverse interpretation of the quiet bit of IEEE 754 floating-point NaN data that some processors use. This includes in particular MIPS architecture processors; the payload used for the canonical qNaN encoding is updated accordingly so as not to interfere with the quiet bit.
This commit is contained in:
parent
c58b274f01
commit
2848b10585
21
ChangeLog
21
ChangeLog
@ -1,3 +1,24 @@
|
||||
2013-05-16 Maciej W. Rozycki <macro@codesourcery.com>
|
||||
|
||||
[BZ #15442]
|
||||
* soft-fp/op-common.h (_FP_FRAC_SNANP): New macro.
|
||||
(_FP_FRAC_SNANP_SEMIRAW): Likewise.
|
||||
(_FP_UNPACK_CANONICAL): Use _FP_FRAC_SNANP.
|
||||
(_FP_CHECK_SIGNAN_SEMIRAW): Use _FP_FRAC_SNANP_SEMIRAW.
|
||||
(_FP_SETQNAN): New macro.
|
||||
(_FP_SETQNAN_SEMIRAW): Likewise.
|
||||
(_FP_PACK_SEMIRAW): Use _FP_SETQNAN.
|
||||
(_FP_PACK_CANONICAL): Use _FP_SETQNAN.
|
||||
(_FP_ISSIGNAN): Use _FP_FRAC_SNANP.
|
||||
(FP_EXTEND): Use _FP_FRAC_SNANP.
|
||||
(FP_TRUNC): Use _FP_SETQNAN_SEMIRAW.
|
||||
* soft-fp/testit.c (gen_special_double): Take _FP_QNANNEGATEDP
|
||||
into account.
|
||||
* sysdeps/sparc/sparc32/soft-fp/sfp-machine.h (_FP_QNANNEGATEDP):
|
||||
New macro.
|
||||
* sysdeps/sparc/sparc64/soft-fp/sfp-machine.h (_FP_QNANNEGATEDP):
|
||||
Likewise.
|
||||
|
||||
2013-05-16 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* math/libm-test.inc (atanh_test_data): Use ERRNO_ERANGE together
|
||||
|
2
NEWS
2
NEWS
@ -17,7 +17,7 @@ Version 2.18
|
||||
15086, 15160, 15214, 15221, 15232, 15234, 15283, 15285, 15287, 15304,
|
||||
15305, 15307, 15309, 15327, 15330, 15335, 15336, 15337, 15342, 15346,
|
||||
15359, 15361, 15366, 15380, 15394, 15395, 15405, 15406, 15409, 15416,
|
||||
15418, 15419, 15423, 15426, 15429, 15448.
|
||||
15418, 15419, 15423, 15426, 15429, 15442, 15448.
|
||||
|
||||
* CVE-2013-0242 Buffer overrun in regexp matcher has been fixed (Bugzilla
|
||||
#15078).
|
||||
|
@ -1,3 +1,9 @@
|
||||
2013-05-16 Maciej W. Rozycki <macro@codesourcery.com>
|
||||
|
||||
[BZ #15442]
|
||||
* sysdeps/aarch64/soft-fp/sfp-machine.h (_FP_QNANNEGATEDP): New
|
||||
macro.
|
||||
|
||||
2013-05-12 Marcus Shawcroft <marcus.shawcroft@linaro.org>
|
||||
|
||||
* sysdeps/unix/sysv/linux/aarch64/clone.S (__clone):
|
||||
|
@ -1,3 +1,9 @@
|
||||
2013-05-16 Maciej W. Rozycki <macro@codesourcery.com>
|
||||
|
||||
[BZ #15442]
|
||||
* sysdeps/alpha/soft-fp/sfp-machine.h (_FP_QNANNEGATEDP): New
|
||||
macro.
|
||||
|
||||
2013-03-06 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/alpha/bits/mman.h (MAP_HUGE_MASK)
|
||||
|
@ -1,3 +1,17 @@
|
||||
2013-05-16 Maciej W. Rozycki <macro@codesourcery.com>
|
||||
|
||||
[BZ #15442]
|
||||
* sysdeps/mips/mips64/soft-fp/sfp-machine.h (_FP_QNANNEGATEDP):
|
||||
New macro.
|
||||
(_FP_NANFRAC_S): Don't set the quiet bit.
|
||||
(_FP_NANFRAC_D): Likewise.
|
||||
(_FP_NANFRAC_Q): Likewise.
|
||||
* sysdeps/mips/soft-fp/sfp-machine.h (_FP_QNANNEGATEDP): New
|
||||
macro.
|
||||
(_FP_NANFRAC_S): Don't set the quiet bit.
|
||||
(_FP_NANFRAC_D): Likewise.
|
||||
(_FP_NANFRAC_Q): Likewise.
|
||||
|
||||
2013-05-16 Ryan S. Arnold <rsa@linux.vnet.ibm.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/mips/kernel_rt_sigframe.h: Add missing
|
||||
|
@ -1,3 +1,9 @@
|
||||
2013-05-16 Maciej W. Rozycki <macro@codesourcery.com>
|
||||
|
||||
[BZ #15442]
|
||||
* sysdeps/powerpc/soft-fp/sfp-machine.h (_FP_QNANNEGATEDP): New
|
||||
macro.
|
||||
|
||||
2013-02-28 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
[BZ #13550]
|
||||
|
@ -25,6 +25,8 @@
|
||||
#define _FP_NANSIGN_Q 0
|
||||
|
||||
#define _FP_KEEPNANFRACP 1
|
||||
#define _FP_QNANNEGATEDP 0
|
||||
|
||||
/* From my experiments it seems X is chosen unless one of the
|
||||
NaNs is sNaN, in which case the result is NANSIGN/NANFRAC. */
|
||||
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
|
||||
|
@ -46,6 +46,7 @@
|
||||
#define _FP_NANSIGN_Q 0
|
||||
|
||||
#define _FP_KEEPNANFRACP 1
|
||||
#define _FP_QNANNEGATEDP 0
|
||||
|
||||
/* Alpha Architecture Handbook, 4.7.10.4 sez that we should prefer any
|
||||
type of NaN in Fb, then Fa. */
|
||||
|
@ -17,14 +17,16 @@
|
||||
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
|
||||
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
|
||||
|
||||
#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
|
||||
#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1)
|
||||
#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1
|
||||
#define _FP_NANFRAC_S (_FP_QNANBIT_S - 1)
|
||||
#define _FP_NANFRAC_D (_FP_QNANBIT_D - 1)
|
||||
#define _FP_NANFRAC_Q (_FP_QNANBIT_Q - 1), -1
|
||||
#define _FP_NANSIGN_S 0
|
||||
#define _FP_NANSIGN_D 0
|
||||
#define _FP_NANSIGN_Q 0
|
||||
|
||||
#define _FP_KEEPNANFRACP 1
|
||||
#define _FP_QNANNEGATEDP 1
|
||||
|
||||
/* From my experiments it seems X is chosen unless one of the
|
||||
NaNs is sNaN, in which case the result is NANSIGN/NANFRAC. */
|
||||
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
|
||||
|
@ -14,14 +14,16 @@
|
||||
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
|
||||
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
|
||||
|
||||
#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
|
||||
#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
|
||||
#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
|
||||
#define _FP_NANFRAC_S (_FP_QNANBIT_S - 1)
|
||||
#define _FP_NANFRAC_D (_FP_QNANBIT_D - 1), -1
|
||||
#define _FP_NANFRAC_Q (_FP_QNANBIT_Q - 1), -1, -1, -1
|
||||
#define _FP_NANSIGN_S 0
|
||||
#define _FP_NANSIGN_D 0
|
||||
#define _FP_NANSIGN_Q 0
|
||||
|
||||
#define _FP_KEEPNANFRACP 1
|
||||
#define _FP_QNANNEGATEDP 1
|
||||
|
||||
/* From my experiments it seems X is chosen unless one of the
|
||||
NaNs is sNaN, in which case the result is NANSIGN/NANFRAC. */
|
||||
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define _FP_NANSIGN_Q 0
|
||||
|
||||
#define _FP_KEEPNANFRACP 1
|
||||
#define _FP_QNANNEGATEDP 0
|
||||
|
||||
/* Someone please check this. */
|
||||
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
|
||||
|
@ -35,6 +35,16 @@
|
||||
_FP_I_TYPE X##_e; \
|
||||
_FP_FRAC_DECL_##wc(X)
|
||||
|
||||
/* Test whether the qNaN bit denotes a signaling NaN. */
|
||||
#define _FP_FRAC_SNANP(fs, X) \
|
||||
((_FP_QNANNEGATEDP) \
|
||||
? (_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
|
||||
: !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))
|
||||
#define _FP_FRAC_SNANP_SEMIRAW(fs, X) \
|
||||
((_FP_QNANNEGATEDP) \
|
||||
? (_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs) \
|
||||
: !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs))
|
||||
|
||||
/*
|
||||
* Finish truely unpacking a native fp value by classifying the kind
|
||||
* of fp value and normalizing both the exponent and the fraction.
|
||||
@ -74,7 +84,7 @@ do { \
|
||||
{ \
|
||||
X##_c = FP_CLS_NAN; \
|
||||
/* Check for signaling NaN */ \
|
||||
if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
|
||||
if (_FP_FRAC_SNANP(fs, X)) \
|
||||
FP_SET_EXCEPTION(FP_EX_INVALID); \
|
||||
} \
|
||||
break; \
|
||||
@ -112,7 +122,7 @@ do { \
|
||||
do { \
|
||||
if (X##_e == _FP_EXPMAX_##fs \
|
||||
&& !_FP_FRAC_ZEROP_##wc(X) \
|
||||
&& !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs)) \
|
||||
&& _FP_FRAC_SNANP_SEMIRAW(fs, X)) \
|
||||
FP_SET_EXCEPTION(FP_EX_INVALID); \
|
||||
} while (0)
|
||||
|
||||
@ -127,6 +137,39 @@ do { \
|
||||
_FP_FRAC_SLL_##wc(R, _FP_WORKBITS); \
|
||||
} while (0)
|
||||
|
||||
/* Make the fractional part a quiet NaN, preserving the payload
|
||||
if possible, otherwise make it the canonical quiet NaN and set
|
||||
the sign bit accordingly. */
|
||||
#define _FP_SETQNAN(fs, wc, X) \
|
||||
do { \
|
||||
if (_FP_QNANNEGATEDP) \
|
||||
{ \
|
||||
_FP_FRAC_HIGH_RAW_##fs(X) &= _FP_QNANBIT_##fs - 1; \
|
||||
if (_FP_FRAC_ZEROP_##wc(X)) \
|
||||
{ \
|
||||
X##_s = _FP_NANSIGN_##fs; \
|
||||
_FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
_FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
|
||||
} while (0)
|
||||
#define _FP_SETQNAN_SEMIRAW(fs, wc, X) \
|
||||
do { \
|
||||
if (_FP_QNANNEGATEDP) \
|
||||
{ \
|
||||
_FP_FRAC_HIGH_##fs(X) &= _FP_QNANBIT_SH_##fs - 1; \
|
||||
if (_FP_FRAC_ZEROP_##wc(X)) \
|
||||
{ \
|
||||
X##_s = _FP_NANSIGN_##fs; \
|
||||
_FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
|
||||
_FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
_FP_FRAC_HIGH_##fs(X) |= _FP_QNANBIT_SH_##fs; \
|
||||
} while (0)
|
||||
|
||||
/* Test whether a biased exponent is normal (not zero or maximum). */
|
||||
#define _FP_EXP_NORMAL(fs, wc, X) (((X##_e + 1) & _FP_EXPMAX_##fs) > 1)
|
||||
|
||||
@ -159,7 +202,7 @@ do { \
|
||||
X##_s = _FP_NANSIGN_##fs; \
|
||||
} \
|
||||
else \
|
||||
_FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
|
||||
_FP_SETQNAN(fs, wc, X); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@ -273,7 +316,7 @@ do { \
|
||||
X##_s = _FP_NANSIGN_##fs; \
|
||||
} \
|
||||
else \
|
||||
_FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
|
||||
_FP_SETQNAN(fs, wc, X); \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
@ -287,7 +330,7 @@ do { \
|
||||
if (X##_e == _FP_EXPMAX_##fs) \
|
||||
{ \
|
||||
if (!_FP_FRAC_ZEROP_##wc(X) \
|
||||
&& !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
|
||||
&& _FP_FRAC_SNANP(fs, X)) \
|
||||
__ret = 1; \
|
||||
} \
|
||||
__ret; \
|
||||
@ -1199,7 +1242,7 @@ do { \
|
||||
D##_e = _FP_EXPMAX_##dfs; \
|
||||
if (!_FP_FRAC_ZEROP_##swc(S)) \
|
||||
{ \
|
||||
if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs)) \
|
||||
if (_FP_FRAC_SNANP(sfs, S)) \
|
||||
FP_SET_EXCEPTION(FP_EX_INVALID); \
|
||||
_FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs \
|
||||
- _FP_FRACBITS_##sfs)); \
|
||||
@ -1286,7 +1329,7 @@ do { \
|
||||
/* Semi-raw NaN must have all workbits cleared. */ \
|
||||
_FP_FRAC_LOW_##dwc(D) \
|
||||
&= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1); \
|
||||
_FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs; \
|
||||
_FP_SETQNAN_SEMIRAW(dfs, dwc, D); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
|
@ -200,17 +200,17 @@ double gen_special_double(int i)
|
||||
case 0:
|
||||
X_c = FP_CLS_NAN;
|
||||
#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
|
||||
__FP_FRAC_SET_2(X, _FP_QNANBIT_D, 0x1234);
|
||||
__FP_FRAC_SET_2(X, _FP_QNANNEGATEDP ? 0 : _FP_QNANBIT_D, 0x1234);
|
||||
#else
|
||||
_FP_FRAC_SET_1(X, _FP_QNANBIT_D | 0x1234);
|
||||
_FP_FRAC_SET_1(X, (_FP_QNANNEGATEDP ? 0 : _FP_QNANBIT_D) | 0x1234);
|
||||
#endif
|
||||
break;
|
||||
case 2:
|
||||
X_c = FP_CLS_NAN;
|
||||
#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
|
||||
__FP_FRAC_SET_2(X, _FP_QNANBIT_D, 0x1);
|
||||
__FP_FRAC_SET_2(X, _FP_QNANNEGATEDP ? 0 : _FP_QNANBIT_D, 0x1);
|
||||
#else
|
||||
_FP_FRAC_SET_1(X, _FP_QNANBIT_D | 0x1);
|
||||
_FP_FRAC_SET_1(X, (_FP_QNANNEGATEDP ? 0 : _FP_QNANBIT_D) | 0x1);
|
||||
#endif
|
||||
break;
|
||||
case 4:
|
||||
|
@ -47,6 +47,7 @@
|
||||
#define _FP_NANSIGN_Q 0
|
||||
|
||||
#define _FP_KEEPNANFRACP 1
|
||||
#define _FP_QNANNEGATEDP 0
|
||||
|
||||
/* If one NaN is signaling and the other is not,
|
||||
* we choose that one, otherwise we choose X.
|
||||
|
@ -60,6 +60,7 @@ do { \
|
||||
#define _FP_NANSIGN_Q 0
|
||||
|
||||
#define _FP_KEEPNANFRACP 1
|
||||
#define _FP_QNANNEGATEDP 0
|
||||
|
||||
/* If one NaN is signaling and the other is not,
|
||||
* we choose that one, otherwise we choose Y.
|
||||
|
Loading…
Reference in New Issue
Block a user