diff options
author | Jiaxun Yang <jiaxun.yang@flygoat.com> | 2025-04-19 08:07:58 -0600 |
---|---|---|
committer | Jeff Law <jlaw@ventanamicro.com> | 2025-04-19 08:07:58 -0600 |
commit | 2a643f55f5acc05dcc7cee133647bf3193d5b563 (patch) | |
tree | a5d50cd818a09759ac9ab1a1d46839e4a8d09cf9 /libgcc | |
parent | 6beb0a14aacd84ec49646237fc0f69c6765f956e (diff) | |
download | gcc-2a643f55f5acc05dcc7cee133647bf3193d5b563.zip gcc-2a643f55f5acc05dcc7cee133647bf3193d5b563.tar.gz gcc-2a643f55f5acc05dcc7cee133647bf3193d5b563.tar.bz2 |
[PATCH v2] sh: Correct NaN signalling bit and propagation rules [PR111814]
As per architecture, SuperH has a reversed NaN signalling bit
vs IEEE754-2008, it also has a NaN propgation rule similar to
MIPS style.
Use mips style float format and mode for all float types, and
correct sfp-machine header accordingly.
PR target/111814
gcc/ChangeLog:
* config/sh/sh-modes.def (RESET_FLOAT_FORMAT): Use mips format.
(FLOAT_MODE): Use mips mode.
libgcc/ChangeLog:
* config/sh/sfp-machine.h (_FP_NANFRAC_B): Reverse signaling bit.
(_FP_NANFRAC_H): Likewise.
(_FP_NANFRAC_S): Likewise.
(_FP_NANFRAC_D): Likewise.
(_FP_NANFRAC_Q): Likewise.
(_FP_KEEPNANFRACP): Enable for target.
(_FP_QNANNEGATEDP): Enable for target.
(_FP_CHOOSENAN): Port from MIPS.
gcc/testsuite/ChangeLog:
* gcc.target/sh/pr111814.c: New test.
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/config/sh/sfp-machine.h | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/libgcc/config/sh/sfp-machine.h b/libgcc/config/sh/sfp-machine.h index 66984d4..67bc415 100644 --- a/libgcc/config/sh/sfp-machine.h +++ b/libgcc/config/sh/sfp-machine.h @@ -39,11 +39,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #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_B _FP_QNANBIT_B -#define _FP_NANFRAC_H _FP_QNANBIT_H -#define _FP_NANFRAC_S _FP_QNANBIT_S -#define _FP_NANFRAC_D _FP_QNANBIT_D, 0 -#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0 +#define _FP_NANFRAC_B (_FP_QNANBIT_B - 1) +#define _FP_NANFRAC_H (_FP_QNANBIT_H - 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 /* The type of the result of a floating point comparison. This must match __libgcc_cmp_return__ in GCC for the target. */ @@ -56,14 +56,24 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); #define _FP_NANSIGN_D 0 #define _FP_NANSIGN_Q 0 -#define _FP_KEEPNANFRACP 0 -#define _FP_QNANNEGATEDP 0 - -#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ - do { \ - R##_s = _FP_NANSIGN_##fs; \ - _FP_FRAC_SET_##wc(R,_FP_NANFRAC_##fs); \ - R##_c = FP_CLS_NAN; \ +#define _FP_KEEPNANFRACP 1 +#define _FP_QNANNEGATEDP 1 + +/* X is chosen unless one of the NaNs is sNaN. */ +# define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ + do { \ + if ((_FP_FRAC_HIGH_RAW_##fs(X) | \ + _FP_FRAC_HIGH_RAW_##fs(Y)) & _FP_QNANBIT_##fs) \ + { \ + R##_s = _FP_NANSIGN_##fs; \ + _FP_FRAC_SET_##wc(R,_FP_NANFRAC_##fs); \ + } \ + else \ + { \ + R##_s = X##_s; \ + _FP_FRAC_COPY_##wc(R,X); \ + } \ + R##_c = FP_CLS_NAN; \ } while (0) #define _FP_TININESS_AFTER_ROUNDING 1 |