Commit 93898c8b by Richard Sandiford Committed by Richard Sandiford

mips.md (divide_condition): New mode attribute.

	* config/mips/mips.md (divide_condition): New mode attribute.
	(div[sd]f3, *div[sd]f3): Use it.  Redefine using :SCALARF.
	(sqrt[sd]f3): Redefine using SCALARF.
	(*recip[sd]f3, *rsqrt<mode>[ab]): Likewise.  Name formerly unnamed
	patterns.

From-SVN: r86721
parent aae0609c
2004-08-29 Richard Sandiford <rsandifo@redhat.com> 2004-08-29 Richard Sandiford <rsandifo@redhat.com>
* config/mips/mips.md (divide_condition): New mode attribute.
(div[sd]f3, *div[sd]f3): Use it. Redefine using :SCALARF.
(sqrt[sd]f3): Redefine using SCALARF.
(*recip[sd]f3, *rsqrt<mode>[ab]): Likewise. Name formerly unnamed
patterns.
2004-08-29 Richard Sandiford <rsandifo@redhat.com>
* config/mips/mips.md (ANYF, SCALARF): New mode macros. * config/mips/mips.md (ANYF, SCALARF): New mode macros.
(loadx, storex, fmt, UNITMODE): New mode attributes. (loadx, storex, fmt, UNITMODE): New mode attributes.
(add{sf,df,v2sf}3, sub{sf,df,v2sf}3): Redefine using :ANYF. (add{sf,df,v2sf}3, sub{sf,df,v2sf}3): Redefine using :ANYF.
......
...@@ -399,6 +399,16 @@ ...@@ -399,6 +399,16 @@
;; floating-point mode. ;; floating-point mode.
(define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")]) (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 ;; This code macro allows all branch instructions to be generated from
;; a single define_expand template. ;; a single define_expand template.
(define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt (define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt
...@@ -1705,18 +1715,18 @@ ...@@ -1705,18 +1715,18 @@
;; .................... ;; ....................
;; ;;
(define_expand "divdf3" (define_expand "div<mode>3"
[(set (match_operand:DF 0 "register_operand") [(set (match_operand:SCALARF 0 "register_operand")
(div:DF (match_operand:DF 1 "reg_or_1_operand") (div:SCALARF (match_operand:SCALARF 1 "reg_or_1_operand")
(match_operand:DF 2 "register_operand")))] (match_operand:SCALARF 2 "register_operand")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" "<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)) 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 ;; If an mfc1 or dmfc1 happens to access the floating point register
;; file at the same time a long latency operation (div, sqrt, recip, ;; file at the same time a long latency operation (div, sqrt, recip,
...@@ -1728,102 +1738,37 @@ ...@@ -1728,102 +1738,37 @@
;; The workaround is to insert an unconditional 'mov' from/to the ;; The workaround is to insert an unconditional 'mov' from/to the
;; long latency op destination register. ;; long latency op destination register.
(define_insn "*divdf3" (define_insn "*div<mode>3"
[(set (match_operand:DF 0 "register_operand" "=f") [(set (match_operand:SCALARF 0 "register_operand" "=f")
(div:DF (match_operand:DF 1 "register_operand" "f") (div:SCALARF (match_operand:SCALARF 1 "register_operand" "f")
(match_operand:DF 2 "register_operand" "f")))] (match_operand:SCALARF 2 "register_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" "<divide_condition>"
{
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"
{ {
if (TARGET_FIX_SB1) 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 else
return "recip.d\t%0,%2"; return "div.<fmt>\t%0,%1,%2";
} }
[(set_attr "type" "frdiv") [(set_attr "type" "fdiv")
(set_attr "mode" "DF") (set_attr "mode" "<MODE>")
(set (attr "length") (set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8) (const_int 8)
(const_int 4)))]) (const_int 4)))])
;; This pattern works around the early SB-1 rev2 core "F1" erratum (see (define_insn "*recip<mode>3"
;; "divdf3" comment for details). [(set (match_operand:SCALARF 0 "register_operand" "=f")
(define_insn "" (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "")
[(set (match_operand:SF 0 "register_operand" "=f") (match_operand:SCALARF 2 "register_operand" "f")))]
(div:SF (match_operand:SF 1 "const_1_operand" "") "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
(match_operand:SF 2 "register_operand" "f")))]
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
{ {
if (TARGET_FIX_SB1) 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 else
return "recip.s\t%0,%2"; return "recip.<fmt>\t%0,%2";
} }
[(set_attr "type" "frdiv") [(set_attr "type" "frdiv")
(set_attr "mode" "SF") (set_attr "mode" "<MODE>")
(set (attr "length") (set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8) (const_int 8)
...@@ -1862,119 +1807,59 @@ ...@@ -1862,119 +1807,59 @@
;; ;;
;; .................... ;; ....................
;; This pattern works around the early SB-1 rev2 core "F1" erratum (see ;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
;; "divdf3" comment for details). ;; "*div[sd]f3" 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)))])
;; This pattern works around the early SB-1 rev2 core "F1" erratum (see (define_insn "sqrt<mode>2"
;; "divdf3" comment for details). [(set (match_operand:SCALARF 0 "register_operand" "=f")
(define_insn "" (sqrt:SCALARF (match_operand:SCALARF 1 "register_operand" "f")))]
[(set (match_operand:SF 0 "register_operand" "=f") "HAVE_SQRT_P()"
(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"
{ {
if (TARGET_FIX_SB1) 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 else
return "rsqrt.s\t%0,%2"; return "sqrt.<fmt>\t%0,%1";
} }
[(set_attr "type" "frsqrt") [(set_attr "type" "fsqrt")
(set_attr "mode" "SF") (set_attr "mode" "<MODE>")
(set (attr "length") (set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8) (const_int 8)
(const_int 4)))]) (const_int 4)))])
;; This pattern works around the early SB-1 rev2 core "F1" erratum (see (define_insn "*rsqrt<mode>a"
;; "divdf3" comment for details). [(set (match_operand:SCALARF 0 "register_operand" "=f")
(define_insn "" (div:SCALARF
[(set (match_operand:DF 0 "register_operand" "=f") (match_operand:SCALARF 1 "const_1_operand" "")
(sqrt:DF (div:DF (match_operand:DF 1 "const_1_operand" "") (sqrt:SCALARF (match_operand:SCALARF 2 "register_operand" "f"))))]
(match_operand:DF 2 "register_operand" "f"))))] "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations"
{ {
if (TARGET_FIX_SB1) 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 else
return "rsqrt.d\t%0,%2"; return "rsqrt.<fmt>\t%0,%2";
} }
[(set_attr "type" "frsqrt") [(set_attr "type" "frsqrt")
(set_attr "mode" "DF") (set_attr "mode" "<MODE>")
(set (attr "length") (set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8) (const_int 8)
(const_int 4)))]) (const_int 4)))])
;; This pattern works around the early SB-1 rev2 core "F1" erratum (see (define_insn "*rsqrt<mode>b"
;; "divdf3" comment for details). [(set (match_operand:SCALARF 0 "register_operand" "=f")
(define_insn "" (sqrt:SCALARF
[(set (match_operand:SF 0 "register_operand" "=f") (div:SCALARF (match_operand:SCALARF 1 "const_1_operand" "")
(sqrt:SF (div:SF (match_operand:SF 1 "const_1_operand" "") (match_operand:SCALARF 2 "register_operand" "f"))))]
(match_operand:SF 2 "register_operand" "f"))))] "ISA_HAS_FP4 && flag_unsafe_math_optimizations"
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
{ {
if (TARGET_FIX_SB1) 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 else
return "rsqrt.s\t%0,%2"; return "rsqrt.<fmt>\t%0,%2";
} }
[(set_attr "type" "frsqrt") [(set_attr "type" "frsqrt")
(set_attr "mode" "SF") (set_attr "mode" "<MODE>")
(set (attr "length") (set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0))
(const_int 8) (const_int 8)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment