diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2010-11-07 08:31:21 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2010-11-07 08:31:21 +0000 |
commit | c7c0f73d6801b4e839775ec2a09c1acf6378dbda (patch) | |
tree | edb7d2ffaa18aad04bf1fc786b747a7550468a9b /gcc | |
parent | 4de2f020aaca3d0a8112acc6234a34bb5d578fa0 (diff) | |
download | gcc-c7c0f73d6801b4e839775ec2a09c1acf6378dbda.zip gcc-c7c0f73d6801b4e839775ec2a09c1acf6378dbda.tar.gz gcc-c7c0f73d6801b4e839775ec2a09c1acf6378dbda.tar.bz2 |
mips.c (mips_rtx_costs): Handle FMA.
gcc/
* config/mips/mips.c (mips_rtx_costs): Handle FMA.
* config/mips/mips.md (*madd4<mode>, *madd3<mode>, *msub4<mode>)
(*msub3<mode>, *nmadd4<mode>_fastmath, *nmadd3<mode>_fastmath)
(*nmsub4<mode>_fastmath, *nmsub3<mode>_fastmath): Delete.
(*nmadd4<mode>, *nmadd3<mode>. *nmsub4<mode>, *nmsub3<mode>): Redefine
to use FMA.
(fma<mode>4, *fma<mode>4_madd3, *fma<mode>4_madd4): New patterns.
(fms<mode>4, *fms<mode>4_msub3, *fms<mode>4_msub4): Likewise.
(fnms<mode>4, *fnms<mode>4_nmadd3, *fnms<mode>4_nmadd4): Likewise.
(fnma<mode>4, *fnma<mode>4_nmsub3, *fnma<mode>4_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
Diffstat (limited to 'gcc')
25 files changed, 1305 insertions, 90 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cb4c17a..8b59066 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2010-11-07 Richard Sandiford <rdsandiford@googlemail.com> + + * config/mips/mips.c (mips_rtx_costs): Handle FMA. + * config/mips/mips.md (*madd4<mode>, *madd3<mode>, *msub4<mode>) + (*msub3<mode>, *nmadd4<mode>_fastmath, *nmadd3<mode>_fastmath) + (*nmsub4<mode>_fastmath, *nmsub3<mode>_fastmath): Delete. + (*nmadd4<mode>, *nmadd3<mode>. *nmsub4<mode>, *nmsub3<mode>): Redefine + to use FMA. + (fma<mode>4, *fma<mode>4_madd3, *fma<mode>4_madd4): New patterns. + (fms<mode>4, *fms<mode>4_msub3, *fms<mode>4_msub4): Likewise. + (fnms<mode>4, *fnms<mode>4_nmadd3, *fnms<mode>4_nmadd4): Likewise. + (fnma<mode>4, *fnma<mode>4_nmsub3, *fnma<mode>4_nmsub4): Likewise. + 2010-11-06 Simon Martin <simartin@users.sourceforge.net> PR c/43384 diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 76c0786..c10e9d1 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 b789394..a5f5d48 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -2077,158 +2077,176 @@ ;; Floating point multiply accumulate instructions. -(define_insn "*madd4<mode>" - [(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.<fmt>\t%0,%3,%1,%2" - [(set_attr "type" "fmadd") - (set_attr "mode" "<UNITMODE>")]) +(define_expand "fma<mode>4" + [(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<mode>" +(define_insn "*fma<mode>4_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.<fmt>\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*msub4<mode>" +(define_insn "*fma<mode>4_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.<fmt>\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.<fmt>\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*msub3<mode>" +(define_expand "fms<mode>4" + [(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 "*fms<mode>4_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.<fmt>\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmadd4<mode>" +(define_insn "*fms<mode>4_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"))))] - "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode) - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (<MODE>mode) - && !HONOR_NANS (<MODE>mode)" - "nmadd.<fmt>\t%0,%3,%1,%2" + (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.<fmt>\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmadd3<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 "fnms<mode>4" + [(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>mode) || ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)) + && !HONOR_SIGNED_ZEROS (<MODE>mode) + && !HONOR_NANS (<MODE>mode)") + +(define_insn "*fnms<mode>4_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")) - (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") + (neg:ANYF (match_operand:ANYF 3 "register_operand" "0"))))] "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode) - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (<MODE>mode) + && !HONOR_SIGNED_ZEROS (<MODE>mode) && !HONOR_NANS (<MODE>mode)" "nmadd.<fmt>\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmadd4<mode>_fastmath" +(define_insn "*fnms<mode>4_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")))] + (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>mode) - && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (<MODE>mode) && !HONOR_NANS (<MODE>mode)" "nmadd.<fmt>\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmadd3<mode>_fastmath" +(define_insn "*nmadd3" [(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")))] - "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode) - && TARGET_FUSED_MADD - && !HONOR_SIGNED_ZEROS (<MODE>mode) - && !HONOR_NANS (<MODE>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" "0"))))] + "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode) && !HONOR_NANS (<MODE>mode)" "nmadd.<fmt>\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmsub4<mode>" +(define_insn "*nmadd4" [(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"))))] - "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode) - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (<MODE>mode) - && !HONOR_NANS (<MODE>mode)" - "nmsub.<fmt>\t%0,%1,%2,%3" + (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>mode) && !HONOR_NANS (<MODE>mode)" + "nmadd.<fmt>\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmsub3<mode>" +;; 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 "fnma<mode>4" + [(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>mode) || ISA_HAS_NMADD4_NMSUB4 (<MODE>mode)) + && !HONOR_SIGNED_ZEROS (<MODE>mode) + && !HONOR_NANS (<MODE>mode)") + +(define_insn "*fnma<mode>4_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"))))] + (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>mode) - && TARGET_FUSED_MADD - && HONOR_SIGNED_ZEROS (<MODE>mode) + && !HONOR_SIGNED_ZEROS (<MODE>mode) && !HONOR_NANS (<MODE>mode)" "nmsub.<fmt>\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmsub4<mode>_fastmath" +(define_insn "*fnma<mode>4_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"))))] + (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>mode) - && TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (<MODE>mode) && !HONOR_NANS (<MODE>mode)" - "nmsub.<fmt>\t%0,%1,%2,%3" + "nmsub.<fmt>\t%0,%3,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) -(define_insn "*nmsub3<mode>_fastmath" +(define_insn "*nmsub3" [(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>mode) - && TARGET_FUSED_MADD - && !HONOR_SIGNED_ZEROS (<MODE>mode) - && !HONOR_NANS (<MODE>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>mode) && !HONOR_NANS (<MODE>mode)" "nmsub.<fmt>\t%0,%1,%2" [(set_attr "type" "fmadd") (set_attr "mode" "<UNITMODE>")]) +(define_insn "*nmsub4" + [(set (match_operand:ANYF 0 "register_operand" "=f") + (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>mode) && !HONOR_NANS (<MODE>mode)" + "nmsub.<fmt>\t%0,%3,%1,%2" + [(set_attr "type" "fmadd") + (set_attr "mode" "<UNITMODE>")]) + ;; ;; .................... ;; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c5ccdb8..806b1d1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,27 @@ +2010-11-07 Richard Sandiford <rdsandiford@googlemail.com> + + * 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 <jason@redhat.com> * 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 0000000..d1674732 --- /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 0000000..bb3f31b --- /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 0000000..17f124f --- /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 0000000..6a6303c --- /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 0000000..2dbff9b --- /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 0000000..383effd --- /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 0000000..4fdfeab --- /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 0000000..16cda12 --- /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 0000000..87b2de1 --- /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 0000000..244f232 --- /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 0000000..c038f19 --- /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 0000000..26c7742 --- /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 0000000..ab0cbdf --- /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 0000000..1a387c2 --- /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 0000000..4ae7f5f --- /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 0000000..410a904 --- /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 0000000..3599837 --- /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 0000000..11817e6 --- /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 0000000..d54138d3 --- /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 0000000..a0fc1b0 --- /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 0a7bc1d..1165b17 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 |