diff options
| author | uweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-07-21 17:15:22 +0000 |
|---|---|---|
| committer | uweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-07-21 17:15:22 +0000 |
| commit | b79906a3c99291824d12c57a9d0eda4ddbf560c8 (patch) | |
| tree | 13c5838936e557ce907e0853e8bd41a01ea10a6b /gcc | |
| parent | e88a1fbf6bb65809452216f99f9357c8d7a1c187 (diff) | |
| download | ppe42-gcc-b79906a3c99291824d12c57a9d0eda4ddbf560c8.tar.gz ppe42-gcc-b79906a3c99291824d12c57a9d0eda4ddbf560c8.zip | |
* config/spu/spu.md ("div<mode>3"): Convert into expander, move
original insn and splitter contents into ...
("*div<mode>3_fast"): ... this new pattern. Enable only if
flag_unsafe_math_optimizations. Add dummy scratch register.
("*div<mode>3_adjusted"): New insn and splitter. Enable only if
!flag_unsafe_math_optimizations. Returns number with next
highest magnitude if this is still less or equal to the true
quotient in magnitude.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@138036 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/ChangeLog | 11 | ||||
| -rw-r--r-- | gcc/config/spu/spu.md | 65 |
2 files changed, 72 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 02675347322..4838ebe83be 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2008-07-21 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * config/spu/spu.md ("div<mode>3"): Convert into expander, move + original insn and splitter contents into ... + ("*div<mode>3_fast"): ... this new pattern. Enable only if + flag_unsafe_math_optimizations. Add dummy scratch register. + ("*div<mode>3_adjusted"): New insn and splitter. Enable only if + !flag_unsafe_math_optimizations. Returns number with next + highest magnitude if this is still less or equal to the true + quotient in magnitude. + 2008-07-21 Rafael Avila de Espindola <espindola@google.com> * Makefile.in: Replace toplev.h with TOPLEV_H. diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md index 6985a683697..c267efd29d1 100644 --- a/gcc/config/spu/spu.md +++ b/gcc/config/spu/spu.md @@ -1721,20 +1721,33 @@ [(set_attr "type" "multi0") (set_attr "length" "80")]) -(define_insn_and_split "div<mode>3" +(define_expand "div<mode>3" + [(parallel + [(set (match_operand:VSF 0 "spu_reg_operand" "") + (div:VSF (match_operand:VSF 1 "spu_reg_operand" "") + (match_operand:VSF 2 "spu_reg_operand" ""))) + (clobber (match_scratch:VSF 3 "")) + (clobber (match_scratch:VSF 4 "")) + (clobber (match_scratch:VSF 5 ""))])] + "" + "") + +(define_insn_and_split "*div<mode>3_fast" [(set (match_operand:VSF 0 "spu_reg_operand" "=r") (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r") (match_operand:VSF 2 "spu_reg_operand" "r"))) (clobber (match_scratch:VSF 3 "=&r")) - (clobber (match_scratch:VSF 4 "=&r"))] - "" + (clobber (match_scratch:VSF 4 "=&r")) + (clobber (scratch:VSF))] + "flag_unsafe_math_optimizations" "#" "reload_completed" [(set (match_dup:VSF 0) (div:VSF (match_dup:VSF 1) (match_dup:VSF 2))) (clobber (match_dup:VSF 3)) - (clobber (match_dup:VSF 4))] + (clobber (match_dup:VSF 4)) + (clobber (scratch:VSF))] { emit_insn (gen_frest_<mode>(operands[3], operands[2])); emit_insn (gen_fi_<mode>(operands[3], operands[2], operands[3])); @@ -1744,6 +1757,50 @@ DONE; }) +(define_insn_and_split "*div<mode>3_adjusted" + [(set (match_operand:VSF 0 "spu_reg_operand" "=r") + (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r") + (match_operand:VSF 2 "spu_reg_operand" "r"))) + (clobber (match_scratch:VSF 3 "=&r")) + (clobber (match_scratch:VSF 4 "=&r")) + (clobber (match_scratch:VSF 5 "=&r"))] + "!flag_unsafe_math_optimizations" + "#" + "reload_completed" + [(set (match_dup:VSF 0) + (div:VSF (match_dup:VSF 1) + (match_dup:VSF 2))) + (clobber (match_dup:VSF 3)) + (clobber (match_dup:VSF 4)) + (clobber (match_dup:VSF 5))] + { + emit_insn (gen_frest_<mode> (operands[3], operands[2])); + emit_insn (gen_fi_<mode> (operands[3], operands[2], operands[3])); + emit_insn (gen_mul<mode>3 (operands[4], operands[1], operands[3])); + emit_insn (gen_fnms_<mode> (operands[5], operands[4], operands[2], operands[1])); + emit_insn (gen_fma_<mode> (operands[3], operands[5], operands[3], operands[4])); + + /* Due to truncation error, the quotient result may be low by 1 ulp. + Conditionally add one if the estimate is too small in magnitude. */ + + emit_move_insn (gen_lowpart (<F2I>mode, operands[4]), + spu_const (<F2I>mode, 0x80000000ULL)); + emit_move_insn (gen_lowpart (<F2I>mode, operands[5]), + spu_const (<F2I>mode, 0x3f800000ULL)); + emit_insn (gen_selb (operands[5], operands[5], operands[1], operands[4])); + + emit_insn (gen_add<f2i>3 (gen_lowpart (<F2I>mode, operands[4]), + gen_lowpart (<F2I>mode, operands[3]), + spu_const (<F2I>mode, 1))); + emit_insn (gen_fnms_<mode> (operands[0], operands[2], operands[4], operands[1])); + emit_insn (gen_mul<mode>3 (operands[0], operands[0], operands[5])); + emit_insn (gen_cgt_<f2i> (gen_lowpart (<F2I>mode, operands[0]), + gen_lowpart (<F2I>mode, operands[0]), + spu_const (<F2I>mode, -1))); + emit_insn (gen_selb (operands[0], operands[3], operands[4], operands[0])); + DONE; + }) + ;; Taken from STI's gcc ;; Does not correctly handle INF or NAN. (define_expand "divdf3" |

