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