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