diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f48ead2329f..fe328374d97 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-03-25 Kyrylo Tkachov + + * config/arm/arm.md (f_sels, f_seld): New types. + (*cmov): New pattern. + * config/arm/predicates.md (arm_vsel_comparison_operator): New + predicate. + 2013-03-25 Kai Tietz * 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 d48bc8c0123..8895080cb03 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" + [(set (match_operand:SDF 0 "s_register_operand" "=") + (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" + "") + (match_operand:SDF 4 "s_register_operand" + "")))] + "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 " + "* + { + 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.\\t%0, %3, %4\"; + case ARM_LT: + case ARM_LE: + case ARM_NE: + case ARM_VC: + return \"vsel%D1.\\t%0, %4, %3\"; + default: + gcc_unreachable (); + } + return \"\"; + }" + [(set_attr "conds" "use") + (set_attr "type" "f_sel")] +) + (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 f493d8284a6..f301df2fcdb 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 f6addcf762d..b8073921b28 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,22 @@ +2013-03-25 Kyrylo Tkachov + + * 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 * 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 00000000000..86e147b1f28 --- /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 00000000000..120f44bf013 --- /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 00000000000..cea08d12ea4 --- /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 00000000000..86f2a04907f --- /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 00000000000..2c4a6ba906d --- /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 00000000000..388e74c1114 --- /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 00000000000..088dc04b274 --- /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 00000000000..d0afdbcec51 --- /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 00000000000..fbcb9ea2b33 --- /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 00000000000..959dab7fa32 --- /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 00000000000..cf67f29f3f8 --- /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 00000000000..2e16423b574 --- /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 00000000000..7f30270c502 --- /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 00000000000..1bb736925f9 --- /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 00000000000..83ad5bf6951 --- /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 00000000000..7d762899cb3 --- /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 } } */