1/* Test that the compiler properly generates floating point multiply
2   and add instructions FMA3 systems.  */
3
4/* { dg-do compile { target { ! { ia32 } } } } */
5/* { dg-options "-O2 -mfma -mno-fma4" } */
6
7#ifndef __FP_FAST_FMAF
8# error "__FP_FAST_FMAF should be defined"
9#endif
10#ifndef __FP_FAST_FMA
11# error "__FP_FAST_FMA should be defined"
12#endif
13
14float
15flt_mul_add (float a, float b, float c)
16{
17  return __builtin_fmaf (a, b, c);
18}
19
20double
21dbl_mul_add (double a, double b, double c)
22{
23  return __builtin_fma (a, b, c);
24}
25
26float
27flt_mul_sub (float a, float b, float c)
28{
29  return __builtin_fmaf (a, b, -c);
30}
31
32double
33dbl_mul_sub (double a, double b, double c)
34{
35  return __builtin_fma (a, b, -c);
36}
37
38float
39flt_neg_mul_add_1 (float a, float b, float c)
40{
41  return __builtin_fmaf (-a, b, c);
42}
43
44double
45dbl_neg_mul_add_1 (double a, double b, double c)
46{
47  return __builtin_fma (-a, b, c);
48}
49
50float
51flt_neg_mul_add_2 (float a, float b, float c)
52{
53  return __builtin_fmaf (a, -b, c);
54}
55
56double
57dbl_neg_mul_add_2 (double a, double b, double c)
58{
59  return __builtin_fma (a, -b, c);
60}
61
62float
63flt_neg_mul_sub (float a, float b, float c)
64{
65  return __builtin_fmaf (-a, b, -c);
66}
67
68double
69dbl_neg_mul_sub (double a, double b, double c)
70{
71  return __builtin_fma (-a, b, -c);
72}
73
74/* { dg-final { scan-assembler-times "vfmadd...ss" 1 } } */
75/* { dg-final { scan-assembler-times "vfmadd...sd" 1 } } */
76/* { dg-final { scan-assembler-times "vfmsub...ss" 1 } } */
77/* { dg-final { scan-assembler-times "vfmsub...sd" 1 } } */
78/* { dg-final { scan-assembler-times "vfnmadd...ss" 2 } } */
79/* { dg-final { scan-assembler-times "vfnmadd...sd" 2 } } */
80/* { dg-final { scan-assembler-times "vfnmsub...ss" 1 } } */
81/* { dg-final { scan-assembler-times "vfnmsub...sd" 1 } } */
82