1  /* { dg-do compile { target { powerpc*-*-* } } } */
       2  /* { dg-skip-if "" { powerpc*-*-darwin* } } */
       3  /* { dg-require-effective-target powerpc_vsx_ok } */
       4  /* { dg-options "-O3 -ftree-vectorize -mdejagnu-cpu=power7 -ffast-math -fno-unroll-loops" } */
       5  /* { dg-final { scan-assembler-times "xvmadd" 4 } } */
       6  /* { dg-final { scan-assembler-times "xsmadd\|fmadd\ " 2 } } */
       7  /* { dg-final { scan-assembler-times "fmadds" 2 } } */
       8  /* { dg-final { scan-assembler-times "xvmsub" 2 } } */
       9  /* { dg-final { scan-assembler-times "xsmsub\|fmsub\ " 1 } } */
      10  /* { dg-final { scan-assembler-times "fmsubs" 1 } } */
      11  /* { dg-final { scan-assembler-times "xvnmadd" 2 } } */
      12  /* { dg-final { scan-assembler-times "xsnmadd\|fnmadd " 1 } } */
      13  /* { dg-final { scan-assembler-times "fnmadds" 1 } } */
      14  /* { dg-final { scan-assembler-times "xvnmsub" 2 } } */
      15  /* { dg-final { scan-assembler-times "xsnmsub\|fnmsub " 1 } } */
      16  /* { dg-final { scan-assembler-times "fnmsubs" 1 } } */
      17  
      18  /* All functions should generate an appropriate (a * b) + c instruction
      19     since -mfused-madd is on by default.  */
      20  
      21  double
      22  builtin_fma (double b, double c, double d)
      23  {
      24    return __builtin_fma (b, c, d);			/* xsmadd{a,m}dp */
      25  }
      26  
      27  double
      28  builtin_fms (double b, double c, double d)
      29  {
      30    return __builtin_fma (b, c, -d);			/* xsmsub{a,b}dp */
      31  }
      32  
      33  double
      34  builtin_fnma (double b, double c, double d)
      35  {
      36    return - __builtin_fma (b, c, d);			/* xsnmadd{a,b}dp */
      37  }
      38  
      39  double
      40  builtin_fnms (double b, double c, double d)
      41  {
      42    return - __builtin_fma (b, c, -d);			/* xsnmsub{a,b}dp */
      43  }
      44  
      45  float
      46  builtin_fmaf (float b, float c, float d)
      47  {
      48    return __builtin_fmaf (b, c, d);			/* fmadds */
      49  }
      50  
      51  float
      52  builtin_fmsf (float b, float c, float d)
      53  {
      54    return __builtin_fmaf (b, c, -d);			/* fmsubs */
      55  }
      56  
      57  float
      58  builtin_fnmaf (float b, float c, float d)
      59  {
      60    return - __builtin_fmaf (b, c, d);			/* fnmadds */
      61  }
      62  
      63  float
      64  builtin_fnmsf (float b, float c, float d)
      65  {
      66    return - __builtin_fmaf (b, c, -d);			/* fnmsubs */
      67  }
      68  
      69  double
      70  normal_fma (double b, double c, double d)
      71  {
      72    return (b * c) + d;					/* xsmadd{a,m}dp */
      73  }
      74  
      75  float
      76  normal_fmaf (float b, float c, float d)
      77  {
      78    return (b * c) + d;					/* fmadds */
      79  }
      80  
      81  #ifndef SIZE
      82  #define SIZE 1024
      83  #endif
      84  
      85  double vda[SIZE] __attribute__((__aligned__(32)));
      86  double vdb[SIZE] __attribute__((__aligned__(32)));
      87  double vdc[SIZE] __attribute__((__aligned__(32)));
      88  double vdd[SIZE] __attribute__((__aligned__(32)));
      89  
      90  float vfa[SIZE] __attribute__((__aligned__(32)));
      91  float vfb[SIZE] __attribute__((__aligned__(32)));
      92  float vfc[SIZE] __attribute__((__aligned__(32)));
      93  float vfd[SIZE] __attribute__((__aligned__(32)));
      94  
      95  void
      96  vector_fma (void)
      97  {
      98    int i;
      99  
     100    for (i = 0; i < SIZE; i++)
     101      vda[i] = __builtin_fma (vdb[i], vdc[i], vdd[i]);	/* xvmadd{a,m}dp */
     102  }
     103  
     104  void
     105  vector_fms (void)
     106  {
     107    int i;
     108  
     109    for (i = 0; i < SIZE; i++)
     110      vda[i] = __builtin_fma (vdb[i], vdc[i], -vdd[i]);	/* xvmsub{a,m}dp */
     111  }
     112  
     113  void
     114  vector_fnma (void)
     115  {
     116    int i;
     117  
     118    for (i = 0; i < SIZE; i++)
     119      vda[i] = - __builtin_fma (vdb[i], vdc[i], vdd[i]);	/* xvnmadd{a,m}dp */
     120  }
     121  
     122  void
     123  vector_fnms (void)
     124  {
     125    int i;
     126  
     127    for (i = 0; i < SIZE; i++)
     128      vda[i] = - __builtin_fma (vdb[i], vdc[i], -vdd[i]);	/* xvnmsub{a,m}dp */
     129  }
     130  
     131  void
     132  vector_fmaf (void)
     133  {
     134    int i;
     135  
     136    for (i = 0; i < SIZE; i++)
     137      vfa[i] = __builtin_fmaf (vfb[i], vfc[i], vfd[i]);	/* xvmadd{a,m}sp */
     138  }
     139  
     140  void
     141  vector_fmsf (void)
     142  {
     143    int i;
     144  
     145    for (i = 0; i < SIZE; i++)
     146      vfa[i] = __builtin_fmaf (vfb[i], vfc[i], -vfd[i]);	/* xvmsub{a,m}sp */
     147  }
     148  
     149  void
     150  vector_fnmaf (void)
     151  {
     152    int i;
     153  
     154    for (i = 0; i < SIZE; i++)
     155      vfa[i] = - __builtin_fmaf (vfb[i], vfc[i], vfd[i]);	/* xvnmadd{a,m}sp */
     156  }
     157  
     158  void
     159  vector_fnmsf (void)
     160  {
     161    int i;
     162  
     163    for (i = 0; i < SIZE; i++)
     164      vfa[i] = - __builtin_fmaf (vfb[i], vfc[i], -vfd[i]); /* xvnmsub{a,m}sp */
     165  }
     166  
     167  void
     168  vnormal_fma (void)
     169  {
     170    int i;
     171  
     172    for (i = 0; i < SIZE; i++)
     173      vda[i] = (vdb[i] * vdc[i]) + vdd[i];		/* xvmadd{a,m}dp */
     174  }
     175  
     176  void
     177  vnormal_fmaf (void)
     178  {
     179    int i;
     180  
     181    for (i = 0; i < SIZE; i++)
     182      vfa[i] = (vfb[i] * vfc[i]) + vfd[i];		/* xvmadd{a,m}sp */
     183  }