The MIPS32 architecture supports madd, msub, nmadd, and nmsub instructions as well as rsqrt and recip instructions even when it doesn't have a 64 bit floating point unit. This was not clear in the original MIPS32 architecture document (MD00086) but was clarified in 2011 (version 3.0.2, March 21, 2011). This patch updates the ISA_HAS_FP4 and ISA_HAS_NMADD4_NMSUB4 macros and the recip_condition mode attribute to allow the use of these instructions for all MIPS32 architectures (with or without FLOAT64).
Testing showed one new test failure (gcc.target/mips/rsqrt-4.c) which I updated to reflect that we can now generate and use a rsqrt.d instruction. I put Chao-ying and Maciej's names on the patch since they did the original changes in GCC but those changes were never checked in upstream. OK to checkin? Steve Ellcey sell...@mips.com In the spec MD00086, page 347 Revision History, 3.0.2, March 21, 2011, RECIP, R SQRT instructions do not require 64-bit FPU. 2012-12-12 Steve Ellcey <sell...@mips.com> Chao-ying Fu <f...@mips.com> Maciej W. Rozycki <ma...@codesourcery.com> * config/mips/mips.h (ISA_HAS_FP4): Allow madd, etc. on all MIPS32R2. (ISA_HAS_NMADD4_NMSUB4): Ditto. * config/mips/mips.md (recip_condition): Allow recip and rsqrt on all MIPS32R2. diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 60b26cb..44874e9 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -858,7 +858,7 @@ struct mips_cpu_info { FP madd and msub instructions, and the FP recip and recip sqrt instructions. */ #define ISA_HAS_FP4 ((ISA_MIPS4 \ - || (ISA_MIPS32R2 && TARGET_FLOAT64) \ + || ISA_MIPS32R2 \ || ISA_MIPS64 \ || ISA_MIPS64R2) \ && !TARGET_MIPS16) @@ -889,10 +889,7 @@ struct mips_cpu_info { /* ISA has floating-point nmadd and nmsub instructions 'd = -((a * b) [+-] c)'. */ #define ISA_HAS_NMADD4_NMSUB4(MODE) \ - ((ISA_MIPS4 \ - || (ISA_MIPS32R2 && (MODE) == V2SFmode) \ - || ISA_MIPS64 \ - || ISA_MIPS64R2) \ + (ISA_HAS_FP4 \ && (!TARGET_MIPS5400 || TARGET_MAD) \ && !TARGET_MIPS16) diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index a3aa922..796597e 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -858,12 +858,10 @@ [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")]) ;; This attribute gives the conditions under which RECIP.fmt and RSQRT.fmt -;; instructions can be used. The MIPS32 and MIPS64 ISAs say that RECIP.D -;; and RSQRT.D are unpredictable when doubles are stored in pairs of FPRs, -;; so for safety's sake, we apply this restriction to all targets. +;; instructions can be used. (define_mode_attr recip_condition [(SF "ISA_HAS_FP4") - (DF "ISA_HAS_FP4 && TARGET_FLOAT64") + (DF "ISA_HAS_FP4") (V2SF "TARGET_SB1")]) ;; This code iterator allows signed and unsigned widening multiplications ============= Test change =========== 2012-12-12 Steve Ellcey <sell...@mips.com> * gcc.target/mips/rsqrt-4.c: Update to show use of sqrt.d. diff --git a/gcc/testsuite/gcc.target/mips/rsqrt-4.c b/gcc/testsuite/gcc.target/mips/rsqrt-4.c index 6b6577e..471dd28 100644 --- a/gcc/testsuite/gcc.target/mips/rsqrt-4.c +++ b/gcc/testsuite/gcc.target/mips/rsqrt-4.c @@ -1,7 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-ffast-math -mips64 -mhard-float -mgp32" } */ /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ -/* { dg-final { scan-assembler-not "\trsqrt.d\t" } } */ +/* { dg-final { scan-assembler-times "\trsqrt.d\t" 2 } } */ /* { dg-final { scan-assembler-times "\trsqrt.s\t" 2 } } */ extern double sqrt(double);