[AArch64] Implement <su><maxmin>v2di3 pattern
authorRenlin Li <renlin.li@arm.com>
Wed, 19 Nov 2014 16:34:38 +0000 (16:34 +0000)
committerRenlin Li <renlin@gcc.gnu.org>
Wed, 19 Nov 2014 16:34:38 +0000 (16:34 +0000)
gcc/:
        PR target/63424
        * config/aarch64/aarch64-simd.md (<su><maxmin>v2di3): New.

gcc/testsuite/:
        PR target/63424
        * gcc.target/aarch64/pr63424.c: New test.

From-SVN: r217786

gcc/ChangeLog
gcc/config/aarch64/aarch64-simd.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/pr63424.c [new file with mode: 0644]

index aeb8fadd94694a6bc114f99e8c470de77a87309e..d7a687a1eedaf6071881a41756e1b871849739dc 100644 (file)
@@ -3,6 +3,11 @@
        * config/rs6000/constraints.md: Avoid signed integer overflows.
        * config/rs6000/predicates.md: Likewise.
 
+2014-11-19  Renlin Li  <Renlin.Li@arm.com>
+
+    PR target/63424
+       * config/aarch64/aarch64-simd.md (<su><maxmin>v2di3): New.
+
 2014-11-19  Renlin Li  <Renlin.Li@arm.com>
 
     PR middle-end/63762
index 43bfec95702d8becdd9ae43f5561d92f6f306e77..2e71cb957d721b31608ba4bf1f5c1e19487d5f08 100644 (file)
   [(set_attr "type" "neon_minmax<q>")]
 )
 
+(define_expand "<su><maxmin>v2di3"
+ [(set (match_operand:V2DI 0 "register_operand" "")
+       (MAXMIN:V2DI (match_operand:V2DI 1 "register_operand" "")
+                    (match_operand:V2DI 2 "register_operand" "")))]
+ "TARGET_SIMD"
+{
+  enum rtx_code cmp_operator;
+  rtx cmp_fmt;
+
+  switch (<CODE>)
+    {
+    case UMIN:
+      cmp_operator = LTU;
+      break;
+    case SMIN:
+      cmp_operator = LT;
+      break;
+    case UMAX:
+      cmp_operator = GTU;
+      break;
+    case SMAX:
+      cmp_operator = GT;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  cmp_fmt = gen_rtx_fmt_ee (cmp_operator, V2DImode, operands[1], operands[2]);
+  emit_insn (gen_aarch64_vcond_internalv2div2di (operands[0], operands[1],
+              operands[2], cmp_fmt, operands[1], operands[2]));
+  DONE;
+})
+
 ;; vec_concat gives a new vector with the low elements from operand 1, and
 ;; the high elements from operand 2.  That is to say, given op1 = { a, b }
 ;; op2 = { c, d }, vec_concat (op1, op2) = { a, b, c, d }.
index f5fb9db873f610b9a2f92588c595e4c880565d22..840a1c14d140b8e57191f3156ff92c8214f79497 100644 (file)
@@ -1,3 +1,7 @@
+2014-11-19  Renlin Li  <Renlin.Li@arm.com>
+    PR target/63424
+       * gcc.target/aarch64/pr63424.c: New test.
+
 2014-11-19  Renlin Li  <Renlin.Li@arm.com>
 
     PR middle-end/63762
diff --git a/gcc/testsuite/gcc.target/aarch64/pr63424.c b/gcc/testsuite/gcc.target/aarch64/pr63424.c
new file mode 100644 (file)
index 0000000..c6bd762
--- /dev/null
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+#include <stdint.h>
+
+uint32_t
+truncate_int (const unsigned long long value)
+{
+  if ( value < 0 )
+    {
+      return 0;
+    }
+  else if ( value > UINT32_MAX )
+    {
+      return UINT32_MAX;
+    }
+  else
+    return (uint32_t)value;
+}
+
+uint32_t
+mul (const unsigned long long x, const unsigned long long y)
+{
+  uint32_t value = truncate_int (x * y);
+  return value;
+}
+
+uint32_t *
+test(unsigned size, uint32_t *a, uint32_t s)
+{
+  unsigned i;
+
+  for (i = 0; i < size; i++)
+    {
+      a[i] = mul (a[i], s);
+    }
+
+  return a;
+}