Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / legacyheaders / gmx_simd_macros.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2012, The GROMACS Development Team
6  * Copyright (c) 2012, by the GROMACS development team, led by
7  * David van der Spoel, Berk Hess, Erik Lindahl, and including many
8  * others, as listed in the AUTHORS file in the top-level source
9  * directory and at http://www.gromacs.org.
10  *
11  * GROMACS is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * as published by the Free Software Foundation; either version 2.1
14  * of the License, or (at your option) any later version.
15  *
16  * GROMACS is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with GROMACS; if not, see
23  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
25  *
26  * If you want to redistribute modifications to GROMACS, please
27  * consider that scientific software is very special. Version
28  * control is crucial - bugs must be traceable. We will be happy to
29  * consider code for inclusion in the official distribution, but
30  * derived work must not be called official GROMACS. Details are found
31  * in the README & COPYING files - if they are missing, get the
32  * official version at http://www.gromacs.org.
33  *
34  * To help us fund GROMACS development, we humbly ask that you cite
35  * the research papers on the package. Check out http://www.gromacs.org.
36  */
37
38 /* The macros in this file are intended to be used for writing
39  * architecture independent SIMD intrinsics code.
40  * To support a new architecture, adding macros here should be (nearly)
41  * all that is needed.
42  */
43
44 /* Undefine all defines used below so we can include this file multiple times
45  * with different settings from the same source file.
46  */
47
48 /* NOTE: floor and blend are NOT available with SSE2 only acceleration */
49
50 #undef GMX_SIMD_WIDTH_HERE
51
52 #undef gmx_epi32
53
54 #undef gmx_mm_pr
55
56 #undef gmx_load_pr
57 #undef gmx_load1_pr
58 #undef gmx_set1_pr
59 #undef gmx_setzero_pr
60 #undef gmx_store_pr
61 #undef gmx_storeu_pr
62
63 #undef gmx_add_pr
64 #undef gmx_sub_pr
65 #undef gmx_mul_pr
66 #undef gmx_max_pr
67 #undef gmx_cmplt_pr
68 #undef gmx_and_pr
69 #undef gmx_or_pr
70 #undef gmx_andnot_pr
71
72 #undef gmx_floor_pr
73 #undef gmx_blendv_pr
74
75 #undef gmx_movemask_pr
76
77 #undef gmx_mm_castsi128_pr
78
79 #undef gmx_cvttpr_epi32
80 #undef gmx_cvtepi32_pr
81
82 #undef gmx_invsqrt_pr
83 #undef gmx_calc_rsq_pr
84 #undef gmx_sum4_pr
85
86 #undef gmx_pmecorrF_pr
87 #undef gmx_pmecorrV_pr
88
89
90 /* By defining GMX_MM128_HERE or GMX_MM256_HERE before including this file
91  * the same intrinsics, with defines, can be compiled for either 128 or 256
92  * bit wide SSE or AVX instructions.
93  * The gmx_ prefix is replaced by _mm_ or _mm256_ (SSE or AVX).
94  * The _pr suffix is replaced by _ps or _pd (single or double precision).
95  * Note that compiler settings will decide if 128-bit intrinsics will
96  * be translated into SSE or AVX instructions.
97  */
98
99 #if !defined GMX_MM128_HERE && !defined GMX_MM256_HERE
100 #error "You should define GMX_MM128_HERE or GMX_MM256_HERE"
101 #endif
102
103 #if defined GMX_MM128_HERE && defined GMX_MM256_HERE
104 #error "You should not define both GMX_MM128_HERE and GMX_MM256_HERE"
105 #endif
106
107 #ifdef GMX_MM128_HERE
108
109 #define gmx_epi32  __m128i
110
111 #ifndef GMX_DOUBLE
112
113 #include "gmx_x86_simd_single.h"
114
115 #define GMX_SIMD_WIDTH_HERE  4
116
117 #define gmx_mm_pr  __m128
118
119 #define gmx_load_pr       _mm_load_ps
120 #define gmx_load1_pr      _mm_load1_ps
121 #define gmx_set1_pr       _mm_set1_ps
122 #define gmx_setzero_pr    _mm_setzero_ps
123 #define gmx_store_pr      _mm_store_ps
124 #define gmx_storeu_pr     _mm_storeu_ps
125
126 #define gmx_add_pr        _mm_add_ps
127 #define gmx_sub_pr        _mm_sub_ps
128 #define gmx_mul_pr        _mm_mul_ps
129 #define gmx_max_pr        _mm_max_ps
130 #define gmx_cmplt_pr      _mm_cmplt_ps
131 #define gmx_and_pr        _mm_and_ps
132 #define gmx_or_pr         _mm_or_ps
133 #define gmx_andnot_pr     _mm_andnot_ps
134
135 #define gmx_floor_pr      _mm_floor_ps
136 #define gmx_blendv_pr     _mm_blendv_ps
137
138 #define gmx_movemask_pr   _mm_movemask_ps
139
140 #define gmx_mm_castsi128_pr gmx_mm_castsi128_ps
141
142 #define gmx_cvttpr_epi32  _mm_cvttps_epi32
143 #define gmx_cvtepi32_pr   _mm_cvtepi32_ps
144
145 #define gmx_invsqrt_pr    gmx_mm_invsqrt_ps
146 #define gmx_calc_rsq_pr   gmx_mm_calc_rsq_ps
147 #define gmx_sum4_pr       gmx_mm_sum4_ps
148
149 #define gmx_pmecorrF_pr   gmx_mm_pmecorrF_ps
150 #define gmx_pmecorrV_pr   gmx_mm_pmecorrV_ps
151
152 #else /* ifndef GMX_DOUBLE */
153
154 #include "gmx_x86_simd_double.h"
155
156 #define GMX_SIMD_WIDTH_HERE  2
157
158 #define gmx_mm_pr  __m128d
159
160 #define gmx_load_pr       _mm_load_pd
161 #define gmx_load1_pr      _mm_load1_pd
162 #define gmx_set1_pr       _mm_set1_pd
163 #define gmx_setzero_pr    _mm_setzero_pd
164 #define gmx_store_pr      _mm_store_pd
165 #define gmx_storeu_pr     _mm_storeu_pd
166
167 #define gmx_add_pr        _mm_add_pd
168 #define gmx_sub_pr        _mm_sub_pd
169 #define gmx_mul_pr        _mm_mul_pd
170 #define gmx_max_pr        _mm_max_pd
171 #define gmx_cmplt_pr      _mm_cmplt_pd
172 #define gmx_and_pr        _mm_and_pd
173 #define gmx_or_pr         _mm_or_pd
174 #define gmx_andnot_pr     _mm_andnot_pd
175
176 #define gmx_floor_pr      _mm_floor_pd
177 #define gmx_blendv_pr     _mm_blendv_pd
178
179 #define gmx_movemask_pr   _mm_movemask_pd
180
181 #define gmx_mm_castsi128_pr gmx_mm_castsi128_pd
182
183 #define gmx_cvttpr_epi32  _mm_cvttpd_epi32
184 #define gmx_cvtepi32_pr   _mm_cvtepi32_pd
185
186 #define gmx_invsqrt_pr    gmx_mm_invsqrt_pd
187 #define gmx_calc_rsq_pr   gmx_mm_calc_rsq_pd
188 #define gmx_sum4_pr       gmx_mm_sum4_pd
189
190 #define gmx_pmecorrF_pr   gmx_mm_pmecorrF_pd
191 #define gmx_pmecorrV_pr   gmx_mm_pmecorrV_pd
192
193 #endif /* ifndef GMX_DOUBLE */
194
195 #endif /* GMX_MM128_HERE */
196
197 #ifdef GMX_MM256_HERE
198
199 #define gmx_epi32 __m256i
200
201 #ifndef GMX_DOUBLE
202
203 #include "gmx_x86_simd_single.h"
204
205 #define GMX_SIMD_WIDTH_HERE  8
206
207 #define gmx_mm_pr  __m256
208
209 #define gmx_load_pr       _mm256_load_ps
210 #define gmx_load1_pr(x)   _mm256_set1_ps((x)[0])
211 #define gmx_set1_pr       _mm256_set1_ps
212 #define gmx_setzero_pr    _mm256_setzero_ps
213 #define gmx_store_pr      _mm256_store_ps
214 #define gmx_storeu_pr     _mm256_storeu_ps
215
216 #define gmx_add_pr        _mm256_add_ps
217 #define gmx_sub_pr        _mm256_sub_ps
218 #define gmx_mul_pr        _mm256_mul_ps
219 #define gmx_max_pr        _mm256_max_ps
220 /* Not-equal (ordered, non-signaling)  */
221 #define gmx_cmpneq_pr(x,y)  _mm256_cmp_ps(x,y,0x0c)
222 /* Less-than (ordered, non-signaling)  */
223 #define gmx_cmplt_pr(x,y) _mm256_cmp_ps(x,y,0x11)
224 #define gmx_and_pr        _mm256_and_ps
225 #define gmx_or_pr         _mm256_or_ps
226 #define gmx_andnot_pr     _mm256_andnot_ps
227
228 #define gmx_floor_pr      _mm256_floor_ps
229 #define gmx_blendv_pr     _mm256_blendv_ps
230
231 #define gmx_movemask_pr   _mm256_movemask_ps
232
233 #define gmx_mm_castsi256_pr _mm256_castsi256_ps
234
235 #define gmx_cvttpr_epi32  _mm256_cvttps_epi32
236
237 #define gmx_invsqrt_pr    gmx_mm256_invsqrt_ps
238 #define gmx_calc_rsq_pr   gmx_mm256_calc_rsq_ps
239 #define gmx_sum4_pr       gmx_mm256_sum4_ps
240
241 #define gmx_pmecorrF_pr   gmx_mm256_pmecorrF_ps
242 #define gmx_pmecorrV_pr   gmx_mm256_pmecorrV_ps
243
244 #define gmx_loaddh_pr     gmx_mm256_load4_ps
245
246 /* Half SIMD-width type */
247 #define gmx_mm_hpr  __m128
248
249 /* Half SIMD-width macros */
250 #define gmx_load_hpr      _mm_load_ps
251 #define gmx_load1_hpr(x)  _mm_set1_ps((x)[0])
252 #define gmx_store_hpr     _mm_store_ps
253 #define gmx_add_hpr       _mm_add_ps
254 #define gmx_sub_hpr       _mm_sub_ps
255
256 #define gmx_sum4_hpr      gmx_mm256_sum4h_m128
257
258 /* Conversion between half and full SIMD-width */
259 #define gmx_2hpr_to_pr    gmx_mm256_set_m128
260
261 #else
262
263 #include "gmx_x86_simd_double.h"
264
265 #define GMX_SIMD_WIDTH_HERE  4
266
267 #define gmx_mm_pr  __m256d
268
269 #define gmx_load_pr       _mm256_load_pd
270 #define gmx_load1_pr(x)   _mm256_set1_pd((x)[0])
271 #define gmx_set1_pr       _mm256_set1_pd
272 #define gmx_setzero_pr    _mm256_setzero_pd
273 #define gmx_store_pr      _mm256_store_pd
274 #define gmx_storeu_pr     _mm256_storeu_pd
275
276 #define gmx_add_pr        _mm256_add_pd
277 #define gmx_sub_pr        _mm256_sub_pd
278 #define gmx_mul_pr        _mm256_mul_pd
279 #define gmx_max_pr        _mm256_max_pd
280 /* Not-equal (ordered, non-signaling)  */
281 #define gmx_cmpneq_pr(x,y)  _mm256_cmp_pd(x,y,0x0c)
282 /* Less-than (ordered, non-signaling)  */
283 #define gmx_cmplt_pr(x,y) _mm256_cmp_pd(x,y,0x11)
284 #define gmx_and_pr        _mm256_and_pd
285 #define gmx_or_pr         _mm256_or_pd
286 #define gmx_andnot_pr     _mm256_andnot_pd
287
288 #define gmx_floor_pr      _mm256_floor_pd
289 #define gmx_blendv_pr     _mm256_blendv_pd
290
291 #define gmx_movemask_pr   _mm256_movemask_pd
292
293 #define gmx_mm_castsi256_pr _mm256_castsi256_pd
294
295 #define gmx_cvttpr_epi32  _mm256_cvttpd_epi32
296
297 #define gmx_invsqrt_pr    gmx_mm256_invsqrt_pd
298 #define gmx_calc_rsq_pr   gmx_mm256_calc_rsq_pd
299 #define gmx_sum4_pr       gmx_mm256_sum4_pd
300
301 #define gmx_pmecorrF_pr   gmx_mm256_pmecorrF_pd
302 #define gmx_pmecorrV_pr   gmx_mm256_pmecorrV_pd
303
304 #endif
305
306 #endif /* GMX_MM256_HERE */