arm.md (f_sels, f_seld): New types.
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Mon, 25 Mar 2013 15:20:44 +0000 (15:20 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Mon, 25 Mar 2013 15:20:44 +0000 (15:20 +0000)
gcc/
2013-03-25  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

* config/arm/arm.md (f_sels, f_seld): New types.
(*cmov<mode>): New pattern.
* config/arm/predicates.md (arm_vsel_comparison_operator): New
predicate.

gcc/testsuite/
2013-03-25  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

* gcc.target/arm/vseleqdf.c: New test.
* gcc.target/arm/vseleqsf.c: Likewise.
* gcc.target/arm/vselgedf.c: Likewise.
* gcc.target/arm/vselgesf.c: Likewise.
* gcc.target/arm/vselgtdf.c: Likewise.
* gcc.target/arm/vselgtsf.c: Likewise.
* gcc.target/arm/vselledf.c: Likewise.
* gcc.target/arm/vsellesf.c: Likewise.
* gcc.target/arm/vselltdf.c: Likewise.
* gcc.target/arm/vselltsf.c: Likewise.
* gcc.target/arm/vselnedf.c: Likewise.
* gcc.target/arm/vselnesf.c: Likewise.
* gcc.target/arm/vselvcdf.c: Likewise.
* gcc.target/arm/vselvcsf.c: Likewise.
* gcc.target/arm/vselvsdf.c: Likewise.
* gcc.target/arm/vselvssf.c: Likewise.

From-SVN: r197052

20 files changed:
gcc/ChangeLog
gcc/config/arm/arm.md
gcc/config/arm/predicates.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/vseleqdf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vseleqsf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vselgedf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vselgesf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vselgtdf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vselgtsf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vselledf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vsellesf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vselltdf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vselltsf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vselnedf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vselnesf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vselvcdf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vselvcsf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vselvsdf.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arm/vselvssf.c [new file with mode: 0644]

index f48ead2..fe32837 100644 (file)
@@ -1,3 +1,10 @@
+2013-03-25  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/arm/arm.md (f_sels, f_seld): New types.
+       (*cmov<mode>): New pattern.
+       * config/arm/predicates.md (arm_vsel_comparison_operator): New
+       predicate.
+
 2013-03-25  Kai Tietz  <ktietz@redhat.com>
 
        * config/i386/xm-mingw32.h (__USE_MINGW_ANSI_STDIO): Enable
index d48bc8c..8895080 100644 (file)
   f_2_r,\
   r_2_f,\
   f_cvt,\
+  f_sels,\
+  f_seld,\
   branch,\
   call,\
   load_byte,\
   }"
 )
 
+(define_insn "*cmov<mode>"
+    [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
+       (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
+                         [(match_operand 2 "cc_register" "") (const_int 0)])
+                         (match_operand:SDF 3 "s_register_operand"
+                                             "<F_constraint>")
+                         (match_operand:SDF 4 "s_register_operand"
+                                             "<F_constraint>")))]
+  "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
+  "*
+  {
+    enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
+    switch (code)
+      {
+      case ARM_GE:
+      case ARM_GT:
+      case ARM_EQ:
+      case ARM_VS:
+        return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
+      case ARM_LT:
+      case ARM_LE:
+      case ARM_NE:
+      case ARM_VC:
+        return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
+      default:
+        gcc_unreachable ();
+      }
+    return \"\";
+  }"
+  [(set_attr "conds" "use")
+   (set_attr "type" "f_sel<vfp_type>")]
+)
+
 (define_insn "*movsicc_insn"
   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
        (if_then_else:SI
index f493d82..f301df2 100644 (file)
 (define_special_predicate "lt_ge_comparison_operator"
   (match_code "lt,ge"))
 
+;; The vsel instruction only accepts the ARM condition codes listed below.
+(define_special_predicate "arm_vsel_comparison_operator"
+  (and (match_operand 0 "expandable_comparison_operator")
+       (match_test "maybe_get_arm_condition_code (op) == ARM_GE
+                    || maybe_get_arm_condition_code (op) == ARM_GT
+                    || maybe_get_arm_condition_code (op) == ARM_EQ
+                    || maybe_get_arm_condition_code (op) == ARM_VS
+                    || maybe_get_arm_condition_code (op) == ARM_LT
+                    || maybe_get_arm_condition_code (op) == ARM_LE
+                    || maybe_get_arm_condition_code (op) == ARM_NE
+                    || maybe_get_arm_condition_code (op) == ARM_VC")))
+
 (define_special_predicate "noov_comparison_operator"
   (match_code "lt,ge,eq,ne"))
 
index f6addcf..b807392 100644 (file)
@@ -1,3 +1,22 @@
+2013-03-25  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * gcc.target/arm/vseleqdf.c: New test.
+       * gcc.target/arm/vseleqsf.c: Likewise.
+       * gcc.target/arm/vselgedf.c: Likewise.
+       * gcc.target/arm/vselgesf.c: Likewise.
+       * gcc.target/arm/vselgtdf.c: Likewise.
+       * gcc.target/arm/vselgtsf.c: Likewise.
+       * gcc.target/arm/vselledf.c: Likewise.
+       * gcc.target/arm/vsellesf.c: Likewise.
+       * gcc.target/arm/vselltdf.c: Likewise.
+       * gcc.target/arm/vselltsf.c: Likewise.
+       * gcc.target/arm/vselnedf.c: Likewise.
+       * gcc.target/arm/vselnesf.c: Likewise.
+       * gcc.target/arm/vselvcdf.c: Likewise.
+       * gcc.target/arm/vselvcsf.c: Likewise.
+       * gcc.target/arm/vselvsdf.c: Likewise.
+       * gcc.target/arm/vselvssf.c: Likewise.
+
 2013-03-25  Kyrylo Tkachov  <kyrylo.tkachov at arm.com>
 
        * gcc.target/aarch64/atomic-comp-swap-release-acquire.c: Move test
diff --git a/gcc/testsuite/gcc.target/arm/vseleqdf.c b/gcc/testsuite/gcc.target/arm/vseleqdf.c
new file mode 100644 (file)
index 0000000..86e147b
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+double
+foo (double x, double y)
+{
+  volatile int i = 0;
+  return i == 0 ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vseleq.f64\td\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vseleqsf.c b/gcc/testsuite/gcc.target/arm/vseleqsf.c
new file mode 100644 (file)
index 0000000..120f44b
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+float
+foo (float x, float y)
+{
+  volatile int i = 0;
+  return i == 0 ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vseleq.f32\ts\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vselgedf.c b/gcc/testsuite/gcc.target/arm/vselgedf.c
new file mode 100644 (file)
index 0000000..cea08d1
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+double
+foo (double x, double y)
+{
+  volatile int i = 0;
+  return i >= 0 ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vselge.f64\td\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vselgesf.c b/gcc/testsuite/gcc.target/arm/vselgesf.c
new file mode 100644 (file)
index 0000000..86f2a04
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+float
+foo (float x, float y)
+{
+  volatile int i = 0;
+  return i >= 0 ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vselge.f32\ts\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vselgtdf.c b/gcc/testsuite/gcc.target/arm/vselgtdf.c
new file mode 100644 (file)
index 0000000..2c4a6ba
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+double
+foo (double x, double y)
+{
+  volatile int i = 0;
+  return i > 0 ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vselgt.f64\td\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vselgtsf.c b/gcc/testsuite/gcc.target/arm/vselgtsf.c
new file mode 100644 (file)
index 0000000..388e74c
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+float
+foo (float x, float y)
+{
+  volatile int i = 0;
+  return i > 0 ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vselgt.f32\ts\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vselledf.c b/gcc/testsuite/gcc.target/arm/vselledf.c
new file mode 100644 (file)
index 0000000..088dc04
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+double
+foo (double x, double y)
+{
+  volatile int i = 0;
+  return i <= 0 ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vselgt.f64\td\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vsellesf.c b/gcc/testsuite/gcc.target/arm/vsellesf.c
new file mode 100644 (file)
index 0000000..d0afdbc
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+float
+foo (float x, float y)
+{
+  volatile int i = 0;
+  return i <= 0 ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vselgt.f32\ts\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vselltdf.c b/gcc/testsuite/gcc.target/arm/vselltdf.c
new file mode 100644 (file)
index 0000000..fbcb9ea
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+double
+foo (double x, double y)
+{
+  volatile int i = 0;
+  return i < 0 ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vselge.f64\td\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vselltsf.c b/gcc/testsuite/gcc.target/arm/vselltsf.c
new file mode 100644 (file)
index 0000000..959dab7
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+float
+foo (float x, float y)
+{
+  volatile int i = 0;
+  return i < 0 ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vselge.f32\ts\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vselnedf.c b/gcc/testsuite/gcc.target/arm/vselnedf.c
new file mode 100644 (file)
index 0000000..cf67f29
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+double
+foo (double x, double y)
+{
+  volatile int i = 0;
+  return i != 0 ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vseleq.f64\td\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vselnesf.c b/gcc/testsuite/gcc.target/arm/vselnesf.c
new file mode 100644 (file)
index 0000000..2e16423
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+float
+foo (float x, float y)
+{
+  volatile int i = 0;
+  return i != 0 ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vseleq.f32\ts\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vselvcdf.c b/gcc/testsuite/gcc.target/arm/vselvcdf.c
new file mode 100644 (file)
index 0000000..7f30270
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+double
+foo (double x, double y)
+{
+  return !__builtin_isunordered (x, y) ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vselvs.f64\td\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vselvcsf.c b/gcc/testsuite/gcc.target/arm/vselvcsf.c
new file mode 100644 (file)
index 0000000..1bb7369
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+float
+foo (float x, float y)
+{
+  return !__builtin_isunordered (x, y) ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vselvs.f32\ts\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vselvsdf.c b/gcc/testsuite/gcc.target/arm/vselvsdf.c
new file mode 100644 (file)
index 0000000..83ad5bf
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+double
+foo (double x, double y)
+{
+  return __builtin_isunordered (x, y) ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vselvs.f64\td\[0-9\]+" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/vselvssf.c b/gcc/testsuite/gcc.target/arm/vselvssf.c
new file mode 100644 (file)
index 0000000..7d76289
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_v8_vfp } */
+
+float
+foo (float x, float y)
+{
+  return __builtin_isunordered (x, y) ? x : y;
+}
+
+/* { dg-final { scan-assembler-times "vselvs.f32\ts\[0-9\]+" 1 } } */