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
This commit is contained in:
Richard Sandiford 2004-08-29 11:54:33 +00:00 committed by Richard Sandiford
parent aae0609ca9
commit 93898c8bc4
2 changed files with 75 additions and 182 deletions

View File

@ -1,3 +1,11 @@
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.

View File

@ -399,6 +399,16 @@
;; 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
@ -1705,18 +1715,18 @@
;; ....................
;;
(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,
@ -1728,102 +1738,37 @@
;; 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"
(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 "div.d\t%0,%1,%2\;mov.d\t%0,%0";
return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0";
else
return "div.d\t%0,%1,%2";
return "div.<fmt>\t%0,%1,%2";
}
[(set_attr "type" "fdiv")
(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 "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)"
(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 "div.s\t%0,%1,%2\;mov.s\t%0,%0";
return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
else
return "div.s\t%0,%1,%2";
return "recip.<fmt>\t%0,%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)
return "recip.d\t%0,%2\;mov.d\t%0,%0";
else
return "recip.d\t%0,%2";
}
[(set_attr "type" "frdiv")
(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 ""
[(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"
{
if (TARGET_FIX_SB1)
return "recip.s\t%0,%2\;mov.s\t%0,%0";
else
return "recip.s\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)
@ -1862,119 +1807,59 @@
;;
;; ....................
;; 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"
;; These patterns work around the early SB-1 rev2 core "F1" erratum (see
;; "*div[sd]f3" comment for details).
(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 "sqrt.d\t%0,%1\;mov.d\t%0,%0";
return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0";
else
return "sqrt.d\t%0,%1";
return "sqrt.<fmt>\t%0,%1";
}
[(set_attr "type" "fsqrt")
(set_attr "mode" "DF")
[(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 "sqrtsf2"
[(set (match_operand:SF 0 "register_operand" "=f")
(sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT && HAVE_SQRT_P()"
(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 "sqrt.s\t%0,%1\;mov.s\t%0,%0";
return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0";
else
return "sqrt.s\t%0,%1";
return "rsqrt.<fmt>\t%0,%2";
}
[(set_attr "type" "fsqrt")
(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)
(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"
(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.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 "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" "")
(sqrt:SF (match_operand:SF 2 "register_operand" "f"))))]
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
{
if (TARGET_FIX_SB1)
return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
else
return "rsqrt.s\t%0,%2";
}
[(set_attr "type" "frsqrt")
(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")
(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"
{
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
;; "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"
{
if (TARGET_FIX_SB1)
return "rsqrt.s\t%0,%2\;mov.s\t%0,%0";
else
return "rsqrt.s\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)