diff options
author | Richard Henderson <rth@redhat.com> | 2005-06-18 15:40:49 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2005-06-18 15:40:49 -0700 |
commit | 2ab1754e1b62ca791c3953713e903750e687cb42 (patch) | |
tree | dcddf82de060145d58d4f0b5d0d26c24cbcedd8b | |
parent | 55d4549de80fcfc37d9c8cbafcbf3b8f1d3d82ae (diff) | |
download | gcc-2ab1754e1b62ca791c3953713e903750e687cb42.zip gcc-2ab1754e1b62ca791c3953713e903750e687cb42.tar.gz gcc-2ab1754e1b62ca791c3953713e903750e687cb42.tar.bz2 |
expr.c (store_constructor): Use store of 0 to indicate value death instead of a clobber.
* expr.c (store_constructor): Use store of 0 to indicate value
death instead of a clobber.
* config/i386/i386.c (ix86_expand_reduc_v4sf): New.
* config/i386/i386-protos.h (ix86_expand_reduc_v4sf): Declare.
* config/i386/sse.md (reduc_plus_v4sf): New.
(reduc_smax_v4sf, reduc_smin_v4sf): New.
From-SVN: r101169
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/i386/i386-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 21 | ||||
-rw-r--r-- | gcc/config/i386/sse.md | 34 | ||||
-rw-r--r-- | gcc/expr.c | 4 |
5 files changed, 68 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6e03eef..67db590 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2005-06-18 Richard Henderson <rth@redhat.com> + + * expr.c (store_constructor): Use store of 0 to indicate value + death instead of a clobber. + + * config/i386/i386.c (ix86_expand_reduc_v4sf): New. + * config/i386/i386-protos.h (ix86_expand_reduc_v4sf): Declare. + * config/i386/sse.md (reduc_plus_v4sf): New. + (reduc_smax_v4sf, reduc_smin_v4sf): New. + 2005-06-18 James A. Morrison <phython@gcc.gnu.org> * fold_const (fold_binary): Fold X % (2**N) to X & (2**N - 1) for diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 142eb5a..2dc0f45 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -230,6 +230,7 @@ extern rtx ix86_tls_get_addr (void); extern void ix86_expand_vector_init (bool, rtx, rtx); extern void ix86_expand_vector_set (bool, rtx, rtx, int); extern void ix86_expand_vector_extract (bool, rtx, rtx, int); +extern void ix86_expand_reduc_v4sf (rtx (*)(rtx, rtx, rtx), rtx, rtx); /* In winnt.c */ extern int i386_pe_dllexport_name_p (const char *); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 781daee..6a5dbdf 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -17366,6 +17366,27 @@ ix86_expand_vector_extract (bool mmx_ok, rtx target, rtx vec, int elt) emit_move_insn (target, tmp); } } + +/* Expand a vector reduction on V4SFmode for SSE1. FN is the binar + pattern to reduce; DEST is the destination; IN is the input vector. */ + +void +ix86_expand_reduc_v4sf (rtx (*fn) (rtx, rtx, rtx), rtx dest, rtx in) +{ + rtx tmp1, tmp2, tmp3; + + tmp1 = gen_reg_rtx (V4SFmode); + tmp2 = gen_reg_rtx (V4SFmode); + tmp3 = gen_reg_rtx (V4SFmode); + + emit_insn (gen_sse_movhlps (tmp1, in, in)); + emit_insn (fn (tmp2, tmp1, in)); + + emit_insn (gen_sse_shufps_1 (tmp3, tmp2, tmp2, + GEN_INT (1), GEN_INT (1), + GEN_INT (1+4), GEN_INT (1+4))); + emit_insn (fn (dest, tmp2, tmp3)); +} /* Implements target hook vector_mode_supported_p. */ static bool diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 48b6cde..e323937 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -653,6 +653,40 @@ [(set_attr "type" "sseadd") (set_attr "mode" "V4SF")]) +(define_expand "reduc_plus_v4sf" + [(match_operand:V4SF 0 "register_operand" "") + (match_operand:V4SF 1 "register_operand" "")] + "TARGET_SSE" +{ + if (TARGET_SSE3) + { + rtx tmp = gen_reg_rtx (V4SFmode); + emit_insn (gen_sse3_haddv4sf3 (tmp, operands[1], operands[1])); + emit_insn (gen_sse3_haddv4sf3 (operands[0], tmp, tmp)); + } + else + ix86_expand_reduc_v4sf (gen_addv4sf3, operands[0], operands[1]); + DONE; +}) + +(define_expand "reduc_smax_v4sf" + [(match_operand:V4SF 0 "register_operand" "") + (match_operand:V4SF 1 "register_operand" "")] + "TARGET_SSE" +{ + ix86_expand_reduc_v4sf (gen_smaxv4sf3, operands[0], operands[1]); + DONE; +}) + +(define_expand "reduc_smin_v4sf" + [(match_operand:V4SF 0 "register_operand" "") + (match_operand:V4SF 1 "register_operand" "")] + "TARGET_SSE" +{ + ix86_expand_reduc_v4sf (gen_sminv4sf3, operands[0], operands[1]); + DONE; +}) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Parallel single-precision floating point comparisons @@ -5151,9 +5151,9 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size) cleared = 1; } + /* Inform later passes that the old value is dead. */ if (!cleared && REG_P (target)) - /* Inform later passes that the old value is dead. */ - emit_insn (gen_rtx_CLOBBER (VOIDmode, target)); + emit_move_insn (target, CONST0_RTX (GET_MODE (target))); /* Store each element of the constructor into the corresponding element of TARGET, determined by counting the elements. */ |