Introduce gmxpre.h for truly global definitions
[alexxy/gromacs.git] / src / gromacs / gmxlib / nonbonded / nb_kernel_avx_128_fma_single / nb_kernel_ElecRF_VdwLJ_GeomW4W4_avx_128_fma_single.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*
36  * Note: this file was generated by the GROMACS avx_128_fma_single kernel generator.
37  */
38 #include "gmxpre.h"
39
40 #include "config.h"
41
42 #include <math.h>
43
44 #include "../nb_kernel.h"
45 #include "gromacs/legacyheaders/types/simple.h"
46 #include "gromacs/math/vec.h"
47 #include "gromacs/legacyheaders/nrnb.h"
48
49 #include "gromacs/simd/math_x86_avx_128_fma_single.h"
50 #include "kernelutil_x86_avx_128_fma_single.h"
51
52 /*
53  * Gromacs nonbonded kernel:   nb_kernel_ElecRF_VdwLJ_GeomW4W4_VF_avx_128_fma_single
54  * Electrostatics interaction: ReactionField
55  * VdW interaction:            LennardJones
56  * Geometry:                   Water4-Water4
57  * Calculate force/pot:        PotentialAndForce
58  */
59 void
60 nb_kernel_ElecRF_VdwLJ_GeomW4W4_VF_avx_128_fma_single
61                     (t_nblist                    * gmx_restrict       nlist,
62                      rvec                        * gmx_restrict          xx,
63                      rvec                        * gmx_restrict          ff,
64                      t_forcerec                  * gmx_restrict          fr,
65                      t_mdatoms                   * gmx_restrict     mdatoms,
66                      nb_kernel_data_t gmx_unused * gmx_restrict kernel_data,
67                      t_nrnb                      * gmx_restrict        nrnb)
68 {
69     /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
70      * just 0 for non-waters.
71      * Suffixes A,B,C,D refer to j loop unrolling done with AVX_128, e.g. for the four different
72      * jnr indices corresponding to data put in the four positions in the SIMD register.
73      */
74     int              i_shift_offset,i_coord_offset,outeriter,inneriter;
75     int              j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
76     int              jnrA,jnrB,jnrC,jnrD;
77     int              jnrlistA,jnrlistB,jnrlistC,jnrlistD;
78     int              j_coord_offsetA,j_coord_offsetB,j_coord_offsetC,j_coord_offsetD;
79     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
80     real             rcutoff_scalar;
81     real             *shiftvec,*fshift,*x,*f;
82     real             *fjptrA,*fjptrB,*fjptrC,*fjptrD;
83     real             scratch[4*DIM];
84     __m128           fscal,rcutoff,rcutoff2,jidxall;
85     int              vdwioffset0;
86     __m128           ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
87     int              vdwioffset1;
88     __m128           ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
89     int              vdwioffset2;
90     __m128           ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
91     int              vdwioffset3;
92     __m128           ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
93     int              vdwjidx0A,vdwjidx0B,vdwjidx0C,vdwjidx0D;
94     __m128           jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
95     int              vdwjidx1A,vdwjidx1B,vdwjidx1C,vdwjidx1D;
96     __m128           jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
97     int              vdwjidx2A,vdwjidx2B,vdwjidx2C,vdwjidx2D;
98     __m128           jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
99     int              vdwjidx3A,vdwjidx3B,vdwjidx3C,vdwjidx3D;
100     __m128           jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
101     __m128           dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
102     __m128           dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
103     __m128           dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
104     __m128           dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
105     __m128           dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
106     __m128           dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
107     __m128           dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
108     __m128           dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
109     __m128           dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
110     __m128           dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
111     __m128           velec,felec,velecsum,facel,crf,krf,krf2;
112     real             *charge;
113     int              nvdwtype;
114     __m128           rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
115     int              *vdwtype;
116     real             *vdwparam;
117     __m128           one_sixth   = _mm_set1_ps(1.0/6.0);
118     __m128           one_twelfth = _mm_set1_ps(1.0/12.0);
119     __m128           dummy_mask,cutoff_mask;
120     __m128           signbit = _mm_castsi128_ps( _mm_set1_epi32(0x80000000) );
121     __m128           one     = _mm_set1_ps(1.0);
122     __m128           two     = _mm_set1_ps(2.0);
123     x                = xx[0];
124     f                = ff[0];
125
126     nri              = nlist->nri;
127     iinr             = nlist->iinr;
128     jindex           = nlist->jindex;
129     jjnr             = nlist->jjnr;
130     shiftidx         = nlist->shift;
131     gid              = nlist->gid;
132     shiftvec         = fr->shift_vec[0];
133     fshift           = fr->fshift[0];
134     facel            = _mm_set1_ps(fr->epsfac);
135     charge           = mdatoms->chargeA;
136     krf              = _mm_set1_ps(fr->ic->k_rf);
137     krf2             = _mm_set1_ps(fr->ic->k_rf*2.0);
138     crf              = _mm_set1_ps(fr->ic->c_rf);
139     nvdwtype         = fr->ntype;
140     vdwparam         = fr->nbfp;
141     vdwtype          = mdatoms->typeA;
142
143     /* Setup water-specific parameters */
144     inr              = nlist->iinr[0];
145     iq1              = _mm_mul_ps(facel,_mm_set1_ps(charge[inr+1]));
146     iq2              = _mm_mul_ps(facel,_mm_set1_ps(charge[inr+2]));
147     iq3              = _mm_mul_ps(facel,_mm_set1_ps(charge[inr+3]));
148     vdwioffset0      = 2*nvdwtype*vdwtype[inr+0];
149
150     jq1              = _mm_set1_ps(charge[inr+1]);
151     jq2              = _mm_set1_ps(charge[inr+2]);
152     jq3              = _mm_set1_ps(charge[inr+3]);
153     vdwjidx0A        = 2*vdwtype[inr+0];
154     c6_00            = _mm_set1_ps(vdwparam[vdwioffset0+vdwjidx0A]);
155     c12_00           = _mm_set1_ps(vdwparam[vdwioffset0+vdwjidx0A+1]);
156     qq11             = _mm_mul_ps(iq1,jq1);
157     qq12             = _mm_mul_ps(iq1,jq2);
158     qq13             = _mm_mul_ps(iq1,jq3);
159     qq21             = _mm_mul_ps(iq2,jq1);
160     qq22             = _mm_mul_ps(iq2,jq2);
161     qq23             = _mm_mul_ps(iq2,jq3);
162     qq31             = _mm_mul_ps(iq3,jq1);
163     qq32             = _mm_mul_ps(iq3,jq2);
164     qq33             = _mm_mul_ps(iq3,jq3);
165
166     /* Avoid stupid compiler warnings */
167     jnrA = jnrB = jnrC = jnrD = 0;
168     j_coord_offsetA = 0;
169     j_coord_offsetB = 0;
170     j_coord_offsetC = 0;
171     j_coord_offsetD = 0;
172
173     outeriter        = 0;
174     inneriter        = 0;
175
176     for(iidx=0;iidx<4*DIM;iidx++)
177     {
178         scratch[iidx] = 0.0;
179     }
180
181     /* Start outer loop over neighborlists */
182     for(iidx=0; iidx<nri; iidx++)
183     {
184         /* Load shift vector for this list */
185         i_shift_offset   = DIM*shiftidx[iidx];
186
187         /* Load limits for loop over neighbors */
188         j_index_start    = jindex[iidx];
189         j_index_end      = jindex[iidx+1];
190
191         /* Get outer coordinate index */
192         inr              = iinr[iidx];
193         i_coord_offset   = DIM*inr;
194
195         /* Load i particle coords and add shift vector */
196         gmx_mm_load_shift_and_4rvec_broadcast_ps(shiftvec+i_shift_offset,x+i_coord_offset,
197                                                  &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
198
199         fix0             = _mm_setzero_ps();
200         fiy0             = _mm_setzero_ps();
201         fiz0             = _mm_setzero_ps();
202         fix1             = _mm_setzero_ps();
203         fiy1             = _mm_setzero_ps();
204         fiz1             = _mm_setzero_ps();
205         fix2             = _mm_setzero_ps();
206         fiy2             = _mm_setzero_ps();
207         fiz2             = _mm_setzero_ps();
208         fix3             = _mm_setzero_ps();
209         fiy3             = _mm_setzero_ps();
210         fiz3             = _mm_setzero_ps();
211
212         /* Reset potential sums */
213         velecsum         = _mm_setzero_ps();
214         vvdwsum          = _mm_setzero_ps();
215
216         /* Start inner kernel loop */
217         for(jidx=j_index_start; jidx<j_index_end && jjnr[jidx+3]>=0; jidx+=4)
218         {
219
220             /* Get j neighbor index, and coordinate index */
221             jnrA             = jjnr[jidx];
222             jnrB             = jjnr[jidx+1];
223             jnrC             = jjnr[jidx+2];
224             jnrD             = jjnr[jidx+3];
225             j_coord_offsetA  = DIM*jnrA;
226             j_coord_offsetB  = DIM*jnrB;
227             j_coord_offsetC  = DIM*jnrC;
228             j_coord_offsetD  = DIM*jnrD;
229
230             /* load j atom coordinates */
231             gmx_mm_load_4rvec_4ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
232                                               x+j_coord_offsetC,x+j_coord_offsetD,
233                                               &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
234                                               &jy2,&jz2,&jx3,&jy3,&jz3);
235
236             /* Calculate displacement vector */
237             dx00             = _mm_sub_ps(ix0,jx0);
238             dy00             = _mm_sub_ps(iy0,jy0);
239             dz00             = _mm_sub_ps(iz0,jz0);
240             dx11             = _mm_sub_ps(ix1,jx1);
241             dy11             = _mm_sub_ps(iy1,jy1);
242             dz11             = _mm_sub_ps(iz1,jz1);
243             dx12             = _mm_sub_ps(ix1,jx2);
244             dy12             = _mm_sub_ps(iy1,jy2);
245             dz12             = _mm_sub_ps(iz1,jz2);
246             dx13             = _mm_sub_ps(ix1,jx3);
247             dy13             = _mm_sub_ps(iy1,jy3);
248             dz13             = _mm_sub_ps(iz1,jz3);
249             dx21             = _mm_sub_ps(ix2,jx1);
250             dy21             = _mm_sub_ps(iy2,jy1);
251             dz21             = _mm_sub_ps(iz2,jz1);
252             dx22             = _mm_sub_ps(ix2,jx2);
253             dy22             = _mm_sub_ps(iy2,jy2);
254             dz22             = _mm_sub_ps(iz2,jz2);
255             dx23             = _mm_sub_ps(ix2,jx3);
256             dy23             = _mm_sub_ps(iy2,jy3);
257             dz23             = _mm_sub_ps(iz2,jz3);
258             dx31             = _mm_sub_ps(ix3,jx1);
259             dy31             = _mm_sub_ps(iy3,jy1);
260             dz31             = _mm_sub_ps(iz3,jz1);
261             dx32             = _mm_sub_ps(ix3,jx2);
262             dy32             = _mm_sub_ps(iy3,jy2);
263             dz32             = _mm_sub_ps(iz3,jz2);
264             dx33             = _mm_sub_ps(ix3,jx3);
265             dy33             = _mm_sub_ps(iy3,jy3);
266             dz33             = _mm_sub_ps(iz3,jz3);
267
268             /* Calculate squared distance and things based on it */
269             rsq00            = gmx_mm_calc_rsq_ps(dx00,dy00,dz00);
270             rsq11            = gmx_mm_calc_rsq_ps(dx11,dy11,dz11);
271             rsq12            = gmx_mm_calc_rsq_ps(dx12,dy12,dz12);
272             rsq13            = gmx_mm_calc_rsq_ps(dx13,dy13,dz13);
273             rsq21            = gmx_mm_calc_rsq_ps(dx21,dy21,dz21);
274             rsq22            = gmx_mm_calc_rsq_ps(dx22,dy22,dz22);
275             rsq23            = gmx_mm_calc_rsq_ps(dx23,dy23,dz23);
276             rsq31            = gmx_mm_calc_rsq_ps(dx31,dy31,dz31);
277             rsq32            = gmx_mm_calc_rsq_ps(dx32,dy32,dz32);
278             rsq33            = gmx_mm_calc_rsq_ps(dx33,dy33,dz33);
279
280             rinv11           = gmx_mm_invsqrt_ps(rsq11);
281             rinv12           = gmx_mm_invsqrt_ps(rsq12);
282             rinv13           = gmx_mm_invsqrt_ps(rsq13);
283             rinv21           = gmx_mm_invsqrt_ps(rsq21);
284             rinv22           = gmx_mm_invsqrt_ps(rsq22);
285             rinv23           = gmx_mm_invsqrt_ps(rsq23);
286             rinv31           = gmx_mm_invsqrt_ps(rsq31);
287             rinv32           = gmx_mm_invsqrt_ps(rsq32);
288             rinv33           = gmx_mm_invsqrt_ps(rsq33);
289
290             rinvsq00         = gmx_mm_inv_ps(rsq00);
291             rinvsq11         = _mm_mul_ps(rinv11,rinv11);
292             rinvsq12         = _mm_mul_ps(rinv12,rinv12);
293             rinvsq13         = _mm_mul_ps(rinv13,rinv13);
294             rinvsq21         = _mm_mul_ps(rinv21,rinv21);
295             rinvsq22         = _mm_mul_ps(rinv22,rinv22);
296             rinvsq23         = _mm_mul_ps(rinv23,rinv23);
297             rinvsq31         = _mm_mul_ps(rinv31,rinv31);
298             rinvsq32         = _mm_mul_ps(rinv32,rinv32);
299             rinvsq33         = _mm_mul_ps(rinv33,rinv33);
300
301             fjx0             = _mm_setzero_ps();
302             fjy0             = _mm_setzero_ps();
303             fjz0             = _mm_setzero_ps();
304             fjx1             = _mm_setzero_ps();
305             fjy1             = _mm_setzero_ps();
306             fjz1             = _mm_setzero_ps();
307             fjx2             = _mm_setzero_ps();
308             fjy2             = _mm_setzero_ps();
309             fjz2             = _mm_setzero_ps();
310             fjx3             = _mm_setzero_ps();
311             fjy3             = _mm_setzero_ps();
312             fjz3             = _mm_setzero_ps();
313
314             /**************************
315              * CALCULATE INTERACTIONS *
316              **************************/
317
318             /* LENNARD-JONES DISPERSION/REPULSION */
319
320             rinvsix          = _mm_mul_ps(_mm_mul_ps(rinvsq00,rinvsq00),rinvsq00);
321             vvdw6            = _mm_mul_ps(c6_00,rinvsix);
322             vvdw12           = _mm_mul_ps(c12_00,_mm_mul_ps(rinvsix,rinvsix));
323             vvdw             = _mm_msub_ps(vvdw12,one_twelfth,_mm_mul_ps(vvdw6,one_sixth));
324             fvdw             = _mm_mul_ps(_mm_sub_ps(vvdw12,vvdw6),rinvsq00);
325
326             /* Update potential sum for this i atom from the interaction with this j atom. */
327             vvdwsum          = _mm_add_ps(vvdwsum,vvdw);
328
329             fscal            = fvdw;
330
331              /* Update vectorial force */
332             fix0             = _mm_macc_ps(dx00,fscal,fix0);
333             fiy0             = _mm_macc_ps(dy00,fscal,fiy0);
334             fiz0             = _mm_macc_ps(dz00,fscal,fiz0);
335
336             fjx0             = _mm_macc_ps(dx00,fscal,fjx0);
337             fjy0             = _mm_macc_ps(dy00,fscal,fjy0);
338             fjz0             = _mm_macc_ps(dz00,fscal,fjz0);
339
340             /**************************
341              * CALCULATE INTERACTIONS *
342              **************************/
343
344             /* REACTION-FIELD ELECTROSTATICS */
345             velec            = _mm_mul_ps(qq11,_mm_sub_ps(_mm_macc_ps(krf,rsq11,rinv11),crf));
346             felec            = _mm_mul_ps(qq11,_mm_msub_ps(rinv11,rinvsq11,krf2));
347
348             /* Update potential sum for this i atom from the interaction with this j atom. */
349             velecsum         = _mm_add_ps(velecsum,velec);
350
351             fscal            = felec;
352
353              /* Update vectorial force */
354             fix1             = _mm_macc_ps(dx11,fscal,fix1);
355             fiy1             = _mm_macc_ps(dy11,fscal,fiy1);
356             fiz1             = _mm_macc_ps(dz11,fscal,fiz1);
357
358             fjx1             = _mm_macc_ps(dx11,fscal,fjx1);
359             fjy1             = _mm_macc_ps(dy11,fscal,fjy1);
360             fjz1             = _mm_macc_ps(dz11,fscal,fjz1);
361
362             /**************************
363              * CALCULATE INTERACTIONS *
364              **************************/
365
366             /* REACTION-FIELD ELECTROSTATICS */
367             velec            = _mm_mul_ps(qq12,_mm_sub_ps(_mm_macc_ps(krf,rsq12,rinv12),crf));
368             felec            = _mm_mul_ps(qq12,_mm_msub_ps(rinv12,rinvsq12,krf2));
369
370             /* Update potential sum for this i atom from the interaction with this j atom. */
371             velecsum         = _mm_add_ps(velecsum,velec);
372
373             fscal            = felec;
374
375              /* Update vectorial force */
376             fix1             = _mm_macc_ps(dx12,fscal,fix1);
377             fiy1             = _mm_macc_ps(dy12,fscal,fiy1);
378             fiz1             = _mm_macc_ps(dz12,fscal,fiz1);
379
380             fjx2             = _mm_macc_ps(dx12,fscal,fjx2);
381             fjy2             = _mm_macc_ps(dy12,fscal,fjy2);
382             fjz2             = _mm_macc_ps(dz12,fscal,fjz2);
383
384             /**************************
385              * CALCULATE INTERACTIONS *
386              **************************/
387
388             /* REACTION-FIELD ELECTROSTATICS */
389             velec            = _mm_mul_ps(qq13,_mm_sub_ps(_mm_macc_ps(krf,rsq13,rinv13),crf));
390             felec            = _mm_mul_ps(qq13,_mm_msub_ps(rinv13,rinvsq13,krf2));
391
392             /* Update potential sum for this i atom from the interaction with this j atom. */
393             velecsum         = _mm_add_ps(velecsum,velec);
394
395             fscal            = felec;
396
397              /* Update vectorial force */
398             fix1             = _mm_macc_ps(dx13,fscal,fix1);
399             fiy1             = _mm_macc_ps(dy13,fscal,fiy1);
400             fiz1             = _mm_macc_ps(dz13,fscal,fiz1);
401
402             fjx3             = _mm_macc_ps(dx13,fscal,fjx3);
403             fjy3             = _mm_macc_ps(dy13,fscal,fjy3);
404             fjz3             = _mm_macc_ps(dz13,fscal,fjz3);
405
406             /**************************
407              * CALCULATE INTERACTIONS *
408              **************************/
409
410             /* REACTION-FIELD ELECTROSTATICS */
411             velec            = _mm_mul_ps(qq21,_mm_sub_ps(_mm_macc_ps(krf,rsq21,rinv21),crf));
412             felec            = _mm_mul_ps(qq21,_mm_msub_ps(rinv21,rinvsq21,krf2));
413
414             /* Update potential sum for this i atom from the interaction with this j atom. */
415             velecsum         = _mm_add_ps(velecsum,velec);
416
417             fscal            = felec;
418
419              /* Update vectorial force */
420             fix2             = _mm_macc_ps(dx21,fscal,fix2);
421             fiy2             = _mm_macc_ps(dy21,fscal,fiy2);
422             fiz2             = _mm_macc_ps(dz21,fscal,fiz2);
423
424             fjx1             = _mm_macc_ps(dx21,fscal,fjx1);
425             fjy1             = _mm_macc_ps(dy21,fscal,fjy1);
426             fjz1             = _mm_macc_ps(dz21,fscal,fjz1);
427
428             /**************************
429              * CALCULATE INTERACTIONS *
430              **************************/
431
432             /* REACTION-FIELD ELECTROSTATICS */
433             velec            = _mm_mul_ps(qq22,_mm_sub_ps(_mm_macc_ps(krf,rsq22,rinv22),crf));
434             felec            = _mm_mul_ps(qq22,_mm_msub_ps(rinv22,rinvsq22,krf2));
435
436             /* Update potential sum for this i atom from the interaction with this j atom. */
437             velecsum         = _mm_add_ps(velecsum,velec);
438
439             fscal            = felec;
440
441              /* Update vectorial force */
442             fix2             = _mm_macc_ps(dx22,fscal,fix2);
443             fiy2             = _mm_macc_ps(dy22,fscal,fiy2);
444             fiz2             = _mm_macc_ps(dz22,fscal,fiz2);
445
446             fjx2             = _mm_macc_ps(dx22,fscal,fjx2);
447             fjy2             = _mm_macc_ps(dy22,fscal,fjy2);
448             fjz2             = _mm_macc_ps(dz22,fscal,fjz2);
449
450             /**************************
451              * CALCULATE INTERACTIONS *
452              **************************/
453
454             /* REACTION-FIELD ELECTROSTATICS */
455             velec            = _mm_mul_ps(qq23,_mm_sub_ps(_mm_macc_ps(krf,rsq23,rinv23),crf));
456             felec            = _mm_mul_ps(qq23,_mm_msub_ps(rinv23,rinvsq23,krf2));
457
458             /* Update potential sum for this i atom from the interaction with this j atom. */
459             velecsum         = _mm_add_ps(velecsum,velec);
460
461             fscal            = felec;
462
463              /* Update vectorial force */
464             fix2             = _mm_macc_ps(dx23,fscal,fix2);
465             fiy2             = _mm_macc_ps(dy23,fscal,fiy2);
466             fiz2             = _mm_macc_ps(dz23,fscal,fiz2);
467
468             fjx3             = _mm_macc_ps(dx23,fscal,fjx3);
469             fjy3             = _mm_macc_ps(dy23,fscal,fjy3);
470             fjz3             = _mm_macc_ps(dz23,fscal,fjz3);
471
472             /**************************
473              * CALCULATE INTERACTIONS *
474              **************************/
475
476             /* REACTION-FIELD ELECTROSTATICS */
477             velec            = _mm_mul_ps(qq31,_mm_sub_ps(_mm_macc_ps(krf,rsq31,rinv31),crf));
478             felec            = _mm_mul_ps(qq31,_mm_msub_ps(rinv31,rinvsq31,krf2));
479
480             /* Update potential sum for this i atom from the interaction with this j atom. */
481             velecsum         = _mm_add_ps(velecsum,velec);
482
483             fscal            = felec;
484
485              /* Update vectorial force */
486             fix3             = _mm_macc_ps(dx31,fscal,fix3);
487             fiy3             = _mm_macc_ps(dy31,fscal,fiy3);
488             fiz3             = _mm_macc_ps(dz31,fscal,fiz3);
489
490             fjx1             = _mm_macc_ps(dx31,fscal,fjx1);
491             fjy1             = _mm_macc_ps(dy31,fscal,fjy1);
492             fjz1             = _mm_macc_ps(dz31,fscal,fjz1);
493
494             /**************************
495              * CALCULATE INTERACTIONS *
496              **************************/
497
498             /* REACTION-FIELD ELECTROSTATICS */
499             velec            = _mm_mul_ps(qq32,_mm_sub_ps(_mm_macc_ps(krf,rsq32,rinv32),crf));
500             felec            = _mm_mul_ps(qq32,_mm_msub_ps(rinv32,rinvsq32,krf2));
501
502             /* Update potential sum for this i atom from the interaction with this j atom. */
503             velecsum         = _mm_add_ps(velecsum,velec);
504
505             fscal            = felec;
506
507              /* Update vectorial force */
508             fix3             = _mm_macc_ps(dx32,fscal,fix3);
509             fiy3             = _mm_macc_ps(dy32,fscal,fiy3);
510             fiz3             = _mm_macc_ps(dz32,fscal,fiz3);
511
512             fjx2             = _mm_macc_ps(dx32,fscal,fjx2);
513             fjy2             = _mm_macc_ps(dy32,fscal,fjy2);
514             fjz2             = _mm_macc_ps(dz32,fscal,fjz2);
515
516             /**************************
517              * CALCULATE INTERACTIONS *
518              **************************/
519
520             /* REACTION-FIELD ELECTROSTATICS */
521             velec            = _mm_mul_ps(qq33,_mm_sub_ps(_mm_macc_ps(krf,rsq33,rinv33),crf));
522             felec            = _mm_mul_ps(qq33,_mm_msub_ps(rinv33,rinvsq33,krf2));
523
524             /* Update potential sum for this i atom from the interaction with this j atom. */
525             velecsum         = _mm_add_ps(velecsum,velec);
526
527             fscal            = felec;
528
529              /* Update vectorial force */
530             fix3             = _mm_macc_ps(dx33,fscal,fix3);
531             fiy3             = _mm_macc_ps(dy33,fscal,fiy3);
532             fiz3             = _mm_macc_ps(dz33,fscal,fiz3);
533
534             fjx3             = _mm_macc_ps(dx33,fscal,fjx3);
535             fjy3             = _mm_macc_ps(dy33,fscal,fjy3);
536             fjz3             = _mm_macc_ps(dz33,fscal,fjz3);
537
538             fjptrA             = f+j_coord_offsetA;
539             fjptrB             = f+j_coord_offsetB;
540             fjptrC             = f+j_coord_offsetC;
541             fjptrD             = f+j_coord_offsetD;
542
543             gmx_mm_decrement_4rvec_4ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,
544                                                    fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,
545                                                    fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
546
547             /* Inner loop uses 353 flops */
548         }
549
550         if(jidx<j_index_end)
551         {
552
553             /* Get j neighbor index, and coordinate index */
554             jnrlistA         = jjnr[jidx];
555             jnrlistB         = jjnr[jidx+1];
556             jnrlistC         = jjnr[jidx+2];
557             jnrlistD         = jjnr[jidx+3];
558             /* Sign of each element will be negative for non-real atoms.
559              * This mask will be 0xFFFFFFFF for dummy entries and 0x0 for real ones,
560              * so use it as val = _mm_andnot_ps(mask,val) to clear dummy entries.
561              */
562             dummy_mask = gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx)),_mm_setzero_si128()));
563             jnrA       = (jnrlistA>=0) ? jnrlistA : 0;
564             jnrB       = (jnrlistB>=0) ? jnrlistB : 0;
565             jnrC       = (jnrlistC>=0) ? jnrlistC : 0;
566             jnrD       = (jnrlistD>=0) ? jnrlistD : 0;
567             j_coord_offsetA  = DIM*jnrA;
568             j_coord_offsetB  = DIM*jnrB;
569             j_coord_offsetC  = DIM*jnrC;
570             j_coord_offsetD  = DIM*jnrD;
571
572             /* load j atom coordinates */
573             gmx_mm_load_4rvec_4ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
574                                               x+j_coord_offsetC,x+j_coord_offsetD,
575                                               &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
576                                               &jy2,&jz2,&jx3,&jy3,&jz3);
577
578             /* Calculate displacement vector */
579             dx00             = _mm_sub_ps(ix0,jx0);
580             dy00             = _mm_sub_ps(iy0,jy0);
581             dz00             = _mm_sub_ps(iz0,jz0);
582             dx11             = _mm_sub_ps(ix1,jx1);
583             dy11             = _mm_sub_ps(iy1,jy1);
584             dz11             = _mm_sub_ps(iz1,jz1);
585             dx12             = _mm_sub_ps(ix1,jx2);
586             dy12             = _mm_sub_ps(iy1,jy2);
587             dz12             = _mm_sub_ps(iz1,jz2);
588             dx13             = _mm_sub_ps(ix1,jx3);
589             dy13             = _mm_sub_ps(iy1,jy3);
590             dz13             = _mm_sub_ps(iz1,jz3);
591             dx21             = _mm_sub_ps(ix2,jx1);
592             dy21             = _mm_sub_ps(iy2,jy1);
593             dz21             = _mm_sub_ps(iz2,jz1);
594             dx22             = _mm_sub_ps(ix2,jx2);
595             dy22             = _mm_sub_ps(iy2,jy2);
596             dz22             = _mm_sub_ps(iz2,jz2);
597             dx23             = _mm_sub_ps(ix2,jx3);
598             dy23             = _mm_sub_ps(iy2,jy3);
599             dz23             = _mm_sub_ps(iz2,jz3);
600             dx31             = _mm_sub_ps(ix3,jx1);
601             dy31             = _mm_sub_ps(iy3,jy1);
602             dz31             = _mm_sub_ps(iz3,jz1);
603             dx32             = _mm_sub_ps(ix3,jx2);
604             dy32             = _mm_sub_ps(iy3,jy2);
605             dz32             = _mm_sub_ps(iz3,jz2);
606             dx33             = _mm_sub_ps(ix3,jx3);
607             dy33             = _mm_sub_ps(iy3,jy3);
608             dz33             = _mm_sub_ps(iz3,jz3);
609
610             /* Calculate squared distance and things based on it */
611             rsq00            = gmx_mm_calc_rsq_ps(dx00,dy00,dz00);
612             rsq11            = gmx_mm_calc_rsq_ps(dx11,dy11,dz11);
613             rsq12            = gmx_mm_calc_rsq_ps(dx12,dy12,dz12);
614             rsq13            = gmx_mm_calc_rsq_ps(dx13,dy13,dz13);
615             rsq21            = gmx_mm_calc_rsq_ps(dx21,dy21,dz21);
616             rsq22            = gmx_mm_calc_rsq_ps(dx22,dy22,dz22);
617             rsq23            = gmx_mm_calc_rsq_ps(dx23,dy23,dz23);
618             rsq31            = gmx_mm_calc_rsq_ps(dx31,dy31,dz31);
619             rsq32            = gmx_mm_calc_rsq_ps(dx32,dy32,dz32);
620             rsq33            = gmx_mm_calc_rsq_ps(dx33,dy33,dz33);
621
622             rinv11           = gmx_mm_invsqrt_ps(rsq11);
623             rinv12           = gmx_mm_invsqrt_ps(rsq12);
624             rinv13           = gmx_mm_invsqrt_ps(rsq13);
625             rinv21           = gmx_mm_invsqrt_ps(rsq21);
626             rinv22           = gmx_mm_invsqrt_ps(rsq22);
627             rinv23           = gmx_mm_invsqrt_ps(rsq23);
628             rinv31           = gmx_mm_invsqrt_ps(rsq31);
629             rinv32           = gmx_mm_invsqrt_ps(rsq32);
630             rinv33           = gmx_mm_invsqrt_ps(rsq33);
631
632             rinvsq00         = gmx_mm_inv_ps(rsq00);
633             rinvsq11         = _mm_mul_ps(rinv11,rinv11);
634             rinvsq12         = _mm_mul_ps(rinv12,rinv12);
635             rinvsq13         = _mm_mul_ps(rinv13,rinv13);
636             rinvsq21         = _mm_mul_ps(rinv21,rinv21);
637             rinvsq22         = _mm_mul_ps(rinv22,rinv22);
638             rinvsq23         = _mm_mul_ps(rinv23,rinv23);
639             rinvsq31         = _mm_mul_ps(rinv31,rinv31);
640             rinvsq32         = _mm_mul_ps(rinv32,rinv32);
641             rinvsq33         = _mm_mul_ps(rinv33,rinv33);
642
643             fjx0             = _mm_setzero_ps();
644             fjy0             = _mm_setzero_ps();
645             fjz0             = _mm_setzero_ps();
646             fjx1             = _mm_setzero_ps();
647             fjy1             = _mm_setzero_ps();
648             fjz1             = _mm_setzero_ps();
649             fjx2             = _mm_setzero_ps();
650             fjy2             = _mm_setzero_ps();
651             fjz2             = _mm_setzero_ps();
652             fjx3             = _mm_setzero_ps();
653             fjy3             = _mm_setzero_ps();
654             fjz3             = _mm_setzero_ps();
655
656             /**************************
657              * CALCULATE INTERACTIONS *
658              **************************/
659
660             /* LENNARD-JONES DISPERSION/REPULSION */
661
662             rinvsix          = _mm_mul_ps(_mm_mul_ps(rinvsq00,rinvsq00),rinvsq00);
663             vvdw6            = _mm_mul_ps(c6_00,rinvsix);
664             vvdw12           = _mm_mul_ps(c12_00,_mm_mul_ps(rinvsix,rinvsix));
665             vvdw             = _mm_msub_ps(vvdw12,one_twelfth,_mm_mul_ps(vvdw6,one_sixth));
666             fvdw             = _mm_mul_ps(_mm_sub_ps(vvdw12,vvdw6),rinvsq00);
667
668             /* Update potential sum for this i atom from the interaction with this j atom. */
669             vvdw             = _mm_andnot_ps(dummy_mask,vvdw);
670             vvdwsum          = _mm_add_ps(vvdwsum,vvdw);
671
672             fscal            = fvdw;
673
674             fscal            = _mm_andnot_ps(dummy_mask,fscal);
675
676              /* Update vectorial force */
677             fix0             = _mm_macc_ps(dx00,fscal,fix0);
678             fiy0             = _mm_macc_ps(dy00,fscal,fiy0);
679             fiz0             = _mm_macc_ps(dz00,fscal,fiz0);
680
681             fjx0             = _mm_macc_ps(dx00,fscal,fjx0);
682             fjy0             = _mm_macc_ps(dy00,fscal,fjy0);
683             fjz0             = _mm_macc_ps(dz00,fscal,fjz0);
684
685             /**************************
686              * CALCULATE INTERACTIONS *
687              **************************/
688
689             /* REACTION-FIELD ELECTROSTATICS */
690             velec            = _mm_mul_ps(qq11,_mm_sub_ps(_mm_macc_ps(krf,rsq11,rinv11),crf));
691             felec            = _mm_mul_ps(qq11,_mm_msub_ps(rinv11,rinvsq11,krf2));
692
693             /* Update potential sum for this i atom from the interaction with this j atom. */
694             velec            = _mm_andnot_ps(dummy_mask,velec);
695             velecsum         = _mm_add_ps(velecsum,velec);
696
697             fscal            = felec;
698
699             fscal            = _mm_andnot_ps(dummy_mask,fscal);
700
701              /* Update vectorial force */
702             fix1             = _mm_macc_ps(dx11,fscal,fix1);
703             fiy1             = _mm_macc_ps(dy11,fscal,fiy1);
704             fiz1             = _mm_macc_ps(dz11,fscal,fiz1);
705
706             fjx1             = _mm_macc_ps(dx11,fscal,fjx1);
707             fjy1             = _mm_macc_ps(dy11,fscal,fjy1);
708             fjz1             = _mm_macc_ps(dz11,fscal,fjz1);
709
710             /**************************
711              * CALCULATE INTERACTIONS *
712              **************************/
713
714             /* REACTION-FIELD ELECTROSTATICS */
715             velec            = _mm_mul_ps(qq12,_mm_sub_ps(_mm_macc_ps(krf,rsq12,rinv12),crf));
716             felec            = _mm_mul_ps(qq12,_mm_msub_ps(rinv12,rinvsq12,krf2));
717
718             /* Update potential sum for this i atom from the interaction with this j atom. */
719             velec            = _mm_andnot_ps(dummy_mask,velec);
720             velecsum         = _mm_add_ps(velecsum,velec);
721
722             fscal            = felec;
723
724             fscal            = _mm_andnot_ps(dummy_mask,fscal);
725
726              /* Update vectorial force */
727             fix1             = _mm_macc_ps(dx12,fscal,fix1);
728             fiy1             = _mm_macc_ps(dy12,fscal,fiy1);
729             fiz1             = _mm_macc_ps(dz12,fscal,fiz1);
730
731             fjx2             = _mm_macc_ps(dx12,fscal,fjx2);
732             fjy2             = _mm_macc_ps(dy12,fscal,fjy2);
733             fjz2             = _mm_macc_ps(dz12,fscal,fjz2);
734
735             /**************************
736              * CALCULATE INTERACTIONS *
737              **************************/
738
739             /* REACTION-FIELD ELECTROSTATICS */
740             velec            = _mm_mul_ps(qq13,_mm_sub_ps(_mm_macc_ps(krf,rsq13,rinv13),crf));
741             felec            = _mm_mul_ps(qq13,_mm_msub_ps(rinv13,rinvsq13,krf2));
742
743             /* Update potential sum for this i atom from the interaction with this j atom. */
744             velec            = _mm_andnot_ps(dummy_mask,velec);
745             velecsum         = _mm_add_ps(velecsum,velec);
746
747             fscal            = felec;
748
749             fscal            = _mm_andnot_ps(dummy_mask,fscal);
750
751              /* Update vectorial force */
752             fix1             = _mm_macc_ps(dx13,fscal,fix1);
753             fiy1             = _mm_macc_ps(dy13,fscal,fiy1);
754             fiz1             = _mm_macc_ps(dz13,fscal,fiz1);
755
756             fjx3             = _mm_macc_ps(dx13,fscal,fjx3);
757             fjy3             = _mm_macc_ps(dy13,fscal,fjy3);
758             fjz3             = _mm_macc_ps(dz13,fscal,fjz3);
759
760             /**************************
761              * CALCULATE INTERACTIONS *
762              **************************/
763
764             /* REACTION-FIELD ELECTROSTATICS */
765             velec            = _mm_mul_ps(qq21,_mm_sub_ps(_mm_macc_ps(krf,rsq21,rinv21),crf));
766             felec            = _mm_mul_ps(qq21,_mm_msub_ps(rinv21,rinvsq21,krf2));
767
768             /* Update potential sum for this i atom from the interaction with this j atom. */
769             velec            = _mm_andnot_ps(dummy_mask,velec);
770             velecsum         = _mm_add_ps(velecsum,velec);
771
772             fscal            = felec;
773
774             fscal            = _mm_andnot_ps(dummy_mask,fscal);
775
776              /* Update vectorial force */
777             fix2             = _mm_macc_ps(dx21,fscal,fix2);
778             fiy2             = _mm_macc_ps(dy21,fscal,fiy2);
779             fiz2             = _mm_macc_ps(dz21,fscal,fiz2);
780
781             fjx1             = _mm_macc_ps(dx21,fscal,fjx1);
782             fjy1             = _mm_macc_ps(dy21,fscal,fjy1);
783             fjz1             = _mm_macc_ps(dz21,fscal,fjz1);
784
785             /**************************
786              * CALCULATE INTERACTIONS *
787              **************************/
788
789             /* REACTION-FIELD ELECTROSTATICS */
790             velec            = _mm_mul_ps(qq22,_mm_sub_ps(_mm_macc_ps(krf,rsq22,rinv22),crf));
791             felec            = _mm_mul_ps(qq22,_mm_msub_ps(rinv22,rinvsq22,krf2));
792
793             /* Update potential sum for this i atom from the interaction with this j atom. */
794             velec            = _mm_andnot_ps(dummy_mask,velec);
795             velecsum         = _mm_add_ps(velecsum,velec);
796
797             fscal            = felec;
798
799             fscal            = _mm_andnot_ps(dummy_mask,fscal);
800
801              /* Update vectorial force */
802             fix2             = _mm_macc_ps(dx22,fscal,fix2);
803             fiy2             = _mm_macc_ps(dy22,fscal,fiy2);
804             fiz2             = _mm_macc_ps(dz22,fscal,fiz2);
805
806             fjx2             = _mm_macc_ps(dx22,fscal,fjx2);
807             fjy2             = _mm_macc_ps(dy22,fscal,fjy2);
808             fjz2             = _mm_macc_ps(dz22,fscal,fjz2);
809
810             /**************************
811              * CALCULATE INTERACTIONS *
812              **************************/
813
814             /* REACTION-FIELD ELECTROSTATICS */
815             velec            = _mm_mul_ps(qq23,_mm_sub_ps(_mm_macc_ps(krf,rsq23,rinv23),crf));
816             felec            = _mm_mul_ps(qq23,_mm_msub_ps(rinv23,rinvsq23,krf2));
817
818             /* Update potential sum for this i atom from the interaction with this j atom. */
819             velec            = _mm_andnot_ps(dummy_mask,velec);
820             velecsum         = _mm_add_ps(velecsum,velec);
821
822             fscal            = felec;
823
824             fscal            = _mm_andnot_ps(dummy_mask,fscal);
825
826              /* Update vectorial force */
827             fix2             = _mm_macc_ps(dx23,fscal,fix2);
828             fiy2             = _mm_macc_ps(dy23,fscal,fiy2);
829             fiz2             = _mm_macc_ps(dz23,fscal,fiz2);
830
831             fjx3             = _mm_macc_ps(dx23,fscal,fjx3);
832             fjy3             = _mm_macc_ps(dy23,fscal,fjy3);
833             fjz3             = _mm_macc_ps(dz23,fscal,fjz3);
834
835             /**************************
836              * CALCULATE INTERACTIONS *
837              **************************/
838
839             /* REACTION-FIELD ELECTROSTATICS */
840             velec            = _mm_mul_ps(qq31,_mm_sub_ps(_mm_macc_ps(krf,rsq31,rinv31),crf));
841             felec            = _mm_mul_ps(qq31,_mm_msub_ps(rinv31,rinvsq31,krf2));
842
843             /* Update potential sum for this i atom from the interaction with this j atom. */
844             velec            = _mm_andnot_ps(dummy_mask,velec);
845             velecsum         = _mm_add_ps(velecsum,velec);
846
847             fscal            = felec;
848
849             fscal            = _mm_andnot_ps(dummy_mask,fscal);
850
851              /* Update vectorial force */
852             fix3             = _mm_macc_ps(dx31,fscal,fix3);
853             fiy3             = _mm_macc_ps(dy31,fscal,fiy3);
854             fiz3             = _mm_macc_ps(dz31,fscal,fiz3);
855
856             fjx1             = _mm_macc_ps(dx31,fscal,fjx1);
857             fjy1             = _mm_macc_ps(dy31,fscal,fjy1);
858             fjz1             = _mm_macc_ps(dz31,fscal,fjz1);
859
860             /**************************
861              * CALCULATE INTERACTIONS *
862              **************************/
863
864             /* REACTION-FIELD ELECTROSTATICS */
865             velec            = _mm_mul_ps(qq32,_mm_sub_ps(_mm_macc_ps(krf,rsq32,rinv32),crf));
866             felec            = _mm_mul_ps(qq32,_mm_msub_ps(rinv32,rinvsq32,krf2));
867
868             /* Update potential sum for this i atom from the interaction with this j atom. */
869             velec            = _mm_andnot_ps(dummy_mask,velec);
870             velecsum         = _mm_add_ps(velecsum,velec);
871
872             fscal            = felec;
873
874             fscal            = _mm_andnot_ps(dummy_mask,fscal);
875
876              /* Update vectorial force */
877             fix3             = _mm_macc_ps(dx32,fscal,fix3);
878             fiy3             = _mm_macc_ps(dy32,fscal,fiy3);
879             fiz3             = _mm_macc_ps(dz32,fscal,fiz3);
880
881             fjx2             = _mm_macc_ps(dx32,fscal,fjx2);
882             fjy2             = _mm_macc_ps(dy32,fscal,fjy2);
883             fjz2             = _mm_macc_ps(dz32,fscal,fjz2);
884
885             /**************************
886              * CALCULATE INTERACTIONS *
887              **************************/
888
889             /* REACTION-FIELD ELECTROSTATICS */
890             velec            = _mm_mul_ps(qq33,_mm_sub_ps(_mm_macc_ps(krf,rsq33,rinv33),crf));
891             felec            = _mm_mul_ps(qq33,_mm_msub_ps(rinv33,rinvsq33,krf2));
892
893             /* Update potential sum for this i atom from the interaction with this j atom. */
894             velec            = _mm_andnot_ps(dummy_mask,velec);
895             velecsum         = _mm_add_ps(velecsum,velec);
896
897             fscal            = felec;
898
899             fscal            = _mm_andnot_ps(dummy_mask,fscal);
900
901              /* Update vectorial force */
902             fix3             = _mm_macc_ps(dx33,fscal,fix3);
903             fiy3             = _mm_macc_ps(dy33,fscal,fiy3);
904             fiz3             = _mm_macc_ps(dz33,fscal,fiz3);
905
906             fjx3             = _mm_macc_ps(dx33,fscal,fjx3);
907             fjy3             = _mm_macc_ps(dy33,fscal,fjy3);
908             fjz3             = _mm_macc_ps(dz33,fscal,fjz3);
909
910             fjptrA             = (jnrlistA>=0) ? f+j_coord_offsetA : scratch;
911             fjptrB             = (jnrlistB>=0) ? f+j_coord_offsetB : scratch;
912             fjptrC             = (jnrlistC>=0) ? f+j_coord_offsetC : scratch;
913             fjptrD             = (jnrlistD>=0) ? f+j_coord_offsetD : scratch;
914
915             gmx_mm_decrement_4rvec_4ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,
916                                                    fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,
917                                                    fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
918
919             /* Inner loop uses 353 flops */
920         }
921
922         /* End of innermost loop */
923
924         gmx_mm_update_iforce_4atom_swizzle_ps(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
925                                               f+i_coord_offset,fshift+i_shift_offset);
926
927         ggid                        = gid[iidx];
928         /* Update potential energies */
929         gmx_mm_update_1pot_ps(velecsum,kernel_data->energygrp_elec+ggid);
930         gmx_mm_update_1pot_ps(vvdwsum,kernel_data->energygrp_vdw+ggid);
931
932         /* Increment number of inner iterations */
933         inneriter                  += j_index_end - j_index_start;
934
935         /* Outer loop uses 26 flops */
936     }
937
938     /* Increment number of outer iterations */
939     outeriter        += nri;
940
941     /* Update outer/inner flops */
942
943     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_VF,outeriter*26 + inneriter*353);
944 }
945 /*
946  * Gromacs nonbonded kernel:   nb_kernel_ElecRF_VdwLJ_GeomW4W4_F_avx_128_fma_single
947  * Electrostatics interaction: ReactionField
948  * VdW interaction:            LennardJones
949  * Geometry:                   Water4-Water4
950  * Calculate force/pot:        Force
951  */
952 void
953 nb_kernel_ElecRF_VdwLJ_GeomW4W4_F_avx_128_fma_single
954                     (t_nblist                    * gmx_restrict       nlist,
955                      rvec                        * gmx_restrict          xx,
956                      rvec                        * gmx_restrict          ff,
957                      t_forcerec                  * gmx_restrict          fr,
958                      t_mdatoms                   * gmx_restrict     mdatoms,
959                      nb_kernel_data_t gmx_unused * gmx_restrict kernel_data,
960                      t_nrnb                      * gmx_restrict        nrnb)
961 {
962     /* Suffixes 0,1,2,3 refer to particle indices for waters in the inner or outer loop, or
963      * just 0 for non-waters.
964      * Suffixes A,B,C,D refer to j loop unrolling done with AVX_128, e.g. for the four different
965      * jnr indices corresponding to data put in the four positions in the SIMD register.
966      */
967     int              i_shift_offset,i_coord_offset,outeriter,inneriter;
968     int              j_index_start,j_index_end,jidx,nri,inr,ggid,iidx;
969     int              jnrA,jnrB,jnrC,jnrD;
970     int              jnrlistA,jnrlistB,jnrlistC,jnrlistD;
971     int              j_coord_offsetA,j_coord_offsetB,j_coord_offsetC,j_coord_offsetD;
972     int              *iinr,*jindex,*jjnr,*shiftidx,*gid;
973     real             rcutoff_scalar;
974     real             *shiftvec,*fshift,*x,*f;
975     real             *fjptrA,*fjptrB,*fjptrC,*fjptrD;
976     real             scratch[4*DIM];
977     __m128           fscal,rcutoff,rcutoff2,jidxall;
978     int              vdwioffset0;
979     __m128           ix0,iy0,iz0,fix0,fiy0,fiz0,iq0,isai0;
980     int              vdwioffset1;
981     __m128           ix1,iy1,iz1,fix1,fiy1,fiz1,iq1,isai1;
982     int              vdwioffset2;
983     __m128           ix2,iy2,iz2,fix2,fiy2,fiz2,iq2,isai2;
984     int              vdwioffset3;
985     __m128           ix3,iy3,iz3,fix3,fiy3,fiz3,iq3,isai3;
986     int              vdwjidx0A,vdwjidx0B,vdwjidx0C,vdwjidx0D;
987     __m128           jx0,jy0,jz0,fjx0,fjy0,fjz0,jq0,isaj0;
988     int              vdwjidx1A,vdwjidx1B,vdwjidx1C,vdwjidx1D;
989     __m128           jx1,jy1,jz1,fjx1,fjy1,fjz1,jq1,isaj1;
990     int              vdwjidx2A,vdwjidx2B,vdwjidx2C,vdwjidx2D;
991     __m128           jx2,jy2,jz2,fjx2,fjy2,fjz2,jq2,isaj2;
992     int              vdwjidx3A,vdwjidx3B,vdwjidx3C,vdwjidx3D;
993     __m128           jx3,jy3,jz3,fjx3,fjy3,fjz3,jq3,isaj3;
994     __m128           dx00,dy00,dz00,rsq00,rinv00,rinvsq00,r00,qq00,c6_00,c12_00;
995     __m128           dx11,dy11,dz11,rsq11,rinv11,rinvsq11,r11,qq11,c6_11,c12_11;
996     __m128           dx12,dy12,dz12,rsq12,rinv12,rinvsq12,r12,qq12,c6_12,c12_12;
997     __m128           dx13,dy13,dz13,rsq13,rinv13,rinvsq13,r13,qq13,c6_13,c12_13;
998     __m128           dx21,dy21,dz21,rsq21,rinv21,rinvsq21,r21,qq21,c6_21,c12_21;
999     __m128           dx22,dy22,dz22,rsq22,rinv22,rinvsq22,r22,qq22,c6_22,c12_22;
1000     __m128           dx23,dy23,dz23,rsq23,rinv23,rinvsq23,r23,qq23,c6_23,c12_23;
1001     __m128           dx31,dy31,dz31,rsq31,rinv31,rinvsq31,r31,qq31,c6_31,c12_31;
1002     __m128           dx32,dy32,dz32,rsq32,rinv32,rinvsq32,r32,qq32,c6_32,c12_32;
1003     __m128           dx33,dy33,dz33,rsq33,rinv33,rinvsq33,r33,qq33,c6_33,c12_33;
1004     __m128           velec,felec,velecsum,facel,crf,krf,krf2;
1005     real             *charge;
1006     int              nvdwtype;
1007     __m128           rinvsix,rvdw,vvdw,vvdw6,vvdw12,fvdw,fvdw6,fvdw12,vvdwsum,sh_vdw_invrcut6;
1008     int              *vdwtype;
1009     real             *vdwparam;
1010     __m128           one_sixth   = _mm_set1_ps(1.0/6.0);
1011     __m128           one_twelfth = _mm_set1_ps(1.0/12.0);
1012     __m128           dummy_mask,cutoff_mask;
1013     __m128           signbit = _mm_castsi128_ps( _mm_set1_epi32(0x80000000) );
1014     __m128           one     = _mm_set1_ps(1.0);
1015     __m128           two     = _mm_set1_ps(2.0);
1016     x                = xx[0];
1017     f                = ff[0];
1018
1019     nri              = nlist->nri;
1020     iinr             = nlist->iinr;
1021     jindex           = nlist->jindex;
1022     jjnr             = nlist->jjnr;
1023     shiftidx         = nlist->shift;
1024     gid              = nlist->gid;
1025     shiftvec         = fr->shift_vec[0];
1026     fshift           = fr->fshift[0];
1027     facel            = _mm_set1_ps(fr->epsfac);
1028     charge           = mdatoms->chargeA;
1029     krf              = _mm_set1_ps(fr->ic->k_rf);
1030     krf2             = _mm_set1_ps(fr->ic->k_rf*2.0);
1031     crf              = _mm_set1_ps(fr->ic->c_rf);
1032     nvdwtype         = fr->ntype;
1033     vdwparam         = fr->nbfp;
1034     vdwtype          = mdatoms->typeA;
1035
1036     /* Setup water-specific parameters */
1037     inr              = nlist->iinr[0];
1038     iq1              = _mm_mul_ps(facel,_mm_set1_ps(charge[inr+1]));
1039     iq2              = _mm_mul_ps(facel,_mm_set1_ps(charge[inr+2]));
1040     iq3              = _mm_mul_ps(facel,_mm_set1_ps(charge[inr+3]));
1041     vdwioffset0      = 2*nvdwtype*vdwtype[inr+0];
1042
1043     jq1              = _mm_set1_ps(charge[inr+1]);
1044     jq2              = _mm_set1_ps(charge[inr+2]);
1045     jq3              = _mm_set1_ps(charge[inr+3]);
1046     vdwjidx0A        = 2*vdwtype[inr+0];
1047     c6_00            = _mm_set1_ps(vdwparam[vdwioffset0+vdwjidx0A]);
1048     c12_00           = _mm_set1_ps(vdwparam[vdwioffset0+vdwjidx0A+1]);
1049     qq11             = _mm_mul_ps(iq1,jq1);
1050     qq12             = _mm_mul_ps(iq1,jq2);
1051     qq13             = _mm_mul_ps(iq1,jq3);
1052     qq21             = _mm_mul_ps(iq2,jq1);
1053     qq22             = _mm_mul_ps(iq2,jq2);
1054     qq23             = _mm_mul_ps(iq2,jq3);
1055     qq31             = _mm_mul_ps(iq3,jq1);
1056     qq32             = _mm_mul_ps(iq3,jq2);
1057     qq33             = _mm_mul_ps(iq3,jq3);
1058
1059     /* Avoid stupid compiler warnings */
1060     jnrA = jnrB = jnrC = jnrD = 0;
1061     j_coord_offsetA = 0;
1062     j_coord_offsetB = 0;
1063     j_coord_offsetC = 0;
1064     j_coord_offsetD = 0;
1065
1066     outeriter        = 0;
1067     inneriter        = 0;
1068
1069     for(iidx=0;iidx<4*DIM;iidx++)
1070     {
1071         scratch[iidx] = 0.0;
1072     }
1073
1074     /* Start outer loop over neighborlists */
1075     for(iidx=0; iidx<nri; iidx++)
1076     {
1077         /* Load shift vector for this list */
1078         i_shift_offset   = DIM*shiftidx[iidx];
1079
1080         /* Load limits for loop over neighbors */
1081         j_index_start    = jindex[iidx];
1082         j_index_end      = jindex[iidx+1];
1083
1084         /* Get outer coordinate index */
1085         inr              = iinr[iidx];
1086         i_coord_offset   = DIM*inr;
1087
1088         /* Load i particle coords and add shift vector */
1089         gmx_mm_load_shift_and_4rvec_broadcast_ps(shiftvec+i_shift_offset,x+i_coord_offset,
1090                                                  &ix0,&iy0,&iz0,&ix1,&iy1,&iz1,&ix2,&iy2,&iz2,&ix3,&iy3,&iz3);
1091
1092         fix0             = _mm_setzero_ps();
1093         fiy0             = _mm_setzero_ps();
1094         fiz0             = _mm_setzero_ps();
1095         fix1             = _mm_setzero_ps();
1096         fiy1             = _mm_setzero_ps();
1097         fiz1             = _mm_setzero_ps();
1098         fix2             = _mm_setzero_ps();
1099         fiy2             = _mm_setzero_ps();
1100         fiz2             = _mm_setzero_ps();
1101         fix3             = _mm_setzero_ps();
1102         fiy3             = _mm_setzero_ps();
1103         fiz3             = _mm_setzero_ps();
1104
1105         /* Start inner kernel loop */
1106         for(jidx=j_index_start; jidx<j_index_end && jjnr[jidx+3]>=0; jidx+=4)
1107         {
1108
1109             /* Get j neighbor index, and coordinate index */
1110             jnrA             = jjnr[jidx];
1111             jnrB             = jjnr[jidx+1];
1112             jnrC             = jjnr[jidx+2];
1113             jnrD             = jjnr[jidx+3];
1114             j_coord_offsetA  = DIM*jnrA;
1115             j_coord_offsetB  = DIM*jnrB;
1116             j_coord_offsetC  = DIM*jnrC;
1117             j_coord_offsetD  = DIM*jnrD;
1118
1119             /* load j atom coordinates */
1120             gmx_mm_load_4rvec_4ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
1121                                               x+j_coord_offsetC,x+j_coord_offsetD,
1122                                               &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
1123                                               &jy2,&jz2,&jx3,&jy3,&jz3);
1124
1125             /* Calculate displacement vector */
1126             dx00             = _mm_sub_ps(ix0,jx0);
1127             dy00             = _mm_sub_ps(iy0,jy0);
1128             dz00             = _mm_sub_ps(iz0,jz0);
1129             dx11             = _mm_sub_ps(ix1,jx1);
1130             dy11             = _mm_sub_ps(iy1,jy1);
1131             dz11             = _mm_sub_ps(iz1,jz1);
1132             dx12             = _mm_sub_ps(ix1,jx2);
1133             dy12             = _mm_sub_ps(iy1,jy2);
1134             dz12             = _mm_sub_ps(iz1,jz2);
1135             dx13             = _mm_sub_ps(ix1,jx3);
1136             dy13             = _mm_sub_ps(iy1,jy3);
1137             dz13             = _mm_sub_ps(iz1,jz3);
1138             dx21             = _mm_sub_ps(ix2,jx1);
1139             dy21             = _mm_sub_ps(iy2,jy1);
1140             dz21             = _mm_sub_ps(iz2,jz1);
1141             dx22             = _mm_sub_ps(ix2,jx2);
1142             dy22             = _mm_sub_ps(iy2,jy2);
1143             dz22             = _mm_sub_ps(iz2,jz2);
1144             dx23             = _mm_sub_ps(ix2,jx3);
1145             dy23             = _mm_sub_ps(iy2,jy3);
1146             dz23             = _mm_sub_ps(iz2,jz3);
1147             dx31             = _mm_sub_ps(ix3,jx1);
1148             dy31             = _mm_sub_ps(iy3,jy1);
1149             dz31             = _mm_sub_ps(iz3,jz1);
1150             dx32             = _mm_sub_ps(ix3,jx2);
1151             dy32             = _mm_sub_ps(iy3,jy2);
1152             dz32             = _mm_sub_ps(iz3,jz2);
1153             dx33             = _mm_sub_ps(ix3,jx3);
1154             dy33             = _mm_sub_ps(iy3,jy3);
1155             dz33             = _mm_sub_ps(iz3,jz3);
1156
1157             /* Calculate squared distance and things based on it */
1158             rsq00            = gmx_mm_calc_rsq_ps(dx00,dy00,dz00);
1159             rsq11            = gmx_mm_calc_rsq_ps(dx11,dy11,dz11);
1160             rsq12            = gmx_mm_calc_rsq_ps(dx12,dy12,dz12);
1161             rsq13            = gmx_mm_calc_rsq_ps(dx13,dy13,dz13);
1162             rsq21            = gmx_mm_calc_rsq_ps(dx21,dy21,dz21);
1163             rsq22            = gmx_mm_calc_rsq_ps(dx22,dy22,dz22);
1164             rsq23            = gmx_mm_calc_rsq_ps(dx23,dy23,dz23);
1165             rsq31            = gmx_mm_calc_rsq_ps(dx31,dy31,dz31);
1166             rsq32            = gmx_mm_calc_rsq_ps(dx32,dy32,dz32);
1167             rsq33            = gmx_mm_calc_rsq_ps(dx33,dy33,dz33);
1168
1169             rinv11           = gmx_mm_invsqrt_ps(rsq11);
1170             rinv12           = gmx_mm_invsqrt_ps(rsq12);
1171             rinv13           = gmx_mm_invsqrt_ps(rsq13);
1172             rinv21           = gmx_mm_invsqrt_ps(rsq21);
1173             rinv22           = gmx_mm_invsqrt_ps(rsq22);
1174             rinv23           = gmx_mm_invsqrt_ps(rsq23);
1175             rinv31           = gmx_mm_invsqrt_ps(rsq31);
1176             rinv32           = gmx_mm_invsqrt_ps(rsq32);
1177             rinv33           = gmx_mm_invsqrt_ps(rsq33);
1178
1179             rinvsq00         = gmx_mm_inv_ps(rsq00);
1180             rinvsq11         = _mm_mul_ps(rinv11,rinv11);
1181             rinvsq12         = _mm_mul_ps(rinv12,rinv12);
1182             rinvsq13         = _mm_mul_ps(rinv13,rinv13);
1183             rinvsq21         = _mm_mul_ps(rinv21,rinv21);
1184             rinvsq22         = _mm_mul_ps(rinv22,rinv22);
1185             rinvsq23         = _mm_mul_ps(rinv23,rinv23);
1186             rinvsq31         = _mm_mul_ps(rinv31,rinv31);
1187             rinvsq32         = _mm_mul_ps(rinv32,rinv32);
1188             rinvsq33         = _mm_mul_ps(rinv33,rinv33);
1189
1190             fjx0             = _mm_setzero_ps();
1191             fjy0             = _mm_setzero_ps();
1192             fjz0             = _mm_setzero_ps();
1193             fjx1             = _mm_setzero_ps();
1194             fjy1             = _mm_setzero_ps();
1195             fjz1             = _mm_setzero_ps();
1196             fjx2             = _mm_setzero_ps();
1197             fjy2             = _mm_setzero_ps();
1198             fjz2             = _mm_setzero_ps();
1199             fjx3             = _mm_setzero_ps();
1200             fjy3             = _mm_setzero_ps();
1201             fjz3             = _mm_setzero_ps();
1202
1203             /**************************
1204              * CALCULATE INTERACTIONS *
1205              **************************/
1206
1207             /* LENNARD-JONES DISPERSION/REPULSION */
1208
1209             rinvsix          = _mm_mul_ps(_mm_mul_ps(rinvsq00,rinvsq00),rinvsq00);
1210             fvdw             = _mm_mul_ps(_mm_msub_ps(c12_00,rinvsix,c6_00),_mm_mul_ps(rinvsix,rinvsq00));
1211
1212             fscal            = fvdw;
1213
1214              /* Update vectorial force */
1215             fix0             = _mm_macc_ps(dx00,fscal,fix0);
1216             fiy0             = _mm_macc_ps(dy00,fscal,fiy0);
1217             fiz0             = _mm_macc_ps(dz00,fscal,fiz0);
1218
1219             fjx0             = _mm_macc_ps(dx00,fscal,fjx0);
1220             fjy0             = _mm_macc_ps(dy00,fscal,fjy0);
1221             fjz0             = _mm_macc_ps(dz00,fscal,fjz0);
1222
1223             /**************************
1224              * CALCULATE INTERACTIONS *
1225              **************************/
1226
1227             /* REACTION-FIELD ELECTROSTATICS */
1228             felec            = _mm_mul_ps(qq11,_mm_msub_ps(rinv11,rinvsq11,krf2));
1229
1230             fscal            = felec;
1231
1232              /* Update vectorial force */
1233             fix1             = _mm_macc_ps(dx11,fscal,fix1);
1234             fiy1             = _mm_macc_ps(dy11,fscal,fiy1);
1235             fiz1             = _mm_macc_ps(dz11,fscal,fiz1);
1236
1237             fjx1             = _mm_macc_ps(dx11,fscal,fjx1);
1238             fjy1             = _mm_macc_ps(dy11,fscal,fjy1);
1239             fjz1             = _mm_macc_ps(dz11,fscal,fjz1);
1240
1241             /**************************
1242              * CALCULATE INTERACTIONS *
1243              **************************/
1244
1245             /* REACTION-FIELD ELECTROSTATICS */
1246             felec            = _mm_mul_ps(qq12,_mm_msub_ps(rinv12,rinvsq12,krf2));
1247
1248             fscal            = felec;
1249
1250              /* Update vectorial force */
1251             fix1             = _mm_macc_ps(dx12,fscal,fix1);
1252             fiy1             = _mm_macc_ps(dy12,fscal,fiy1);
1253             fiz1             = _mm_macc_ps(dz12,fscal,fiz1);
1254
1255             fjx2             = _mm_macc_ps(dx12,fscal,fjx2);
1256             fjy2             = _mm_macc_ps(dy12,fscal,fjy2);
1257             fjz2             = _mm_macc_ps(dz12,fscal,fjz2);
1258
1259             /**************************
1260              * CALCULATE INTERACTIONS *
1261              **************************/
1262
1263             /* REACTION-FIELD ELECTROSTATICS */
1264             felec            = _mm_mul_ps(qq13,_mm_msub_ps(rinv13,rinvsq13,krf2));
1265
1266             fscal            = felec;
1267
1268              /* Update vectorial force */
1269             fix1             = _mm_macc_ps(dx13,fscal,fix1);
1270             fiy1             = _mm_macc_ps(dy13,fscal,fiy1);
1271             fiz1             = _mm_macc_ps(dz13,fscal,fiz1);
1272
1273             fjx3             = _mm_macc_ps(dx13,fscal,fjx3);
1274             fjy3             = _mm_macc_ps(dy13,fscal,fjy3);
1275             fjz3             = _mm_macc_ps(dz13,fscal,fjz3);
1276
1277             /**************************
1278              * CALCULATE INTERACTIONS *
1279              **************************/
1280
1281             /* REACTION-FIELD ELECTROSTATICS */
1282             felec            = _mm_mul_ps(qq21,_mm_msub_ps(rinv21,rinvsq21,krf2));
1283
1284             fscal            = felec;
1285
1286              /* Update vectorial force */
1287             fix2             = _mm_macc_ps(dx21,fscal,fix2);
1288             fiy2             = _mm_macc_ps(dy21,fscal,fiy2);
1289             fiz2             = _mm_macc_ps(dz21,fscal,fiz2);
1290
1291             fjx1             = _mm_macc_ps(dx21,fscal,fjx1);
1292             fjy1             = _mm_macc_ps(dy21,fscal,fjy1);
1293             fjz1             = _mm_macc_ps(dz21,fscal,fjz1);
1294
1295             /**************************
1296              * CALCULATE INTERACTIONS *
1297              **************************/
1298
1299             /* REACTION-FIELD ELECTROSTATICS */
1300             felec            = _mm_mul_ps(qq22,_mm_msub_ps(rinv22,rinvsq22,krf2));
1301
1302             fscal            = felec;
1303
1304              /* Update vectorial force */
1305             fix2             = _mm_macc_ps(dx22,fscal,fix2);
1306             fiy2             = _mm_macc_ps(dy22,fscal,fiy2);
1307             fiz2             = _mm_macc_ps(dz22,fscal,fiz2);
1308
1309             fjx2             = _mm_macc_ps(dx22,fscal,fjx2);
1310             fjy2             = _mm_macc_ps(dy22,fscal,fjy2);
1311             fjz2             = _mm_macc_ps(dz22,fscal,fjz2);
1312
1313             /**************************
1314              * CALCULATE INTERACTIONS *
1315              **************************/
1316
1317             /* REACTION-FIELD ELECTROSTATICS */
1318             felec            = _mm_mul_ps(qq23,_mm_msub_ps(rinv23,rinvsq23,krf2));
1319
1320             fscal            = felec;
1321
1322              /* Update vectorial force */
1323             fix2             = _mm_macc_ps(dx23,fscal,fix2);
1324             fiy2             = _mm_macc_ps(dy23,fscal,fiy2);
1325             fiz2             = _mm_macc_ps(dz23,fscal,fiz2);
1326
1327             fjx3             = _mm_macc_ps(dx23,fscal,fjx3);
1328             fjy3             = _mm_macc_ps(dy23,fscal,fjy3);
1329             fjz3             = _mm_macc_ps(dz23,fscal,fjz3);
1330
1331             /**************************
1332              * CALCULATE INTERACTIONS *
1333              **************************/
1334
1335             /* REACTION-FIELD ELECTROSTATICS */
1336             felec            = _mm_mul_ps(qq31,_mm_msub_ps(rinv31,rinvsq31,krf2));
1337
1338             fscal            = felec;
1339
1340              /* Update vectorial force */
1341             fix3             = _mm_macc_ps(dx31,fscal,fix3);
1342             fiy3             = _mm_macc_ps(dy31,fscal,fiy3);
1343             fiz3             = _mm_macc_ps(dz31,fscal,fiz3);
1344
1345             fjx1             = _mm_macc_ps(dx31,fscal,fjx1);
1346             fjy1             = _mm_macc_ps(dy31,fscal,fjy1);
1347             fjz1             = _mm_macc_ps(dz31,fscal,fjz1);
1348
1349             /**************************
1350              * CALCULATE INTERACTIONS *
1351              **************************/
1352
1353             /* REACTION-FIELD ELECTROSTATICS */
1354             felec            = _mm_mul_ps(qq32,_mm_msub_ps(rinv32,rinvsq32,krf2));
1355
1356             fscal            = felec;
1357
1358              /* Update vectorial force */
1359             fix3             = _mm_macc_ps(dx32,fscal,fix3);
1360             fiy3             = _mm_macc_ps(dy32,fscal,fiy3);
1361             fiz3             = _mm_macc_ps(dz32,fscal,fiz3);
1362
1363             fjx2             = _mm_macc_ps(dx32,fscal,fjx2);
1364             fjy2             = _mm_macc_ps(dy32,fscal,fjy2);
1365             fjz2             = _mm_macc_ps(dz32,fscal,fjz2);
1366
1367             /**************************
1368              * CALCULATE INTERACTIONS *
1369              **************************/
1370
1371             /* REACTION-FIELD ELECTROSTATICS */
1372             felec            = _mm_mul_ps(qq33,_mm_msub_ps(rinv33,rinvsq33,krf2));
1373
1374             fscal            = felec;
1375
1376              /* Update vectorial force */
1377             fix3             = _mm_macc_ps(dx33,fscal,fix3);
1378             fiy3             = _mm_macc_ps(dy33,fscal,fiy3);
1379             fiz3             = _mm_macc_ps(dz33,fscal,fiz3);
1380
1381             fjx3             = _mm_macc_ps(dx33,fscal,fjx3);
1382             fjy3             = _mm_macc_ps(dy33,fscal,fjy3);
1383             fjz3             = _mm_macc_ps(dz33,fscal,fjz3);
1384
1385             fjptrA             = f+j_coord_offsetA;
1386             fjptrB             = f+j_coord_offsetB;
1387             fjptrC             = f+j_coord_offsetC;
1388             fjptrD             = f+j_coord_offsetD;
1389
1390             gmx_mm_decrement_4rvec_4ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,
1391                                                    fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,
1392                                                    fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
1393
1394             /* Inner loop uses 303 flops */
1395         }
1396
1397         if(jidx<j_index_end)
1398         {
1399
1400             /* Get j neighbor index, and coordinate index */
1401             jnrlistA         = jjnr[jidx];
1402             jnrlistB         = jjnr[jidx+1];
1403             jnrlistC         = jjnr[jidx+2];
1404             jnrlistD         = jjnr[jidx+3];
1405             /* Sign of each element will be negative for non-real atoms.
1406              * This mask will be 0xFFFFFFFF for dummy entries and 0x0 for real ones,
1407              * so use it as val = _mm_andnot_ps(mask,val) to clear dummy entries.
1408              */
1409             dummy_mask = gmx_mm_castsi128_ps(_mm_cmplt_epi32(_mm_loadu_si128((const __m128i *)(jjnr+jidx)),_mm_setzero_si128()));
1410             jnrA       = (jnrlistA>=0) ? jnrlistA : 0;
1411             jnrB       = (jnrlistB>=0) ? jnrlistB : 0;
1412             jnrC       = (jnrlistC>=0) ? jnrlistC : 0;
1413             jnrD       = (jnrlistD>=0) ? jnrlistD : 0;
1414             j_coord_offsetA  = DIM*jnrA;
1415             j_coord_offsetB  = DIM*jnrB;
1416             j_coord_offsetC  = DIM*jnrC;
1417             j_coord_offsetD  = DIM*jnrD;
1418
1419             /* load j atom coordinates */
1420             gmx_mm_load_4rvec_4ptr_swizzle_ps(x+j_coord_offsetA,x+j_coord_offsetB,
1421                                               x+j_coord_offsetC,x+j_coord_offsetD,
1422                                               &jx0,&jy0,&jz0,&jx1,&jy1,&jz1,&jx2,
1423                                               &jy2,&jz2,&jx3,&jy3,&jz3);
1424
1425             /* Calculate displacement vector */
1426             dx00             = _mm_sub_ps(ix0,jx0);
1427             dy00             = _mm_sub_ps(iy0,jy0);
1428             dz00             = _mm_sub_ps(iz0,jz0);
1429             dx11             = _mm_sub_ps(ix1,jx1);
1430             dy11             = _mm_sub_ps(iy1,jy1);
1431             dz11             = _mm_sub_ps(iz1,jz1);
1432             dx12             = _mm_sub_ps(ix1,jx2);
1433             dy12             = _mm_sub_ps(iy1,jy2);
1434             dz12             = _mm_sub_ps(iz1,jz2);
1435             dx13             = _mm_sub_ps(ix1,jx3);
1436             dy13             = _mm_sub_ps(iy1,jy3);
1437             dz13             = _mm_sub_ps(iz1,jz3);
1438             dx21             = _mm_sub_ps(ix2,jx1);
1439             dy21             = _mm_sub_ps(iy2,jy1);
1440             dz21             = _mm_sub_ps(iz2,jz1);
1441             dx22             = _mm_sub_ps(ix2,jx2);
1442             dy22             = _mm_sub_ps(iy2,jy2);
1443             dz22             = _mm_sub_ps(iz2,jz2);
1444             dx23             = _mm_sub_ps(ix2,jx3);
1445             dy23             = _mm_sub_ps(iy2,jy3);
1446             dz23             = _mm_sub_ps(iz2,jz3);
1447             dx31             = _mm_sub_ps(ix3,jx1);
1448             dy31             = _mm_sub_ps(iy3,jy1);
1449             dz31             = _mm_sub_ps(iz3,jz1);
1450             dx32             = _mm_sub_ps(ix3,jx2);
1451             dy32             = _mm_sub_ps(iy3,jy2);
1452             dz32             = _mm_sub_ps(iz3,jz2);
1453             dx33             = _mm_sub_ps(ix3,jx3);
1454             dy33             = _mm_sub_ps(iy3,jy3);
1455             dz33             = _mm_sub_ps(iz3,jz3);
1456
1457             /* Calculate squared distance and things based on it */
1458             rsq00            = gmx_mm_calc_rsq_ps(dx00,dy00,dz00);
1459             rsq11            = gmx_mm_calc_rsq_ps(dx11,dy11,dz11);
1460             rsq12            = gmx_mm_calc_rsq_ps(dx12,dy12,dz12);
1461             rsq13            = gmx_mm_calc_rsq_ps(dx13,dy13,dz13);
1462             rsq21            = gmx_mm_calc_rsq_ps(dx21,dy21,dz21);
1463             rsq22            = gmx_mm_calc_rsq_ps(dx22,dy22,dz22);
1464             rsq23            = gmx_mm_calc_rsq_ps(dx23,dy23,dz23);
1465             rsq31            = gmx_mm_calc_rsq_ps(dx31,dy31,dz31);
1466             rsq32            = gmx_mm_calc_rsq_ps(dx32,dy32,dz32);
1467             rsq33            = gmx_mm_calc_rsq_ps(dx33,dy33,dz33);
1468
1469             rinv11           = gmx_mm_invsqrt_ps(rsq11);
1470             rinv12           = gmx_mm_invsqrt_ps(rsq12);
1471             rinv13           = gmx_mm_invsqrt_ps(rsq13);
1472             rinv21           = gmx_mm_invsqrt_ps(rsq21);
1473             rinv22           = gmx_mm_invsqrt_ps(rsq22);
1474             rinv23           = gmx_mm_invsqrt_ps(rsq23);
1475             rinv31           = gmx_mm_invsqrt_ps(rsq31);
1476             rinv32           = gmx_mm_invsqrt_ps(rsq32);
1477             rinv33           = gmx_mm_invsqrt_ps(rsq33);
1478
1479             rinvsq00         = gmx_mm_inv_ps(rsq00);
1480             rinvsq11         = _mm_mul_ps(rinv11,rinv11);
1481             rinvsq12         = _mm_mul_ps(rinv12,rinv12);
1482             rinvsq13         = _mm_mul_ps(rinv13,rinv13);
1483             rinvsq21         = _mm_mul_ps(rinv21,rinv21);
1484             rinvsq22         = _mm_mul_ps(rinv22,rinv22);
1485             rinvsq23         = _mm_mul_ps(rinv23,rinv23);
1486             rinvsq31         = _mm_mul_ps(rinv31,rinv31);
1487             rinvsq32         = _mm_mul_ps(rinv32,rinv32);
1488             rinvsq33         = _mm_mul_ps(rinv33,rinv33);
1489
1490             fjx0             = _mm_setzero_ps();
1491             fjy0             = _mm_setzero_ps();
1492             fjz0             = _mm_setzero_ps();
1493             fjx1             = _mm_setzero_ps();
1494             fjy1             = _mm_setzero_ps();
1495             fjz1             = _mm_setzero_ps();
1496             fjx2             = _mm_setzero_ps();
1497             fjy2             = _mm_setzero_ps();
1498             fjz2             = _mm_setzero_ps();
1499             fjx3             = _mm_setzero_ps();
1500             fjy3             = _mm_setzero_ps();
1501             fjz3             = _mm_setzero_ps();
1502
1503             /**************************
1504              * CALCULATE INTERACTIONS *
1505              **************************/
1506
1507             /* LENNARD-JONES DISPERSION/REPULSION */
1508
1509             rinvsix          = _mm_mul_ps(_mm_mul_ps(rinvsq00,rinvsq00),rinvsq00);
1510             fvdw             = _mm_mul_ps(_mm_msub_ps(c12_00,rinvsix,c6_00),_mm_mul_ps(rinvsix,rinvsq00));
1511
1512             fscal            = fvdw;
1513
1514             fscal            = _mm_andnot_ps(dummy_mask,fscal);
1515
1516              /* Update vectorial force */
1517             fix0             = _mm_macc_ps(dx00,fscal,fix0);
1518             fiy0             = _mm_macc_ps(dy00,fscal,fiy0);
1519             fiz0             = _mm_macc_ps(dz00,fscal,fiz0);
1520
1521             fjx0             = _mm_macc_ps(dx00,fscal,fjx0);
1522             fjy0             = _mm_macc_ps(dy00,fscal,fjy0);
1523             fjz0             = _mm_macc_ps(dz00,fscal,fjz0);
1524
1525             /**************************
1526              * CALCULATE INTERACTIONS *
1527              **************************/
1528
1529             /* REACTION-FIELD ELECTROSTATICS */
1530             felec            = _mm_mul_ps(qq11,_mm_msub_ps(rinv11,rinvsq11,krf2));
1531
1532             fscal            = felec;
1533
1534             fscal            = _mm_andnot_ps(dummy_mask,fscal);
1535
1536              /* Update vectorial force */
1537             fix1             = _mm_macc_ps(dx11,fscal,fix1);
1538             fiy1             = _mm_macc_ps(dy11,fscal,fiy1);
1539             fiz1             = _mm_macc_ps(dz11,fscal,fiz1);
1540
1541             fjx1             = _mm_macc_ps(dx11,fscal,fjx1);
1542             fjy1             = _mm_macc_ps(dy11,fscal,fjy1);
1543             fjz1             = _mm_macc_ps(dz11,fscal,fjz1);
1544
1545             /**************************
1546              * CALCULATE INTERACTIONS *
1547              **************************/
1548
1549             /* REACTION-FIELD ELECTROSTATICS */
1550             felec            = _mm_mul_ps(qq12,_mm_msub_ps(rinv12,rinvsq12,krf2));
1551
1552             fscal            = felec;
1553
1554             fscal            = _mm_andnot_ps(dummy_mask,fscal);
1555
1556              /* Update vectorial force */
1557             fix1             = _mm_macc_ps(dx12,fscal,fix1);
1558             fiy1             = _mm_macc_ps(dy12,fscal,fiy1);
1559             fiz1             = _mm_macc_ps(dz12,fscal,fiz1);
1560
1561             fjx2             = _mm_macc_ps(dx12,fscal,fjx2);
1562             fjy2             = _mm_macc_ps(dy12,fscal,fjy2);
1563             fjz2             = _mm_macc_ps(dz12,fscal,fjz2);
1564
1565             /**************************
1566              * CALCULATE INTERACTIONS *
1567              **************************/
1568
1569             /* REACTION-FIELD ELECTROSTATICS */
1570             felec            = _mm_mul_ps(qq13,_mm_msub_ps(rinv13,rinvsq13,krf2));
1571
1572             fscal            = felec;
1573
1574             fscal            = _mm_andnot_ps(dummy_mask,fscal);
1575
1576              /* Update vectorial force */
1577             fix1             = _mm_macc_ps(dx13,fscal,fix1);
1578             fiy1             = _mm_macc_ps(dy13,fscal,fiy1);
1579             fiz1             = _mm_macc_ps(dz13,fscal,fiz1);
1580
1581             fjx3             = _mm_macc_ps(dx13,fscal,fjx3);
1582             fjy3             = _mm_macc_ps(dy13,fscal,fjy3);
1583             fjz3             = _mm_macc_ps(dz13,fscal,fjz3);
1584
1585             /**************************
1586              * CALCULATE INTERACTIONS *
1587              **************************/
1588
1589             /* REACTION-FIELD ELECTROSTATICS */
1590             felec            = _mm_mul_ps(qq21,_mm_msub_ps(rinv21,rinvsq21,krf2));
1591
1592             fscal            = felec;
1593
1594             fscal            = _mm_andnot_ps(dummy_mask,fscal);
1595
1596              /* Update vectorial force */
1597             fix2             = _mm_macc_ps(dx21,fscal,fix2);
1598             fiy2             = _mm_macc_ps(dy21,fscal,fiy2);
1599             fiz2             = _mm_macc_ps(dz21,fscal,fiz2);
1600
1601             fjx1             = _mm_macc_ps(dx21,fscal,fjx1);
1602             fjy1             = _mm_macc_ps(dy21,fscal,fjy1);
1603             fjz1             = _mm_macc_ps(dz21,fscal,fjz1);
1604
1605             /**************************
1606              * CALCULATE INTERACTIONS *
1607              **************************/
1608
1609             /* REACTION-FIELD ELECTROSTATICS */
1610             felec            = _mm_mul_ps(qq22,_mm_msub_ps(rinv22,rinvsq22,krf2));
1611
1612             fscal            = felec;
1613
1614             fscal            = _mm_andnot_ps(dummy_mask,fscal);
1615
1616              /* Update vectorial force */
1617             fix2             = _mm_macc_ps(dx22,fscal,fix2);
1618             fiy2             = _mm_macc_ps(dy22,fscal,fiy2);
1619             fiz2             = _mm_macc_ps(dz22,fscal,fiz2);
1620
1621             fjx2             = _mm_macc_ps(dx22,fscal,fjx2);
1622             fjy2             = _mm_macc_ps(dy22,fscal,fjy2);
1623             fjz2             = _mm_macc_ps(dz22,fscal,fjz2);
1624
1625             /**************************
1626              * CALCULATE INTERACTIONS *
1627              **************************/
1628
1629             /* REACTION-FIELD ELECTROSTATICS */
1630             felec            = _mm_mul_ps(qq23,_mm_msub_ps(rinv23,rinvsq23,krf2));
1631
1632             fscal            = felec;
1633
1634             fscal            = _mm_andnot_ps(dummy_mask,fscal);
1635
1636              /* Update vectorial force */
1637             fix2             = _mm_macc_ps(dx23,fscal,fix2);
1638             fiy2             = _mm_macc_ps(dy23,fscal,fiy2);
1639             fiz2             = _mm_macc_ps(dz23,fscal,fiz2);
1640
1641             fjx3             = _mm_macc_ps(dx23,fscal,fjx3);
1642             fjy3             = _mm_macc_ps(dy23,fscal,fjy3);
1643             fjz3             = _mm_macc_ps(dz23,fscal,fjz3);
1644
1645             /**************************
1646              * CALCULATE INTERACTIONS *
1647              **************************/
1648
1649             /* REACTION-FIELD ELECTROSTATICS */
1650             felec            = _mm_mul_ps(qq31,_mm_msub_ps(rinv31,rinvsq31,krf2));
1651
1652             fscal            = felec;
1653
1654             fscal            = _mm_andnot_ps(dummy_mask,fscal);
1655
1656              /* Update vectorial force */
1657             fix3             = _mm_macc_ps(dx31,fscal,fix3);
1658             fiy3             = _mm_macc_ps(dy31,fscal,fiy3);
1659             fiz3             = _mm_macc_ps(dz31,fscal,fiz3);
1660
1661             fjx1             = _mm_macc_ps(dx31,fscal,fjx1);
1662             fjy1             = _mm_macc_ps(dy31,fscal,fjy1);
1663             fjz1             = _mm_macc_ps(dz31,fscal,fjz1);
1664
1665             /**************************
1666              * CALCULATE INTERACTIONS *
1667              **************************/
1668
1669             /* REACTION-FIELD ELECTROSTATICS */
1670             felec            = _mm_mul_ps(qq32,_mm_msub_ps(rinv32,rinvsq32,krf2));
1671
1672             fscal            = felec;
1673
1674             fscal            = _mm_andnot_ps(dummy_mask,fscal);
1675
1676              /* Update vectorial force */
1677             fix3             = _mm_macc_ps(dx32,fscal,fix3);
1678             fiy3             = _mm_macc_ps(dy32,fscal,fiy3);
1679             fiz3             = _mm_macc_ps(dz32,fscal,fiz3);
1680
1681             fjx2             = _mm_macc_ps(dx32,fscal,fjx2);
1682             fjy2             = _mm_macc_ps(dy32,fscal,fjy2);
1683             fjz2             = _mm_macc_ps(dz32,fscal,fjz2);
1684
1685             /**************************
1686              * CALCULATE INTERACTIONS *
1687              **************************/
1688
1689             /* REACTION-FIELD ELECTROSTATICS */
1690             felec            = _mm_mul_ps(qq33,_mm_msub_ps(rinv33,rinvsq33,krf2));
1691
1692             fscal            = felec;
1693
1694             fscal            = _mm_andnot_ps(dummy_mask,fscal);
1695
1696              /* Update vectorial force */
1697             fix3             = _mm_macc_ps(dx33,fscal,fix3);
1698             fiy3             = _mm_macc_ps(dy33,fscal,fiy3);
1699             fiz3             = _mm_macc_ps(dz33,fscal,fiz3);
1700
1701             fjx3             = _mm_macc_ps(dx33,fscal,fjx3);
1702             fjy3             = _mm_macc_ps(dy33,fscal,fjy3);
1703             fjz3             = _mm_macc_ps(dz33,fscal,fjz3);
1704
1705             fjptrA             = (jnrlistA>=0) ? f+j_coord_offsetA : scratch;
1706             fjptrB             = (jnrlistB>=0) ? f+j_coord_offsetB : scratch;
1707             fjptrC             = (jnrlistC>=0) ? f+j_coord_offsetC : scratch;
1708             fjptrD             = (jnrlistD>=0) ? f+j_coord_offsetD : scratch;
1709
1710             gmx_mm_decrement_4rvec_4ptr_swizzle_ps(fjptrA,fjptrB,fjptrC,fjptrD,
1711                                                    fjx0,fjy0,fjz0,fjx1,fjy1,fjz1,
1712                                                    fjx2,fjy2,fjz2,fjx3,fjy3,fjz3);
1713
1714             /* Inner loop uses 303 flops */
1715         }
1716
1717         /* End of innermost loop */
1718
1719         gmx_mm_update_iforce_4atom_swizzle_ps(fix0,fiy0,fiz0,fix1,fiy1,fiz1,fix2,fiy2,fiz2,fix3,fiy3,fiz3,
1720                                               f+i_coord_offset,fshift+i_shift_offset);
1721
1722         /* Increment number of inner iterations */
1723         inneriter                  += j_index_end - j_index_start;
1724
1725         /* Outer loop uses 24 flops */
1726     }
1727
1728     /* Increment number of outer iterations */
1729     outeriter        += nri;
1730
1731     /* Update outer/inner flops */
1732
1733     inc_nrnb(nrnb,eNR_NBKERNEL_ELEC_VDW_W4W4_F,outeriter*24 + inneriter*303);
1734 }