diff options
author | cgd <cgd@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-08-22 22:36:42 +0000 |
---|---|---|
committer | cgd <cgd@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-08-22 22:36:42 +0000 |
commit | aae4c6423e72f16322265cb00d61d44f27364efe (patch) | |
tree | 696b3199dad4763226cb2c4ca1d91a77a4c97568 /gcc/config | |
parent | ec64a609bf7f60b8d6c0329280df99fbe5d8ca6c (diff) |
2003-08-22 Chris Demetriou <cgd@broadcom.com>
* config/mips/mips.h (MASK_FIX_SB1, TARGET_FIX_SB1): New defines.
(TARGET_SWITCHES): Add -mfix-sb1 and -mno-fix-sb1.
* config/mips/mips.md (divdf3, divsf3, sqrtdf2, sqrtsf2): Work
around SB-1 errata if TARGET_FIX_SB1 is set.
(recip.d insn, recip.s insn, rsqrt.d insn, rsqrt.s insn): Likewise.
* doc/invoke.texi: Document MIPS -mfix-sb1 and -mno-fix-sb1.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@70707 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/mips/mips.h | 6 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 141 |
2 files changed, 130 insertions, 17 deletions
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 27a4a03eeb4..38aa9510487 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -170,6 +170,7 @@ extern const struct mips_cpu_info *mips_tune_info; #define MASK_UNINIT_CONST_IN_RODATA \ 0x00800000 /* Store uninitialized consts in rodata */ +#define MASK_FIX_SB1 0x01000000 /* Work around SB-1 errata. */ /* Debug switches, not documented */ #define MASK_DEBUG 0 /* unused */ @@ -255,6 +256,7 @@ extern const struct mips_cpu_info *mips_tune_info; #define TARGET_BRANCHLIKELY (target_flags & MASK_BRANCHLIKELY) +#define TARGET_FIX_SB1 (target_flags & MASK_FIX_SB1) /* True if we should use NewABI-style relocation operators for symbolic addresses. This is never true for mips16 code, @@ -580,6 +582,10 @@ extern const struct mips_cpu_info *mips_tune_info; N_("Work around early 4300 hardware bug")}, \ {"no-fix4300", -MASK_4300_MUL_FIX, \ N_("Don't work around early 4300 hardware bug")}, \ + {"fix-sb1", MASK_FIX_SB1, \ + N_("Work around errata for early SB-1 revision 2 cores")}, \ + {"no-fix-sb1", -MASK_FIX_SB1, \ + N_("Don't work around errata for early SB-1 revision 2 cores")}, \ {"check-zero-division",-MASK_NO_CHECK_ZERO_DIV, \ N_("Trap on integer divide by zero")}, \ {"no-check-zero-division", MASK_NO_CHECK_ZERO_DIV, \ diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 832140e409e..e843d53734c 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -2365,41 +2365,104 @@ ;; .................... ;; +;; This pattern works 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, +;; sqrt) iterates an intermediate result back through the floating +;; point register file bypass, then instead returning the correct +;; register value the mfc1 or dmfc1 operation returns the intermediate +;; result of the long latency operation. +;; +;; 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" - "div.d\t%0,%1,%2" +{ + 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 "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). +;; +;; 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_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" - "div.s\t%0,%1,%2" + "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 "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_float_1_operand" "") (match_operand:DF 2 "register_operand" "f")))] "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations" - "recip.d\t%0,%2" +{ + 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" "fdiv") - (set_attr "mode" "DF")]) + (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_float_1_operand" "") (match_operand:SF 2 "register_operand" "f")))] "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations" - "recip.s\t%0,%2" +{ + 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" "fdiv") - (set_attr "mode" "SF")]) + (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)))]) (define_insn "divmodsi4" [(set (match_operand:SI 0 "register_operand" "=l") @@ -2456,39 +2519,83 @@ ;; ;; .................... +;; 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" - "sqrt.d\t%0,%1" +{ + 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 "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()" - "sqrt.s\t%0,%1" +{ + 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 "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_float_1_operand" "") (sqrt:DF (match_operand:DF 2 "register_operand" "f"))))] "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && flag_unsafe_math_optimizations" - "rsqrt.d\t%0,%2" +{ + 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 "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_float_1_operand" "") (sqrt:SF (match_operand:SF 2 "register_operand" "f"))))] "ISA_HAS_FP4 && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations" - "rsqrt.s\t%0,%2" +{ + 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 "mode" "SF") + (set (attr "length") + (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) + (const_int 8) + (const_int 4)))]) ;; ;; .................... |