Patchwork Add vcond/vcondu patterns to sparc backend.

login
register
mail settings
Submitter David Miller
Date Nov. 1, 2011, 8:48 a.m.
Message ID <20111101.044842.1200588465165112031.davem@davemloft.net>
Download mbox | patch
Permalink /patch/123042/
State New
Headers show

Comments

David Miller - Nov. 1, 2011, 8:48 a.m.
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(-)

Patch

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  <davem@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  <aoliva@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")