1/* Test whether using target specific options, we can generate FMA4 code.  */
2/* { dg-do compile } */
3/* { dg-require-effective-target lp64 } */
4/* { dg-options "-O2 -march=k8" } */
5
6extern void exit (int);
7
8#define FMA4_ATTR __attribute__((__target__("fma4")))
9extern float  flt_mul_add     (float a, float b, float c) FMA4_ATTR;
10extern float  flt_mul_sub     (float a, float b, float c) FMA4_ATTR;
11extern float  flt_neg_mul_add (float a, float b, float c) FMA4_ATTR;
12extern float  flt_neg_mul_sub (float a, float b, float c) FMA4_ATTR;
13
14extern double dbl_mul_add     (double a, double b, double c) FMA4_ATTR;
15extern double dbl_mul_sub     (double a, double b, double c) FMA4_ATTR;
16extern double dbl_neg_mul_add (double a, double b, double c) FMA4_ATTR;
17extern double dbl_neg_mul_sub (double a, double b, double c) FMA4_ATTR;
18
19float
20flt_mul_add (float a, float b, float c)
21{
22  return (a * b) + c;
23}
24
25double
26dbl_mul_add (double a, double b, double c)
27{
28  return (a * b) + c;
29}
30
31float
32flt_mul_sub (float a, float b, float c)
33{
34  return (a * b) - c;
35}
36
37double
38dbl_mul_sub (double a, double b, double c)
39{
40  return (a * b) - c;
41}
42
43float
44flt_neg_mul_add (float a, float b, float c)
45{
46  return (-(a * b)) + c;
47}
48
49double
50dbl_neg_mul_add (double a, double b, double c)
51{
52  return (-(a * b)) + c;
53}
54
55float
56flt_neg_mul_sub (float a, float b, float c)
57{
58  return (-(a * b)) - c;
59}
60
61double
62dbl_neg_mul_sub (double a, double b, double c)
63{
64  return (-(a * b)) - c;
65}
66
67float  f[10] = { 2, 3, 4 };
68double d[10] = { 2, 3, 4 };
69
70int main ()
71{
72  f[3] = flt_mul_add (f[0], f[1], f[2]);
73  f[4] = flt_mul_sub (f[0], f[1], f[2]);
74  f[5] = flt_neg_mul_add (f[0], f[1], f[2]);
75  f[6] = flt_neg_mul_sub (f[0], f[1], f[2]);
76
77  d[3] = dbl_mul_add (d[0], d[1], d[2]);
78  d[4] = dbl_mul_sub (d[0], d[1], d[2]);
79  d[5] = dbl_neg_mul_add (d[0], d[1], d[2]);
80  d[6] = dbl_neg_mul_sub (d[0], d[1], d[2]);
81  exit (0);
82}
83
84/* { dg-final { scan-assembler "vfmaddss" } } */
85/* { dg-final { scan-assembler "vfmaddsd" } } */
86/* { dg-final { scan-assembler "vfmsubss" } } */
87/* { dg-final { scan-assembler "vfmsubsd" } } */
88/* { dg-final { scan-assembler "vfnmaddss" } } */
89/* { dg-final { scan-assembler "vfnmaddsd" } } */
90/* { dg-final { scan-assembler "vfnmsubss" } } */
91/* { dg-final { scan-assembler "vfnmsubsd" } } */
92/* { dg-final { scan-assembler "call\t(.*)flt_mul_add" } } */
93/* { dg-final { scan-assembler "call\t(.*)flt_mul_sub" } } */
94/* { dg-final { scan-assembler "call\t(.*)flt_neg_mul_add" } } */
95/* { dg-final { scan-assembler "call\t(.*)flt_neg_mul_sub" } } */
96/* { dg-final { scan-assembler "call\t(.*)dbl_mul_add" } } */
97/* { dg-final { scan-assembler "call\t(.*)dbl_mul_sub" } } */
98/* { dg-final { scan-assembler "call\t(.*)dbl_neg_mul_add" } } */
99/* { dg-final { scan-assembler "call\t(.*)dbl_neg_mul_sub" } } */
100