I really wanted to make this work using the define_expand rtl to
generate the pattern, but I ran into two problems:

1) In addition to mode "GCM", we also need to iterate over "P" mode
   for the sake of the rtl of fpcmp and cmask.  So we'd get dups in
   the insn output files.

2) I couldn't substitute the mode attribute "<gcm_name>" into the
   cmask unspec code.  ie. UNSPEC_CMASK<gcm_name> didn't work.

Anyways, at least there is one expander function shared between the
signed and unsigned cases.

Committed to trunk.

gcc/

        * config/sparc/sparc.c (sparc_expand_vcond): New function.
        * config/sparc/sparc-protos.h (sparc_expand_vcond): Declare it.
        * config/sparc/sparc.md (vcond<mode><mode>): New VIS3 expander.
        (vconduv8qiv8qi): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180733 
138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                   |    7 +++++++
 gcc/config/sparc/sparc-protos.h |    1 +
 gcc/config/sparc/sparc.c        |   37 +++++++++++++++++++++++++++++++++++++
 gcc/config/sparc/sparc.md       |   30 ++++++++++++++++++++++++++++++
 4 files changed, 75 insertions(+), 0 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d5f725b..d6a9c4d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2011-11-01  David S. Miller  <da...@davemloft.net>
+
+       * config/sparc/sparc.c (sparc_expand_vcond): New function.
+       * config/sparc/sparc-protos.h (sparc_expand_vcond): Declare it.
+       * config/sparc/sparc.md (vcond<mode><mode>): New VIS3 expander.
+       (vconduv8qiv8qi): Likewise.
+
 2011-11-01  Alexandre Oliva  <aol...@redhat.com>
 
        PR debug/50869
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index 108e105..b9a094e 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -108,6 +108,7 @@ extern const char *output_v8plus_mult (rtx, rtx *, const 
char *);
 extern void sparc_expand_vector_init (rtx, rtx);
 extern void sparc_expand_vec_perm_bmask(enum machine_mode, rtx);
 extern bool sparc_expand_conditional_move (enum machine_mode, rtx *);
+extern void sparc_expand_vcond (enum machine_mode, rtx *, int, int);
 #endif /* RTX_CODE */
 
 #endif /* __SPARC_PROTOS_H__ */
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index fd1b190..6431405 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -11531,4 +11531,41 @@ sparc_expand_conditional_move (enum machine_mode mode, 
rtx *operands)
   return true;
 }
 
+void
+sparc_expand_vcond (enum machine_mode mode, rtx *operands, int ccode, int 
fcode)
+{
+  rtx mask, cop0, cop1, fcmp, cmask, bshuf, gsr;
+  enum rtx_code code = GET_CODE (operands[3]);
+
+  mask = gen_reg_rtx (Pmode);
+  cop0 = operands[4];
+  cop1 = operands[5];
+  if (code == LT || code == GE)
+    {
+      rtx t;
+
+      code = swap_condition (code);
+      t = cop0; cop0 = cop1; cop1 = t;
+    }
+
+  gsr = gen_rtx_REG (DImode, SPARC_GSR_REG);
+
+  fcmp = gen_rtx_UNSPEC (Pmode,
+                        gen_rtvec (1, gen_rtx_fmt_ee (code, mode, cop0, cop1)),
+                        fcode);
+
+  cmask = gen_rtx_UNSPEC (DImode,
+                         gen_rtvec (2, mask, gsr),
+                         ccode);
+
+  bshuf = gen_rtx_UNSPEC (mode,
+                         gen_rtvec (3, operands[1], operands[2], gsr),
+                         UNSPEC_BSHUFFLE);
+
+  emit_insn (gen_rtx_SET (VOIDmode, mask, fcmp));
+  emit_insn (gen_rtx_SET (VOIDmode, gsr, cmask));
+
+  emit_insn (gen_rtx_SET (VOIDmode, operands[0], bshuf));
+}
+
 #include "gt-sparc.h"
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index fbd1a87..5924403 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -8299,6 +8299,36 @@
   [(set_attr "type" "fpmul")
    (set_attr "fptype" "double")])
 
+(define_expand "vcond<mode><mode>"
+  [(match_operand:GCM 0 "register_operand" "")
+   (match_operand:GCM 1 "register_operand" "")
+   (match_operand:GCM 2 "register_operand" "")
+   (match_operator 3 ""
+     [(match_operand:GCM 4 "register_operand" "")
+      (match_operand:GCM 5 "register_operand" "")])]
+  "TARGET_VIS3"
+{
+  sparc_expand_vcond (<MODE>mode, operands,
+                      UNSPEC_CMASK<gcm_name>,
+                      UNSPEC_FCMP);
+  DONE;
+})
+
+(define_expand "vconduv8qiv8qi"
+  [(match_operand:V8QI 0 "register_operand" "")
+   (match_operand:V8QI 1 "register_operand" "")
+   (match_operand:V8QI 2 "register_operand" "")
+   (match_operator 3 ""
+     [(match_operand:V8QI 4 "register_operand" "")
+      (match_operand:V8QI 5 "register_operand" "")])]
+  "TARGET_VIS3"
+{
+  sparc_expand_vcond (V8QImode, operands,
+                      UNSPEC_CMASK8,
+                      UNSPEC_FUCMP);
+  DONE;
+})
+
 (define_insn "array8<P:mode>_vis"
   [(set (match_operand:P 0 "register_operand" "=r")
         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
-- 
1.7.6.401.g6a319

Reply via email to