aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2010-11-07 08:31:21 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2010-11-07 08:31:21 +0000
commitc7c0f73d6801b4e839775ec2a09c1acf6378dbda (patch)
treeedb7d2ffaa18aad04bf1fc786b747a7550468a9b /gcc/testsuite
parent4de2f020aaca3d0a8112acc6234a34bb5d578fa0 (diff)
downloadgcc-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/testsuite')
-rw-r--r--gcc/testsuite/ChangeLog24
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-1.c82
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-10.c62
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-11.c79
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-12.c82
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-13.c81
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-14.c64
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-15.c65
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-16.c62
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-17.c82
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-18.c81
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-19.c79
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-2.c16
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-20.c81
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-3.c16
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-4.c17
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-5.c17
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-6.c16
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-7.c16
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-8.c81
-rw-r--r--gcc/testsuite/gcc.target/mips/fma-9.c70
-rw-r--r--gcc/testsuite/gcc.target/mips/mips.exp7
22 files changed, 1180 insertions, 0 deletions
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