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