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