===================================================================
@@ -3967,7 +3967,7 @@ mips_rtx_costs (rtx x, int code, int out
case DIV:
/* Check for a reciprocal. */
if (float_mode_p
- && ISA_HAS_FP4
+ && ISA_HAS_FP_RECIP_RSQRT (mode)
&& flag_unsafe_math_optimizations
&& XEXP (x, 0) == CONST1_RTX (mode))
{
===================================================================
@@ -921,6 +921,21 @@ struct mips_cpu_info {
'c = -((a * b) [+-] c)'. */
#define ISA_HAS_NMADD3_NMSUB3 TARGET_LOONGSON_2EF
+/* ISA has floating-point RECIP.fmt and RSQRT.fmt instructions. The
+ MIPS64 rev. 1 ISA says 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 the MIPS IV ISA too. */
+#define ISA_HAS_FP_RECIP_RSQRT(MODE) \
+ (((ISA_HAS_FP4 \
+ || (ISA_MIPS32R2 && !TARGET_MIPS16)) \
+ && ((MODE) == SFmode \
+ || ((TARGET_FLOAT64 \
+ || !(ISA_MIPS4 \
+ || ISA_MIPS64)) \
+ && (MODE) == DFmode))) \
+ || ((TARGET_SB1 && !TARGET_MIPS16) \
+ && (MODE) == V2SFmode))
+
/* ISA has count leading zeroes/ones instruction (not implemented). */
#define ISA_HAS_CLZ_CLO ((ISA_MIPS32 \
|| ISA_MIPS32R2 \
===================================================================
@@ -881,15 +881,6 @@
(define_mode_attr sqrt_condition
[(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.
-(define_mode_attr recip_condition
- [(SF "ISA_HAS_FP4")
- (DF "ISA_HAS_FP4 && TARGET_FLOAT64")
- (V2SF "TARGET_SB1")])
-
;; This code iterator allows signed and unsigned widening multiplications
;; to use the same template.
(define_code_iterator any_extend [sign_extend zero_extend])
@@ -2501,7 +2492,8 @@
"<divide_condition>"
{
if (const_1_operand (operands[1], <MODE>mode))
- if (!(<recip_condition> && flag_unsafe_math_optimizations))
+ if (!(ISA_HAS_FP_RECIP_RSQRT (<MODE>mode)
+ && flag_unsafe_math_optimizations))
operands[1] = force_reg (<MODE>mode, operands[1]);
})
@@ -2539,7 +2531,7 @@
[(set (match_operand:ANYF 0 "register_operand" "=f")
(div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
(match_operand:ANYF 2 "register_operand" "f")))]
- "<recip_condition> && flag_unsafe_math_optimizations"
+ "ISA_HAS_FP_RECIP_RSQRT (<MODE>mode) && flag_unsafe_math_optimizations"
{
if (TARGET_FIX_SB1)
return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
@@ -2674,7 +2666,7 @@
[(set (match_operand:ANYF 0 "register_operand" "=f")
(div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
(sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))]
- "<recip_condition> && flag_unsafe_math_optimizations"
+ "ISA_HAS_FP_RECIP_RSQRT (<MODE>mode) && flag_unsafe_math_optimizations"
{
if (TARGET_FIX_SB1)
return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
@@ -2692,7 +2684,7 @@
[(set (match_operand:ANYF 0 "register_operand" "=f")
(sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "")
(match_operand:ANYF 2 "register_operand" "f"))))]
- "<recip_condition> && flag_unsafe_math_optimizations"
+ "ISA_HAS_FP_RECIP_RSQRT (<MODE>mode) && flag_unsafe_math_optimizations"
{
if (TARGET_FIX_SB1)
return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";