diff mbox

[05/10] mips: Support vec_unpack[su] for Loongson.

Message ID 1324486822-18225-6-git-send-email-rth@redhat.com
State New
Headers show

Commit Message

Richard Henderson Dec. 21, 2011, 5 p.m. UTC
---
 gcc/config/mips/loongson.md   |   36 ++++++++++++++++++++++++++++++++
 gcc/config/mips/mips-protos.h |    1 +
 gcc/config/mips/mips.c        |   45 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 0 deletions(-)
diff mbox

Patch

diff --git a/gcc/config/mips/loongson.md b/gcc/config/mips/loongson.md
index 325838d..8404bf0 100644
--- a/gcc/config/mips/loongson.md
+++ b/gcc/config/mips/loongson.md
@@ -643,6 +643,42 @@ 
     FAIL;
 })
 
+(define_expand "vec_unpacks_lo_<mode>"
+  [(match_operand:<V_stretch_half> 0 "register_operand" "")
+   (match_operand:VHB 1 "register_operand" "")]
+  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
+{
+  mips_expand_vec_unpack (operands, false, false);
+  DONE;
+})
+
+(define_expand "vec_unpacks_hi_<mode>"
+  [(match_operand:<V_stretch_half> 0 "register_operand" "")
+   (match_operand:VHB 1 "register_operand" "")]
+  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
+{
+  mips_expand_vec_unpack (operands, false, true);
+  DONE;
+})
+
+(define_expand "vec_unpacku_lo_<mode>"
+  [(match_operand:<V_stretch_half> 0 "register_operand" "")
+   (match_operand:VHB 1 "register_operand" "")]
+  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
+{
+  mips_expand_vec_unpack (operands, true, false);
+  DONE;
+})
+
+(define_expand "vec_unpacku_hi_<mode>"
+  [(match_operand:<V_stretch_half> 0 "register_operand" "")
+   (match_operand:VHB 1 "register_operand" "")]
+  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
+{
+  mips_expand_vec_unpack (operands, true, true);
+  DONE;
+})
+
 ;; Integer division and modulus.  For integer multiplication, see mips.md.
 
 (define_insn "<u>div<mode>3"
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 37c958d..82c8c33 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -329,6 +329,7 @@  extern void mips_expand_atomic_qihi (union mips_gen_fn_ptrs,
 
 extern void mips_expand_vector_init (rtx, rtx);
 extern bool mips_expand_vec_perm_const (rtx op[4]);
+extern void mips_expand_vec_unpack (rtx op[2], bool, bool);
 
 extern bool mips_eh_uses (unsigned int);
 extern bool mips_epilogue_uses (unsigned int);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 0ac1096..b3a3ad0 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -16611,6 +16611,51 @@  mips_vectorize_vec_perm_const_ok (enum machine_mode vmode,
 
   return ret;
 }
+
+/* Expand an integral vector unpack operation.  */
+
+void
+mips_expand_vec_unpack (rtx operands[2], bool unsigned_p, bool high_p)
+{
+  enum machine_mode imode = GET_MODE (operands[1]);
+  rtx (*unpack) (rtx, rtx, rtx);
+  rtx (*cmpgt) (rtx, rtx, rtx);
+  rtx tmp, dest, zero;
+
+  switch (imode)
+    {
+    case V8QImode:
+      if (high_p)
+	unpack = gen_loongson_punpckhbh;
+      else
+	unpack = gen_loongson_punpcklbh;
+      cmpgt = gen_loongson_pcmpgtb;
+      break;
+    case V4HImode:
+      if (high_p)
+	unpack = gen_loongson_punpckhhw;
+      else
+	unpack = gen_loongson_punpcklhw;
+      cmpgt = gen_loongson_pcmpgth;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  zero = force_reg (imode, CONST0_RTX (imode));
+  if (unsigned_p)
+    tmp = zero;
+  else
+    {
+      tmp = gen_reg_rtx (imode);
+      emit_insn (cmpgt (tmp, zero, operands[1]));
+    }
+
+  dest = gen_reg_rtx (imode);
+  emit_insn (unpack (dest, operands[1], tmp));
+
+  emit_move_insn (operands[0], gen_lowpart (GET_MODE (operands[0]), dest));
+}
 
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP