+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
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
(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"))
+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
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */
--- /dev/null
+/* { 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 } } */