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