diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f48ead2329f79b42d8b5078c840c7911907759c1..fe328374d97f0d33aad80d81de4609154eb46e8e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index d48bc8c01239b3c8c8e470b9220727535310cc14..8895080cb0322fa1da63551749dfbea2bb0ebff5 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -288,6 +288,8 @@ f_2_r,\ r_2_f,\ f_cvt,\ + f_sels,\ + f_seld,\ branch,\ call,\ load_byte,\ @@ -8102,6 +8104,39 @@ }" ) +(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 diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index f493d8284a67b95756532abf8b75347042fc5797..f301df2fcdb92392bb61e73fd52730ddf3c57ae3 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -270,6 +270,18 @@ (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")) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f6addcf762d35433b628987666592bb394af1aa2..b8073921b28a7fb6150414a174ad51f9b2c4e016 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000000000000000000000000000000000000..86e147b1f28d0a1da49915ad8ea17d8ccccd8b5a --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vseleqdf.c @@ -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 index 0000000000000000000000000000000000000000..120f44bf01330a54c732c086db838ab195332d49 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vseleqsf.c @@ -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 index 0000000000000000000000000000000000000000..cea08d12ea4a6b9fe8fda168a9bc0ede85ec8b02 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vselgedf.c @@ -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 index 0000000000000000000000000000000000000000..86f2a04907fae41b7e5baa8478a1ca507f9bcaa6 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vselgesf.c @@ -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 index 0000000000000000000000000000000000000000..2c4a6ba906d5460916ec6313f67138fdd84df300 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vselgtdf.c @@ -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 index 0000000000000000000000000000000000000000..388e74c111443b8fc1ca81dabdf85857995d3fcd --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vselgtsf.c @@ -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 index 0000000000000000000000000000000000000000..088dc04b27499ef1860b9c16f58b23b12b2acf6e --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vselledf.c @@ -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 index 0000000000000000000000000000000000000000..d0afdbcec5127c1ff5f4ce4d5348044d5df8afb5 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vsellesf.c @@ -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 index 0000000000000000000000000000000000000000..fbcb9ea2b33bbf40b2533035b8c721f51ac01c53 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vselltdf.c @@ -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 index 0000000000000000000000000000000000000000..959dab7fa32ff6bf5c5aeaa7414fcf0e9e26703d --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vselltsf.c @@ -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 index 0000000000000000000000000000000000000000..cf67f29f3f8befaf84623a255542c2266fd52ca9 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vselnedf.c @@ -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 index 0000000000000000000000000000000000000000..2e16423b57415ad0ca06a723cc94b707734033cb --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vselnesf.c @@ -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 index 0000000000000000000000000000000000000000..7f30270c502259aff31024c8d47b45b2309accea --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vselvcdf.c @@ -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 index 0000000000000000000000000000000000000000..1bb736925f9d23c1822eb7b725ffe0fd98468c68 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vselvcsf.c @@ -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 index 0000000000000000000000000000000000000000..83ad5bf695105178c261265f2b849e9e5713b56d --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vselvsdf.c @@ -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 index 0000000000000000000000000000000000000000..7d762899cb38a9a7b7d6a1c1f9976d63defd6db0 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/vselvssf.c @@ -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 } } */