diff options
author | YunQiang Su <syq@gcc.gnu.org> | 2024-06-08 11:31:19 +0800 |
---|---|---|
committer | YunQiang Su <syq@gcc.gnu.org> | 2024-06-13 09:42:42 +0800 |
commit | e3e5fd0c24c9b82d824da27bf8455bb3654e8eff (patch) | |
tree | 356dcafc728341b7da8035f982ac77806d96becd /gcc/config/mips/mips.h | |
parent | 8a5d0d72ea8c324bbfa2cff1284fa8e473fc466d (diff) | |
download | gcc-e3e5fd0c24c9b82d824da27bf8455bb3654e8eff.zip gcc-e3e5fd0c24c9b82d824da27bf8455bb3654e8eff.tar.gz gcc-e3e5fd0c24c9b82d824da27bf8455bb3654e8eff.tar.bz2 |
MIPS: Use signaling fcmp instructions for LT/LE/LTGT
LT/LE: c.lt.fmt/c.le.fmt on pre-R6 and cmp.lt.fmt/cmp.le.fmt have
different semantic:
c.lt.fmt will signal for all NaN, including qNaN;
cmp.lt.fmt will only signal sNaN, while not qNaN;
cmp.slt.fmt has the same semantic as c.lt.fmt;
lt/le of RTL will signaling qNaN.
while in `s<code>_<SCALARF:mode>_using_<FPCC:mode>`, RTL operation
`lt`/`le` are convert to c/cmp's lt/le, which is correct for C.cond.fmt,
while not for CMP.cond.fmt. Let's convert them to slt/sle if ISA_HAS_CCF.
For LTGT, which signals qNaN, `sne` of r6 has same semantic, while pre-R6
has only inverse one `ngl`. Thus for RTL we have to use the `uneq` as the
operator, and introduce a new CC mode: CCEmode to mark it as signaling.
This patch can fix
gcc.dg/torture/pr91323.c for pre-R6;
gcc.dg/torture/builtin-iseqsig-* for R6.
gcc:
* config/mips/mips-modes.def: New CC_MODE CCE.
* config/mips/mips-protos.h(mips_output_compare): New function.
* config/mips/mips.cc(mips_allocate_fcc): Set CCEmode count=1.
(mips_emit_compare): Use CCEmode for LTGT/LT/LE for pre-R6.
(mips_output_compare): New function. Convert lt/le to slt/sle
for R6; convert ueq to ngl for CCEmode.
(mips_hard_regno_mode_ok_uncached): Mention CCEmode.
* config/mips/mips.h: Mention CCEmode for LOAD_EXTEND_OP.
* config/mips/mips.md(FPCC): Add CCE.
(define_mode_iterator MOVECC): Mention CCE.
(define_mode_attr reg): Add CCE with "z".
(define_mode_attr fpcmp): Add CCE with "c".
(define_code_attr fcond): ltgt should use sne instead of ne.
(s<code>_<SCALARF:mode>_using_<FPCC:mode>): call mips_output_compare.
Diffstat (limited to 'gcc/config/mips/mips.h')
-rw-r--r-- | gcc/config/mips/mips.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 9d96596..d18ca7d 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -1771,7 +1771,7 @@ FP_ASM_SPEC "\ /* When in 64-bit mode, move insns will sign extend SImode and CCmode moves. All other references are zero extended. */ #define LOAD_EXTEND_OP(MODE) \ - (TARGET_64BIT && ((MODE) == SImode || (MODE) == CCmode) \ + (TARGET_64BIT && ((MODE) == SImode || (MODE) == CCmode || (MODE) == CCEmode) \ ? SIGN_EXTEND : ZERO_EXTEND) /* Define this macro if it is advisable to hold scalars in registers |