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