From c7c0f73d6801b4e839775ec2a09c1acf6378dbda Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sun, 7 Nov 2010 08:31:21 +0000 Subject: [PATCH] mips.c (mips_rtx_costs): Handle FMA. gcc/ * config/mips/mips.c (mips_rtx_costs): Handle FMA. * config/mips/mips.md (*madd4, *madd3, *msub4) (*msub3, *nmadd4_fastmath, *nmadd3_fastmath) (*nmsub4_fastmath, *nmsub3_fastmath): Delete. (*nmadd4, *nmadd3. *nmsub4, *nmsub3): Redefine to use FMA. (fma4, *fma4_madd3, *fma4_madd4): New patterns. (fms4, *fms4_msub3, *fms4_msub4): Likewise. (fnms4, *fnms4_nmadd3, *fnms4_nmadd4): Likewise. (fnma4, *fnma4_nmsub3, *fnma4_nmsub4): Likewise. gcc/testsuite/ * gcc.target/mips/mips.exp: Add support for -ffp-contract. * gcc.target/mips/fma-1.c: New test. * gcc.target/mips/fma-2.c: Likewise. * gcc.target/mips/fma-3.c: Likewise. * gcc.target/mips/fma-4.c: Likewise. * gcc.target/mips/fma-5.c: Likewise. * gcc.target/mips/fma-6.c: Likewise. * gcc.target/mips/fma-7.c: Likewise. * gcc.target/mips/fma-8.c: Likewise. * gcc.target/mips/fma-9.c: Likewise. * gcc.target/mips/fma-10.c: Likewise. * gcc.target/mips/fma-11.c: Likewise. * gcc.target/mips/fma-12.c: Likewise. * gcc.target/mips/fma-13.c: Likewise. * gcc.target/mips/fma-14.c: Likewise. * gcc.target/mips/fma-15.c: Likewise. * gcc.target/mips/fma-16.c: Likewise. * gcc.target/mips/fma-17.c: Likewise. * gcc.target/mips/fma-18.c: Likewise. * gcc.target/mips/fma-19.c: Likewise. * gcc.target/mips/fma-20.c: Likewise. From-SVN: r166414 --- gcc/ChangeLog | 13 ++ gcc/config/mips/mips.c | 4 + gcc/config/mips/mips.md | 212 ++++++++++++++----------- gcc/testsuite/ChangeLog | 24 +++ gcc/testsuite/gcc.target/mips/fma-1.c | 82 ++++++++++ gcc/testsuite/gcc.target/mips/fma-10.c | 62 ++++++++ gcc/testsuite/gcc.target/mips/fma-11.c | 79 +++++++++ gcc/testsuite/gcc.target/mips/fma-12.c | 82 ++++++++++ gcc/testsuite/gcc.target/mips/fma-13.c | 81 ++++++++++ gcc/testsuite/gcc.target/mips/fma-14.c | 64 ++++++++ gcc/testsuite/gcc.target/mips/fma-15.c | 65 ++++++++ gcc/testsuite/gcc.target/mips/fma-16.c | 62 ++++++++ gcc/testsuite/gcc.target/mips/fma-17.c | 82 ++++++++++ gcc/testsuite/gcc.target/mips/fma-18.c | 81 ++++++++++ gcc/testsuite/gcc.target/mips/fma-19.c | 79 +++++++++ gcc/testsuite/gcc.target/mips/fma-2.c | 16 ++ gcc/testsuite/gcc.target/mips/fma-20.c | 81 ++++++++++ gcc/testsuite/gcc.target/mips/fma-3.c | 16 ++ gcc/testsuite/gcc.target/mips/fma-4.c | 17 ++ gcc/testsuite/gcc.target/mips/fma-5.c | 17 ++ gcc/testsuite/gcc.target/mips/fma-6.c | 16 ++ gcc/testsuite/gcc.target/mips/fma-7.c | 16 ++ gcc/testsuite/gcc.target/mips/fma-8.c | 81 ++++++++++ gcc/testsuite/gcc.target/mips/fma-9.c | 70 ++++++++ gcc/testsuite/gcc.target/mips/mips.exp | 7 + 25 files changed, 1312 insertions(+), 97 deletions(-) create mode 100644 gcc/testsuite/gcc.target/mips/fma-1.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-10.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-11.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-12.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-13.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-14.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-15.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-16.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-17.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-18.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-19.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-2.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-20.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-3.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-4.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-5.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-6.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-7.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-8.c create mode 100644 gcc/testsuite/gcc.target/mips/fma-9.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cb4c17a7ee8..8b590661467 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2010-11-07 Richard Sandiford + + * config/mips/mips.c (mips_rtx_costs): Handle FMA. + * config/mips/mips.md (*madd4, *madd3, *msub4) + (*msub3, *nmadd4_fastmath, *nmadd3_fastmath) + (*nmsub4_fastmath, *nmsub3_fastmath): Delete. + (*nmadd4, *nmadd3. *nmsub4, *nmsub3): Redefine + to use FMA. + (fma4, *fma4_madd3, *fma4_madd4): New patterns. + (fms4, *fms4_msub3, *fms4_msub4): Likewise. + (fnms4, *fnms4_nmadd3, *fnms4_nmadd4): Likewise. + (fnma4, *fnma4_nmsub3, *fnma4_nmsub4): Likewise. + 2010-11-06 Simon Martin PR c/43384 diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 76c0786713e..c10e9d1a759 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -3827,6 +3827,10 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed) *total = mips_cost->int_mult_si; return false; + case FMA: + *total = mips_fp_mult_cost (mode); + return false; + case DIV: /* Check for a reciprocal. */ if (float_mode_p diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index b7893941408..a5f5d488b6b 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -2077,155 +2077,173 @@ ;; Floating point multiply accumulate instructions. -(define_insn "*madd4" - [(set (match_operand:ANYF 0 "register_operand" "=f") - (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "f")))] - "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD" - "madd.\t%0,%3,%1,%2" - [(set_attr "type" "fmadd") - (set_attr "mode" "")]) +(define_expand "fma4" + [(set (match_operand:ANYF 0 "register_operand") + (fma:ANYF (match_operand:ANYF 1 "register_operand") + (match_operand:ANYF 2 "register_operand") + (match_operand:ANYF 3 "register_operand")))] + "ISA_HAS_FP_MADD3_MSUB3 || ISA_HAS_FP_MADD4_MSUB4") -(define_insn "*madd3" +(define_insn "*fma4_madd3" [(set (match_operand:ANYF 0 "register_operand" "=f") - (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "0")))] - "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD" + (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f") + (match_operand:ANYF 3 "register_operand" "0")))] + "ISA_HAS_FP_MADD3_MSUB3" "madd.\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "")]) -(define_insn "*msub4" +(define_insn "*fma4_madd4" [(set (match_operand:ANYF 0 "register_operand" "=f") - (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "f")))] - "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD" - "msub.\t%0,%3,%1,%2" + (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f") + (match_operand:ANYF 3 "register_operand" "f")))] + "ISA_HAS_FP_MADD4_MSUB4" + "madd.\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "")]) -(define_insn "*msub3" +(define_expand "fms4" + [(set (match_operand:ANYF 0 "register_operand") + (fma:ANYF (match_operand:ANYF 1 "register_operand") + (match_operand:ANYF 2 "register_operand") + (neg:ANYF (match_operand:ANYF 3 "register_operand"))))] + "ISA_HAS_FP_MADD3_MSUB3 || ISA_HAS_FP_MADD4_MSUB4") + +(define_insn "*fms4_msub3" [(set (match_operand:ANYF 0 "register_operand" "=f") - (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "0")))] - "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD" + (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f") + (neg:ANYF (match_operand:ANYF 3 "register_operand" "0"))))] + "ISA_HAS_FP_MADD3_MSUB3" "msub.\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "")]) -(define_insn "*nmadd4" +(define_insn "*fms4_msub4" [(set (match_operand:ANYF 0 "register_operand" "=f") - (neg:ANYF (plus:ANYF - (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "f"))))] + (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f") + (neg:ANYF (match_operand:ANYF 3 "register_operand" "f"))))] + "ISA_HAS_FP_MADD4_MSUB4" + "msub.\t%0,%3,%1,%2" + [(set_attr "type" "fmadd") + (set_attr "mode" "")]) + +;; If we're ignoring signed zeros, we can use NMADD (-(a * b + c)) to +;; implement fnms (-a * b - c, which is unconditionally equivalent to +;; -(a * b) - c). +(define_expand "fnms4" + [(set (match_operand:ANYF 0 "register_operand") + (fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand")) + (match_operand:ANYF 2 "register_operand") + (neg:ANYF (match_operand:ANYF 3 "register_operand"))))] + "(ISA_HAS_NMADD3_NMSUB3 (mode) || ISA_HAS_NMADD4_NMSUB4 (mode)) + && !HONOR_SIGNED_ZEROS (mode) + && !HONOR_NANS (mode)") + +(define_insn "*fnms4_nmadd3" + [(set (match_operand:ANYF 0 "register_operand" "=f") + (fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) + (match_operand:ANYF 2 "register_operand" "f") + (neg:ANYF (match_operand:ANYF 3 "register_operand" "0"))))] + "ISA_HAS_NMADD3_NMSUB3 (mode) + && !HONOR_SIGNED_ZEROS (mode) + && !HONOR_NANS (mode)" + "nmadd.\t%0,%1,%2" + [(set_attr "type" "fmadd") + (set_attr "mode" "")]) + +(define_insn "*fnms4_nmadd4" + [(set (match_operand:ANYF 0 "register_operand" "=f") + (fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) + (match_operand:ANYF 2 "register_operand" "f") + (neg:ANYF (match_operand:ANYF 3 "register_operand" "f"))))] "ISA_HAS_NMADD4_NMSUB4 (mode) - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (mode) + && !HONOR_SIGNED_ZEROS (mode) && !HONOR_NANS (mode)" "nmadd.\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "")]) -(define_insn "*nmadd3" +(define_insn "*nmadd3" [(set (match_operand:ANYF 0 "register_operand" "=f") - (neg:ANYF (plus:ANYF - (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") - (match_operand:ANYF 2 "register_operand" "f")) + (neg:ANYF + (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f") (match_operand:ANYF 3 "register_operand" "0"))))] - "ISA_HAS_NMADD3_NMSUB3 (mode) - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (mode) - && !HONOR_NANS (mode)" + "ISA_HAS_NMADD3_NMSUB3 (mode) && !HONOR_NANS (mode)" "nmadd.\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "")]) -(define_insn "*nmadd4_fastmath" +(define_insn "*nmadd4" [(set (match_operand:ANYF 0 "register_operand" "=f") - (minus:ANYF - (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "f")))] - "ISA_HAS_NMADD4_NMSUB4 (mode) - && TARGET_FUSED_MADD - && !HONOR_SIGNED_ZEROS (mode) - && !HONOR_NANS (mode)" + (neg:ANYF + (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f") + (match_operand:ANYF 3 "register_operand" "f"))))] + "ISA_HAS_NMADD4_NMSUB4 (mode) && !HONOR_NANS (mode)" "nmadd.\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "")]) -(define_insn "*nmadd3_fastmath" +;; If we're ignoring signed zeros, we can use NMSUB (-(a * b - c)) to +;; implement fnma (-a * b + c, which is unconditionally equivalent to +;; -(a * b) + c). +(define_expand "fnma4" + [(set (match_operand:ANYF 0 "register_operand") + (fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand")) + (match_operand:ANYF 2 "register_operand") + (match_operand:ANYF 3 "register_operand")))] + "(ISA_HAS_NMADD3_NMSUB3 (mode) || ISA_HAS_NMADD4_NMSUB4 (mode)) + && !HONOR_SIGNED_ZEROS (mode) + && !HONOR_NANS (mode)") + +(define_insn "*fnma4_nmsub3" [(set (match_operand:ANYF 0 "register_operand" "=f") - (minus:ANYF - (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) - (match_operand:ANYF 2 "register_operand" "f")) - (match_operand:ANYF 3 "register_operand" "0")))] + (fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) + (match_operand:ANYF 2 "register_operand" "f") + (match_operand:ANYF 3 "register_operand" "0")))] "ISA_HAS_NMADD3_NMSUB3 (mode) - && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (mode) && !HONOR_NANS (mode)" - "nmadd.\t%0,%1,%2" + "nmsub.\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "")]) -(define_insn "*nmsub4" +(define_insn "*fnma4_nmsub4" [(set (match_operand:ANYF 0 "register_operand" "=f") - (neg:ANYF (minus:ANYF - (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") - (match_operand:ANYF 3 "register_operand" "f")) - (match_operand:ANYF 1 "register_operand" "f"))))] + (fma:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) + (match_operand:ANYF 2 "register_operand" "f") + (match_operand:ANYF 3 "register_operand" "f")))] "ISA_HAS_NMADD4_NMSUB4 (mode) - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (mode) + && !HONOR_SIGNED_ZEROS (mode) && !HONOR_NANS (mode)" - "nmsub.\t%0,%1,%2,%3" + "nmsub.\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "")]) -(define_insn "*nmsub3" +(define_insn "*nmsub3" [(set (match_operand:ANYF 0 "register_operand" "=f") - (neg:ANYF (minus:ANYF - (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") - (match_operand:ANYF 3 "register_operand" "f")) - (match_operand:ANYF 1 "register_operand" "0"))))] - "ISA_HAS_NMADD3_NMSUB3 (mode) - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (mode) - && !HONOR_NANS (mode)" + (neg:ANYF + (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f") + (neg:ANYF (match_operand:ANYF 3 "register_operand" "0")))))] + "ISA_HAS_NMADD3_NMSUB3 (mode) && !HONOR_NANS (mode)" "nmsub.\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "")]) -(define_insn "*nmsub4_fastmath" +(define_insn "*nmsub4" [(set (match_operand:ANYF 0 "register_operand" "=f") - (minus:ANYF - (match_operand:ANYF 1 "register_operand" "f") - (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") - (match_operand:ANYF 3 "register_operand" "f"))))] - "ISA_HAS_NMADD4_NMSUB4 (mode) - && TARGET_FUSED_MADD - && !HONOR_SIGNED_ZEROS (mode) - && !HONOR_NANS (mode)" - "nmsub.\t%0,%1,%2,%3" - [(set_attr "type" "fmadd") - (set_attr "mode" "")]) - -(define_insn "*nmsub3_fastmath" - [(set (match_operand:ANYF 0 "register_operand" "=f") - (minus:ANYF - (match_operand:ANYF 1 "register_operand" "f") - (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") - (match_operand:ANYF 3 "register_operand" "0"))))] - "ISA_HAS_NMADD3_NMSUB3 (mode) - && TARGET_FUSED_MADD - && !HONOR_SIGNED_ZEROS (mode) - && !HONOR_NANS (mode)" - "nmsub.\t%0,%1,%2" + (neg:ANYF + (fma:ANYF (match_operand:ANYF 1 "register_operand" "f") + (match_operand:ANYF 2 "register_operand" "f") + (neg:ANYF (match_operand:ANYF 3 "register_operand" "f")))))] + "ISA_HAS_NMADD4_NMSUB4 (mode) && !HONOR_NANS (mode)" + "nmsub.\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "")]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c5ccdb80005..806b1d14a64 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,27 @@ +2010-11-07 Richard Sandiford + + * gcc.target/mips/mips.exp: Add support for -ffp-contract. + * gcc.target/mips/fma-1.c: New test. + * gcc.target/mips/fma-2.c: Likewise. + * gcc.target/mips/fma-3.c: Likewise. + * gcc.target/mips/fma-4.c: Likewise. + * gcc.target/mips/fma-5.c: Likewise. + * gcc.target/mips/fma-6.c: Likewise. + * gcc.target/mips/fma-7.c: Likewise. + * gcc.target/mips/fma-8.c: Likewise. + * gcc.target/mips/fma-9.c: Likewise. + * gcc.target/mips/fma-10.c: Likewise. + * gcc.target/mips/fma-11.c: Likewise. + * gcc.target/mips/fma-12.c: Likewise. + * gcc.target/mips/fma-13.c: Likewise. + * gcc.target/mips/fma-14.c: Likewise. + * gcc.target/mips/fma-15.c: Likewise. + * gcc.target/mips/fma-16.c: Likewise. + * gcc.target/mips/fma-17.c: Likewise. + * gcc.target/mips/fma-18.c: Likewise. + * gcc.target/mips/fma-19.c: Likewise. + * gcc.target/mips/fma-20.c: Likewise. + 2010-11-06 Jason Merrill * g++.dg/cpp0x/constexpr-ctor3.C: New. diff --git a/gcc/testsuite/gcc.target/mips/fma-1.c b/gcc/testsuite/gcc.target/mips/fma-1.c new file mode 100644 index 00000000000..d167473259e --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-1.c @@ -0,0 +1,82 @@ +/* { dg-options "-mgp64 -mhard-float isa>=4 -O3 -fno-fast-math -ffp-contract=off" } */ +/* { dg-final { scan-assembler-times "\tmadd\\.s\t" 3 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.s\t" 3 } } */ +/* { dg-final { scan-assembler-times "\tmadd\\.d\t" 3 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.d\t" 3 } } */ +/* { dg-final { scan-assembler-not "\tnmadd\\." } } */ +/* { dg-final { scan-assembler-not "\tnmsub\\." } } */ + +/* We should not use NMADD or NMSUB without -ffinite-math-only because + those instructions may perform arithmetic negation. */ + +NOMIPS16 float +madd_s (float b, float c, float d) +{ + return __builtin_fmaf (b, c, d); +} + +NOMIPS16 float +msub_s (float b, float c, float d) +{ + return __builtin_fmaf (b, c, -d); +} + +NOMIPS16 float +not_nmadd_s (float b, float c, float d) +{ + return -__builtin_fmaf (b, c, d); +} + +NOMIPS16 float +not_nmsub_s (float b, float c, float d) +{ + return -__builtin_fmaf (b, c, -d); +} + +NOMIPS16 float +not_nmadd_s_2 (float b, float c, float d) +{ + return __builtin_fmaf (-b, c, -d); +} + +NOMIPS16 float +not_nmsub_s_2 (float b, float c, float d) +{ + return __builtin_fmaf (-b, c, d); +} + +NOMIPS16 double +madd_d (double b, double c, double d) +{ + return __builtin_fma (b, c, d); +} + +NOMIPS16 double +msub_d (double b, double c, double d) +{ + return __builtin_fma (b, c, -d); +} + +NOMIPS16 double +not_nmadd_d (double b, double c, double d) +{ + return -__builtin_fma (b, c, d); +} + +NOMIPS16 double +not_nmsub_d (double b, double c, double d) +{ + return -__builtin_fma (b, c, -d); +} + +NOMIPS16 double +not_nmadd_d_2 (double b, double c, double d) +{ + return __builtin_fma (-b, c, -d); +} + +NOMIPS16 double +not_nmsub_d_2 (double b, double c, double d) +{ + return __builtin_fma (-b, c, d); +} diff --git a/gcc/testsuite/gcc.target/mips/fma-10.c b/gcc/testsuite/gcc.target/mips/fma-10.c new file mode 100644 index 00000000000..bb3f31b954d --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-10.c @@ -0,0 +1,62 @@ +/* { dg-options "-mpaired-single -O -ffast-math -ftree-vectorize" } */ +/* { dg-final { scan-assembler-times "\tmadd\\.ps\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.ps\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.ps\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.ps\t" 2 } } */ + +#define N 512 +float a[N], b[N], c[N], d[N]; + +NOMIPS16 void +madd_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = __builtin_fmaf (b[i], c[i], d[i]); +} + +NOMIPS16 float +msub_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = __builtin_fmaf (b[i], c[i], -d[i]); +} + +NOMIPS16 float +nmadd_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -__builtin_fmaf (b[i], c[i], d[i]); +} + +NOMIPS16 float +nmsub_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -__builtin_fmaf (b[i], c[i], -d[i]); +} + +NOMIPS16 float +nmadd_ps_2 (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = __builtin_fmaf (-b[i], c[i], -d[i]); +} + +NOMIPS16 float +nmsub_ps_2 (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = __builtin_fmaf (-b[i], c[i], d[i]); +} diff --git a/gcc/testsuite/gcc.target/mips/fma-11.c b/gcc/testsuite/gcc.target/mips/fma-11.c new file mode 100644 index 00000000000..17f124f2818 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-11.c @@ -0,0 +1,79 @@ +/* { dg-options "-mgp64 -mhard-float isa>=4 -O3 -fno-fast-math -ffp-contract=off" } */ +/* { dg-final { scan-assembler-not "\tmadd\\." } } */ +/* { dg-final { scan-assembler-not "\tmsub\\." } } */ +/* { dg-final { scan-assembler-not "\tnmadd\\." } } */ +/* { dg-final { scan-assembler-not "\tnmsub\\." } } */ + +/* No function should use fused operations, however high the -O level. */ + +NOMIPS16 float +not_madd_s (float b, float c, float d) +{ + return b * c + d; +} + +NOMIPS16 float +not_msub_s (float b, float c, float d) +{ + return b * c + -d; +} + +NOMIPS16 float +not_nmadd_s (float b, float c, float d) +{ + return -(b * c + d); +} + +NOMIPS16 float +not_nmsub_s (float b, float c, float d) +{ + return -(b * c + -d); +} + +NOMIPS16 float +not_nmadd_s_2 (float b, float c, float d) +{ + return -b * c - d; +} + +NOMIPS16 float +not_nmsub_s_2 (float b, float c, float d) +{ + return -b * c + d; +} + +NOMIPS16 double +not_madd_d (double b, double c, double d) +{ + return b * c + d; +} + +NOMIPS16 double +not_msub_d (double b, double c, double d) +{ + return b * c + -d; +} + +NOMIPS16 double +not_nmadd_d (double b, double c, double d) +{ + return -(b * c + d); +} + +NOMIPS16 double +not_nmsub_d (double b, double c, double d) +{ + return -(b * c + -d); +} + +NOMIPS16 double +not_nmadd_d_2 (double b, double c, double d) +{ + return -b * c - d; +} + +NOMIPS16 double +not_nmsub_d_2 (double b, double c, double d) +{ + return -b * c + d; +} diff --git a/gcc/testsuite/gcc.target/mips/fma-12.c b/gcc/testsuite/gcc.target/mips/fma-12.c new file mode 100644 index 00000000000..6a6303c394d --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-12.c @@ -0,0 +1,82 @@ +/* { dg-options "-mgp64 -mhard-float isa>=4 -O2 -fno-fast-math -ffp-contract=fast" } */ +/* { dg-final { scan-assembler-times "\tmadd\\.s\t" 3 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.s\t" 3 } } */ +/* { dg-final { scan-assembler-times "\tmadd\\.d\t" 3 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.d\t" 3 } } */ +/* { dg-final { scan-assembler-not "\tnmadd\\." } } */ +/* { dg-final { scan-assembler-not "\tnmsub\\." } } */ + +/* We should not use NMADD or NMSUB without -ffinite-math-only because + those instructions may perform arithmetic negation. */ + +NOMIPS16 float +madd_s (float b, float c, float d) +{ + return b * c + d; +} + +NOMIPS16 float +msub_s (float b, float c, float d) +{ + return b * c + -d; +} + +NOMIPS16 float +not_nmadd_s (float b, float c, float d) +{ + return -(b * c + d); +} + +NOMIPS16 float +not_nmsub_s (float b, float c, float d) +{ + return -(b * c + -d); +} + +NOMIPS16 float +not_nmadd_s_2 (float b, float c, float d) +{ + return -b * c - d; +} + +NOMIPS16 float +not_nmsub_s_2 (float b, float c, float d) +{ + return -b * c + d; +} + +NOMIPS16 double +madd_d (double b, double c, double d) +{ + return b * c + d; +} + +NOMIPS16 double +msub_d (double b, double c, double d) +{ + return b * c + -d; +} + +NOMIPS16 double +not_nmadd_d (double b, double c, double d) +{ + return -(b * c + d); +} + +NOMIPS16 double +not_nmsub_d (double b, double c, double d) +{ + return -(b * c + -d); +} + +NOMIPS16 double +not_nmadd_d_2 (double b, double c, double d) +{ + return -b * c - d; +} + +NOMIPS16 double +not_nmsub_d_2 (double b, double c, double d) +{ + return -b * c + d; +} diff --git a/gcc/testsuite/gcc.target/mips/fma-13.c b/gcc/testsuite/gcc.target/mips/fma-13.c new file mode 100644 index 00000000000..2dbff9b1d49 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-13.c @@ -0,0 +1,81 @@ +/* { dg-options "-mgp64 -mhard-float isa>=4 -O2 -ffast-math" } */ +/* { dg-final { scan-assembler-times "\tmadd\\.s\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.s\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.s\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.s\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tmadd\\.d\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.d\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.d\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.d\t" 2 } } */ + +NOMIPS16 float +madd_s (float b, float c, float d) +{ + return b * c + d; +} + +NOMIPS16 float +msub_s (float b, float c, float d) +{ + return b * c + -d; +} + +NOMIPS16 float +nmadd_s (float b, float c, float d) +{ + return -(b * c + d); +} + +NOMIPS16 float +nmsub_s (float b, float c, float d) +{ + return -(b * c + -d); +} + +NOMIPS16 float +nmadd_s_2 (float b, float c, float d) +{ + return -b * c - d; +} + +NOMIPS16 float +nmsub_s_2 (float b, float c, float d) +{ + return -b * c + d; +} + +NOMIPS16 double +madd_d (double b, double c, double d) +{ + return b * c + d; +} + +NOMIPS16 double +msub_d (double b, double c, double d) +{ + return b * c + -d; +} + +NOMIPS16 double +nmadd_d (double b, double c, double d) +{ + return -(b * c + d); +} + +NOMIPS16 double +nmsub_d (double b, double c, double d) +{ + return -(b * c + -d); +} + +NOMIPS16 double +nmadd_d_2 (double b, double c, double d) +{ + return -b * c - d; +} + +NOMIPS16 double +nmsub_d_2 (double b, double c, double d) +{ + return -b * c + d; +} diff --git a/gcc/testsuite/gcc.target/mips/fma-14.c b/gcc/testsuite/gcc.target/mips/fma-14.c new file mode 100644 index 00000000000..383effdc336 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-14.c @@ -0,0 +1,64 @@ +/* { dg-options "-mpaired-single -O3 -fno-fast-math -ftree-vectorize -ffp-contract=off" } */ +/* { dg-final { scan-assembler-not "\tmadd\\." } } */ +/* { dg-final { scan-assembler-not "\tmsub\\." } } */ +/* { dg-final { scan-assembler-not "\tnmadd\\." } } */ +/* { dg-final { scan-assembler-not "\tnmsub\\." } } */ + +/* No function should use fused operations, however high the -O level. */ + +#define N 512 +float a[N], b[N], c[N], d[N]; + +NOMIPS16 void +not_madd_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = b[i] * c[i] + d[i]; +} + +NOMIPS16 float +not_msub_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = b[i] * c[i] - d[i]; +} + +NOMIPS16 float +not_nmadd_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -(b[i] * c[i] + d[i]); +} + +NOMIPS16 float +not_nmsub_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -(b[i] * c[i] - d[i]); +} + +NOMIPS16 float +not_nmadd_ps_2 (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -b[i] * c[i] - d[i]; +} + +NOMIPS16 float +not_nmsub_ps_2 (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -b[i] * c[i] + d[i]; +} diff --git a/gcc/testsuite/gcc.target/mips/fma-15.c b/gcc/testsuite/gcc.target/mips/fma-15.c new file mode 100644 index 00000000000..4fdfeabaf56 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-15.c @@ -0,0 +1,65 @@ +/* { dg-options "-mpaired-single -O2 -fno-fast-math -ftree-vectorize -ffp-contract=fast" } */ +/* { dg-final { scan-assembler "\tmadd\\.ps" } } */ +/* { dg-final { scan-assembler "\tmsub\\.ps" } } */ +/* { dg-final { scan-assembler-not "\tnmadd\\." } } */ +/* { dg-final { scan-assembler-not "\tnmsub\\." } } */ + +/* We should not use NMADD or NMSUB without -ffinite-math-only because + those instructions may perform arithmetic negation. */ + +#define N 512 +float a[N], b[N], c[N], d[N]; + +NOMIPS16 void +madd_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = b[i] * c[i] + d[i]; +} + +NOMIPS16 float +msub_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = b[i] * c[i] - d[i]; +} + +NOMIPS16 float +not_nmadd_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -(b[i] * c[i] + d[i]); +} + +NOMIPS16 float +not_nmsub_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -(b[i] * c[i] - d[i]); +} + +NOMIPS16 float +not_nmadd_ps_2 (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -b[i] * c[i] - d[i]; +} + +NOMIPS16 float +not_nmsub_ps_2 (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -b[i] * c[i] + d[i]; +} diff --git a/gcc/testsuite/gcc.target/mips/fma-16.c b/gcc/testsuite/gcc.target/mips/fma-16.c new file mode 100644 index 00000000000..16cda123316 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-16.c @@ -0,0 +1,62 @@ +/* { dg-options "-mpaired-single -O2 -ffast-math -ftree-vectorize" } */ +/* { dg-final { scan-assembler-times "\tmadd\\.ps" 1 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.ps" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.ps" 2 } } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.ps" 2 } } */ + +#define N 512 +float a[N], b[N], c[N], d[N]; + +NOMIPS16 void +madd_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = b[i] * c[i] + d[i]; +} + +NOMIPS16 float +msub_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = b[i] * c[i] - d[i]; +} + +NOMIPS16 float +nmadd_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -(b[i] * c[i] + d[i]); +} + +NOMIPS16 float +nmsub_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -(b[i] * c[i] - d[i]); +} + +NOMIPS16 float +nmadd_ps_2 (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -b[i] * c[i] - d[i]; +} + +NOMIPS16 float +nmsub_ps_2 (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -b[i] * c[i] + d[i]; +} diff --git a/gcc/testsuite/gcc.target/mips/fma-17.c b/gcc/testsuite/gcc.target/mips/fma-17.c new file mode 100644 index 00000000000..87b2de1a916 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-17.c @@ -0,0 +1,82 @@ +/* { dg-options "-mgp64 -mhard-float isa=loongson -O3 -fno-fast-math -ffp-contract=off" } */ +/* { dg-final { scan-assembler-times "\tmadd\\.s\t" 3 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.s\t" 3 } } */ +/* { dg-final { scan-assembler-times "\tmadd\\.d\t" 3 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.d\t" 3 } } */ +/* { dg-final { scan-assembler-not "\tnmadd\\." } } */ +/* { dg-final { scan-assembler-not "\tnmsub\\." } } */ + +/* We should not use NMADD or NMSUB without -ffinite-math-only because + those instructions may perform arithmetic negation. */ + +NOMIPS16 float +madd_s (float b, float c, float d) +{ + return __builtin_fmaf (b, c, d); +} + +NOMIPS16 float +msub_s (float b, float c, float d) +{ + return __builtin_fmaf (b, c, -d); +} + +NOMIPS16 float +not_nmadd_s (float b, float c, float d) +{ + return -__builtin_fmaf (b, c, d); +} + +NOMIPS16 float +not_nmsub_s (float b, float c, float d) +{ + return -__builtin_fmaf (b, c, -d); +} + +NOMIPS16 float +not_nmadd_s_2 (float b, float c, float d) +{ + return __builtin_fmaf (-b, c, -d); +} + +NOMIPS16 float +not_nmsub_s_2 (float b, float c, float d) +{ + return __builtin_fmaf (-b, c, d); +} + +NOMIPS16 double +madd_d (double b, double c, double d) +{ + return __builtin_fma (b, c, d); +} + +NOMIPS16 double +msub_d (double b, double c, double d) +{ + return __builtin_fma (b, c, -d); +} + +NOMIPS16 double +not_nmadd_d (double b, double c, double d) +{ + return -__builtin_fma (b, c, d); +} + +NOMIPS16 double +not_nmsub_d (double b, double c, double d) +{ + return -__builtin_fma (b, c, -d); +} + +NOMIPS16 double +not_nmadd_d_2 (double b, double c, double d) +{ + return __builtin_fma (-b, c, -d); +} + +NOMIPS16 double +not_nmsub_d_2 (double b, double c, double d) +{ + return __builtin_fma (-b, c, d); +} diff --git a/gcc/testsuite/gcc.target/mips/fma-18.c b/gcc/testsuite/gcc.target/mips/fma-18.c new file mode 100644 index 00000000000..244f232f8ad --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-18.c @@ -0,0 +1,81 @@ +/* { dg-options "-mgp64 -mhard-float isa=loongson -O -ffast-math" } */ +/* { dg-final { scan-assembler-times "\tmadd\\.s\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.s\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.s\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.s\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tmadd\\.d\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.d\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.d\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.d\t" 2 } } */ + +NOMIPS16 float +madd_s (float b, float c, float d) +{ + return __builtin_fmaf (b, c, d); +} + +NOMIPS16 float +msub_s (float b, float c, float d) +{ + return __builtin_fmaf (b, c, -d); +} + +NOMIPS16 float +nmadd_s (float b, float c, float d) +{ + return -__builtin_fmaf (b, c, d); +} + +NOMIPS16 float +nmsub_s (float b, float c, float d) +{ + return -__builtin_fmaf (b, c, -d); +} + +NOMIPS16 float +nmadd_s_2 (float b, float c, float d) +{ + return __builtin_fmaf (-b, c, -d); +} + +NOMIPS16 float +not_nmsub_s_2 (float b, float c, float d) +{ + return __builtin_fmaf (-b, c, d); +} + +NOMIPS16 double +madd_d (double b, double c, double d) +{ + return __builtin_fma (b, c, d); +} + +NOMIPS16 double +msub_d (double b, double c, double d) +{ + return __builtin_fma (b, c, -d); +} + +NOMIPS16 double +nmadd_d (double b, double c, double d) +{ + return -__builtin_fma (b, c, d); +} + +NOMIPS16 double +nmsub_d (double b, double c, double d) +{ + return -__builtin_fma (b, c, -d); +} + +NOMIPS16 double +nmadd_d_2 (double b, double c, double d) +{ + return __builtin_fma (-b, c, -d); +} + +NOMIPS16 double +nmsub_d_2 (double b, double c, double d) +{ + return __builtin_fma (-b, c, d); +} diff --git a/gcc/testsuite/gcc.target/mips/fma-19.c b/gcc/testsuite/gcc.target/mips/fma-19.c new file mode 100644 index 00000000000..c038f191d9c --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-19.c @@ -0,0 +1,79 @@ +/* { dg-options "-mgp64 -mhard-float isa=loongson -O3 -fno-fast-math -ffp-contract=off" } */ +/* { dg-final { scan-assembler-not "\tmadd\\." } } */ +/* { dg-final { scan-assembler-not "\tmsub\\." } } */ +/* { dg-final { scan-assembler-not "\tnmadd\\." } } */ +/* { dg-final { scan-assembler-not "\tnmsub\\." } } */ + +/* No function should use fused operations, however high the -O level. */ + +NOMIPS16 float +not_madd_s (float b, float c, float d) +{ + return b * c + d; +} + +NOMIPS16 float +not_msub_s (float b, float c, float d) +{ + return b * c + -d; +} + +NOMIPS16 float +not_nmadd_s (float b, float c, float d) +{ + return -(b * c + d); +} + +NOMIPS16 float +not_nmsub_s (float b, float c, float d) +{ + return -(b * c + -d); +} + +NOMIPS16 float +not_nmadd_s_2 (float b, float c, float d) +{ + return -b * c - d; +} + +NOMIPS16 float +not_nmsub_s_2 (float b, float c, float d) +{ + return -b * c + d; +} + +NOMIPS16 double +not_madd_d (double b, double c, double d) +{ + return b * c + d; +} + +NOMIPS16 double +not_msub_d (double b, double c, double d) +{ + return b * c + -d; +} + +NOMIPS16 double +not_nmadd_d (double b, double c, double d) +{ + return -(b * c + d); +} + +NOMIPS16 double +not_nmsub_d (double b, double c, double d) +{ + return -(b * c + -d); +} + +NOMIPS16 double +not_nmadd_d_2 (double b, double c, double d) +{ + return -b * c - d; +} + +NOMIPS16 double +not_nmsub_d_2 (double b, double c, double d) +{ + return -b * c + d; +} diff --git a/gcc/testsuite/gcc.target/mips/fma-2.c b/gcc/testsuite/gcc.target/mips/fma-2.c new file mode 100644 index 00000000000..26c77421a08 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-2.c @@ -0,0 +1,16 @@ +/* { dg-options "-mgp64 -mhard-float isa>=4 -O3 -fno-fast-math -ffp-contract=off -ffinite-math-only" } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.s\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.d\t" 1 } } */ +/* { dg-final { scan-assembler-not "\tnmsub\\." } } */ + +NOMIPS16 float +nmadd_s (float b, float c, float d) +{ + return -__builtin_fmaf (b, c, d); +} + +NOMIPS16 double +nmadd_d (double b, double c, double d) +{ + return -__builtin_fma (b, c, d); +} diff --git a/gcc/testsuite/gcc.target/mips/fma-20.c b/gcc/testsuite/gcc.target/mips/fma-20.c new file mode 100644 index 00000000000..ab0cbdfb791 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-20.c @@ -0,0 +1,81 @@ +/* { dg-options "-mgp64 -mhard-float isa=loongson -O2 -ffast-math" } */ +/* { dg-final { scan-assembler-times "\tmadd\\.s\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.s\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.s\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.s\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tmadd\\.d\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.d\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.d\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.d\t" 2 } } */ + +NOMIPS16 float +madd_s (float b, float c, float d) +{ + return b * c + d; +} + +NOMIPS16 float +msub_s (float b, float c, float d) +{ + return b * c + -d; +} + +NOMIPS16 float +nmadd_s (float b, float c, float d) +{ + return -(b * c + d); +} + +NOMIPS16 float +nmsub_s (float b, float c, float d) +{ + return -(b * c + -d); +} + +NOMIPS16 float +nmadd_s_2 (float b, float c, float d) +{ + return -b * c - d; +} + +NOMIPS16 float +nmsub_s_2 (float b, float c, float d) +{ + return -b * c + d; +} + +NOMIPS16 double +madd_d (double b, double c, double d) +{ + return b * c + d; +} + +NOMIPS16 double +msub_d (double b, double c, double d) +{ + return b * c + -d; +} + +NOMIPS16 double +nmadd_d (double b, double c, double d) +{ + return -(b * c + d); +} + +NOMIPS16 double +nmsub_d (double b, double c, double d) +{ + return -(b * c + -d); +} + +NOMIPS16 double +nmadd_d_2 (double b, double c, double d) +{ + return -b * c - d; +} + +NOMIPS16 double +nmsub_d_2 (double b, double c, double d) +{ + return -b * c + d; +} diff --git a/gcc/testsuite/gcc.target/mips/fma-3.c b/gcc/testsuite/gcc.target/mips/fma-3.c new file mode 100644 index 00000000000..1a387c23bb6 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-3.c @@ -0,0 +1,16 @@ +/* { dg-options "-mgp64 -mhard-float isa>=4 -O3 -fno-fast-math -ffp-contract=off -ffinite-math-only" } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.s\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.d\t" 1 } } */ +/* { dg-final { scan-assembler-not "\tnmadd\\." } } */ + +NOMIPS16 float +nmsub_s (float b, float c, float d) +{ + return -__builtin_fmaf (b, c, -d); +} + +NOMIPS16 double +nmsub_d (double b, double c, double d) +{ + return -__builtin_fma (b, c, -d); +} diff --git a/gcc/testsuite/gcc.target/mips/fma-4.c b/gcc/testsuite/gcc.target/mips/fma-4.c new file mode 100644 index 00000000000..4ae7f5f4b67 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-4.c @@ -0,0 +1,17 @@ +/* { dg-options "-mgp64 -mhard-float isa>=4 -O3 -fno-fast-math -ffp-contract=off -ffinite-math-only" } */ +/* { dg-final { scan-assembler-not "\tnmadd\\." } } */ +/* { dg-final { scan-assembler-not "\tnmsub\\." } } */ + +/* These patterns can only use NMADD if -fno-signed-zeros is in effect. */ + +NOMIPS16 float +not_nmadd_s_2 (float b, float c, float d) +{ + return __builtin_fmaf (-b, c, -d); +} + +NOMIPS16 double +not_nmadd_d_2 (double b, double c, double d) +{ + return __builtin_fma (-b, c, -d); +} diff --git a/gcc/testsuite/gcc.target/mips/fma-5.c b/gcc/testsuite/gcc.target/mips/fma-5.c new file mode 100644 index 00000000000..410a904734a --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-5.c @@ -0,0 +1,17 @@ +/* { dg-options "-mgp64 -mhard-float isa>=4 -O3 -fno-fast-math -ffp-contract=off -ffinite-math-only" } */ +/* { dg-final { scan-assembler-not "\tnmadd\\." } } */ +/* { dg-final { scan-assembler-not "\tnmsub\\." } } */ + +/* These patterns can only use NMSUB if -fno-signed-zeros is in effect. */ + +NOMIPS16 float +not_nmsub_s_2 (float b, float c, float d) +{ + return __builtin_fmaf (-b, c, d); +} + +NOMIPS16 double +not_nmsub_d_2 (double b, double c, double d) +{ + return __builtin_fma (-b, c, d); +} diff --git a/gcc/testsuite/gcc.target/mips/fma-6.c b/gcc/testsuite/gcc.target/mips/fma-6.c new file mode 100644 index 00000000000..359983721d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-6.c @@ -0,0 +1,16 @@ +/* { dg-options "-mgp64 -mhard-float isa>=4 -O3 -ffast-math" } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.s\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.d\t" 1 } } */ +/* { dg-final { scan-assembler-not "\tnmsub\\." } } */ + +NOMIPS16 float +nmadd_s_2 (float b, float c, float d) +{ + return __builtin_fmaf (-b, c, -d); +} + +NOMIPS16 double +nmadd_d_2 (double b, double c, double d) +{ + return __builtin_fma (-b, c, -d); +} diff --git a/gcc/testsuite/gcc.target/mips/fma-7.c b/gcc/testsuite/gcc.target/mips/fma-7.c new file mode 100644 index 00000000000..11817e63627 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-7.c @@ -0,0 +1,16 @@ +/* { dg-options "-mgp64 -mhard-float isa>=4 -O3 -ffast-math" } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.s\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.d\t" 1 } } */ +/* { dg-final { scan-assembler-not "\tnmadd\\." } } */ + +NOMIPS16 float +nmsub_s_2 (float b, float c, float d) +{ + return __builtin_fmaf (-b, c, d); +} + +NOMIPS16 double +nmsub_d_2 (double b, double c, double d) +{ + return __builtin_fma (-b, c, d); +} diff --git a/gcc/testsuite/gcc.target/mips/fma-8.c b/gcc/testsuite/gcc.target/mips/fma-8.c new file mode 100644 index 00000000000..d54138d3df4 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-8.c @@ -0,0 +1,81 @@ +/* { dg-options "-mgp64 -mhard-float isa>=4 -O -ffast-math" } */ +/* { dg-final { scan-assembler-times "\tmadd\\.s\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.s\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.s\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.s\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tmadd\\.d\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tmsub\\.d\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tnmadd\\.d\t" 2 } } */ +/* { dg-final { scan-assembler-times "\tnmsub\\.d\t" 2 } } */ + +NOMIPS16 float +madd_s (float b, float c, float d) +{ + return __builtin_fmaf (b, c, d); +} + +NOMIPS16 float +msub_s (float b, float c, float d) +{ + return __builtin_fmaf (b, c, -d); +} + +NOMIPS16 float +nmadd_s (float b, float c, float d) +{ + return -__builtin_fmaf (b, c, d); +} + +NOMIPS16 float +nmsub_s (float b, float c, float d) +{ + return -__builtin_fmaf (b, c, -d); +} + +NOMIPS16 float +nmadd_s_2 (float b, float c, float d) +{ + return __builtin_fmaf (-b, c, -d); +} + +NOMIPS16 float +nmsub_s_2 (float b, float c, float d) +{ + return __builtin_fmaf (-b, c, d); +} + +NOMIPS16 double +madd_d (double b, double c, double d) +{ + return __builtin_fma (b, c, d); +} + +NOMIPS16 double +msub_d (double b, double c, double d) +{ + return __builtin_fma (b, c, -d); +} + +NOMIPS16 double +nmadd_d (double b, double c, double d) +{ + return -__builtin_fma (b, c, d); +} + +NOMIPS16 double +nmsub_d (double b, double c, double d) +{ + return -__builtin_fma (b, c, -d); +} + +NOMIPS16 double +nmadd_d_2 (double b, double c, double d) +{ + return __builtin_fma (-b, c, -d); +} + +NOMIPS16 double +nmsub_d_2 (double b, double c, double d) +{ + return __builtin_fma (-b, c, d); +} diff --git a/gcc/testsuite/gcc.target/mips/fma-9.c b/gcc/testsuite/gcc.target/mips/fma-9.c new file mode 100644 index 00000000000..a0fc1b084c3 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/fma-9.c @@ -0,0 +1,70 @@ +/* { dg-options "-mpaired-single -O3 -fno-fast-math -ftree-vectorize -ffp-contract=off" } */ +/* { dg-final { scan-assembler "\tmadd\\.ps\t" } } */ +/* { dg-final { scan-assembler "\tmsub\\.s\t" } } */ +/* { dg-final { scan-assembler-not "\tmsub\\.ps\t" } } */ +/* { dg-final { scan-assembler-not "\tnmadd\\." } } */ +/* { dg-final { scan-assembler-not "\tnmsub\\." } } */ + +/* We should not use NMADD or NMSUB without -ffinite-math-only because + those instructions may perform arithmetic negation. We don't really + expect the nmadd_ps and nmsub_ps functions to use MADD.PS and MSUB.PS, + but there's no reason in principle why they shouldn't. + + ??? At the moment, we don't vectorize msub_ps, but we probably should. */ + +#define N 512 +float a[N], b[N], c[N], d[N]; + +NOMIPS16 void +madd_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = __builtin_fmaf (b[i], c[i], d[i]); +} + +NOMIPS16 float +msub_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = __builtin_fmaf (b[i], c[i], -d[i]); +} + +NOMIPS16 float +not_nmadd_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -__builtin_fmaf (b[i], c[i], d[i]); +} + +NOMIPS16 float +not_nmsub_ps (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = -__builtin_fmaf (b[i], c[i], -d[i]); +} + +NOMIPS16 float +not_nmadd_ps_2 (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = __builtin_fmaf (-b[i], c[i], -d[i]); +} + +NOMIPS16 float +not_nmsub_ps_2 (void) +{ + int i; + + for (i = 0; i < N; i++) + a[i] = __builtin_fmaf (-b[i], c[i], d[i]); +} diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp index 0a7bc1de8dd..1165b17cdf9 100644 --- a/gcc/testsuite/gcc.target/mips/mips.exp +++ b/gcc/testsuite/gcc.target/mips/mips.exp @@ -292,6 +292,13 @@ foreach option { lappend mips_option_groups $option "-f(no-|)$option" } +# Add -ffoo= options to mips_option_groups. +foreach option { + fp-contract +} { + lappend mips_option_groups $option "-f$option=.*" +} + # A list of option groups that have an impact on the ABI. set mips_abi_groups { abi