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