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