2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2014, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
36 #ifndef GMX_SIMD_IMPLEMENTATION_IBM_QPX_H
37 #define GMX_SIMD_IMPLEMENTATION_IBM_QPX_H
44 /* IBM QPX SIMD instruction wrappers
46 * Please see documentation in gromacs/simd/simd.h for the available
49 /* Capability definitions for IBM QPX */
50 #define GMX_SIMD_HAVE_FLOAT
51 #define GMX_SIMD_HAVE_DOUBLE
52 #define GMX_SIMD_HAVE_HARDWARE
53 #undef GMX_SIMD_HAVE_STOREU
54 #undef GMX_SIMD_HAVE_STOREU
55 #undef GMX_SIMD_HAVE_LOGICAL
56 #define GMX_SIMD_HAVE_FMA
57 #undef GMX_SIMD_HAVE_FRACTION
58 #define GMX_SIMD_HAVE_FINT32
59 #undef GMX_SIMD_HAVE_FINT32_EXTRACT
60 #undef GMX_SIMD_HAVE_FINT32_LOGICAL
61 #undef GMX_SIMD_HAVE_FINT32_ARITHMETICS
62 #define GMX_SIMD_HAVE_DINT32
63 #undef GMX_SIMD_HAVE_DINT32_EXTRACT
64 #undef GMX_SIMD_HAVE_DINT32_LOGICAL
65 #undef GMX_SIMD_HAVE_DINT32_ARITHMETICS
66 #define GMX_SIMD4_HAVE_FLOAT
67 #define GMX_SIMD4_HAVE_DOUBLE
69 /* Implementation details */
70 #define GMX_SIMD_FLOAT_WIDTH 4
71 #define GMX_SIMD_DOUBLE_WIDTH 4
72 #define GMX_SIMD_FINT32_WIDTH 4
73 #define GMX_SIMD_DINT32_WIDTH 4
74 #define GMX_SIMD_RSQRT_BITS 14
75 #define GMX_SIMD_RCP_BITS 14
77 /****************************************************
78 * SINGLE PRECISION SIMD IMPLEMENTATION *
79 ****************************************************/
80 #define gmx_simd_float_t vector4double
82 # define gmx_simd_load_f(m) vec_ld(0, (float *)(m))
83 # define gmx_simd_store_f(m, a) vec_st(a, 0, (float *)(m))
85 # define gmx_simd_load_f(m) vec_lda(0, (float *)(m))
86 # define gmx_simd_store_f(m, a) vec_sta(a, 0, (float *)(m))
88 # define gmx_simd_load1_f(m) vec_lds(0, (float *)(m))
89 #define gmx_simd_set1_f(x) vec_splats(x)
90 /* No support for unaligned load/store */
91 #define gmx_simd_setzero_f gmx_simd_setzero_ibm_qpx
92 #define gmx_simd_add_f(a, b) vec_add(a, b)
93 #define gmx_simd_sub_f(a, b) vec_sub(a, b)
94 #define gmx_simd_mul_f(a, b) vec_mul(a, b)
95 #define gmx_simd_fmadd_f(a, b, c) vec_madd(a, b, c)
96 #define gmx_simd_fmsub_f(a, b, c) vec_msub(a, b, c)
97 /* IBM uses an alternative FMA definition, so -a*b+c=-(a*b-c) is "nmsub" */
98 #define gmx_simd_fnmadd_f(a, b, c) vec_nmsub(a, b, c)
99 /* IBM uses an alternative FMA definition, so -a*b-c=-(a*b+c) is "nmadd" */
100 #define gmx_simd_fnmsub_f(a, b, c) vec_nmadd(a, b, c)
101 /* gmx_simd_and_f not supported - no bitwise logical ops */
102 /* gmx_simd_andnot_f not supported - no bitwise logical ops */
103 /* gmx_simd_or_f not supported - no bitwise logical ops */
104 /* gmx_simd_xor_f not supported - no bitwise logical ops */
105 #define gmx_simd_rsqrt_f(a) vec_rsqrte(a)
106 #define gmx_simd_rcp_f(a) vec_re(a)
107 #define gmx_simd_fabs_f(a) vec_abs(a)
108 #define gmx_simd_fneg_f gmx_simd_fneg_ibm_qpx
109 #define gmx_simd_max_f(a, b) vec_sel(b, a, vec_sub(a, b))
110 #define gmx_simd_min_f(a, b) vec_sel(b, a, vec_sub(b, a))
111 /* Note: It is critical to use vec_cfid(vec_ctid(a)) for the implementation
112 * of gmx_simd_round_f(), since vec_round() does not adhere to the FP control
113 * word rounding scheme. We rely on float-to-float and float-to-integer
114 * rounding being the same for half-way values in a few algorithms.
116 #define gmx_simd_round_f(a) vec_cfid(vec_ctid(a))
117 #define gmx_simd_trunc_f(a) vec_trunc(a)
118 #define gmx_simd_fraction_f(x) vec_sub(x, vec_trunc(x))
119 #define gmx_simd_get_exponent_f(a) gmx_simd_get_exponent_ibm_qpx(a)
120 #define gmx_simd_get_mantissa_f(a) gmx_simd_get_mantissa_ibm_qpx(a)
121 #define gmx_simd_set_exponent_f(a) gmx_simd_set_exponent_ibm_qpx(a)
122 /* integer datatype corresponding to float: gmx_simd_fint32_t */
123 #define gmx_simd_fint32_t vector4double
125 # define gmx_simd_load_fi(m) vec_ldia(0, (int *)(m))
127 # define gmx_simd_load_fi(m) vec_ldiaa(0, (int *)(m))
129 #define gmx_simd_set1_fi(i) gmx_simd_set1_int_ibm_qpx(i)
130 #define gmx_simd_store_fi(m, x) vec_st(x, 0, (int *)(m))
131 #define gmx_simd_setzero_fi gmx_simd_setzero_ibm_qpx
132 #define gmx_simd_cvt_f2i(a) vec_ctiw(a)
133 #define gmx_simd_cvtt_f2i(a) vec_ctiwz(a)
134 #define gmx_simd_cvt_i2f(a) vec_cfid(a)
135 /* Integer simd extract not available */
136 /* Integer logical ops on gmx_simd_fint32_t not supported */
137 /* Integer arithmetic ops on gmx_simd_fint32_t not supported */
138 /* Boolean & comparison operations on gmx_simd_float_t */
139 #define gmx_simd_fbool_t vector4double
140 #define gmx_simd_cmpeq_f(a, b) vec_cmpeq(a, b)
141 #define gmx_simd_cmplt_f(a, b) vec_cmplt((a), (b))
142 #define gmx_simd_cmple_f(a, b) gmx_simd_or_fb(vec_cmpeq(a, b), vec_cmplt(a, b))
143 #define gmx_simd_and_fb(a, b) vec_and(a, b)
144 #define gmx_simd_or_fb(a, b) vec_or(a, b)
145 #define gmx_simd_anytrue_fb(a) gmx_simd_anytrue_bool_ibm_qpx(a)
146 #define gmx_simd_blendzero_f(a, sel) vec_sel(vec_splats(0.0), a, sel)
147 #define gmx_simd_blendnotzero_f(a, sel) vec_sel(a, vec_splats(0.0), sel)
148 #define gmx_simd_blendv_f(a, b, sel) vec_sel(a, b, sel)
149 #define gmx_simd_reduce_f(a) gmx_simd_reduce_ibm_qpx(a)
152 /* Boolean & comparison operations on gmx_simd_fint32_t not supported */
153 /* Conversions between different booleans not supported */
155 static __attribute__((always_inline)) vector4double
156 gmx_simd_fneg_ibm_qpx(vector4double a)
160 /****************************************************
161 * DOUBLE PRECISION SIMD IMPLEMENTATION *
162 ****************************************************/
163 #define gmx_simd_double_t vector4double
165 # define gmx_simd_load_d(m) vec_ld(0, (double *)(m))
166 # define gmx_simd_store_d(m, a) vec_st(a, 0, (double *)(m))
168 # define gmx_simd_load_d(m) vec_lda(0, (double *)(m))
169 # define gmx_simd_store_d(m, a) vec_sta(a, 0, (double *)(m))
171 # define gmx_simd_load1_d(m) vec_lds(0, (double *)(m))
172 #define gmx_simd_set1_d(x) vec_splats(x)
173 /* No support for unaligned load/store */
174 #define gmx_simd_setzero_d gmx_simd_setzero_ibm_qpx
175 #define gmx_simd_add_d(a, b) vec_add(a, b)
176 #define gmx_simd_sub_d(a, b) vec_sub(a, b)
177 #define gmx_simd_mul_d(a, b) vec_mul(a, b)
178 #define gmx_simd_fmadd_d(a, b, c) vec_madd(a, b, c)
179 #define gmx_simd_fmsub_d(a, b, c) vec_msub(a, b, c)
180 /* IBM uses an alternative FMA definition, so -a*b+c=-(a*b-c) is "nmsub" */
181 #define gmx_simd_fnmadd_d(a, b, c) vec_nmsub(a, b, c)
182 /* IBM uses an alternative FMA definition, so -a*b-c=-(a*b+c) is "nmadd" */
183 #define gmx_simd_fnmsub_d(a, b, c) vec_nmadd(a, b, c)
184 /* gmx_simd_and_d not supported - no bitwise logical ops */
185 /* gmx_simd_andnot_d not supported - no bitwise logical ops */
186 /* gmx_simd_or_d not supported - no bitwise logical ops */
187 /* gmx_simd_xor_d not supported - no bitwise logical ops */
188 #define gmx_simd_rsqrt_d(a) vec_rsqrte(a)
189 #define gmx_simd_rcp_d(a) vec_re(a)
190 #define gmx_simd_fabs_d(a) vec_abs(a)
191 #define gmx_simd_fneg_d gmx_simd_fneg_ibm_qpx
192 #define gmx_simd_max_d(a, b) vec_sel(b, a, vec_sub(a, b))
193 #define gmx_simd_min_d(a, b) vec_sel(b, a, vec_sub(b, a))
194 /* Note: It is critical to use vec_cfid(vec_ctid(a)) for the implementation
195 * of gmx_simd_round_f(), since vec_round() does not adhere to the FP control
196 * word rounding scheme. We rely on float-to-float and float-to-integer
197 * rounding being the same for half-way values in a few algorithms.
199 #define gmx_simd_round_d(a) vec_cfid(vec_ctid(a))
200 #define gmx_simd_trunc_d(a) vec_trunc(a)
201 #define gmx_simd_fraction_d(x) vec_sub(x, vec_trunc(x))
202 #define gmx_simd_get_exponent_d(a) gmx_simd_get_exponent_ibm_qpx(a)
203 #define gmx_simd_get_mantissa_d(a) gmx_simd_get_mantissa_ibm_qpx(a)
204 #define gmx_simd_set_exponent_d(a) gmx_simd_set_exponent_ibm_qpx(a)
205 /* integer datatype corresponding to double: gmx_simd_dint32_t */
206 #define gmx_simd_dint32_t vector4double
208 # define gmx_simd_load_di(m) vec_ldia(0, (int *)(m))
210 # define gmx_simd_load_di(m) vec_ldiaa(0, (int *)(m))
212 #define gmx_simd_set1_di(i) gmx_simd_set1_int_ibm_qpx(i)
213 #define gmx_simd_store_di(m, x) vec_st(x, 0, (int *)(m))
214 #define gmx_simd_setzero_di gmx_simd_setzero_ibm_qpx
215 #define gmx_simd_cvt_d2i(a) vec_ctiw(a)
216 #define gmx_simd_cvtt_d2i(a) vec_ctiwz(a)
217 #define gmx_simd_cvt_i2d(a) vec_cfid(a)
218 /* Integer simd extract not available */
219 /* Integer logical ops on gmx_simd_dint32_t not supported */
220 /* Integer arithmetic ops on gmx_simd_dint32_t not supported */
221 /* Boolean & comparison operations on gmx_simd_double_t */
222 #define gmx_simd_dbool_t vector4double
223 #define gmx_simd_cmpeq_d(a, b) vec_cmpeq(a, b)
224 #define gmx_simd_cmplt_d(a, b) vec_cmplt((a), (b))
225 #define gmx_simd_cmple_d(a, b) gmx_simd_or_fb(vec_cmpeq(a, b), vec_cmplt(a, b))
226 #define gmx_simd_and_db(a, b) vec_and(a, b)
227 #define gmx_simd_or_db(a, b) vec_or(a, b)
228 #define gmx_simd_anytrue_db(a) gmx_simd_anytrue_bool_ibm_qpx(a)
229 #define gmx_simd_blendzero_d(a, sel) vec_sel(vec_splats(0.0), a, sel)
230 #define gmx_simd_blendnotzero_d(a, sel) vec_sel(a, vec_splats(0.0), sel)
231 #define gmx_simd_blendv_d(a, b, sel) vec_sel(a, b, sel)
232 #define gmx_simd_reduce_d(a) gmx_simd_reduce_ibm_qpx(a)
234 /* Boolean & comparison operations on gmx_simd_dint32_t not supported */
235 /* Conversions between different booleans not supported */
238 /****************************************************
239 * IMPLEMENTATION HELPER FUNCTIONS *
240 ****************************************************/
241 static __attribute__((always_inline)) vector4double gmx_simdcall
242 gmx_simd_setzero_ibm_qpx(void)
244 return vec_splats(0.0);
247 static __attribute__((always_inline)) vector4double gmx_simdcall
248 gmx_simd_get_exponent_ibm_qpx(vector4double x)
250 const gmx_int64_t expmask = 0x7ff0000000000000LL;
251 const gmx_int64_t expbase = 1023;
252 gmx_int64_t idata[4] __attribute__((aligned(32)));
254 /* Store to memory */
256 /* Perform integer arithmetics in general registers. */
257 idata[0] = ((idata[0] & expmask) >> 52) - expbase;
258 idata[1] = ((idata[1] & expmask) >> 52) - expbase;
259 idata[2] = ((idata[2] & expmask) >> 52) - expbase;
260 idata[3] = ((idata[3] & expmask) >> 52) - expbase;
261 /* Reload from memory */
262 return vec_cfid(vec_ld(0, idata));
265 static __attribute__((always_inline)) vector4double gmx_simdcall
266 gmx_simd_get_mantissa_ibm_qpx(vector4double x)
268 const gmx_int64_t exp_and_sign_mask = 0xfff0000000000000LL;
269 const gmx_int64_t ione = 0x3ff0000000000000LL;
270 gmx_int64_t idata[4] __attribute__((aligned(32)));
272 /* Store to memory */
274 /* Perform integer arithmetics in general registers. */
275 idata[0] = (idata[0] & (~exp_and_sign_mask)) | ione;
276 idata[1] = (idata[1] & (~exp_and_sign_mask)) | ione;
277 idata[2] = (idata[2] & (~exp_and_sign_mask)) | ione;
278 idata[3] = (idata[3] & (~exp_and_sign_mask)) | ione;
279 /* Reload from memory */
280 return vec_ld(0, idata);
283 static __attribute__((always_inline)) vector4double gmx_simdcall
284 gmx_simd_set_exponent_ibm_qpx(vector4double x)
286 const gmx_int64_t expbase = 1023;
287 gmx_int64_t idata[4] __attribute__((aligned(32)));
289 /* Store to memory for shifts. It is REALLY critical that we use the same
290 * rounding mode as for gmx_simd_round_r() here. In particular, for QPX
291 * this means we implement gmx_simd_round_r(a) as vec_cfid(vec_ctid(a)),
292 * since vec_round() uses a different rounding scheme.
294 vec_st(vec_ctid(x), 0, idata);
295 /* Perform integer arithmetics in general registers. */
296 idata[0] = (idata[0] + expbase) << 52;
297 idata[1] = (idata[1] + expbase) << 52;
298 idata[2] = (idata[2] + expbase) << 52;
299 idata[3] = (idata[3] + expbase) << 52;
300 /* Reload from memory */
301 return vec_ld(0, idata);
304 static __attribute__((always_inline)) double gmx_simdcall
305 gmx_simd_reduce_ibm_qpx(vector4double x)
307 vector4double y = vec_sldw(x, x, 2);
311 z = vec_sldw(y, y, 1);
313 return vec_extract(y, 0);
316 static __attribute__((always_inline)) vector4double gmx_simdcall
317 gmx_simd_set1_int_ibm_qpx(int i)
319 int idata[4] __attribute__((aligned(32)));
323 /* Reload from memory */
324 return vec_splat(vec_ldia(0, idata), 0);
327 /* This works in both single and double */
328 static __attribute__((always_inline)) int gmx_simdcall
329 gmx_simd_anytrue_bool_ibm_qpx(vector4double a)
331 vector4double b = vec_sldw(a, a, 2);
334 b = vec_sldw(a, a, 1);
336 return (vec_extract(a, 0) > 0);
339 /* QPX is already 4-wide both in single and double, so just reuse for SIMD4 */
342 #define gmx_simd4_float_t gmx_simd_float_t
343 #define gmx_simd4_load_f gmx_simd_load_f
344 #define gmx_simd4_load1_f gmx_simd_load1_f
345 #define gmx_simd4_set1_f gmx_simd_set1_f
346 #define gmx_simd4_store_f gmx_simd_store_f
347 #define gmx_simd4_loadu_f gmx_simd_loadu_f
348 #define gmx_simd4_storeu_f gmx_simd_storeu_f
349 #define gmx_simd4_setzero_f gmx_simd_setzero_f
350 #define gmx_simd4_add_f gmx_simd_add_f
351 #define gmx_simd4_sub_f gmx_simd_sub_f
352 #define gmx_simd4_mul_f gmx_simd_mul_f
353 #define gmx_simd4_fmadd_f gmx_simd_fmadd_f
354 #define gmx_simd4_fmsub_f gmx_simd_fmsub_f
355 #define gmx_simd4_fnmadd_f gmx_simd_fnmadd_f
356 #define gmx_simd4_fnmsub_f gmx_simd_fnmsub_f
357 #define gmx_simd4_and_f gmx_simd_and_f
358 #define gmx_simd4_andnot_f gmx_simd_andnot_f
359 #define gmx_simd4_or_f gmx_simd_or_f
360 #define gmx_simd4_xor_f gmx_simd_xor_f
361 #define gmx_simd4_rsqrt_f gmx_simd_rsqrt_f
362 #define gmx_simd4_rcp_f gmx_simd_rcp_f
363 #define gmx_simd4_fabs_f gmx_simd_fabs_f
364 #define gmx_simd4_fneg_f gmx_simd_fneg_f
365 #define gmx_simd4_max_f gmx_simd_max_f
366 #define gmx_simd4_min_f gmx_simd_min_f
367 #define gmx_simd4_round_f gmx_simd_round_f
368 #define gmx_simd4_trunc_f gmx_simd_trunc_f
369 #define gmx_simd4_fraction_f gmx_simd_fraction_f
370 #define gmx_simd4_get_exponent_f gmx_simd_get_exponent_f
371 #define gmx_simd4_get_mantissa_f gmx_simd_get_mantissa_f
372 #define gmx_simd4_set_exponent_f gmx_simd_set_exponent_f
373 #define gmx_simd4_dotproduct3_f gmx_simd4_dotproduct3_f_ibm_qpx
374 #define gmx_simd4_fint32_t gmx_simd_fint32_t
375 #define gmx_simd4_load_fi gmx_simd_load_fi
376 #define gmx_simd4_load1_fi gmx_simd_load1_fi
377 #define gmx_simd4_set1_fi gmx_simd_set1_fi
378 #define gmx_simd4_store_fi gmx_simd_store_fi
379 #define gmx_simd4_loadu_fi gmx_simd_loadu_fi
380 #define gmx_simd4_storeu_fi gmx_simd_storeu_fi
381 #define gmx_simd4_setzero_fi gmx_simd_setzero_fi
382 #define gmx_simd4_cvt_f2i gmx_simd_cvt_f2i
383 #define gmx_simd4_cvtt_f2i gmx_simd_cvtt_f2i
384 #define gmx_simd4_cvt_i2f gmx_simd_cvt_i2f
385 #define gmx_simd4_fbool_t gmx_simd_fbool_t
386 #define gmx_simd4_cmpeq_f gmx_simd_cmpeq_f
387 #define gmx_simd4_cmplt_f gmx_simd_cmplt_f
388 #define gmx_simd4_cmple_f gmx_simd_cmple_f
389 #define gmx_simd4_and_fb gmx_simd_and_fb
390 #define gmx_simd4_or_fb gmx_simd_or_fb
391 #define gmx_simd4_anytrue_fb gmx_simd_anytrue_fb
392 #define gmx_simd4_blendzero_f gmx_simd_blendzero_f
393 #define gmx_simd4_blendnotzero_f gmx_simd_blendnotzero_f
394 #define gmx_simd4_blendv_f gmx_simd_blendv_f
395 #define gmx_simd4_reduce_f gmx_simd_reduce_f
397 #define gmx_simd4_double_t gmx_simd_double_t
398 #define gmx_simd4_load_d gmx_simd_load_d
399 #define gmx_simd4_load1_d gmx_simd_load1_d
400 #define gmx_simd4_set1_d gmx_simd_set1_d
401 #define gmx_simd4_store_d gmx_simd_store_d
402 #define gmx_simd4_loadu_d gmx_simd_loadu_d
403 #define gmx_simd4_storeu_d gmx_simd_storeu_d
404 #define gmx_simd4_setzero_d gmx_simd_setzero_d
405 #define gmx_simd4_add_d gmx_simd_add_d
406 #define gmx_simd4_sub_d gmx_simd_sub_d
407 #define gmx_simd4_mul_d gmx_simd_mul_d
408 #define gmx_simd4_fmadd_d gmx_simd_fmadd_d
409 #define gmx_simd4_fmsub_d gmx_simd_fmsub_d
410 #define gmx_simd4_fnmadd_d gmx_simd_fnmadd_d
411 #define gmx_simd4_fnmsub_d gmx_simd_fnmsub_d
412 #define gmx_simd4_and_d gmx_simd_and_d
413 #define gmx_simd4_andnot_d gmx_simd_andnot_d
414 #define gmx_simd4_or_d gmx_simd_or_d
415 #define gmx_simd4_xor_d gmx_simd_xor_d
416 #define gmx_simd4_rsqrt_d gmx_simd_rsqrt_d
417 #define gmx_simd4_rcp_d gmx_simd_rcp_d
418 #define gmx_simd4_fabs_d gmx_simd_fabs_d
419 #define gmx_simd4_fneg_d gmx_simd_fneg_d
420 #define gmx_simd4_max_d gmx_simd_max_d
421 #define gmx_simd4_min_d gmx_simd_min_d
422 #define gmx_simd4_round_d gmx_simd_round_d
423 #define gmx_simd4_trunc_d gmx_simd_trunc_d
424 #define gmx_simd4_fraction_d gmx_simd_fraction_d
425 #define gmx_simd4_get_exponent_d gmx_simd_get_exponent_d
426 #define gmx_simd4_get_mantissa_d gmx_simd_get_mantissa_d
427 #define gmx_simd4_set_exponent_d gmx_simd_set_exponent_d
428 #define gmx_simd4_dotproduct3_d gmx_simd4_dotproduct3_d_ibm_qpx
429 #define gmx_simd4_dint32_t gmx_simd_dint32_t
430 #define gmx_simd4_load_di gmx_simd_load_di
431 #define gmx_simd4_load1_di gmx_simd_load1_di
432 #define gmx_simd4_set1_di gmx_simd_set1_di
433 #define gmx_simd4_store_di gmx_simd_store_di
434 #define gmx_simd4_loadu_di gmx_simd_loadu_di
435 #define gmx_simd4_storeu_di gmx_simd_storeu_di
436 #define gmx_simd4_setzero_di gmx_simd_setzero_di
437 #define gmx_simd4_cvt_d2i gmx_simd_cvt_d2i
438 #define gmx_simd4_cvtt_d2i gmx_simd_cvtt_d2i
439 #define gmx_simd4_cvt_i2f gmx_simd_cvt_i2f
440 #define gmx_simd4_dbool_t gmx_simd_dbool_t
441 #define gmx_simd4_cmpeq_d gmx_simd_cmpeq_d
442 #define gmx_simd4_cmplt_d gmx_simd_cmplt_d
443 #define gmx_simd4_cmple_d gmx_simd_cmple_d
444 #define gmx_simd4_and_db gmx_simd_and_db
445 #define gmx_simd4_or_db gmx_simd_or_db
446 #define gmx_simd4_anytrue_db gmx_simd_anytrue_db
447 #define gmx_simd4_blendzero_d gmx_simd_blendzero_d
448 #define gmx_simd4_blendnotzero_d gmx_simd_blendnotzero_d
449 #define gmx_simd4_blendv_d gmx_simd_blendv_d
450 #define gmx_simd4_reduce_d gmx_simd_reduce_d
452 static __attribute__((always_inline)) double gmx_simdcall
453 gmx_simd4_dotproduct3_d_ibm_qpx(vector4double a, vector4double b)
455 vector4double dp_sh0 = vec_mul(a, b);
456 vector4double dp_sh1 = vec_sldw(dp_sh0, dp_sh0, 1);
457 vector4double dp_sh2 = vec_sldw(dp_sh0, dp_sh0, 2);
458 vector4double dp = vec_add(dp_sh2, vec_add(dp_sh0, dp_sh1));
460 return vec_extract(dp, 0);
463 static __attribute__((always_inline)) float gmx_simdcall
464 gmx_simd4_dotproduct3_f_ibm_qpx(vector4double a, vector4double b)
466 return (float)gmx_simd4_dotproduct3_d_ibm_qpx(a, b);
469 /* Function to check whether SIMD operations have resulted in overflow.
470 * For now, this is unfortunately a dummy for this architecture.
473 gmx_simd_check_and_reset_overflow(void)
478 #endif /* GMX_SIMD_IMPLEMENTATION_IBM_QPX_H */