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:
parent
aae0609ca9
commit
93898c8bc4
@ -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.
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user