From b70a541a5230a0e4ff04dda5f0a4c8c2dfdf6a9e Mon Sep 17 00:00:00 2001 From: rsandifo Date: Sun, 29 Aug 2004 11:54:33 +0000 Subject: [PATCH] * 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[ab]): Likewise. Name formerly unnamed patterns. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@86721 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++ gcc/config/mips/mips.md | 247 +++++++++++++----------------------------------- 2 files changed, 74 insertions(+), 181 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b4f7b5f1785..bcfbc0b9dbd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2004-08-29 Richard Sandiford + * 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[ab]): Likewise. Name formerly unnamed + patterns. + +2004-08-29 Richard Sandiford + * config/mips/mips.md (ANYF, SCALARF): New mode macros. (loadx, storex, fmt, UNITMODE): New mode attributes. (add{sf,df,v2sf}3, sub{sf,df,v2sf}3): Redefine using :ANYF. diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index b1357e0fbbd..3e220d07d96 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -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 "div3" + [(set (match_operand:SCALARF 0 "register_operand") + (div:SCALARF (match_operand:SCALARF 1 "reg_or_1_operand") + (match_operand:SCALARF 2 "register_operand")))] + "" { - if (const_1_operand (operands[1], DFmode)) + if (const_1_operand (operands[1], mode)) if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations)) - operands[1] = force_reg (DFmode, operands[1]); + operands[1] = force_reg (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" -{ - 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 "*div3" + [(set (match_operand:SCALARF 0 "register_operand" "=f") + (div:SCALARF (match_operand:SCALARF 1 "register_operand" "f") + (match_operand:SCALARF 2 "register_operand" "f")))] + "" { if (TARGET_FIX_SB1) - return "recip.d\t%0,%2\;mov.d\t%0,%0"; + return "div.\t%0,%1,%2\;mov.\t%0,%0"; else - return "recip.d\t%0,%2"; + return "div.\t%0,%1,%2"; } - [(set_attr "type" "frdiv") - (set_attr "mode" "DF") + [(set_attr "type" "fdiv") + (set_attr "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 "*recip3" + [(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.\t%0,%2\;mov.\t%0,%0"; else - return "recip.s\t%0,%2"; + return "recip.\t%0,%2"; } - [(set_attr "type" "frdiv") - (set_attr "mode" "SF") + [(set_attr "type" "frdiv") + (set_attr "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" -{ - 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 "sqrt2" + [(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.\t%0,%1\;mov.\t%0,%0"; else - return "rsqrt.s\t%0,%2"; + return "sqrt.\t%0,%1"; } - [(set_attr "type" "frsqrt") - (set_attr "mode" "SF") + [(set_attr "type" "fsqrt") + (set_attr "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 "*rsqrta" + [(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.\t%0,%2\;mov.\t%0,%0"; else - return "rsqrt.d\t%0,%2"; + return "rsqrt.\t%0,%2"; } - [(set_attr "type" "frsqrt") - (set_attr "mode" "DF") + [(set_attr "type" "frsqrt") + (set_attr "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 "*rsqrtb" + [(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.\t%0,%2\;mov.\t%0,%0"; else - return "rsqrt.s\t%0,%2"; + return "rsqrt.\t%0,%2"; } - [(set_attr "type" "frsqrt") - (set_attr "mode" "SF") + [(set_attr "type" "frsqrt") + (set_attr "mode" "") (set (attr "length") (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) (const_int 8) -- 2.11.4.GIT