;; floating-point mode.
(define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
+;; This attribute works around the early SB-1 rev2 core "F2" erratum:
+;;
+;; In certain cases, div.s and div.ps may have a rounding error
+;; and/or wrong inexact flag.
+;;
+;; Therefore, we only allow div.s if not working around SB-1 rev2
+;; errata or if a slight loss of precision is OK.
+(define_mode_attr divide_condition
+ [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations")])
+
;; This code macro allows all branch instructions to be generated from
;; a single define_expand template.
(define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
;; ....................
;;
-(define_expand "divdf3"
- [(set (match_operand:DF 0 "register_operand")
- (div:DF (match_operand:DF 1 "reg_or_1_operand")
- (match_operand:DF 2 "register_operand")))]
- "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
+(define_expand "div<mode>3"
+ [(set (match_operand:SCALARF 0 "register_operand")
+ (div:SCALARF (match_operand:SCALARF 1 "reg_or_1_operand")
+ (match_operand:SCALARF 2 "register_operand")))]
+ "<divide_condition>"
{
- if (const_1_operand (operands[1], DFmode))
+ if (const_1_operand (operands[1], <MODE>mode))
if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
- operands[1] = force_reg (DFmode, operands[1]);
+ operands[1] = force_reg (<MODE>mode, operands[1]);
})
-;; This pattern works around the early SB-1 rev2 core "F1" erratum:
+;; These patterns work around the early SB-1 rev2 core "F1" erratum:
;;
;; If an mfc1 or dmfc1 happens to access the floating point register
;; file at the same time a long latency operation (div, sqrt, recip,
;; The workaround is to insert an unconditional 'mov' from/to the
;; long latency op destination register.
-(define_insn "*divdf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (div:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f")))]
- "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
-{
- if (TARGET_FIX_SB1)
- return "div.d\t%0,%1,%2\;mov.d\t%0,%0";
- else
- return "div.d\t%0,%1,%2";
-}
- [(set_attr "type" "fdiv")
- (set_attr "mode" "DF")
- (set (attr "length")
- (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
- (const_int 8)
- (const_int 4)))])
-
-
-;; This pattern works around the early SB-1 rev2 core "F2" erratum:
-;;
-;; In certain cases, div.s and div.ps may have a rounding error
-;; and/or wrong inexact flag.
-;;
-;; Therefore, we only allow div.s if not working around SB-1 rev2
-;; errata, or if working around those errata and a slight loss of
-;; precision is OK (i.e., flag_unsafe_math_optimizations is set).
-(define_expand "divsf3"
- [(set (match_operand:SF 0 "register_operand")
- (div:SF (match_operand:SF 1 "reg_or_1_operand")
- (match_operand:SF 2 "register_operand")))]
- "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
-{
- if (const_1_operand (operands[1], SFmode))
- if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations))
- operands[1] = force_reg (SFmode, operands[1]);
-})
-
-;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
-;; "divdf3" comment for details).
-;;
-;; This pattern works around the early SB-1 rev2 core "F2" erratum (see
-;; "divsf3" comment for details).
-(define_insn "*divsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (div:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f")))]
- "TARGET_HARD_FLOAT && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)"
-{
- if (TARGET_FIX_SB1)
- return "div.s\t%0,%1,%2\;mov.s\t%0,%0";
- else
- return "div.s\t%0,%1,%2";
-}
- [(set_attr "type" "fdiv")
- (set_attr "mode" "SF")
- (set (attr "length")
- (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
- (const_int 8)
- (const_int 4)))])
-
-;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
-;; "divdf3" comment for details).
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (div:DF (match_operand:DF 1 "const_1_operand" "")
- (match_operand:DF 2 "register_operand" "f")))]
- "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
+(define_insn "*div<mode>3"
+ [(set (match_operand:SCALARF 0 "register_operand" "=f")
+ (div:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
+ (match_operand:SCALARF 2 "register_operand" "f")))]
+ "<divide_condition>"
{
if (TARGET_FIX_SB1)
- return "recip.d\t%0,%2\;mov.d\t%0,%0";
+ return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
else
- return "recip.d\t%0,%2";
+ return "div.<fmt>\t%0,%1,%2";
}
- [(set_attr "type" "frdiv")
- (set_attr "mode" "DF")
+ [(set_attr "type" "fdiv")
+ (set_attr "mode" "<MODE>")
(set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8)
(const_int 4)))])
-;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
-;; "divdf3" comment for details).
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (div:SF (match_operand:SF 1 "const_1_operand" "")
- (match_operand:SF 2 "register_operand" "f")))]
- "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
+(define_insn "*recip<mode>3"
+ [(set (match_operand:SCALARF 0 "register_operand" "=f")
+ (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "")
+ (match_operand:SCALARF 2 "register_operand" "f")))]
+ "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
{
if (TARGET_FIX_SB1)
- return "recip.s\t%0,%2\;mov.s\t%0,%0";
+ return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
else
- return "recip.s\t%0,%2";
+ return "recip.<fmt>\t%0,%2";
}
- [(set_attr "type" "frdiv")
- (set_attr "mode" "SF")
+ [(set_attr "type" "frdiv")
+ (set_attr "mode" "<MODE>")
(set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8)
;;
;; ....................
-;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
-;; "divdf3" comment for details).
-(define_insn "sqrtdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
- "TARGET_HARD_FLOAT && HAVE_SQRT_P() && TARGET_DOUBLE_FLOAT"
-{
- if (TARGET_FIX_SB1)
- return "sqrt.d\t%0,%1\;mov.d\t%0,%0";
- else
- return "sqrt.d\t%0,%1";
-}
- [(set_attr "type" "fsqrt")
- (set_attr "mode" "DF")
- (set (attr "length")
- (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
- (const_int 8)
- (const_int 4)))])
-
-;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
-;; "divdf3" comment for details).
-(define_insn "sqrtsf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
- "TARGET_HARD_FLOAT && HAVE_SQRT_P()"
-{
- if (TARGET_FIX_SB1)
- return "sqrt.s\t%0,%1\;mov.s\t%0,%0";
- else
- return "sqrt.s\t%0,%1";
-}
- [(set_attr "type" "fsqrt")
- (set_attr "mode" "SF")
- (set (attr "length")
- (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
- (const_int 8)
- (const_int 4)))])
-
-;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
-;; "divdf3" comment for details).
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (div:DF (match_operand:DF 1 "const_1_operand" "")
- (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))]
- "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
-{
- if (TARGET_FIX_SB1)
- return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
- else
- return "rsqrt.d\t%0,%2";
-}
- [(set_attr "type" "frsqrt")
- (set_attr "mode" "DF")
- (set (attr "length")
- (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
- (const_int 8)
- (const_int 4)))])
+;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
+;; "*div[sd]f3" comment for details).
-;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
-;; "divdf3" comment for details).
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (div:SF (match_operand:SF 1 "const_1_operand" "")
- (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
- "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
+(define_insn "sqrt<mode>2"
+ [(set (match_operand:SCALARF 0 "register_operand" "=f")
+ (sqrt:SCALARF (match_operand:SCALARF 1 "register_operand" "f")))]
+ "HAVE_SQRT_P()"
{
if (TARGET_FIX_SB1)
- return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
+ return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
else
- return "rsqrt.s\t%0,%2";
+ return "sqrt.<fmt>\t%0,%1";
}
- [(set_attr "type" "frsqrt")
- (set_attr "mode" "SF")
+ [(set_attr "type" "fsqrt")
+ (set_attr "mode" "<MODE>")
(set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8)
(const_int 4)))])
-;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
-;; "divdf3" comment for details).
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (sqrt:DF (div:DF (match_operand:DF 1 "const_1_operand" "")
- (match_operand:DF 2 "register_operand" "f"))))]
- "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
+(define_insn "*rsqrt<mode>a"
+ [(set (match_operand:SCALARF 0 "register_operand" "=f")
+ (div:SCALARF
+ (match_operand:SCALARF 1 "const_1_operand" "")
+ (sqrt:SCALARF (match_operand:SCALARF 2 "register_operand" "f"))))]
+ "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
{
if (TARGET_FIX_SB1)
- return "rsqrt.d\t%0,%2\;mov.d\t%0,%0";
+ return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
else
- return "rsqrt.d\t%0,%2";
+ return "rsqrt.<fmt>\t%0,%2";
}
- [(set_attr "type" "frsqrt")
- (set_attr "mode" "DF")
+ [(set_attr "type" "frsqrt")
+ (set_attr "mode" "<MODE>")
(set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8)
(const_int 4)))])
-;; This pattern works around the early SB-1 rev2 core "F1" erratum (see
-;; "divdf3" comment for details).
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (sqrt:SF (div:SF (match_operand:SF 1 "const_1_operand" "")
- (match_operand:SF 2 "register_operand" "f"))))]
- "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
+(define_insn "*rsqrt<mode>b"
+ [(set (match_operand:SCALARF 0 "register_operand" "=f")
+ (sqrt:SCALARF
+ (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "")
+ (match_operand:SCALARF 2 "register_operand" "f"))))]
+ "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
{
if (TARGET_FIX_SB1)
- return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
+ return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
else
- return "rsqrt.s\t%0,%2";
+ return "rsqrt.<fmt>\t%0,%2";
}
- [(set_attr "type" "frsqrt")
- (set_attr "mode" "SF")
+ [(set_attr "type" "frsqrt")
+ (set_attr "mode" "<MODE>")
(set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8)