Added option to gmx nmeig to print ZPE.
[alexxy/gromacs.git] / src / gromacs / gmxlib / nonbonded / nb_kernel_avx_128_fma_double / nb_kernel_ElecEwSh_VdwLJEwSh_GeomW3W3_avx_128_fma_double.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2013,2014,2015,2017, 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.
8  *
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.
13  *
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.
18  *
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.
23  *
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.
31  *
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.
34  */
35 /*
36  * Note: this file was generated by the GROMACS avx_128_fma_double kernel generator.
37  */
38 #include "gmxpre.h"
39
40 #include "config.h"
41
42 #include <math.h>
43
44 #include "../nb_kernel.h"
45 #include "gromacs/gmxlib/nrnb.h"
46
47 #include "kernelutil_x86_avx_128_fma_double.h"
48
49 /*
50  * Gromacs nonbonded kernel:   nb_kernel_ElecEwSh_VdwLJEwSh_GeomW3W3_VF_avx_128_fma_double
51  * Electrostatics interaction: Ewald
52  * VdW interaction:            LJEwald
53  * Geometry:                   Water3-Water3
54  * Calculate force/pot:        PotentialAndForce
55  */
56 void
57 nb_kernel_ElecEwSh_VdwLJEwSh_GeomW3W3_VF_avx_128_fma_double
58                     (t_nblist                    * gmx_restrict       nlist,
59                      rvec                        * gmx_restrict          xx,
60                      rvec                        * gmx_restrict          ff,
61                      struct t_forcerec           * gmx_restrict          fr,
62                      t_mdatoms                   * gmx_restrict     mdatoms,
63                      nb_kernel_data_t gmx_unused * gmx_restrict kernel_data,
64                      t_nrnb                      * gmx_restrict        nrnb)
65 {
66     /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
67      * just 0 for non-waters.
68      * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
69      * jnr indices corresponding to data put in the four positions in the SIMD register.
70      */
71     int              i_shift_offset,i_coord_offset,outeriter,inneriter;
72     int              j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
73     int              jnrA,jnrB;
74     int              j_coord_offsetA,j_coord_offsetB;
75     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
76     real             rcutoff_scalar;
77     real             *shiftvec,*fshift,*x,*f;
78     __m128d          tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
79     int              vdwioffset0;
80     __m128d          ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
81     int              vdwioffset1;
82     __m128d          ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
83     int              vdwioffset2;
84     __m128d          ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
85     int              vdwjidx0A,vdwjidx0B;
86     __m128d          jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
87     int              vdwjidx1A,vdwjidx1B;
88     __m128d          jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
89     int              vdwjidx2A,vdwjidx2B;
90     __m128d          jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
91     __m128d          dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
92     __m128d          dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
93     __m128d          dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
94     __m128d          dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
95     __m128d          dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
96     __m128d          dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
97     __m128d          dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
98     __m128d          dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
99     __m128d          dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
100     __m128d          velec,felec,velecsum,facel,crf,krf,krf2;
101     real             *charge;
102     int              nvdwtype;
103     __m128d          rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
104     int              *vdwtype;
105     real             *vdwparam;
106     __m128d          one_sixth   = _mm_set1_pd(1.0/6.0);
107     __m128d          one_twelfth = _mm_set1_pd(1.0/12.0);
108     __m128d           c6grid_00;
109     __m128d           c6grid_01;
110     __m128d           c6grid_02;
111     __m128d           c6grid_10;
112     __m128d           c6grid_11;
113     __m128d           c6grid_12;
114     __m128d           c6grid_20;
115     __m128d           c6grid_21;
116     __m128d           c6grid_22;
117     real             *vdwgridparam;
118     __m128d           ewclj,ewclj2,ewclj6,ewcljrsq,poly,exponent,f6A,f6B,sh_lj_ewald;
119     __m128d           one_half  = _mm_set1_pd(0.5);
120     __m128d           minus_one = _mm_set1_pd(-1.0);
121     __m128i          ewitab;
122     __m128d          ewtabscale,eweps,twoeweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
123     real             *ewtab;
124     __m128d          dummy_mask,cutoff_mask;
125     __m128d          signbit   = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
126     __m128d          one     = _mm_set1_pd(1.0);
127     __m128d          two     = _mm_set1_pd(2.0);
128     x                = xx[0];
129     f                = ff[0];
130
131     nri              = nlist->nri;
132     iinr             = nlist->iinr;
133     jindex           = nlist->jindex;
134     jjnr             = nlist->jjnr;
135     shiftidx         = nlist->shift;
136     gid              = nlist->gid;
137     shiftvec         = fr->shift_vec[0];
138     fshift           = fr->fshift[0];
139     facel            = _mm_set1_pd(fr->ic->epsfac);
140     charge           = mdatoms->chargeA;
141     nvdwtype         = fr->ntype;
142     vdwparam         = fr->nbfp;
143     vdwtype          = mdatoms->typeA;
144     vdwgridparam     = fr->ljpme_c6grid;
145     sh_lj_ewald      = _mm_set1_pd(fr->ic->sh_lj_ewald);
146     ewclj            = _mm_set1_pd(fr->ic->ewaldcoeff_lj);
147     ewclj2           = _mm_mul_pd(minus_one,_mm_mul_pd(ewclj,ewclj));
148
149     sh_ewald         = _mm_set1_pd(fr->ic->sh_ewald);
150     ewtab            = fr->ic->tabq_coul_FDV0;
151     ewtabscale       = _mm_set1_pd(fr->ic->tabq_scale);
152     ewtabhalfspace   = _mm_set1_pd(0.5/fr->ic->tabq_scale);
153
154     /* Setup water-specific parameters */
155     inr              = nlist->iinr[0];
156     iq0              = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
157     iq1              = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
158     iq2              = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
159     vdwioffset0      = 2*nvdwtype*vdwtype[inr+0];
160
161     jq0              = _mm_set1_pd(charge[inr+0]);
162     jq1              = _mm_set1_pd(charge[inr+1]);
163     jq2              = _mm_set1_pd(charge[inr+2]);
164     vdwjidx0A        = 2*vdwtype[inr+0];
165     qq00             = _mm_mul_pd(iq0,jq0);
166     c6_00            = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
167     c12_00           = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
168     c6grid_00        = _mm_set1_pd(vdwgridparam[vdwioffset0+vdwjidx0A]);
169     qq01             = _mm_mul_pd(iq0,jq1);
170     qq02             = _mm_mul_pd(iq0,jq2);
171     qq10             = _mm_mul_pd(iq1,jq0);
172     qq11             = _mm_mul_pd(iq1,jq1);
173     qq12             = _mm_mul_pd(iq1,jq2);
174     qq20             = _mm_mul_pd(iq2,jq0);
175     qq21             = _mm_mul_pd(iq2,jq1);
176     qq22             = _mm_mul_pd(iq2,jq2);
177
178     /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
179     rcutoff_scalar   = fr->ic->rcoulomb;
180     rcutoff          = _mm_set1_pd(rcutoff_scalar);
181     rcutoff2         = _mm_mul_pd(rcutoff,rcutoff);
182
183     sh_vdw_invrcut6  = _mm_set1_pd(fr->ic->sh_invrc6);
184     rvdw             = _mm_set1_pd(fr->ic->rvdw);
185
186     /* Avoid stupid compiler warnings */
187     jnrA = jnrB = 0;
188     j_coord_offsetA = 0;
189     j_coord_offsetB = 0;
190
191     outeriter        = 0;
192     inneriter        = 0;
193
194     /* Start outer loop over neighborlists */
195     for(iidx=0; iidx<nri; iidx++)
196     {
197         /* Load shift vector for this list */
198         i_shift_offset   = DIM*shiftidx[iidx];
199
200         /* Load limits for loop over neighbors */
201         j_index_start    = jindex[iidx];
202         j_index_end      = jindex[iidx+1];
203
204         /* Get outer coordinate index */
205         inr              = iinr[iidx];
206         i_coord_offset   = DIM*inr;
207
208         /* Load i particle coords and add shift vector */
209         gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
210                                                  &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
211
212         fix0             = _mm_setzero_pd();
213         fiy0             = _mm_setzero_pd();
214         fiz0             = _mm_setzero_pd();
215         fix1             = _mm_setzero_pd();
216         fiy1             = _mm_setzero_pd();
217         fiz1             = _mm_setzero_pd();
218         fix2             = _mm_setzero_pd();
219         fiy2             = _mm_setzero_pd();
220         fiz2             = _mm_setzero_pd();
221
222         /* Reset potential sums */
223         velecsum         = _mm_setzero_pd();
224         vvdwsum          = _mm_setzero_pd();
225
226         /* Start inner kernel loop */
227         for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
228         {
229
230             /* Get j neighbor index, and coordinate index */
231             jnrA             = jjnr[jidx];
232             jnrB             = jjnr[jidx+1];
233             j_coord_offsetA  = DIM*jnrA;
234             j_coord_offsetB  = DIM*jnrB;
235
236             /* load j atom coordinates */
237             gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
238                                               &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
239
240             /* Calculate displacement vector */
241             dx00             = _mm_sub_pd(ix0,jx0);
242             dy00             = _mm_sub_pd(iy0,jy0);
243             dz00             = _mm_sub_pd(iz0,jz0);
244             dx01             = _mm_sub_pd(ix0,jx1);
245             dy01             = _mm_sub_pd(iy0,jy1);
246             dz01             = _mm_sub_pd(iz0,jz1);
247             dx02             = _mm_sub_pd(ix0,jx2);
248             dy02             = _mm_sub_pd(iy0,jy2);
249             dz02             = _mm_sub_pd(iz0,jz2);
250             dx10             = _mm_sub_pd(ix1,jx0);
251             dy10             = _mm_sub_pd(iy1,jy0);
252             dz10             = _mm_sub_pd(iz1,jz0);
253             dx11             = _mm_sub_pd(ix1,jx1);
254             dy11             = _mm_sub_pd(iy1,jy1);
255             dz11             = _mm_sub_pd(iz1,jz1);
256             dx12             = _mm_sub_pd(ix1,jx2);
257             dy12             = _mm_sub_pd(iy1,jy2);
258             dz12             = _mm_sub_pd(iz1,jz2);
259             dx20             = _mm_sub_pd(ix2,jx0);
260             dy20             = _mm_sub_pd(iy2,jy0);
261             dz20             = _mm_sub_pd(iz2,jz0);
262             dx21             = _mm_sub_pd(ix2,jx1);
263             dy21             = _mm_sub_pd(iy2,jy1);
264             dz21             = _mm_sub_pd(iz2,jz1);
265             dx22             = _mm_sub_pd(ix2,jx2);
266             dy22             = _mm_sub_pd(iy2,jy2);
267             dz22             = _mm_sub_pd(iz2,jz2);
268
269             /* Calculate squared distance and things based on it */
270             rsq00            = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
271             rsq01            = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
272             rsq02            = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
273             rsq10            = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
274             rsq11            = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
275             rsq12            = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
276             rsq20            = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
277             rsq21            = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
278             rsq22            = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
279
280             rinv00           = avx128fma_invsqrt_d(rsq00);
281             rinv01           = avx128fma_invsqrt_d(rsq01);
282             rinv02           = avx128fma_invsqrt_d(rsq02);
283             rinv10           = avx128fma_invsqrt_d(rsq10);
284             rinv11           = avx128fma_invsqrt_d(rsq11);
285             rinv12           = avx128fma_invsqrt_d(rsq12);
286             rinv20           = avx128fma_invsqrt_d(rsq20);
287             rinv21           = avx128fma_invsqrt_d(rsq21);
288             rinv22           = avx128fma_invsqrt_d(rsq22);
289
290             rinvsq00         = _mm_mul_pd(rinv00,rinv00);
291             rinvsq01         = _mm_mul_pd(rinv01,rinv01);
292             rinvsq02         = _mm_mul_pd(rinv02,rinv02);
293             rinvsq10         = _mm_mul_pd(rinv10,rinv10);
294             rinvsq11         = _mm_mul_pd(rinv11,rinv11);
295             rinvsq12         = _mm_mul_pd(rinv12,rinv12);
296             rinvsq20         = _mm_mul_pd(rinv20,rinv20);
297             rinvsq21         = _mm_mul_pd(rinv21,rinv21);
298             rinvsq22         = _mm_mul_pd(rinv22,rinv22);
299
300             fjx0             = _mm_setzero_pd();
301             fjy0             = _mm_setzero_pd();
302             fjz0             = _mm_setzero_pd();
303             fjx1             = _mm_setzero_pd();
304             fjy1             = _mm_setzero_pd();
305             fjz1             = _mm_setzero_pd();
306             fjx2             = _mm_setzero_pd();
307             fjy2             = _mm_setzero_pd();
308             fjz2             = _mm_setzero_pd();
309
310             /**************************
311              * CALCULATE INTERACTIONS *
312              **************************/
313
314             if (gmx_mm_any_lt(rsq00,rcutoff2))
315             {
316
317             r00              = _mm_mul_pd(rsq00,rinv00);
318
319             /* EWALD ELECTROSTATICS */
320
321             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
322             ewrt             = _mm_mul_pd(r00,ewtabscale);
323             ewitab           = _mm_cvttpd_epi32(ewrt);
324 #ifdef __XOP__
325             eweps            = _mm_frcz_pd(ewrt);
326 #else
327             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
328 #endif
329             twoeweps         = _mm_add_pd(eweps,eweps);
330             ewitab           = _mm_slli_epi32(ewitab,2);
331             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
332             ewtabD           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,1) );
333             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
334             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
335             ewtabFn          = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,1) +2);
336             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
337             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
338             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
339             velec            = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
340             felec            = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
341
342             /* Analytical LJ-PME */
343             rinvsix          = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
344             ewcljrsq         = _mm_mul_pd(ewclj2,rsq00);
345             ewclj6           = _mm_mul_pd(ewclj2,_mm_mul_pd(ewclj2,ewclj2));
346             exponent         = avx128fma_exp_d(ewcljrsq);
347             /* poly = exp(-(beta*r)^2) * (1 + (beta*r)^2 + (beta*r)^4 /2) */
348             poly             = _mm_mul_pd(exponent,_mm_macc_pd(_mm_mul_pd(ewcljrsq,ewcljrsq),one_half,_mm_sub_pd(one,ewcljrsq)));
349             /* vvdw6 = [C6 - C6grid * (1-poly)]/r6 */
350             vvdw6            = _mm_mul_pd(_mm_macc_pd(-c6grid_00,_mm_sub_pd(one,poly),c6_00),rinvsix);
351             vvdw12           = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
352             vvdw             = _mm_msub_pd(_mm_nmacc_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6),vvdw12),one_twelfth,
353                                _mm_mul_pd(_mm_sub_pd(vvdw6,_mm_macc_pd(c6grid_00,sh_lj_ewald,_mm_mul_pd(c6_00,sh_vdw_invrcut6))),one_sixth));
354             /* fvdw = vvdw12/r - (vvdw6/r + (C6grid * exponent * beta^6)/r) */
355             fvdw             = _mm_mul_pd(_mm_add_pd(vvdw12,_mm_msub_pd(_mm_mul_pd(c6grid_00,one_sixth),_mm_mul_pd(exponent,ewclj6),vvdw6)),rinvsq00);
356
357             cutoff_mask      = _mm_cmplt_pd(rsq00,rcutoff2);
358
359             /* Update potential sum for this i atom from the interaction with this j atom. */
360             velec            = _mm_and_pd(velec,cutoff_mask);
361             velecsum         = _mm_add_pd(velecsum,velec);
362             vvdw             = _mm_and_pd(vvdw,cutoff_mask);
363             vvdwsum          = _mm_add_pd(vvdwsum,vvdw);
364
365             fscal            = _mm_add_pd(felec,fvdw);
366
367             fscal            = _mm_and_pd(fscal,cutoff_mask);
368
369             /* Update vectorial force */
370             fix0             = _mm_macc_pd(dx00,fscal,fix0);
371             fiy0             = _mm_macc_pd(dy00,fscal,fiy0);
372             fiz0             = _mm_macc_pd(dz00,fscal,fiz0);
373             
374             fjx0             = _mm_macc_pd(dx00,fscal,fjx0);
375             fjy0             = _mm_macc_pd(dy00,fscal,fjy0);
376             fjz0             = _mm_macc_pd(dz00,fscal,fjz0);
377
378             }
379
380             /**************************
381              * CALCULATE INTERACTIONS *
382              **************************/
383
384             if (gmx_mm_any_lt(rsq01,rcutoff2))
385             {
386
387             r01              = _mm_mul_pd(rsq01,rinv01);
388
389             /* EWALD ELECTROSTATICS */
390
391             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
392             ewrt             = _mm_mul_pd(r01,ewtabscale);
393             ewitab           = _mm_cvttpd_epi32(ewrt);
394 #ifdef __XOP__
395             eweps            = _mm_frcz_pd(ewrt);
396 #else
397             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
398 #endif
399             twoeweps         = _mm_add_pd(eweps,eweps);
400             ewitab           = _mm_slli_epi32(ewitab,2);
401             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
402             ewtabD           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,1) );
403             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
404             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
405             ewtabFn          = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,1) +2);
406             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
407             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
408             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
409             velec            = _mm_mul_pd(qq01,_mm_sub_pd(_mm_sub_pd(rinv01,sh_ewald),velec));
410             felec            = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
411
412             cutoff_mask      = _mm_cmplt_pd(rsq01,rcutoff2);
413
414             /* Update potential sum for this i atom from the interaction with this j atom. */
415             velec            = _mm_and_pd(velec,cutoff_mask);
416             velecsum         = _mm_add_pd(velecsum,velec);
417
418             fscal            = felec;
419
420             fscal            = _mm_and_pd(fscal,cutoff_mask);
421
422             /* Update vectorial force */
423             fix0             = _mm_macc_pd(dx01,fscal,fix0);
424             fiy0             = _mm_macc_pd(dy01,fscal,fiy0);
425             fiz0             = _mm_macc_pd(dz01,fscal,fiz0);
426             
427             fjx1             = _mm_macc_pd(dx01,fscal,fjx1);
428             fjy1             = _mm_macc_pd(dy01,fscal,fjy1);
429             fjz1             = _mm_macc_pd(dz01,fscal,fjz1);
430
431             }
432
433             /**************************
434              * CALCULATE INTERACTIONS *
435              **************************/
436
437             if (gmx_mm_any_lt(rsq02,rcutoff2))
438             {
439
440             r02              = _mm_mul_pd(rsq02,rinv02);
441
442             /* EWALD ELECTROSTATICS */
443
444             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
445             ewrt             = _mm_mul_pd(r02,ewtabscale);
446             ewitab           = _mm_cvttpd_epi32(ewrt);
447 #ifdef __XOP__
448             eweps            = _mm_frcz_pd(ewrt);
449 #else
450             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
451 #endif
452             twoeweps         = _mm_add_pd(eweps,eweps);
453             ewitab           = _mm_slli_epi32(ewitab,2);
454             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
455             ewtabD           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,1) );
456             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
457             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
458             ewtabFn          = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,1) +2);
459             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
460             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
461             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
462             velec            = _mm_mul_pd(qq02,_mm_sub_pd(_mm_sub_pd(rinv02,sh_ewald),velec));
463             felec            = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
464
465             cutoff_mask      = _mm_cmplt_pd(rsq02,rcutoff2);
466
467             /* Update potential sum for this i atom from the interaction with this j atom. */
468             velec            = _mm_and_pd(velec,cutoff_mask);
469             velecsum         = _mm_add_pd(velecsum,velec);
470
471             fscal            = felec;
472
473             fscal            = _mm_and_pd(fscal,cutoff_mask);
474
475             /* Update vectorial force */
476             fix0             = _mm_macc_pd(dx02,fscal,fix0);
477             fiy0             = _mm_macc_pd(dy02,fscal,fiy0);
478             fiz0             = _mm_macc_pd(dz02,fscal,fiz0);
479             
480             fjx2             = _mm_macc_pd(dx02,fscal,fjx2);
481             fjy2             = _mm_macc_pd(dy02,fscal,fjy2);
482             fjz2             = _mm_macc_pd(dz02,fscal,fjz2);
483
484             }
485
486             /**************************
487              * CALCULATE INTERACTIONS *
488              **************************/
489
490             if (gmx_mm_any_lt(rsq10,rcutoff2))
491             {
492
493             r10              = _mm_mul_pd(rsq10,rinv10);
494
495             /* EWALD ELECTROSTATICS */
496
497             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
498             ewrt             = _mm_mul_pd(r10,ewtabscale);
499             ewitab           = _mm_cvttpd_epi32(ewrt);
500 #ifdef __XOP__
501             eweps            = _mm_frcz_pd(ewrt);
502 #else
503             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
504 #endif
505             twoeweps         = _mm_add_pd(eweps,eweps);
506             ewitab           = _mm_slli_epi32(ewitab,2);
507             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
508             ewtabD           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,1) );
509             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
510             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
511             ewtabFn          = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,1) +2);
512             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
513             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
514             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
515             velec            = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
516             felec            = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
517
518             cutoff_mask      = _mm_cmplt_pd(rsq10,rcutoff2);
519
520             /* Update potential sum for this i atom from the interaction with this j atom. */
521             velec            = _mm_and_pd(velec,cutoff_mask);
522             velecsum         = _mm_add_pd(velecsum,velec);
523
524             fscal            = felec;
525
526             fscal            = _mm_and_pd(fscal,cutoff_mask);
527
528             /* Update vectorial force */
529             fix1             = _mm_macc_pd(dx10,fscal,fix1);
530             fiy1             = _mm_macc_pd(dy10,fscal,fiy1);
531             fiz1             = _mm_macc_pd(dz10,fscal,fiz1);
532             
533             fjx0             = _mm_macc_pd(dx10,fscal,fjx0);
534             fjy0             = _mm_macc_pd(dy10,fscal,fjy0);
535             fjz0             = _mm_macc_pd(dz10,fscal,fjz0);
536
537             }
538
539             /**************************
540              * CALCULATE INTERACTIONS *
541              **************************/
542
543             if (gmx_mm_any_lt(rsq11,rcutoff2))
544             {
545
546             r11              = _mm_mul_pd(rsq11,rinv11);
547
548             /* EWALD ELECTROSTATICS */
549
550             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
551             ewrt             = _mm_mul_pd(r11,ewtabscale);
552             ewitab           = _mm_cvttpd_epi32(ewrt);
553 #ifdef __XOP__
554             eweps            = _mm_frcz_pd(ewrt);
555 #else
556             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
557 #endif
558             twoeweps         = _mm_add_pd(eweps,eweps);
559             ewitab           = _mm_slli_epi32(ewitab,2);
560             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
561             ewtabD           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,1) );
562             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
563             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
564             ewtabFn          = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,1) +2);
565             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
566             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
567             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
568             velec            = _mm_mul_pd(qq11,_mm_sub_pd(_mm_sub_pd(rinv11,sh_ewald),velec));
569             felec            = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
570
571             cutoff_mask      = _mm_cmplt_pd(rsq11,rcutoff2);
572
573             /* Update potential sum for this i atom from the interaction with this j atom. */
574             velec            = _mm_and_pd(velec,cutoff_mask);
575             velecsum         = _mm_add_pd(velecsum,velec);
576
577             fscal            = felec;
578
579             fscal            = _mm_and_pd(fscal,cutoff_mask);
580
581             /* Update vectorial force */
582             fix1             = _mm_macc_pd(dx11,fscal,fix1);
583             fiy1             = _mm_macc_pd(dy11,fscal,fiy1);
584             fiz1             = _mm_macc_pd(dz11,fscal,fiz1);
585             
586             fjx1             = _mm_macc_pd(dx11,fscal,fjx1);
587             fjy1             = _mm_macc_pd(dy11,fscal,fjy1);
588             fjz1             = _mm_macc_pd(dz11,fscal,fjz1);
589
590             }
591
592             /**************************
593              * CALCULATE INTERACTIONS *
594              **************************/
595
596             if (gmx_mm_any_lt(rsq12,rcutoff2))
597             {
598
599             r12              = _mm_mul_pd(rsq12,rinv12);
600
601             /* EWALD ELECTROSTATICS */
602
603             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
604             ewrt             = _mm_mul_pd(r12,ewtabscale);
605             ewitab           = _mm_cvttpd_epi32(ewrt);
606 #ifdef __XOP__
607             eweps            = _mm_frcz_pd(ewrt);
608 #else
609             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
610 #endif
611             twoeweps         = _mm_add_pd(eweps,eweps);
612             ewitab           = _mm_slli_epi32(ewitab,2);
613             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
614             ewtabD           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,1) );
615             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
616             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
617             ewtabFn          = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,1) +2);
618             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
619             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
620             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
621             velec            = _mm_mul_pd(qq12,_mm_sub_pd(_mm_sub_pd(rinv12,sh_ewald),velec));
622             felec            = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
623
624             cutoff_mask      = _mm_cmplt_pd(rsq12,rcutoff2);
625
626             /* Update potential sum for this i atom from the interaction with this j atom. */
627             velec            = _mm_and_pd(velec,cutoff_mask);
628             velecsum         = _mm_add_pd(velecsum,velec);
629
630             fscal            = felec;
631
632             fscal            = _mm_and_pd(fscal,cutoff_mask);
633
634             /* Update vectorial force */
635             fix1             = _mm_macc_pd(dx12,fscal,fix1);
636             fiy1             = _mm_macc_pd(dy12,fscal,fiy1);
637             fiz1             = _mm_macc_pd(dz12,fscal,fiz1);
638             
639             fjx2             = _mm_macc_pd(dx12,fscal,fjx2);
640             fjy2             = _mm_macc_pd(dy12,fscal,fjy2);
641             fjz2             = _mm_macc_pd(dz12,fscal,fjz2);
642
643             }
644
645             /**************************
646              * CALCULATE INTERACTIONS *
647              **************************/
648
649             if (gmx_mm_any_lt(rsq20,rcutoff2))
650             {
651
652             r20              = _mm_mul_pd(rsq20,rinv20);
653
654             /* EWALD ELECTROSTATICS */
655
656             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
657             ewrt             = _mm_mul_pd(r20,ewtabscale);
658             ewitab           = _mm_cvttpd_epi32(ewrt);
659 #ifdef __XOP__
660             eweps            = _mm_frcz_pd(ewrt);
661 #else
662             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
663 #endif
664             twoeweps         = _mm_add_pd(eweps,eweps);
665             ewitab           = _mm_slli_epi32(ewitab,2);
666             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
667             ewtabD           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,1) );
668             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
669             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
670             ewtabFn          = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,1) +2);
671             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
672             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
673             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
674             velec            = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
675             felec            = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
676
677             cutoff_mask      = _mm_cmplt_pd(rsq20,rcutoff2);
678
679             /* Update potential sum for this i atom from the interaction with this j atom. */
680             velec            = _mm_and_pd(velec,cutoff_mask);
681             velecsum         = _mm_add_pd(velecsum,velec);
682
683             fscal            = felec;
684
685             fscal            = _mm_and_pd(fscal,cutoff_mask);
686
687             /* Update vectorial force */
688             fix2             = _mm_macc_pd(dx20,fscal,fix2);
689             fiy2             = _mm_macc_pd(dy20,fscal,fiy2);
690             fiz2             = _mm_macc_pd(dz20,fscal,fiz2);
691             
692             fjx0             = _mm_macc_pd(dx20,fscal,fjx0);
693             fjy0             = _mm_macc_pd(dy20,fscal,fjy0);
694             fjz0             = _mm_macc_pd(dz20,fscal,fjz0);
695
696             }
697
698             /**************************
699              * CALCULATE INTERACTIONS *
700              **************************/
701
702             if (gmx_mm_any_lt(rsq21,rcutoff2))
703             {
704
705             r21              = _mm_mul_pd(rsq21,rinv21);
706
707             /* EWALD ELECTROSTATICS */
708
709             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
710             ewrt             = _mm_mul_pd(r21,ewtabscale);
711             ewitab           = _mm_cvttpd_epi32(ewrt);
712 #ifdef __XOP__
713             eweps            = _mm_frcz_pd(ewrt);
714 #else
715             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
716 #endif
717             twoeweps         = _mm_add_pd(eweps,eweps);
718             ewitab           = _mm_slli_epi32(ewitab,2);
719             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
720             ewtabD           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,1) );
721             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
722             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
723             ewtabFn          = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,1) +2);
724             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
725             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
726             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
727             velec            = _mm_mul_pd(qq21,_mm_sub_pd(_mm_sub_pd(rinv21,sh_ewald),velec));
728             felec            = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
729
730             cutoff_mask      = _mm_cmplt_pd(rsq21,rcutoff2);
731
732             /* Update potential sum for this i atom from the interaction with this j atom. */
733             velec            = _mm_and_pd(velec,cutoff_mask);
734             velecsum         = _mm_add_pd(velecsum,velec);
735
736             fscal            = felec;
737
738             fscal            = _mm_and_pd(fscal,cutoff_mask);
739
740             /* Update vectorial force */
741             fix2             = _mm_macc_pd(dx21,fscal,fix2);
742             fiy2             = _mm_macc_pd(dy21,fscal,fiy2);
743             fiz2             = _mm_macc_pd(dz21,fscal,fiz2);
744             
745             fjx1             = _mm_macc_pd(dx21,fscal,fjx1);
746             fjy1             = _mm_macc_pd(dy21,fscal,fjy1);
747             fjz1             = _mm_macc_pd(dz21,fscal,fjz1);
748
749             }
750
751             /**************************
752              * CALCULATE INTERACTIONS *
753              **************************/
754
755             if (gmx_mm_any_lt(rsq22,rcutoff2))
756             {
757
758             r22              = _mm_mul_pd(rsq22,rinv22);
759
760             /* EWALD ELECTROSTATICS */
761
762             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
763             ewrt             = _mm_mul_pd(r22,ewtabscale);
764             ewitab           = _mm_cvttpd_epi32(ewrt);
765 #ifdef __XOP__
766             eweps            = _mm_frcz_pd(ewrt);
767 #else
768             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
769 #endif
770             twoeweps         = _mm_add_pd(eweps,eweps);
771             ewitab           = _mm_slli_epi32(ewitab,2);
772             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
773             ewtabD           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,1) );
774             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
775             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
776             ewtabFn          = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,1) +2);
777             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
778             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
779             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
780             velec            = _mm_mul_pd(qq22,_mm_sub_pd(_mm_sub_pd(rinv22,sh_ewald),velec));
781             felec            = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
782
783             cutoff_mask      = _mm_cmplt_pd(rsq22,rcutoff2);
784
785             /* Update potential sum for this i atom from the interaction with this j atom. */
786             velec            = _mm_and_pd(velec,cutoff_mask);
787             velecsum         = _mm_add_pd(velecsum,velec);
788
789             fscal            = felec;
790
791             fscal            = _mm_and_pd(fscal,cutoff_mask);
792
793             /* Update vectorial force */
794             fix2             = _mm_macc_pd(dx22,fscal,fix2);
795             fiy2             = _mm_macc_pd(dy22,fscal,fiy2);
796             fiz2             = _mm_macc_pd(dz22,fscal,fiz2);
797             
798             fjx2             = _mm_macc_pd(dx22,fscal,fjx2);
799             fjy2             = _mm_macc_pd(dy22,fscal,fjy2);
800             fjz2             = _mm_macc_pd(dz22,fscal,fjz2);
801
802             }
803
804             gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
805
806             /* Inner loop uses 470 flops */
807         }
808
809         if(jidx<j_index_end)
810         {
811
812             jnrA             = jjnr[jidx];
813             j_coord_offsetA  = DIM*jnrA;
814
815             /* load j atom coordinates */
816             gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
817                                               &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
818
819             /* Calculate displacement vector */
820             dx00             = _mm_sub_pd(ix0,jx0);
821             dy00             = _mm_sub_pd(iy0,jy0);
822             dz00             = _mm_sub_pd(iz0,jz0);
823             dx01             = _mm_sub_pd(ix0,jx1);
824             dy01             = _mm_sub_pd(iy0,jy1);
825             dz01             = _mm_sub_pd(iz0,jz1);
826             dx02             = _mm_sub_pd(ix0,jx2);
827             dy02             = _mm_sub_pd(iy0,jy2);
828             dz02             = _mm_sub_pd(iz0,jz2);
829             dx10             = _mm_sub_pd(ix1,jx0);
830             dy10             = _mm_sub_pd(iy1,jy0);
831             dz10             = _mm_sub_pd(iz1,jz0);
832             dx11             = _mm_sub_pd(ix1,jx1);
833             dy11             = _mm_sub_pd(iy1,jy1);
834             dz11             = _mm_sub_pd(iz1,jz1);
835             dx12             = _mm_sub_pd(ix1,jx2);
836             dy12             = _mm_sub_pd(iy1,jy2);
837             dz12             = _mm_sub_pd(iz1,jz2);
838             dx20             = _mm_sub_pd(ix2,jx0);
839             dy20             = _mm_sub_pd(iy2,jy0);
840             dz20             = _mm_sub_pd(iz2,jz0);
841             dx21             = _mm_sub_pd(ix2,jx1);
842             dy21             = _mm_sub_pd(iy2,jy1);
843             dz21             = _mm_sub_pd(iz2,jz1);
844             dx22             = _mm_sub_pd(ix2,jx2);
845             dy22             = _mm_sub_pd(iy2,jy2);
846             dz22             = _mm_sub_pd(iz2,jz2);
847
848             /* Calculate squared distance and things based on it */
849             rsq00            = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
850             rsq01            = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
851             rsq02            = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
852             rsq10            = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
853             rsq11            = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
854             rsq12            = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
855             rsq20            = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
856             rsq21            = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
857             rsq22            = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
858
859             rinv00           = avx128fma_invsqrt_d(rsq00);
860             rinv01           = avx128fma_invsqrt_d(rsq01);
861             rinv02           = avx128fma_invsqrt_d(rsq02);
862             rinv10           = avx128fma_invsqrt_d(rsq10);
863             rinv11           = avx128fma_invsqrt_d(rsq11);
864             rinv12           = avx128fma_invsqrt_d(rsq12);
865             rinv20           = avx128fma_invsqrt_d(rsq20);
866             rinv21           = avx128fma_invsqrt_d(rsq21);
867             rinv22           = avx128fma_invsqrt_d(rsq22);
868
869             rinvsq00         = _mm_mul_pd(rinv00,rinv00);
870             rinvsq01         = _mm_mul_pd(rinv01,rinv01);
871             rinvsq02         = _mm_mul_pd(rinv02,rinv02);
872             rinvsq10         = _mm_mul_pd(rinv10,rinv10);
873             rinvsq11         = _mm_mul_pd(rinv11,rinv11);
874             rinvsq12         = _mm_mul_pd(rinv12,rinv12);
875             rinvsq20         = _mm_mul_pd(rinv20,rinv20);
876             rinvsq21         = _mm_mul_pd(rinv21,rinv21);
877             rinvsq22         = _mm_mul_pd(rinv22,rinv22);
878
879             fjx0             = _mm_setzero_pd();
880             fjy0             = _mm_setzero_pd();
881             fjz0             = _mm_setzero_pd();
882             fjx1             = _mm_setzero_pd();
883             fjy1             = _mm_setzero_pd();
884             fjz1             = _mm_setzero_pd();
885             fjx2             = _mm_setzero_pd();
886             fjy2             = _mm_setzero_pd();
887             fjz2             = _mm_setzero_pd();
888
889             /**************************
890              * CALCULATE INTERACTIONS *
891              **************************/
892
893             if (gmx_mm_any_lt(rsq00,rcutoff2))
894             {
895
896             r00              = _mm_mul_pd(rsq00,rinv00);
897
898             /* EWALD ELECTROSTATICS */
899
900             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
901             ewrt             = _mm_mul_pd(r00,ewtabscale);
902             ewitab           = _mm_cvttpd_epi32(ewrt);
903 #ifdef __XOP__
904             eweps            = _mm_frcz_pd(ewrt);
905 #else
906             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
907 #endif
908             twoeweps         = _mm_add_pd(eweps,eweps);
909             ewitab           = _mm_slli_epi32(ewitab,2);
910             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
911             ewtabD           = _mm_setzero_pd();
912             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
913             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
914             ewtabFn          = _mm_setzero_pd();
915             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
916             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
917             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
918             velec            = _mm_mul_pd(qq00,_mm_sub_pd(_mm_sub_pd(rinv00,sh_ewald),velec));
919             felec            = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
920
921             /* Analytical LJ-PME */
922             rinvsix          = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
923             ewcljrsq         = _mm_mul_pd(ewclj2,rsq00);
924             ewclj6           = _mm_mul_pd(ewclj2,_mm_mul_pd(ewclj2,ewclj2));
925             exponent         = avx128fma_exp_d(ewcljrsq);
926             /* poly = exp(-(beta*r)^2) * (1 + (beta*r)^2 + (beta*r)^4 /2) */
927             poly             = _mm_mul_pd(exponent,_mm_macc_pd(_mm_mul_pd(ewcljrsq,ewcljrsq),one_half,_mm_sub_pd(one,ewcljrsq)));
928             /* vvdw6 = [C6 - C6grid * (1-poly)]/r6 */
929             vvdw6            = _mm_mul_pd(_mm_macc_pd(-c6grid_00,_mm_sub_pd(one,poly),c6_00),rinvsix);
930             vvdw12           = _mm_mul_pd(c12_00,_mm_mul_pd(rinvsix,rinvsix));
931             vvdw             = _mm_msub_pd(_mm_nmacc_pd(c12_00,_mm_mul_pd(sh_vdw_invrcut6,sh_vdw_invrcut6),vvdw12),one_twelfth,
932                                _mm_mul_pd(_mm_sub_pd(vvdw6,_mm_macc_pd(c6grid_00,sh_lj_ewald,_mm_mul_pd(c6_00,sh_vdw_invrcut6))),one_sixth));
933             /* fvdw = vvdw12/r - (vvdw6/r + (C6grid * exponent * beta^6)/r) */
934             fvdw             = _mm_mul_pd(_mm_add_pd(vvdw12,_mm_msub_pd(_mm_mul_pd(c6grid_00,one_sixth),_mm_mul_pd(exponent,ewclj6),vvdw6)),rinvsq00);
935
936             cutoff_mask      = _mm_cmplt_pd(rsq00,rcutoff2);
937
938             /* Update potential sum for this i atom from the interaction with this j atom. */
939             velec            = _mm_and_pd(velec,cutoff_mask);
940             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
941             velecsum         = _mm_add_pd(velecsum,velec);
942             vvdw             = _mm_and_pd(vvdw,cutoff_mask);
943             vvdw             = _mm_unpacklo_pd(vvdw,_mm_setzero_pd());
944             vvdwsum          = _mm_add_pd(vvdwsum,vvdw);
945
946             fscal            = _mm_add_pd(felec,fvdw);
947
948             fscal            = _mm_and_pd(fscal,cutoff_mask);
949
950             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
951
952             /* Update vectorial force */
953             fix0             = _mm_macc_pd(dx00,fscal,fix0);
954             fiy0             = _mm_macc_pd(dy00,fscal,fiy0);
955             fiz0             = _mm_macc_pd(dz00,fscal,fiz0);
956             
957             fjx0             = _mm_macc_pd(dx00,fscal,fjx0);
958             fjy0             = _mm_macc_pd(dy00,fscal,fjy0);
959             fjz0             = _mm_macc_pd(dz00,fscal,fjz0);
960
961             }
962
963             /**************************
964              * CALCULATE INTERACTIONS *
965              **************************/
966
967             if (gmx_mm_any_lt(rsq01,rcutoff2))
968             {
969
970             r01              = _mm_mul_pd(rsq01,rinv01);
971
972             /* EWALD ELECTROSTATICS */
973
974             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
975             ewrt             = _mm_mul_pd(r01,ewtabscale);
976             ewitab           = _mm_cvttpd_epi32(ewrt);
977 #ifdef __XOP__
978             eweps            = _mm_frcz_pd(ewrt);
979 #else
980             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
981 #endif
982             twoeweps         = _mm_add_pd(eweps,eweps);
983             ewitab           = _mm_slli_epi32(ewitab,2);
984             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
985             ewtabD           = _mm_setzero_pd();
986             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
987             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
988             ewtabFn          = _mm_setzero_pd();
989             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
990             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
991             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
992             velec            = _mm_mul_pd(qq01,_mm_sub_pd(_mm_sub_pd(rinv01,sh_ewald),velec));
993             felec            = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
994
995             cutoff_mask      = _mm_cmplt_pd(rsq01,rcutoff2);
996
997             /* Update potential sum for this i atom from the interaction with this j atom. */
998             velec            = _mm_and_pd(velec,cutoff_mask);
999             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
1000             velecsum         = _mm_add_pd(velecsum,velec);
1001
1002             fscal            = felec;
1003
1004             fscal            = _mm_and_pd(fscal,cutoff_mask);
1005
1006             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1007
1008             /* Update vectorial force */
1009             fix0             = _mm_macc_pd(dx01,fscal,fix0);
1010             fiy0             = _mm_macc_pd(dy01,fscal,fiy0);
1011             fiz0             = _mm_macc_pd(dz01,fscal,fiz0);
1012             
1013             fjx1             = _mm_macc_pd(dx01,fscal,fjx1);
1014             fjy1             = _mm_macc_pd(dy01,fscal,fjy1);
1015             fjz1             = _mm_macc_pd(dz01,fscal,fjz1);
1016
1017             }
1018
1019             /**************************
1020              * CALCULATE INTERACTIONS *
1021              **************************/
1022
1023             if (gmx_mm_any_lt(rsq02,rcutoff2))
1024             {
1025
1026             r02              = _mm_mul_pd(rsq02,rinv02);
1027
1028             /* EWALD ELECTROSTATICS */
1029
1030             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1031             ewrt             = _mm_mul_pd(r02,ewtabscale);
1032             ewitab           = _mm_cvttpd_epi32(ewrt);
1033 #ifdef __XOP__
1034             eweps            = _mm_frcz_pd(ewrt);
1035 #else
1036             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1037 #endif
1038             twoeweps         = _mm_add_pd(eweps,eweps);
1039             ewitab           = _mm_slli_epi32(ewitab,2);
1040             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
1041             ewtabD           = _mm_setzero_pd();
1042             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
1043             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
1044             ewtabFn          = _mm_setzero_pd();
1045             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
1046             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
1047             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
1048             velec            = _mm_mul_pd(qq02,_mm_sub_pd(_mm_sub_pd(rinv02,sh_ewald),velec));
1049             felec            = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
1050
1051             cutoff_mask      = _mm_cmplt_pd(rsq02,rcutoff2);
1052
1053             /* Update potential sum for this i atom from the interaction with this j atom. */
1054             velec            = _mm_and_pd(velec,cutoff_mask);
1055             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
1056             velecsum         = _mm_add_pd(velecsum,velec);
1057
1058             fscal            = felec;
1059
1060             fscal            = _mm_and_pd(fscal,cutoff_mask);
1061
1062             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1063
1064             /* Update vectorial force */
1065             fix0             = _mm_macc_pd(dx02,fscal,fix0);
1066             fiy0             = _mm_macc_pd(dy02,fscal,fiy0);
1067             fiz0             = _mm_macc_pd(dz02,fscal,fiz0);
1068             
1069             fjx2             = _mm_macc_pd(dx02,fscal,fjx2);
1070             fjy2             = _mm_macc_pd(dy02,fscal,fjy2);
1071             fjz2             = _mm_macc_pd(dz02,fscal,fjz2);
1072
1073             }
1074
1075             /**************************
1076              * CALCULATE INTERACTIONS *
1077              **************************/
1078
1079             if (gmx_mm_any_lt(rsq10,rcutoff2))
1080             {
1081
1082             r10              = _mm_mul_pd(rsq10,rinv10);
1083
1084             /* EWALD ELECTROSTATICS */
1085
1086             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1087             ewrt             = _mm_mul_pd(r10,ewtabscale);
1088             ewitab           = _mm_cvttpd_epi32(ewrt);
1089 #ifdef __XOP__
1090             eweps            = _mm_frcz_pd(ewrt);
1091 #else
1092             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1093 #endif
1094             twoeweps         = _mm_add_pd(eweps,eweps);
1095             ewitab           = _mm_slli_epi32(ewitab,2);
1096             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
1097             ewtabD           = _mm_setzero_pd();
1098             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
1099             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
1100             ewtabFn          = _mm_setzero_pd();
1101             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
1102             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
1103             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
1104             velec            = _mm_mul_pd(qq10,_mm_sub_pd(_mm_sub_pd(rinv10,sh_ewald),velec));
1105             felec            = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
1106
1107             cutoff_mask      = _mm_cmplt_pd(rsq10,rcutoff2);
1108
1109             /* Update potential sum for this i atom from the interaction with this j atom. */
1110             velec            = _mm_and_pd(velec,cutoff_mask);
1111             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
1112             velecsum         = _mm_add_pd(velecsum,velec);
1113
1114             fscal            = felec;
1115
1116             fscal            = _mm_and_pd(fscal,cutoff_mask);
1117
1118             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1119
1120             /* Update vectorial force */
1121             fix1             = _mm_macc_pd(dx10,fscal,fix1);
1122             fiy1             = _mm_macc_pd(dy10,fscal,fiy1);
1123             fiz1             = _mm_macc_pd(dz10,fscal,fiz1);
1124             
1125             fjx0             = _mm_macc_pd(dx10,fscal,fjx0);
1126             fjy0             = _mm_macc_pd(dy10,fscal,fjy0);
1127             fjz0             = _mm_macc_pd(dz10,fscal,fjz0);
1128
1129             }
1130
1131             /**************************
1132              * CALCULATE INTERACTIONS *
1133              **************************/
1134
1135             if (gmx_mm_any_lt(rsq11,rcutoff2))
1136             {
1137
1138             r11              = _mm_mul_pd(rsq11,rinv11);
1139
1140             /* EWALD ELECTROSTATICS */
1141
1142             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1143             ewrt             = _mm_mul_pd(r11,ewtabscale);
1144             ewitab           = _mm_cvttpd_epi32(ewrt);
1145 #ifdef __XOP__
1146             eweps            = _mm_frcz_pd(ewrt);
1147 #else
1148             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1149 #endif
1150             twoeweps         = _mm_add_pd(eweps,eweps);
1151             ewitab           = _mm_slli_epi32(ewitab,2);
1152             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
1153             ewtabD           = _mm_setzero_pd();
1154             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
1155             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
1156             ewtabFn          = _mm_setzero_pd();
1157             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
1158             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
1159             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
1160             velec            = _mm_mul_pd(qq11,_mm_sub_pd(_mm_sub_pd(rinv11,sh_ewald),velec));
1161             felec            = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
1162
1163             cutoff_mask      = _mm_cmplt_pd(rsq11,rcutoff2);
1164
1165             /* Update potential sum for this i atom from the interaction with this j atom. */
1166             velec            = _mm_and_pd(velec,cutoff_mask);
1167             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
1168             velecsum         = _mm_add_pd(velecsum,velec);
1169
1170             fscal            = felec;
1171
1172             fscal            = _mm_and_pd(fscal,cutoff_mask);
1173
1174             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1175
1176             /* Update vectorial force */
1177             fix1             = _mm_macc_pd(dx11,fscal,fix1);
1178             fiy1             = _mm_macc_pd(dy11,fscal,fiy1);
1179             fiz1             = _mm_macc_pd(dz11,fscal,fiz1);
1180             
1181             fjx1             = _mm_macc_pd(dx11,fscal,fjx1);
1182             fjy1             = _mm_macc_pd(dy11,fscal,fjy1);
1183             fjz1             = _mm_macc_pd(dz11,fscal,fjz1);
1184
1185             }
1186
1187             /**************************
1188              * CALCULATE INTERACTIONS *
1189              **************************/
1190
1191             if (gmx_mm_any_lt(rsq12,rcutoff2))
1192             {
1193
1194             r12              = _mm_mul_pd(rsq12,rinv12);
1195
1196             /* EWALD ELECTROSTATICS */
1197
1198             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1199             ewrt             = _mm_mul_pd(r12,ewtabscale);
1200             ewitab           = _mm_cvttpd_epi32(ewrt);
1201 #ifdef __XOP__
1202             eweps            = _mm_frcz_pd(ewrt);
1203 #else
1204             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1205 #endif
1206             twoeweps         = _mm_add_pd(eweps,eweps);
1207             ewitab           = _mm_slli_epi32(ewitab,2);
1208             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
1209             ewtabD           = _mm_setzero_pd();
1210             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
1211             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
1212             ewtabFn          = _mm_setzero_pd();
1213             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
1214             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
1215             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
1216             velec            = _mm_mul_pd(qq12,_mm_sub_pd(_mm_sub_pd(rinv12,sh_ewald),velec));
1217             felec            = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
1218
1219             cutoff_mask      = _mm_cmplt_pd(rsq12,rcutoff2);
1220
1221             /* Update potential sum for this i atom from the interaction with this j atom. */
1222             velec            = _mm_and_pd(velec,cutoff_mask);
1223             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
1224             velecsum         = _mm_add_pd(velecsum,velec);
1225
1226             fscal            = felec;
1227
1228             fscal            = _mm_and_pd(fscal,cutoff_mask);
1229
1230             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1231
1232             /* Update vectorial force */
1233             fix1             = _mm_macc_pd(dx12,fscal,fix1);
1234             fiy1             = _mm_macc_pd(dy12,fscal,fiy1);
1235             fiz1             = _mm_macc_pd(dz12,fscal,fiz1);
1236             
1237             fjx2             = _mm_macc_pd(dx12,fscal,fjx2);
1238             fjy2             = _mm_macc_pd(dy12,fscal,fjy2);
1239             fjz2             = _mm_macc_pd(dz12,fscal,fjz2);
1240
1241             }
1242
1243             /**************************
1244              * CALCULATE INTERACTIONS *
1245              **************************/
1246
1247             if (gmx_mm_any_lt(rsq20,rcutoff2))
1248             {
1249
1250             r20              = _mm_mul_pd(rsq20,rinv20);
1251
1252             /* EWALD ELECTROSTATICS */
1253
1254             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1255             ewrt             = _mm_mul_pd(r20,ewtabscale);
1256             ewitab           = _mm_cvttpd_epi32(ewrt);
1257 #ifdef __XOP__
1258             eweps            = _mm_frcz_pd(ewrt);
1259 #else
1260             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1261 #endif
1262             twoeweps         = _mm_add_pd(eweps,eweps);
1263             ewitab           = _mm_slli_epi32(ewitab,2);
1264             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
1265             ewtabD           = _mm_setzero_pd();
1266             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
1267             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
1268             ewtabFn          = _mm_setzero_pd();
1269             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
1270             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
1271             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
1272             velec            = _mm_mul_pd(qq20,_mm_sub_pd(_mm_sub_pd(rinv20,sh_ewald),velec));
1273             felec            = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
1274
1275             cutoff_mask      = _mm_cmplt_pd(rsq20,rcutoff2);
1276
1277             /* Update potential sum for this i atom from the interaction with this j atom. */
1278             velec            = _mm_and_pd(velec,cutoff_mask);
1279             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
1280             velecsum         = _mm_add_pd(velecsum,velec);
1281
1282             fscal            = felec;
1283
1284             fscal            = _mm_and_pd(fscal,cutoff_mask);
1285
1286             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1287
1288             /* Update vectorial force */
1289             fix2             = _mm_macc_pd(dx20,fscal,fix2);
1290             fiy2             = _mm_macc_pd(dy20,fscal,fiy2);
1291             fiz2             = _mm_macc_pd(dz20,fscal,fiz2);
1292             
1293             fjx0             = _mm_macc_pd(dx20,fscal,fjx0);
1294             fjy0             = _mm_macc_pd(dy20,fscal,fjy0);
1295             fjz0             = _mm_macc_pd(dz20,fscal,fjz0);
1296
1297             }
1298
1299             /**************************
1300              * CALCULATE INTERACTIONS *
1301              **************************/
1302
1303             if (gmx_mm_any_lt(rsq21,rcutoff2))
1304             {
1305
1306             r21              = _mm_mul_pd(rsq21,rinv21);
1307
1308             /* EWALD ELECTROSTATICS */
1309
1310             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1311             ewrt             = _mm_mul_pd(r21,ewtabscale);
1312             ewitab           = _mm_cvttpd_epi32(ewrt);
1313 #ifdef __XOP__
1314             eweps            = _mm_frcz_pd(ewrt);
1315 #else
1316             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1317 #endif
1318             twoeweps         = _mm_add_pd(eweps,eweps);
1319             ewitab           = _mm_slli_epi32(ewitab,2);
1320             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
1321             ewtabD           = _mm_setzero_pd();
1322             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
1323             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
1324             ewtabFn          = _mm_setzero_pd();
1325             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
1326             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
1327             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
1328             velec            = _mm_mul_pd(qq21,_mm_sub_pd(_mm_sub_pd(rinv21,sh_ewald),velec));
1329             felec            = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
1330
1331             cutoff_mask      = _mm_cmplt_pd(rsq21,rcutoff2);
1332
1333             /* Update potential sum for this i atom from the interaction with this j atom. */
1334             velec            = _mm_and_pd(velec,cutoff_mask);
1335             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
1336             velecsum         = _mm_add_pd(velecsum,velec);
1337
1338             fscal            = felec;
1339
1340             fscal            = _mm_and_pd(fscal,cutoff_mask);
1341
1342             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1343
1344             /* Update vectorial force */
1345             fix2             = _mm_macc_pd(dx21,fscal,fix2);
1346             fiy2             = _mm_macc_pd(dy21,fscal,fiy2);
1347             fiz2             = _mm_macc_pd(dz21,fscal,fiz2);
1348             
1349             fjx1             = _mm_macc_pd(dx21,fscal,fjx1);
1350             fjy1             = _mm_macc_pd(dy21,fscal,fjy1);
1351             fjz1             = _mm_macc_pd(dz21,fscal,fjz1);
1352
1353             }
1354
1355             /**************************
1356              * CALCULATE INTERACTIONS *
1357              **************************/
1358
1359             if (gmx_mm_any_lt(rsq22,rcutoff2))
1360             {
1361
1362             r22              = _mm_mul_pd(rsq22,rinv22);
1363
1364             /* EWALD ELECTROSTATICS */
1365
1366             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1367             ewrt             = _mm_mul_pd(r22,ewtabscale);
1368             ewitab           = _mm_cvttpd_epi32(ewrt);
1369 #ifdef __XOP__
1370             eweps            = _mm_frcz_pd(ewrt);
1371 #else
1372             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1373 #endif
1374             twoeweps         = _mm_add_pd(eweps,eweps);
1375             ewitab           = _mm_slli_epi32(ewitab,2);
1376             ewtabF           = _mm_load_pd( ewtab + _mm_extract_epi32(ewitab,0) );
1377             ewtabD           = _mm_setzero_pd();
1378             GMX_MM_TRANSPOSE2_PD(ewtabF,ewtabD);
1379             ewtabV           = _mm_load_sd( ewtab + _mm_extract_epi32(ewitab,0) +2);
1380             ewtabFn          = _mm_setzero_pd();
1381             GMX_MM_TRANSPOSE2_PD(ewtabV,ewtabFn);
1382             felec            = _mm_macc_pd(eweps,ewtabD,ewtabF);
1383             velec            = _mm_nmacc_pd(_mm_mul_pd(ewtabhalfspace,eweps) ,_mm_add_pd(ewtabF,felec), ewtabV);
1384             velec            = _mm_mul_pd(qq22,_mm_sub_pd(_mm_sub_pd(rinv22,sh_ewald),velec));
1385             felec            = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
1386
1387             cutoff_mask      = _mm_cmplt_pd(rsq22,rcutoff2);
1388
1389             /* Update potential sum for this i atom from the interaction with this j atom. */
1390             velec            = _mm_and_pd(velec,cutoff_mask);
1391             velec            = _mm_unpacklo_pd(velec,_mm_setzero_pd());
1392             velecsum         = _mm_add_pd(velecsum,velec);
1393
1394             fscal            = felec;
1395
1396             fscal            = _mm_and_pd(fscal,cutoff_mask);
1397
1398             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
1399
1400             /* Update vectorial force */
1401             fix2             = _mm_macc_pd(dx22,fscal,fix2);
1402             fiy2             = _mm_macc_pd(dy22,fscal,fiy2);
1403             fiz2             = _mm_macc_pd(dz22,fscal,fiz2);
1404             
1405             fjx2             = _mm_macc_pd(dx22,fscal,fjx2);
1406             fjy2             = _mm_macc_pd(dy22,fscal,fjy2);
1407             fjz2             = _mm_macc_pd(dz22,fscal,fjz2);
1408
1409             }
1410
1411             gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
1412
1413             /* Inner loop uses 470 flops */
1414         }
1415
1416         /* End of innermost loop */
1417
1418         gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
1419                                               f+i_coord_offset,fshift+i_shift_offset);
1420
1421         ggid                        = gid[iidx];
1422         /* Update potential energies */
1423         gmx_mm_update_1pot_pd(velecsum,kernel_data->energygrp_elec+ggid);
1424         gmx_mm_update_1pot_pd(vvdwsum,kernel_data->energygrp_vdw+ggid);
1425
1426         /* Increment number of inner iterations */
1427         inneriter                  += j_index_end - j_index_start;
1428
1429         /* Outer loop uses 20 flops */
1430     }
1431
1432     /* Increment number of outer iterations */
1433     outeriter        += nri;
1434
1435     /* Update outer/inner flops */
1436
1437     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_VF,outeriter*20 + inneriter*470);
1438 }
1439 /*
1440  * Gromacs nonbonded kernel:   nb_kernel_ElecEwSh_VdwLJEwSh_GeomW3W3_F_avx_128_fma_double
1441  * Electrostatics interaction: Ewald
1442  * VdW interaction:            LJEwald
1443  * Geometry:                   Water3-Water3
1444  * Calculate force/pot:        Force
1445  */
1446 void
1447 nb_kernel_ElecEwSh_VdwLJEwSh_GeomW3W3_F_avx_128_fma_double
1448                     (t_nblist                    * gmx_restrict       nlist,
1449                      rvec                        * gmx_restrict          xx,
1450                      rvec                        * gmx_restrict          ff,
1451                      struct t_forcerec           * gmx_restrict          fr,
1452                      t_mdatoms                   * gmx_restrict     mdatoms,
1453                      nb_kernel_data_t gmx_unused * gmx_restrict kernel_data,
1454                      t_nrnb                      * gmx_restrict        nrnb)
1455 {
1456     /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
1457      * just 0 for non-waters.
1458      * Suffixes A,B refer to j loop unrolling done with SSE double precision, e.g. for the two different
1459      * jnr indices corresponding to data put in the four positions in the SIMD register.
1460      */
1461     int              i_shift_offset,i_coord_offset,outeriter,inneriter;
1462     int              j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
1463     int              jnrA,jnrB;
1464     int              j_coord_offsetA,j_coord_offsetB;
1465     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
1466     real             rcutoff_scalar;
1467     real             *shiftvec,*fshift,*x,*f;
1468     __m128d          tx,ty,tz,fscal,rcutoff,rcutoff2,jidxall;
1469     int              vdwioffset0;
1470     __m128d          ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
1471     int              vdwioffset1;
1472     __m128d          ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
1473     int              vdwioffset2;
1474     __m128d          ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
1475     int              vdwjidx0A,vdwjidx0B;
1476     __m128d          jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
1477     int              vdwjidx1A,vdwjidx1B;
1478     __m128d          jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
1479     int              vdwjidx2A,vdwjidx2B;
1480     __m128d          jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
1481     __m128d          dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
1482     __m128d          dx01,dy01,dz01,rsq01,rinv01,rinvsq01,r01,qq01,c6_01,c12_01;
1483     __m128d          dx02,dy02,dz02,rsq02,rinv02,rinvsq02,r02,qq02,c6_02,c12_02;
1484     __m128d          dx10,dy10,dz10,rsq10,rinv10,rinvsq10,r10,qq10,c6_10,c12_10;
1485     __m128d          dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
1486     __m128d          dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
1487     __m128d          dx20,dy20,dz20,rsq20,rinv20,rinvsq20,r20,qq20,c6_20,c12_20;
1488     __m128d          dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
1489     __m128d          dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
1490     __m128d          velec,felec,velecsum,facel,crf,krf,krf2;
1491     real             *charge;
1492     int              nvdwtype;
1493     __m128d          rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
1494     int              *vdwtype;
1495     real             *vdwparam;
1496     __m128d          one_sixth   = _mm_set1_pd(1.0/6.0);
1497     __m128d          one_twelfth = _mm_set1_pd(1.0/12.0);
1498     __m128d           c6grid_00;
1499     __m128d           c6grid_01;
1500     __m128d           c6grid_02;
1501     __m128d           c6grid_10;
1502     __m128d           c6grid_11;
1503     __m128d           c6grid_12;
1504     __m128d           c6grid_20;
1505     __m128d           c6grid_21;
1506     __m128d           c6grid_22;
1507     real             *vdwgridparam;
1508     __m128d           ewclj,ewclj2,ewclj6,ewcljrsq,poly,exponent,f6A,f6B,sh_lj_ewald;
1509     __m128d           one_half  = _mm_set1_pd(0.5);
1510     __m128d           minus_one = _mm_set1_pd(-1.0);
1511     __m128i          ewitab;
1512     __m128d          ewtabscale,eweps,twoeweps,sh_ewald,ewrt,ewtabhalfspace,ewtabF,ewtabFn,ewtabD,ewtabV;
1513     real             *ewtab;
1514     __m128d          dummy_mask,cutoff_mask;
1515     __m128d          signbit   = gmx_mm_castsi128_pd( _mm_set_epi32(0x80000000,0x00000000,0x80000000,0x00000000) );
1516     __m128d          one     = _mm_set1_pd(1.0);
1517     __m128d          two     = _mm_set1_pd(2.0);
1518     x                = xx[0];
1519     f                = ff[0];
1520
1521     nri              = nlist->nri;
1522     iinr             = nlist->iinr;
1523     jindex           = nlist->jindex;
1524     jjnr             = nlist->jjnr;
1525     shiftidx         = nlist->shift;
1526     gid              = nlist->gid;
1527     shiftvec         = fr->shift_vec[0];
1528     fshift           = fr->fshift[0];
1529     facel            = _mm_set1_pd(fr->ic->epsfac);
1530     charge           = mdatoms->chargeA;
1531     nvdwtype         = fr->ntype;
1532     vdwparam         = fr->nbfp;
1533     vdwtype          = mdatoms->typeA;
1534     vdwgridparam     = fr->ljpme_c6grid;
1535     sh_lj_ewald      = _mm_set1_pd(fr->ic->sh_lj_ewald);
1536     ewclj            = _mm_set1_pd(fr->ic->ewaldcoeff_lj);
1537     ewclj2           = _mm_mul_pd(minus_one,_mm_mul_pd(ewclj,ewclj));
1538
1539     sh_ewald         = _mm_set1_pd(fr->ic->sh_ewald);
1540     ewtab            = fr->ic->tabq_coul_F;
1541     ewtabscale       = _mm_set1_pd(fr->ic->tabq_scale);
1542     ewtabhalfspace   = _mm_set1_pd(0.5/fr->ic->tabq_scale);
1543
1544     /* Setup water-specific parameters */
1545     inr              = nlist->iinr[0];
1546     iq0              = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+0]));
1547     iq1              = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+1]));
1548     iq2              = _mm_mul_pd(facel,_mm_set1_pd(charge[inr+2]));
1549     vdwioffset0      = 2*nvdwtype*vdwtype[inr+0];
1550
1551     jq0              = _mm_set1_pd(charge[inr+0]);
1552     jq1              = _mm_set1_pd(charge[inr+1]);
1553     jq2              = _mm_set1_pd(charge[inr+2]);
1554     vdwjidx0A        = 2*vdwtype[inr+0];
1555     qq00             = _mm_mul_pd(iq0,jq0);
1556     c6_00            = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A]);
1557     c12_00           = _mm_set1_pd(vdwparam[vdwioffset0+vdwjidx0A+1]);
1558     c6grid_00        = _mm_set1_pd(vdwgridparam[vdwioffset0+vdwjidx0A]);
1559     qq01             = _mm_mul_pd(iq0,jq1);
1560     qq02             = _mm_mul_pd(iq0,jq2);
1561     qq10             = _mm_mul_pd(iq1,jq0);
1562     qq11             = _mm_mul_pd(iq1,jq1);
1563     qq12             = _mm_mul_pd(iq1,jq2);
1564     qq20             = _mm_mul_pd(iq2,jq0);
1565     qq21             = _mm_mul_pd(iq2,jq1);
1566     qq22             = _mm_mul_pd(iq2,jq2);
1567
1568     /* When we use explicit cutoffs the value must be identical for elec and VdW, so use elec as an arbitrary choice */
1569     rcutoff_scalar   = fr->ic->rcoulomb;
1570     rcutoff          = _mm_set1_pd(rcutoff_scalar);
1571     rcutoff2         = _mm_mul_pd(rcutoff,rcutoff);
1572
1573     sh_vdw_invrcut6  = _mm_set1_pd(fr->ic->sh_invrc6);
1574     rvdw             = _mm_set1_pd(fr->ic->rvdw);
1575
1576     /* Avoid stupid compiler warnings */
1577     jnrA = jnrB = 0;
1578     j_coord_offsetA = 0;
1579     j_coord_offsetB = 0;
1580
1581     outeriter        = 0;
1582     inneriter        = 0;
1583
1584     /* Start outer loop over neighborlists */
1585     for(iidx=0; iidx<nri; iidx++)
1586     {
1587         /* Load shift vector for this list */
1588         i_shift_offset   = DIM*shiftidx[iidx];
1589
1590         /* Load limits for loop over neighbors */
1591         j_index_start    = jindex[iidx];
1592         j_index_end      = jindex[iidx+1];
1593
1594         /* Get outer coordinate index */
1595         inr              = iinr[iidx];
1596         i_coord_offset   = DIM*inr;
1597
1598         /* Load i particle coords and add shift vector */
1599         gmx_mm_load_shift_and_3rvec_broadcast_pd(shiftvec+i_shift_offset,x+i_coord_offset,
1600                                                  &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2);
1601
1602         fix0             = _mm_setzero_pd();
1603         fiy0             = _mm_setzero_pd();
1604         fiz0             = _mm_setzero_pd();
1605         fix1             = _mm_setzero_pd();
1606         fiy1             = _mm_setzero_pd();
1607         fiz1             = _mm_setzero_pd();
1608         fix2             = _mm_setzero_pd();
1609         fiy2             = _mm_setzero_pd();
1610         fiz2             = _mm_setzero_pd();
1611
1612         /* Start inner kernel loop */
1613         for(jidx=j_index_start; jidx<j_index_end-1; jidx+=2)
1614         {
1615
1616             /* Get j neighbor index, and coordinate index */
1617             jnrA             = jjnr[jidx];
1618             jnrB             = jjnr[jidx+1];
1619             j_coord_offsetA  = DIM*jnrA;
1620             j_coord_offsetB  = DIM*jnrB;
1621
1622             /* load j atom coordinates */
1623             gmx_mm_load_3rvec_2ptr_swizzle_pd(x+j_coord_offsetA,x+j_coord_offsetB,
1624                                               &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
1625
1626             /* Calculate displacement vector */
1627             dx00             = _mm_sub_pd(ix0,jx0);
1628             dy00             = _mm_sub_pd(iy0,jy0);
1629             dz00             = _mm_sub_pd(iz0,jz0);
1630             dx01             = _mm_sub_pd(ix0,jx1);
1631             dy01             = _mm_sub_pd(iy0,jy1);
1632             dz01             = _mm_sub_pd(iz0,jz1);
1633             dx02             = _mm_sub_pd(ix0,jx2);
1634             dy02             = _mm_sub_pd(iy0,jy2);
1635             dz02             = _mm_sub_pd(iz0,jz2);
1636             dx10             = _mm_sub_pd(ix1,jx0);
1637             dy10             = _mm_sub_pd(iy1,jy0);
1638             dz10             = _mm_sub_pd(iz1,jz0);
1639             dx11             = _mm_sub_pd(ix1,jx1);
1640             dy11             = _mm_sub_pd(iy1,jy1);
1641             dz11             = _mm_sub_pd(iz1,jz1);
1642             dx12             = _mm_sub_pd(ix1,jx2);
1643             dy12             = _mm_sub_pd(iy1,jy2);
1644             dz12             = _mm_sub_pd(iz1,jz2);
1645             dx20             = _mm_sub_pd(ix2,jx0);
1646             dy20             = _mm_sub_pd(iy2,jy0);
1647             dz20             = _mm_sub_pd(iz2,jz0);
1648             dx21             = _mm_sub_pd(ix2,jx1);
1649             dy21             = _mm_sub_pd(iy2,jy1);
1650             dz21             = _mm_sub_pd(iz2,jz1);
1651             dx22             = _mm_sub_pd(ix2,jx2);
1652             dy22             = _mm_sub_pd(iy2,jy2);
1653             dz22             = _mm_sub_pd(iz2,jz2);
1654
1655             /* Calculate squared distance and things based on it */
1656             rsq00            = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
1657             rsq01            = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
1658             rsq02            = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
1659             rsq10            = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
1660             rsq11            = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
1661             rsq12            = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
1662             rsq20            = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
1663             rsq21            = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
1664             rsq22            = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
1665
1666             rinv00           = avx128fma_invsqrt_d(rsq00);
1667             rinv01           = avx128fma_invsqrt_d(rsq01);
1668             rinv02           = avx128fma_invsqrt_d(rsq02);
1669             rinv10           = avx128fma_invsqrt_d(rsq10);
1670             rinv11           = avx128fma_invsqrt_d(rsq11);
1671             rinv12           = avx128fma_invsqrt_d(rsq12);
1672             rinv20           = avx128fma_invsqrt_d(rsq20);
1673             rinv21           = avx128fma_invsqrt_d(rsq21);
1674             rinv22           = avx128fma_invsqrt_d(rsq22);
1675
1676             rinvsq00         = _mm_mul_pd(rinv00,rinv00);
1677             rinvsq01         = _mm_mul_pd(rinv01,rinv01);
1678             rinvsq02         = _mm_mul_pd(rinv02,rinv02);
1679             rinvsq10         = _mm_mul_pd(rinv10,rinv10);
1680             rinvsq11         = _mm_mul_pd(rinv11,rinv11);
1681             rinvsq12         = _mm_mul_pd(rinv12,rinv12);
1682             rinvsq20         = _mm_mul_pd(rinv20,rinv20);
1683             rinvsq21         = _mm_mul_pd(rinv21,rinv21);
1684             rinvsq22         = _mm_mul_pd(rinv22,rinv22);
1685
1686             fjx0             = _mm_setzero_pd();
1687             fjy0             = _mm_setzero_pd();
1688             fjz0             = _mm_setzero_pd();
1689             fjx1             = _mm_setzero_pd();
1690             fjy1             = _mm_setzero_pd();
1691             fjz1             = _mm_setzero_pd();
1692             fjx2             = _mm_setzero_pd();
1693             fjy2             = _mm_setzero_pd();
1694             fjz2             = _mm_setzero_pd();
1695
1696             /**************************
1697              * CALCULATE INTERACTIONS *
1698              **************************/
1699
1700             if (gmx_mm_any_lt(rsq00,rcutoff2))
1701             {
1702
1703             r00              = _mm_mul_pd(rsq00,rinv00);
1704
1705             /* EWALD ELECTROSTATICS */
1706
1707             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1708             ewrt             = _mm_mul_pd(r00,ewtabscale);
1709             ewitab           = _mm_cvttpd_epi32(ewrt);
1710 #ifdef __XOP__
1711             eweps            = _mm_frcz_pd(ewrt);
1712 #else
1713             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1714 #endif
1715             twoeweps         = _mm_add_pd(eweps,eweps);
1716             gmx_mm_load_2pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),ewtab+_mm_extract_epi32(ewitab,1),
1717                                          &ewtabF,&ewtabFn);
1718             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
1719             felec            = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
1720
1721             /* Analytical LJ-PME */
1722             rinvsix          = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
1723             ewcljrsq         = _mm_mul_pd(ewclj2,rsq00);
1724             ewclj6           = _mm_mul_pd(ewclj2,_mm_mul_pd(ewclj2,ewclj2));
1725             exponent         = avx128fma_exp_d(ewcljrsq);
1726             /* poly = exp(-(beta*r)^2) * (1 + (beta*r)^2 + (beta*r)^4 /2) */
1727             poly             = _mm_mul_pd(exponent,_mm_macc_pd(_mm_mul_pd(ewcljrsq,ewcljrsq),one_half,_mm_sub_pd(one,ewcljrsq)));
1728             /* f6A = 6 * C6grid * (1 - poly) */
1729             f6A              = _mm_mul_pd(c6grid_00,_mm_sub_pd(one,poly));
1730             /* f6B = C6grid * exponent * beta^6 */
1731             f6B              = _mm_mul_pd(_mm_mul_pd(c6grid_00,one_sixth),_mm_mul_pd(exponent,ewclj6));
1732             /* fvdw = 12*C12/r13 - ((6*C6 - f6A)/r6 + f6B)/r */
1733             fvdw              = _mm_mul_pd(_mm_macc_pd(_mm_msub_pd(c12_00,rinvsix,_mm_sub_pd(c6_00,f6A)),rinvsix,f6B),rinvsq00);
1734
1735             cutoff_mask      = _mm_cmplt_pd(rsq00,rcutoff2);
1736
1737             fscal            = _mm_add_pd(felec,fvdw);
1738
1739             fscal            = _mm_and_pd(fscal,cutoff_mask);
1740
1741             /* Update vectorial force */
1742             fix0             = _mm_macc_pd(dx00,fscal,fix0);
1743             fiy0             = _mm_macc_pd(dy00,fscal,fiy0);
1744             fiz0             = _mm_macc_pd(dz00,fscal,fiz0);
1745             
1746             fjx0             = _mm_macc_pd(dx00,fscal,fjx0);
1747             fjy0             = _mm_macc_pd(dy00,fscal,fjy0);
1748             fjz0             = _mm_macc_pd(dz00,fscal,fjz0);
1749
1750             }
1751
1752             /**************************
1753              * CALCULATE INTERACTIONS *
1754              **************************/
1755
1756             if (gmx_mm_any_lt(rsq01,rcutoff2))
1757             {
1758
1759             r01              = _mm_mul_pd(rsq01,rinv01);
1760
1761             /* EWALD ELECTROSTATICS */
1762
1763             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1764             ewrt             = _mm_mul_pd(r01,ewtabscale);
1765             ewitab           = _mm_cvttpd_epi32(ewrt);
1766 #ifdef __XOP__
1767             eweps            = _mm_frcz_pd(ewrt);
1768 #else
1769             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1770 #endif
1771             twoeweps         = _mm_add_pd(eweps,eweps);
1772             gmx_mm_load_2pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),ewtab+_mm_extract_epi32(ewitab,1),
1773                                          &ewtabF,&ewtabFn);
1774             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
1775             felec            = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
1776
1777             cutoff_mask      = _mm_cmplt_pd(rsq01,rcutoff2);
1778
1779             fscal            = felec;
1780
1781             fscal            = _mm_and_pd(fscal,cutoff_mask);
1782
1783             /* Update vectorial force */
1784             fix0             = _mm_macc_pd(dx01,fscal,fix0);
1785             fiy0             = _mm_macc_pd(dy01,fscal,fiy0);
1786             fiz0             = _mm_macc_pd(dz01,fscal,fiz0);
1787             
1788             fjx1             = _mm_macc_pd(dx01,fscal,fjx1);
1789             fjy1             = _mm_macc_pd(dy01,fscal,fjy1);
1790             fjz1             = _mm_macc_pd(dz01,fscal,fjz1);
1791
1792             }
1793
1794             /**************************
1795              * CALCULATE INTERACTIONS *
1796              **************************/
1797
1798             if (gmx_mm_any_lt(rsq02,rcutoff2))
1799             {
1800
1801             r02              = _mm_mul_pd(rsq02,rinv02);
1802
1803             /* EWALD ELECTROSTATICS */
1804
1805             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1806             ewrt             = _mm_mul_pd(r02,ewtabscale);
1807             ewitab           = _mm_cvttpd_epi32(ewrt);
1808 #ifdef __XOP__
1809             eweps            = _mm_frcz_pd(ewrt);
1810 #else
1811             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1812 #endif
1813             twoeweps         = _mm_add_pd(eweps,eweps);
1814             gmx_mm_load_2pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),ewtab+_mm_extract_epi32(ewitab,1),
1815                                          &ewtabF,&ewtabFn);
1816             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
1817             felec            = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
1818
1819             cutoff_mask      = _mm_cmplt_pd(rsq02,rcutoff2);
1820
1821             fscal            = felec;
1822
1823             fscal            = _mm_and_pd(fscal,cutoff_mask);
1824
1825             /* Update vectorial force */
1826             fix0             = _mm_macc_pd(dx02,fscal,fix0);
1827             fiy0             = _mm_macc_pd(dy02,fscal,fiy0);
1828             fiz0             = _mm_macc_pd(dz02,fscal,fiz0);
1829             
1830             fjx2             = _mm_macc_pd(dx02,fscal,fjx2);
1831             fjy2             = _mm_macc_pd(dy02,fscal,fjy2);
1832             fjz2             = _mm_macc_pd(dz02,fscal,fjz2);
1833
1834             }
1835
1836             /**************************
1837              * CALCULATE INTERACTIONS *
1838              **************************/
1839
1840             if (gmx_mm_any_lt(rsq10,rcutoff2))
1841             {
1842
1843             r10              = _mm_mul_pd(rsq10,rinv10);
1844
1845             /* EWALD ELECTROSTATICS */
1846
1847             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1848             ewrt             = _mm_mul_pd(r10,ewtabscale);
1849             ewitab           = _mm_cvttpd_epi32(ewrt);
1850 #ifdef __XOP__
1851             eweps            = _mm_frcz_pd(ewrt);
1852 #else
1853             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1854 #endif
1855             twoeweps         = _mm_add_pd(eweps,eweps);
1856             gmx_mm_load_2pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),ewtab+_mm_extract_epi32(ewitab,1),
1857                                          &ewtabF,&ewtabFn);
1858             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
1859             felec            = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
1860
1861             cutoff_mask      = _mm_cmplt_pd(rsq10,rcutoff2);
1862
1863             fscal            = felec;
1864
1865             fscal            = _mm_and_pd(fscal,cutoff_mask);
1866
1867             /* Update vectorial force */
1868             fix1             = _mm_macc_pd(dx10,fscal,fix1);
1869             fiy1             = _mm_macc_pd(dy10,fscal,fiy1);
1870             fiz1             = _mm_macc_pd(dz10,fscal,fiz1);
1871             
1872             fjx0             = _mm_macc_pd(dx10,fscal,fjx0);
1873             fjy0             = _mm_macc_pd(dy10,fscal,fjy0);
1874             fjz0             = _mm_macc_pd(dz10,fscal,fjz0);
1875
1876             }
1877
1878             /**************************
1879              * CALCULATE INTERACTIONS *
1880              **************************/
1881
1882             if (gmx_mm_any_lt(rsq11,rcutoff2))
1883             {
1884
1885             r11              = _mm_mul_pd(rsq11,rinv11);
1886
1887             /* EWALD ELECTROSTATICS */
1888
1889             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1890             ewrt             = _mm_mul_pd(r11,ewtabscale);
1891             ewitab           = _mm_cvttpd_epi32(ewrt);
1892 #ifdef __XOP__
1893             eweps            = _mm_frcz_pd(ewrt);
1894 #else
1895             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1896 #endif
1897             twoeweps         = _mm_add_pd(eweps,eweps);
1898             gmx_mm_load_2pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),ewtab+_mm_extract_epi32(ewitab,1),
1899                                          &ewtabF,&ewtabFn);
1900             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
1901             felec            = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
1902
1903             cutoff_mask      = _mm_cmplt_pd(rsq11,rcutoff2);
1904
1905             fscal            = felec;
1906
1907             fscal            = _mm_and_pd(fscal,cutoff_mask);
1908
1909             /* Update vectorial force */
1910             fix1             = _mm_macc_pd(dx11,fscal,fix1);
1911             fiy1             = _mm_macc_pd(dy11,fscal,fiy1);
1912             fiz1             = _mm_macc_pd(dz11,fscal,fiz1);
1913             
1914             fjx1             = _mm_macc_pd(dx11,fscal,fjx1);
1915             fjy1             = _mm_macc_pd(dy11,fscal,fjy1);
1916             fjz1             = _mm_macc_pd(dz11,fscal,fjz1);
1917
1918             }
1919
1920             /**************************
1921              * CALCULATE INTERACTIONS *
1922              **************************/
1923
1924             if (gmx_mm_any_lt(rsq12,rcutoff2))
1925             {
1926
1927             r12              = _mm_mul_pd(rsq12,rinv12);
1928
1929             /* EWALD ELECTROSTATICS */
1930
1931             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1932             ewrt             = _mm_mul_pd(r12,ewtabscale);
1933             ewitab           = _mm_cvttpd_epi32(ewrt);
1934 #ifdef __XOP__
1935             eweps            = _mm_frcz_pd(ewrt);
1936 #else
1937             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1938 #endif
1939             twoeweps         = _mm_add_pd(eweps,eweps);
1940             gmx_mm_load_2pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),ewtab+_mm_extract_epi32(ewitab,1),
1941                                          &ewtabF,&ewtabFn);
1942             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
1943             felec            = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
1944
1945             cutoff_mask      = _mm_cmplt_pd(rsq12,rcutoff2);
1946
1947             fscal            = felec;
1948
1949             fscal            = _mm_and_pd(fscal,cutoff_mask);
1950
1951             /* Update vectorial force */
1952             fix1             = _mm_macc_pd(dx12,fscal,fix1);
1953             fiy1             = _mm_macc_pd(dy12,fscal,fiy1);
1954             fiz1             = _mm_macc_pd(dz12,fscal,fiz1);
1955             
1956             fjx2             = _mm_macc_pd(dx12,fscal,fjx2);
1957             fjy2             = _mm_macc_pd(dy12,fscal,fjy2);
1958             fjz2             = _mm_macc_pd(dz12,fscal,fjz2);
1959
1960             }
1961
1962             /**************************
1963              * CALCULATE INTERACTIONS *
1964              **************************/
1965
1966             if (gmx_mm_any_lt(rsq20,rcutoff2))
1967             {
1968
1969             r20              = _mm_mul_pd(rsq20,rinv20);
1970
1971             /* EWALD ELECTROSTATICS */
1972
1973             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
1974             ewrt             = _mm_mul_pd(r20,ewtabscale);
1975             ewitab           = _mm_cvttpd_epi32(ewrt);
1976 #ifdef __XOP__
1977             eweps            = _mm_frcz_pd(ewrt);
1978 #else
1979             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
1980 #endif
1981             twoeweps         = _mm_add_pd(eweps,eweps);
1982             gmx_mm_load_2pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),ewtab+_mm_extract_epi32(ewitab,1),
1983                                          &ewtabF,&ewtabFn);
1984             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
1985             felec            = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
1986
1987             cutoff_mask      = _mm_cmplt_pd(rsq20,rcutoff2);
1988
1989             fscal            = felec;
1990
1991             fscal            = _mm_and_pd(fscal,cutoff_mask);
1992
1993             /* Update vectorial force */
1994             fix2             = _mm_macc_pd(dx20,fscal,fix2);
1995             fiy2             = _mm_macc_pd(dy20,fscal,fiy2);
1996             fiz2             = _mm_macc_pd(dz20,fscal,fiz2);
1997             
1998             fjx0             = _mm_macc_pd(dx20,fscal,fjx0);
1999             fjy0             = _mm_macc_pd(dy20,fscal,fjy0);
2000             fjz0             = _mm_macc_pd(dz20,fscal,fjz0);
2001
2002             }
2003
2004             /**************************
2005              * CALCULATE INTERACTIONS *
2006              **************************/
2007
2008             if (gmx_mm_any_lt(rsq21,rcutoff2))
2009             {
2010
2011             r21              = _mm_mul_pd(rsq21,rinv21);
2012
2013             /* EWALD ELECTROSTATICS */
2014
2015             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
2016             ewrt             = _mm_mul_pd(r21,ewtabscale);
2017             ewitab           = _mm_cvttpd_epi32(ewrt);
2018 #ifdef __XOP__
2019             eweps            = _mm_frcz_pd(ewrt);
2020 #else
2021             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
2022 #endif
2023             twoeweps         = _mm_add_pd(eweps,eweps);
2024             gmx_mm_load_2pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),ewtab+_mm_extract_epi32(ewitab,1),
2025                                          &ewtabF,&ewtabFn);
2026             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
2027             felec            = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
2028
2029             cutoff_mask      = _mm_cmplt_pd(rsq21,rcutoff2);
2030
2031             fscal            = felec;
2032
2033             fscal            = _mm_and_pd(fscal,cutoff_mask);
2034
2035             /* Update vectorial force */
2036             fix2             = _mm_macc_pd(dx21,fscal,fix2);
2037             fiy2             = _mm_macc_pd(dy21,fscal,fiy2);
2038             fiz2             = _mm_macc_pd(dz21,fscal,fiz2);
2039             
2040             fjx1             = _mm_macc_pd(dx21,fscal,fjx1);
2041             fjy1             = _mm_macc_pd(dy21,fscal,fjy1);
2042             fjz1             = _mm_macc_pd(dz21,fscal,fjz1);
2043
2044             }
2045
2046             /**************************
2047              * CALCULATE INTERACTIONS *
2048              **************************/
2049
2050             if (gmx_mm_any_lt(rsq22,rcutoff2))
2051             {
2052
2053             r22              = _mm_mul_pd(rsq22,rinv22);
2054
2055             /* EWALD ELECTROSTATICS */
2056
2057             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
2058             ewrt             = _mm_mul_pd(r22,ewtabscale);
2059             ewitab           = _mm_cvttpd_epi32(ewrt);
2060 #ifdef __XOP__
2061             eweps            = _mm_frcz_pd(ewrt);
2062 #else
2063             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
2064 #endif
2065             twoeweps         = _mm_add_pd(eweps,eweps);
2066             gmx_mm_load_2pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),ewtab+_mm_extract_epi32(ewitab,1),
2067                                          &ewtabF,&ewtabFn);
2068             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
2069             felec            = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
2070
2071             cutoff_mask      = _mm_cmplt_pd(rsq22,rcutoff2);
2072
2073             fscal            = felec;
2074
2075             fscal            = _mm_and_pd(fscal,cutoff_mask);
2076
2077             /* Update vectorial force */
2078             fix2             = _mm_macc_pd(dx22,fscal,fix2);
2079             fiy2             = _mm_macc_pd(dy22,fscal,fiy2);
2080             fiz2             = _mm_macc_pd(dz22,fscal,fiz2);
2081             
2082             fjx2             = _mm_macc_pd(dx22,fscal,fjx2);
2083             fjy2             = _mm_macc_pd(dy22,fscal,fjy2);
2084             fjz2             = _mm_macc_pd(dz22,fscal,fjz2);
2085
2086             }
2087
2088             gmx_mm_decrement_3rvec_2ptr_swizzle_pd(f+j_coord_offsetA,f+j_coord_offsetB,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
2089
2090             /* Inner loop uses 399 flops */
2091         }
2092
2093         if(jidx<j_index_end)
2094         {
2095
2096             jnrA             = jjnr[jidx];
2097             j_coord_offsetA  = DIM*jnrA;
2098
2099             /* load j atom coordinates */
2100             gmx_mm_load_3rvec_1ptr_swizzle_pd(x+j_coord_offsetA,
2101                                               &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,&jy2,&jz2);
2102
2103             /* Calculate displacement vector */
2104             dx00             = _mm_sub_pd(ix0,jx0);
2105             dy00             = _mm_sub_pd(iy0,jy0);
2106             dz00             = _mm_sub_pd(iz0,jz0);
2107             dx01             = _mm_sub_pd(ix0,jx1);
2108             dy01             = _mm_sub_pd(iy0,jy1);
2109             dz01             = _mm_sub_pd(iz0,jz1);
2110             dx02             = _mm_sub_pd(ix0,jx2);
2111             dy02             = _mm_sub_pd(iy0,jy2);
2112             dz02             = _mm_sub_pd(iz0,jz2);
2113             dx10             = _mm_sub_pd(ix1,jx0);
2114             dy10             = _mm_sub_pd(iy1,jy0);
2115             dz10             = _mm_sub_pd(iz1,jz0);
2116             dx11             = _mm_sub_pd(ix1,jx1);
2117             dy11             = _mm_sub_pd(iy1,jy1);
2118             dz11             = _mm_sub_pd(iz1,jz1);
2119             dx12             = _mm_sub_pd(ix1,jx2);
2120             dy12             = _mm_sub_pd(iy1,jy2);
2121             dz12             = _mm_sub_pd(iz1,jz2);
2122             dx20             = _mm_sub_pd(ix2,jx0);
2123             dy20             = _mm_sub_pd(iy2,jy0);
2124             dz20             = _mm_sub_pd(iz2,jz0);
2125             dx21             = _mm_sub_pd(ix2,jx1);
2126             dy21             = _mm_sub_pd(iy2,jy1);
2127             dz21             = _mm_sub_pd(iz2,jz1);
2128             dx22             = _mm_sub_pd(ix2,jx2);
2129             dy22             = _mm_sub_pd(iy2,jy2);
2130             dz22             = _mm_sub_pd(iz2,jz2);
2131
2132             /* Calculate squared distance and things based on it */
2133             rsq00            = gmx_mm_calc_rsq_pd(dx00,dy00,dz00);
2134             rsq01            = gmx_mm_calc_rsq_pd(dx01,dy01,dz01);
2135             rsq02            = gmx_mm_calc_rsq_pd(dx02,dy02,dz02);
2136             rsq10            = gmx_mm_calc_rsq_pd(dx10,dy10,dz10);
2137             rsq11            = gmx_mm_calc_rsq_pd(dx11,dy11,dz11);
2138             rsq12            = gmx_mm_calc_rsq_pd(dx12,dy12,dz12);
2139             rsq20            = gmx_mm_calc_rsq_pd(dx20,dy20,dz20);
2140             rsq21            = gmx_mm_calc_rsq_pd(dx21,dy21,dz21);
2141             rsq22            = gmx_mm_calc_rsq_pd(dx22,dy22,dz22);
2142
2143             rinv00           = avx128fma_invsqrt_d(rsq00);
2144             rinv01           = avx128fma_invsqrt_d(rsq01);
2145             rinv02           = avx128fma_invsqrt_d(rsq02);
2146             rinv10           = avx128fma_invsqrt_d(rsq10);
2147             rinv11           = avx128fma_invsqrt_d(rsq11);
2148             rinv12           = avx128fma_invsqrt_d(rsq12);
2149             rinv20           = avx128fma_invsqrt_d(rsq20);
2150             rinv21           = avx128fma_invsqrt_d(rsq21);
2151             rinv22           = avx128fma_invsqrt_d(rsq22);
2152
2153             rinvsq00         = _mm_mul_pd(rinv00,rinv00);
2154             rinvsq01         = _mm_mul_pd(rinv01,rinv01);
2155             rinvsq02         = _mm_mul_pd(rinv02,rinv02);
2156             rinvsq10         = _mm_mul_pd(rinv10,rinv10);
2157             rinvsq11         = _mm_mul_pd(rinv11,rinv11);
2158             rinvsq12         = _mm_mul_pd(rinv12,rinv12);
2159             rinvsq20         = _mm_mul_pd(rinv20,rinv20);
2160             rinvsq21         = _mm_mul_pd(rinv21,rinv21);
2161             rinvsq22         = _mm_mul_pd(rinv22,rinv22);
2162
2163             fjx0             = _mm_setzero_pd();
2164             fjy0             = _mm_setzero_pd();
2165             fjz0             = _mm_setzero_pd();
2166             fjx1             = _mm_setzero_pd();
2167             fjy1             = _mm_setzero_pd();
2168             fjz1             = _mm_setzero_pd();
2169             fjx2             = _mm_setzero_pd();
2170             fjy2             = _mm_setzero_pd();
2171             fjz2             = _mm_setzero_pd();
2172
2173             /**************************
2174              * CALCULATE INTERACTIONS *
2175              **************************/
2176
2177             if (gmx_mm_any_lt(rsq00,rcutoff2))
2178             {
2179
2180             r00              = _mm_mul_pd(rsq00,rinv00);
2181
2182             /* EWALD ELECTROSTATICS */
2183
2184             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
2185             ewrt             = _mm_mul_pd(r00,ewtabscale);
2186             ewitab           = _mm_cvttpd_epi32(ewrt);
2187 #ifdef __XOP__
2188             eweps            = _mm_frcz_pd(ewrt);
2189 #else
2190             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
2191 #endif
2192             twoeweps         = _mm_add_pd(eweps,eweps);
2193             gmx_mm_load_1pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
2194             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
2195             felec            = _mm_mul_pd(_mm_mul_pd(qq00,rinv00),_mm_sub_pd(rinvsq00,felec));
2196
2197             /* Analytical LJ-PME */
2198             rinvsix          = _mm_mul_pd(_mm_mul_pd(rinvsq00,rinvsq00),rinvsq00);
2199             ewcljrsq         = _mm_mul_pd(ewclj2,rsq00);
2200             ewclj6           = _mm_mul_pd(ewclj2,_mm_mul_pd(ewclj2,ewclj2));
2201             exponent         = avx128fma_exp_d(ewcljrsq);
2202             /* poly = exp(-(beta*r)^2) * (1 + (beta*r)^2 + (beta*r)^4 /2) */
2203             poly             = _mm_mul_pd(exponent,_mm_macc_pd(_mm_mul_pd(ewcljrsq,ewcljrsq),one_half,_mm_sub_pd(one,ewcljrsq)));
2204             /* f6A = 6 * C6grid * (1 - poly) */
2205             f6A              = _mm_mul_pd(c6grid_00,_mm_sub_pd(one,poly));
2206             /* f6B = C6grid * exponent * beta^6 */
2207             f6B              = _mm_mul_pd(_mm_mul_pd(c6grid_00,one_sixth),_mm_mul_pd(exponent,ewclj6));
2208             /* fvdw = 12*C12/r13 - ((6*C6 - f6A)/r6 + f6B)/r */
2209             fvdw              = _mm_mul_pd(_mm_macc_pd(_mm_msub_pd(c12_00,rinvsix,_mm_sub_pd(c6_00,f6A)),rinvsix,f6B),rinvsq00);
2210
2211             cutoff_mask      = _mm_cmplt_pd(rsq00,rcutoff2);
2212
2213             fscal            = _mm_add_pd(felec,fvdw);
2214
2215             fscal            = _mm_and_pd(fscal,cutoff_mask);
2216
2217             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
2218
2219             /* Update vectorial force */
2220             fix0             = _mm_macc_pd(dx00,fscal,fix0);
2221             fiy0             = _mm_macc_pd(dy00,fscal,fiy0);
2222             fiz0             = _mm_macc_pd(dz00,fscal,fiz0);
2223             
2224             fjx0             = _mm_macc_pd(dx00,fscal,fjx0);
2225             fjy0             = _mm_macc_pd(dy00,fscal,fjy0);
2226             fjz0             = _mm_macc_pd(dz00,fscal,fjz0);
2227
2228             }
2229
2230             /**************************
2231              * CALCULATE INTERACTIONS *
2232              **************************/
2233
2234             if (gmx_mm_any_lt(rsq01,rcutoff2))
2235             {
2236
2237             r01              = _mm_mul_pd(rsq01,rinv01);
2238
2239             /* EWALD ELECTROSTATICS */
2240
2241             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
2242             ewrt             = _mm_mul_pd(r01,ewtabscale);
2243             ewitab           = _mm_cvttpd_epi32(ewrt);
2244 #ifdef __XOP__
2245             eweps            = _mm_frcz_pd(ewrt);
2246 #else
2247             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
2248 #endif
2249             twoeweps         = _mm_add_pd(eweps,eweps);
2250             gmx_mm_load_1pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
2251             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
2252             felec            = _mm_mul_pd(_mm_mul_pd(qq01,rinv01),_mm_sub_pd(rinvsq01,felec));
2253
2254             cutoff_mask      = _mm_cmplt_pd(rsq01,rcutoff2);
2255
2256             fscal            = felec;
2257
2258             fscal            = _mm_and_pd(fscal,cutoff_mask);
2259
2260             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
2261
2262             /* Update vectorial force */
2263             fix0             = _mm_macc_pd(dx01,fscal,fix0);
2264             fiy0             = _mm_macc_pd(dy01,fscal,fiy0);
2265             fiz0             = _mm_macc_pd(dz01,fscal,fiz0);
2266             
2267             fjx1             = _mm_macc_pd(dx01,fscal,fjx1);
2268             fjy1             = _mm_macc_pd(dy01,fscal,fjy1);
2269             fjz1             = _mm_macc_pd(dz01,fscal,fjz1);
2270
2271             }
2272
2273             /**************************
2274              * CALCULATE INTERACTIONS *
2275              **************************/
2276
2277             if (gmx_mm_any_lt(rsq02,rcutoff2))
2278             {
2279
2280             r02              = _mm_mul_pd(rsq02,rinv02);
2281
2282             /* EWALD ELECTROSTATICS */
2283
2284             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
2285             ewrt             = _mm_mul_pd(r02,ewtabscale);
2286             ewitab           = _mm_cvttpd_epi32(ewrt);
2287 #ifdef __XOP__
2288             eweps            = _mm_frcz_pd(ewrt);
2289 #else
2290             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
2291 #endif
2292             twoeweps         = _mm_add_pd(eweps,eweps);
2293             gmx_mm_load_1pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
2294             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
2295             felec            = _mm_mul_pd(_mm_mul_pd(qq02,rinv02),_mm_sub_pd(rinvsq02,felec));
2296
2297             cutoff_mask      = _mm_cmplt_pd(rsq02,rcutoff2);
2298
2299             fscal            = felec;
2300
2301             fscal            = _mm_and_pd(fscal,cutoff_mask);
2302
2303             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
2304
2305             /* Update vectorial force */
2306             fix0             = _mm_macc_pd(dx02,fscal,fix0);
2307             fiy0             = _mm_macc_pd(dy02,fscal,fiy0);
2308             fiz0             = _mm_macc_pd(dz02,fscal,fiz0);
2309             
2310             fjx2             = _mm_macc_pd(dx02,fscal,fjx2);
2311             fjy2             = _mm_macc_pd(dy02,fscal,fjy2);
2312             fjz2             = _mm_macc_pd(dz02,fscal,fjz2);
2313
2314             }
2315
2316             /**************************
2317              * CALCULATE INTERACTIONS *
2318              **************************/
2319
2320             if (gmx_mm_any_lt(rsq10,rcutoff2))
2321             {
2322
2323             r10              = _mm_mul_pd(rsq10,rinv10);
2324
2325             /* EWALD ELECTROSTATICS */
2326
2327             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
2328             ewrt             = _mm_mul_pd(r10,ewtabscale);
2329             ewitab           = _mm_cvttpd_epi32(ewrt);
2330 #ifdef __XOP__
2331             eweps            = _mm_frcz_pd(ewrt);
2332 #else
2333             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
2334 #endif
2335             twoeweps         = _mm_add_pd(eweps,eweps);
2336             gmx_mm_load_1pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
2337             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
2338             felec            = _mm_mul_pd(_mm_mul_pd(qq10,rinv10),_mm_sub_pd(rinvsq10,felec));
2339
2340             cutoff_mask      = _mm_cmplt_pd(rsq10,rcutoff2);
2341
2342             fscal            = felec;
2343
2344             fscal            = _mm_and_pd(fscal,cutoff_mask);
2345
2346             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
2347
2348             /* Update vectorial force */
2349             fix1             = _mm_macc_pd(dx10,fscal,fix1);
2350             fiy1             = _mm_macc_pd(dy10,fscal,fiy1);
2351             fiz1             = _mm_macc_pd(dz10,fscal,fiz1);
2352             
2353             fjx0             = _mm_macc_pd(dx10,fscal,fjx0);
2354             fjy0             = _mm_macc_pd(dy10,fscal,fjy0);
2355             fjz0             = _mm_macc_pd(dz10,fscal,fjz0);
2356
2357             }
2358
2359             /**************************
2360              * CALCULATE INTERACTIONS *
2361              **************************/
2362
2363             if (gmx_mm_any_lt(rsq11,rcutoff2))
2364             {
2365
2366             r11              = _mm_mul_pd(rsq11,rinv11);
2367
2368             /* EWALD ELECTROSTATICS */
2369
2370             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
2371             ewrt             = _mm_mul_pd(r11,ewtabscale);
2372             ewitab           = _mm_cvttpd_epi32(ewrt);
2373 #ifdef __XOP__
2374             eweps            = _mm_frcz_pd(ewrt);
2375 #else
2376             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
2377 #endif
2378             twoeweps         = _mm_add_pd(eweps,eweps);
2379             gmx_mm_load_1pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
2380             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
2381             felec            = _mm_mul_pd(_mm_mul_pd(qq11,rinv11),_mm_sub_pd(rinvsq11,felec));
2382
2383             cutoff_mask      = _mm_cmplt_pd(rsq11,rcutoff2);
2384
2385             fscal            = felec;
2386
2387             fscal            = _mm_and_pd(fscal,cutoff_mask);
2388
2389             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
2390
2391             /* Update vectorial force */
2392             fix1             = _mm_macc_pd(dx11,fscal,fix1);
2393             fiy1             = _mm_macc_pd(dy11,fscal,fiy1);
2394             fiz1             = _mm_macc_pd(dz11,fscal,fiz1);
2395             
2396             fjx1             = _mm_macc_pd(dx11,fscal,fjx1);
2397             fjy1             = _mm_macc_pd(dy11,fscal,fjy1);
2398             fjz1             = _mm_macc_pd(dz11,fscal,fjz1);
2399
2400             }
2401
2402             /**************************
2403              * CALCULATE INTERACTIONS *
2404              **************************/
2405
2406             if (gmx_mm_any_lt(rsq12,rcutoff2))
2407             {
2408
2409             r12              = _mm_mul_pd(rsq12,rinv12);
2410
2411             /* EWALD ELECTROSTATICS */
2412
2413             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
2414             ewrt             = _mm_mul_pd(r12,ewtabscale);
2415             ewitab           = _mm_cvttpd_epi32(ewrt);
2416 #ifdef __XOP__
2417             eweps            = _mm_frcz_pd(ewrt);
2418 #else
2419             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
2420 #endif
2421             twoeweps         = _mm_add_pd(eweps,eweps);
2422             gmx_mm_load_1pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
2423             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
2424             felec            = _mm_mul_pd(_mm_mul_pd(qq12,rinv12),_mm_sub_pd(rinvsq12,felec));
2425
2426             cutoff_mask      = _mm_cmplt_pd(rsq12,rcutoff2);
2427
2428             fscal            = felec;
2429
2430             fscal            = _mm_and_pd(fscal,cutoff_mask);
2431
2432             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
2433
2434             /* Update vectorial force */
2435             fix1             = _mm_macc_pd(dx12,fscal,fix1);
2436             fiy1             = _mm_macc_pd(dy12,fscal,fiy1);
2437             fiz1             = _mm_macc_pd(dz12,fscal,fiz1);
2438             
2439             fjx2             = _mm_macc_pd(dx12,fscal,fjx2);
2440             fjy2             = _mm_macc_pd(dy12,fscal,fjy2);
2441             fjz2             = _mm_macc_pd(dz12,fscal,fjz2);
2442
2443             }
2444
2445             /**************************
2446              * CALCULATE INTERACTIONS *
2447              **************************/
2448
2449             if (gmx_mm_any_lt(rsq20,rcutoff2))
2450             {
2451
2452             r20              = _mm_mul_pd(rsq20,rinv20);
2453
2454             /* EWALD ELECTROSTATICS */
2455
2456             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
2457             ewrt             = _mm_mul_pd(r20,ewtabscale);
2458             ewitab           = _mm_cvttpd_epi32(ewrt);
2459 #ifdef __XOP__
2460             eweps            = _mm_frcz_pd(ewrt);
2461 #else
2462             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
2463 #endif
2464             twoeweps         = _mm_add_pd(eweps,eweps);
2465             gmx_mm_load_1pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
2466             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
2467             felec            = _mm_mul_pd(_mm_mul_pd(qq20,rinv20),_mm_sub_pd(rinvsq20,felec));
2468
2469             cutoff_mask      = _mm_cmplt_pd(rsq20,rcutoff2);
2470
2471             fscal            = felec;
2472
2473             fscal            = _mm_and_pd(fscal,cutoff_mask);
2474
2475             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
2476
2477             /* Update vectorial force */
2478             fix2             = _mm_macc_pd(dx20,fscal,fix2);
2479             fiy2             = _mm_macc_pd(dy20,fscal,fiy2);
2480             fiz2             = _mm_macc_pd(dz20,fscal,fiz2);
2481             
2482             fjx0             = _mm_macc_pd(dx20,fscal,fjx0);
2483             fjy0             = _mm_macc_pd(dy20,fscal,fjy0);
2484             fjz0             = _mm_macc_pd(dz20,fscal,fjz0);
2485
2486             }
2487
2488             /**************************
2489              * CALCULATE INTERACTIONS *
2490              **************************/
2491
2492             if (gmx_mm_any_lt(rsq21,rcutoff2))
2493             {
2494
2495             r21              = _mm_mul_pd(rsq21,rinv21);
2496
2497             /* EWALD ELECTROSTATICS */
2498
2499             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
2500             ewrt             = _mm_mul_pd(r21,ewtabscale);
2501             ewitab           = _mm_cvttpd_epi32(ewrt);
2502 #ifdef __XOP__
2503             eweps            = _mm_frcz_pd(ewrt);
2504 #else
2505             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
2506 #endif
2507             twoeweps         = _mm_add_pd(eweps,eweps);
2508             gmx_mm_load_1pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
2509             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
2510             felec            = _mm_mul_pd(_mm_mul_pd(qq21,rinv21),_mm_sub_pd(rinvsq21,felec));
2511
2512             cutoff_mask      = _mm_cmplt_pd(rsq21,rcutoff2);
2513
2514             fscal            = felec;
2515
2516             fscal            = _mm_and_pd(fscal,cutoff_mask);
2517
2518             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
2519
2520             /* Update vectorial force */
2521             fix2             = _mm_macc_pd(dx21,fscal,fix2);
2522             fiy2             = _mm_macc_pd(dy21,fscal,fiy2);
2523             fiz2             = _mm_macc_pd(dz21,fscal,fiz2);
2524             
2525             fjx1             = _mm_macc_pd(dx21,fscal,fjx1);
2526             fjy1             = _mm_macc_pd(dy21,fscal,fjy1);
2527             fjz1             = _mm_macc_pd(dz21,fscal,fjz1);
2528
2529             }
2530
2531             /**************************
2532              * CALCULATE INTERACTIONS *
2533              **************************/
2534
2535             if (gmx_mm_any_lt(rsq22,rcutoff2))
2536             {
2537
2538             r22              = _mm_mul_pd(rsq22,rinv22);
2539
2540             /* EWALD ELECTROSTATICS */
2541
2542             /* Calculate Ewald table index by multiplying r with scale and truncate to integer */
2543             ewrt             = _mm_mul_pd(r22,ewtabscale);
2544             ewitab           = _mm_cvttpd_epi32(ewrt);
2545 #ifdef __XOP__
2546             eweps            = _mm_frcz_pd(ewrt);
2547 #else
2548             eweps            = _mm_sub_pd(ewrt,_mm_round_pd(ewrt, _MM_FROUND_FLOOR));
2549 #endif
2550             twoeweps         = _mm_add_pd(eweps,eweps);
2551             gmx_mm_load_1pair_swizzle_pd(ewtab+_mm_extract_epi32(ewitab,0),&ewtabF,&ewtabFn);
2552             felec            = _mm_macc_pd(eweps,ewtabFn,_mm_mul_pd( _mm_sub_pd(one,eweps),ewtabF));
2553             felec            = _mm_mul_pd(_mm_mul_pd(qq22,rinv22),_mm_sub_pd(rinvsq22,felec));
2554
2555             cutoff_mask      = _mm_cmplt_pd(rsq22,rcutoff2);
2556
2557             fscal            = felec;
2558
2559             fscal            = _mm_and_pd(fscal,cutoff_mask);
2560
2561             fscal            = _mm_unpacklo_pd(fscal,_mm_setzero_pd());
2562
2563             /* Update vectorial force */
2564             fix2             = _mm_macc_pd(dx22,fscal,fix2);
2565             fiy2             = _mm_macc_pd(dy22,fscal,fiy2);
2566             fiz2             = _mm_macc_pd(dz22,fscal,fiz2);
2567             
2568             fjx2             = _mm_macc_pd(dx22,fscal,fjx2);
2569             fjy2             = _mm_macc_pd(dy22,fscal,fjy2);
2570             fjz2             = _mm_macc_pd(dz22,fscal,fjz2);
2571
2572             }
2573
2574             gmx_mm_decrement_3rvec_1ptr_swizzle_pd(f+j_coord_offsetA,fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,fjx2,fjy2,fjz2);
2575
2576             /* Inner loop uses 399 flops */
2577         }
2578
2579         /* End of innermost loop */
2580
2581         gmx_mm_update_iforce_3atom_swizzle_pd(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,
2582                                               f+i_coord_offset,fshift+i_shift_offset);
2583
2584         /* Increment number of inner iterations */
2585         inneriter                  += j_index_end - j_index_start;
2586
2587         /* Outer loop uses 18 flops */
2588     }
2589
2590     /* Increment number of outer iterations */
2591     outeriter        += nri;
2592
2593     /* Update outer/inner flops */
2594
2595     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W3W3_F,outeriter*18 + inneriter*399);
2596 }